Skip to content

Rules on any sensor reading ​

/admin/manage/rule: Rules → Add Rule → a condition whose Check is "Sensor reading (any field)"

Most rule checks come from a fixed list: temperature, humidity, people count, entries, a button press. A sensor that reports something not on that list could be seen on the Devices page but not used in a rule: a PIR's occupied, a door contact's open, a light sensor's illuminance, a leak sensor, a CO₂ probe, or a sensor you onboarded yourself with fields of your own.

Sensor reading (any field) removes the list. A condition names a field the sensor's decoder produces, and the rule fires on it like any other. Two operators come with it for readings that stay true for a while, Becomes (changes to) and Changes (any change), so a rule can count an event once rather than every packet.

If you have not built a rule before, read Your first rule first; this page covers only what is different.

How it works ​

Every packet a registered sensor sends is decoded into named fields: occupied, temperature, illuminance, press_type, total_people, or a Custom Type's own field names. On the same packet the rule engine is handed every one of those fields, and a real-time rule that watches that device, the zone the device sits in, a label the device carries, the person or asset it is bound to, or the floor (venue) or site (location) it is on is checked right then. A floor or site rule is checked this way when every one of its conditions is a reading of one device (a sensor field, battery, device status, signal, a button press); each device on the floor is judged on its own reading.

Nothing is checked for a device nobody has written a rule about: the engine keeps an index of which devices and zones have a real-time rule, and a packet from any other device costs it nothing. That is what keeps ten thousand beacons a minute from becoming ten thousand jobs a minute.

Levels and edges ​

A temperature is a level: it is 31 °C for as long as it is 31 °C. A PIR's occupied, a door's door_open and a button's press_type are events dressed as levels: the value sits at 1 for the whole visit. That difference decides which operator to use.

OperatorFires whenUse it for
Equal to, Greater than …the reading is on the far side of the line, each time the rule is checked, as often as repeat at most every allows"too bright", "too much CO₂", "tank below 10 %"
Becomes (changes to) Xthe reading changes to X: it was something else on the previous packet"somebody walked in" (occupied becomes 1), "the door opened" (door_open becomes 1), "the tank is now empty"
Changes (any change)the reading differs from the previous packet, whatever the values"log every state change", "the mode switched"
Level, edge and held-for, on the same hour of a toilet PIR A PIR reports occupied as 1 from minute 5 to minute 25 and again from minute 32 to minute 40. A rule on occupied equal to 1 set to repeat at most every ten minutes fires at minutes 5, 15 and 32: it keeps firing while the level stays true. A rule on occupied becomes 1 fires at 5 and 32, once per visit. A rule on occupied equal to 1, only after it has held for 15 minutes, fires once at minute 20; the second visit lasts eight minutes and never qualifies. PIR readingoccupied1 · VISIT, 20 MIN1 · 8 MIN00equal 1repeat: 10 minSTILL 1, 10 MIN LATERbecomes 1fires on the changeONE FIRING PER VISITequal 1held for 15 min15 MIN CLOCK8 MIN — CLOCK RESETS0102030405060 MIN● = THE RULE FIRES
The same hour of one PIR, three ways to write the rule. A level keeps firing for as long as it stays true, as often as "Repeat at most every" lets it. An edge fires once each time the value changes to what you named. "Only after it has held for" fires once the condition has been true without a break for that long, and any break restarts the clock.

A level rule on one device is checked at most once a minute, so a sensor advertising ten times a second does not fire a rule ten times a second. An edge is checked the moment the field changes, without that one-minute pause, and never on the first packet after the rule is saved, because there is no previous value yet; a restart does not count as a visit. A button press is treated as an edge by nature: each press is checked at once.

The other operators (Equal to, Not equal to, Less than, Greater than, Between, Contains) compare the field's value as the sensor gives it: numbers as numbers, text as text (case does not matter), and true / on / yes as 1, false / off / no as 0.

How to write one ​

  1. Rules → Add Rule. Open what the rule watches (the Watches box on the Flow view, or the row in the Watches card on the Card view) and set Watch to Device (one tag or sensor) (the PIR, the door contact), the Zone it is in, a Label it carries, or the Venue or Location it is on, then pick Which one. A zone rule fires on any device in that zone that reports the field; a Label, Venue or Location rule on any device carrying the label or on that floor or site, each judged on its own.
  2. Add a condition: Add a condition under the When card on the Card view, or drag Condition from the Nodes palette on the Flow view. Set Check to Sensor reading (any field) (in the Devices group). A Field box appears and lists the fields that device (or the zone's devices) has reported so far: Reported by this device: occupied, battery, …. Pick one or type it. A sensor that has not reported yet lists nothing; type the name the decoder uses. For a Label, Person / asset, Venue or Location rule the list stays empty; type the name.
  3. Operator and Value: Becomes (changes to) 1 for a presence event; Greater than 800 for a light level; Equal to single for a single press. Changes (any change) needs no value.
  4. Repeat at most every, in the Checked card on the Card view (Checked stays Real-time): for an edge, leave it at the smallest the builder accepts, 30 sec. For a level, use a real interval, or a reading that stays over the line fires every time it is checked.
  5. Add an Action as usual: an alert, a message, a webhook, a work order, or Add a row to a data table if you want to count it and report on it.
  6. Test. On a Device rule, Right now compares the field with the last value the device reported (true now or not now); an edge says fires on a change. On a zone, floor or site rule it shows no reading yet, because the reading belongs to each device, and a Label rule has no single reading to show. The replay below it cannot replay sensor fields and says so.
  7. Save.

The shortest repeat is 30 seconds

Type less and the box turns red and Save says "Repeat at most every" must be between 30 seconds and one day. For an edge rule this means two changes less than 30 seconds apart produce one firing. For toilet visits or door openings that is almost always what you want.

Only after it has held for a while ​

A condition normally acts on the first reading that matches. Fill in Only after it has held for (minutes) and it acts once the condition has been true without a break for that long: this table has been occupied for 45 minutes, the tank has been below 20 % for half an hour. Any break restarts the clock, so a person standing up for a moment does not bank the time.

  • It applies to ordinary comparisons, not to Becomes or Changes. An edge is a single reading by definition, so the box disappears when you pick one.
  • Each device is timed separately. A Label rule covering forty tables keeps forty clocks and forty repeat at most every intervals, and each fires for its own table.
  • A rule is normally checked when a reading arrives. Omaya also re-checks every real-time rule with a held-for condition once a minute by itself, with each device's last reading, so it fires even if the sensor only reports on change: a Device rule, a Label rule for each device whose clock is running, and a Zone rule both on the room's own figures and for each of its sensors whose clock is running. It lands within a minute of the time you set, not exactly on it.

Examples ​

These use the Level 2 toilets at Northwind Tower, where Siti Nur cleans, and the Server Room that Daniel Lim looks after.

Count toilet visits, male and female. A door counter on the corridor, a PIR (occupied) in the male toilet. Table Toilet visits: visits number, side text, toilet zone. Rule Male toilet visit: watch the PIR (or the male toilet zone), condition occupied Becomes 1, repeat at most every 30 sec; action Add a row → visits = 1, side = male, toilet = {{zone_uid}}. Rule Corridor entry: watch the counter, entry Changes (not Greater than 0: a level is checked at most once a minute and would miss entries); action → visits = {{value}}, side = all. Report: sum visits by side and Hour. Female is all minus male. The whole recipe is in Data tables.

Server Room door left open. A door contact reporting door_open (the field name a MOKO S01P uses; check yours on the device's View panel). Two rules, both watching the door contact device:

  • Door opened: door_open Becomes 1 → add a row to a Door log table with state = open.
  • Door still open: Checks Real-time; door_open Equal to 1, only after it has held for 10 minutes; repeat at most every 30 min → In-App Alert "Server Room door has been open for over 10 minutes", and a Mini app notification to Daniel. The once-a-minute re-check uses the last value the contact reported, so it works even when the contact reports only on change.

Lights on in an empty room. A light sensor (illuminance) and a PIR in the same zone. Rule watching the zone: illuminance Greater than 200 AND occupied Equal to 0, repeat at most every 1 hour → an alert, or a Home Assistant action to switch the light off. Both fields must have been reported by devices in that zone; a zone rule takes each field from the device that reported it.

Which button was pressed. A multi-function button reporting press_type. Rule Call a cleaner: press_type Equal to double → Raise a work order with work type cleaning. Rule Help: press_type Equal to long → In-App Alert and a Mini app notification to Hafiz Ismail at the guard desk. (For a panic button use the Button pressed condition and the Page these people action, or make it on Devices → Panic Buttons, which writes that rule for you.)

A sensor you onboarded yourself. A Custom Type with a field you named water_level. Rule: water_level Less than 10 → alert. The field appears in the picker as soon as the sensor has reported once. See Add an unknown sensor.

Log every state change of anything. Rule watching a device, condition on the field you want with Changes, repeat at most every 30 sec, action Add a row with state = {{value}} → a data table with one row per change, reportable by hour or day.

Placeholders in the action ​

A rule's templates (an alert message, a data-table column, a webhook body) can carry the reading: {{value}} is the value of the first condition's field; any field by name ({{occupied}}, {{illuminance}}, {{press_type}}) is also available, along with {{zone.name}}, {{device.name}}, {{rule_name}} and, in a data-table column, {{now}}, {{today}} and {{time}}. A work order's title and description take the same double braces. For a Label or Person / asset rule, {{device.name}} is the device that fired it and {{entity.name}} the person or asset it is bound to.

Questions and problems ​

The field is not in the picker. The device has not reported since the picker learned about it (it learns from packets), or the rule watches a label, a person or asset, a venue or a location. Type the name; it works the same, and a venue or location rule fires on the field for every device on that floor or site.

The rule never fires. Check the device's Last Seen on Device → Sensor: no packet, no check. For an edge, remember the first packet after saving only records the value; the next change fires. For a zone rule, the device must have that zone on its record; for a venue or location rule, that floor or site, and every condition must be a device reading (a floor rule mixing a sensor field with, say, the floor's people count is checked on the floor's own figures, which carry no sensor fields). For a Label rule, give a newly labelled device ten minutes.

It fires far too often. A level rule on a reading that stays over the line, with a short repeat at most every. Lengthen it, add "Only after it has held for", or make it an edge.

It fired once and never again. Becomes 1 on a sensor that reports 1 constantly and never goes back to 0: a PIR whose hold-off is longer than the gaps between visitors, so it never sees "empty". Shorten the sensor's hold-off, or count Changes and halve.

Two visits in quick succession counted as one. Repeat at most every: the builder's shortest is 30 seconds. And a PIR is "someone went in", not a head count; two people entering together are one trigger.

A Label rule fired once for a device and not again. That device is inside its own repeat at most every; each device carrying the label has its own. See Your first rule.

→ Data tables: your own report for what to do with the rows · Rule metrics for the fixed checks that are still there.

Last updated:

Omaya platform documentation