View Source Options for Rule Sets

General Structure

A Rule Set has the following structure:

Rule Set
├── Status Name 1
│   ├── ignore # optional
│   ├── as_string # optional, defaults to false
│   ├── Option 1
│   ├── Option 2
│   └── Option 3
└── Status Name 2
    ├── Option A
    └── Option B
  1. The Status Name is your referral or id for tracking and adding values. Example: temperature or battery_voltage.
  2. An Option could be something like cold, warm, low, critical. A Status can transition between it's options.
  3. If you wish to ignore values, you may set this up as well. If an ignored value is received, it is treated as if it was never received.

Defining Constraints Options

Available constraints

The basic constraints are:

  • min: minimum, including. For numeric values and durations.
  • max: maximum, including. For numeric values and durations.
  • lt: less than. For numeric values and durations.
  • gt: greater than. For numeric values and durations.
  • is: a value or list of values
  • not: a value or list of values
  • contains: a String to be used on String-inputs
  • matches: a regex expression or list of regex expressions (match any -> valid) to be used on String inputs.

Specific constraints are

  • n_of_m: only for constraints.count. Can not be mixed with other constraints. This allows to set a constraint where n in the last m messages need to fullfil the value constraints.

Constraints structure

You may define rules for each option to define when a transition to this option should occur.

Option
├── value
│   └── min, max, is, not, lt, gt, contains, matches
└── constraints
    ├── duration
    │   └── min, max, is, not, lt, gt
    ├── previous_status
    │   └──  is, not
    └── count
        └── n_of_m OR min, max, is, not, lt, gt

How constraints are evaluated

For each Option, the constraints for value are evaluated first. If the check fails, the option is excluded from any further checks.

If the value constraints are fulfilled, Statux will update its internal state to remember that the value passed the checks and is considered valid. It will then continue to check the other constraints to see if a transition should happen or is blocked by count, duration or previous_status constraints.

Returning custom option identifiers

Be default, each option is identified as its atom representation, so for a Rule Set like

```none
{ "temperature": {
  "ignore": {"value": {"is": null}},
  "status": {
    "warm": {"value": {"min": 21.0}},
    "cold": {"value": {"max": 18.5}}
}}}
```

the options of status :temperature would be :warm or :cold. However, you may adjust this by adding a "return_as" statement to the JSON:

```none
{ "temperature": {
  "ignore": {"value": {"is": null}},
  "status": {
    "warm": {"value": {"min": 21.0}, "return_as": "Is is me, or is it getting hot in here?"},
    "cold": {"value": {"max": 18.5}, "return_as": "Ice ice baby"}
}}}
```

Now, instead of :warm, the value would be "Is is me, or is it getting hot in here?".

Examples for Constraints

  1. Check wether a value is in the range of 10 and 20 for at least 5 consecutive messages:

     "option" {
       "value": {"min": 10, "max": 20},
       "constraints": {"count": {"min": 5}}
     }
  2. Check wether a value has been in the range of 10 and 20 at least of 3 of 5 messages in the last 10 minutes:

     "option" {
       "value": {"min": 10, "max": 20},
       "constraints": {"count": {"n_of_m": [3, 5]}, "duration": {"min": "PT10M"}}
     }

    Durations may be given as ISO8601 Durations or as a numeric value in seconds.

    The duration is only evaluated when a message is received! It does not automatically transition after a given time.

  3. Check for specific values or exclude specific values.

    Valid only if the value is exactly "hello world"

     "option" {
       "value": {"is": "hello world"},
     }

    Valid if the value contains "hello" but is not "hello world" or "hello you".

     "option" {
       "value": {"contains": "hello", "not": ["hello world", "hello you"]},
     }

Examples Rule Set

Rule Set to track car battery voltages with.

{
  "battery_voltage": {
    "ignore": {"value": {"is": null}},
    "status": {
      "critical": {
        "value": {"lt": 11.7},
        "constraints": {
          "count": {"min": 3},
          "duration": {"min": "PT10M"}
        },
      },
      "low": {
        "value": {"lt": 12.0, "min": 11.7},
        "constraints": {
          "count": {"min": 3},
          "duration": {"min": 300},
          "previous_status": {"not": "critical"}
        },
      },
      "ok": {
        "value": {"min": 12.0},
        "constraints": {
          "count": {"n_of_m": [3,5]},
          "previous_status": {"not": "critical"}
        },
}}}}

Note that the critical state can not be left! It has to be left manually, e.g. by an operator who confirms the issue was resolved and presses a button to force the state to be set to another value.

Blocking the exit of critical might not be of most value here, but imagine a machine that stops after a failure and needs repairs. It should not restart operation by itself but require someone to manually start it, to make sure maintenance is completed and there is no person with their hands inside the machine.