Documentation Index
Fetch the complete documentation index at: https://docs.coreflux.org/llms.txt
Use this file to discover all available pages before exploring further.
Reacting to Threshold Crossings
Most alarm logic boils down to “if a value crosses a threshold, alert someone.” LoT does this in a handful of lines: read the current value, read the threshold from config, compare, publish if exceeded.When to Reach for This
Any time you need to detect that something has gone outside an acceptable range — temperature too high, tank too full, vibration too strong, fill level too low, pollution above a limit. This is one of the first patterns most projects need.The Simple Version
A CO2 monitor in a conference room:- The threshold lives in
config/, not in the Action. A facilities manager can change it at runtime without redeploying anything. If the limit shifts from 1000 ppm to 1200 ppm, just publish the new value toconfig/co2_maxand the next reading uses the new limit. - The alert topic is separate from the data topic. Anyone subscribing to
alerts/#gets every alert in the system, regardless of source. Dashboards, notifiers, and on-call systems all use the same channel. - No state tracking in this version. The Action fires every time a reading exceeds the threshold, so you’ll get repeated alerts while CO2 stays high. If you have downstream notification infrastructure that handles deduplication, that’s fine. If you don’t, see the state-tracking variant below.
Optional: Standardize the Alarm Format with a Model
Plain text alerts work, but as your system grows you’ll want consistent structure — every alarm in the same JSON shape so dashboards and databases can parse them uniformly. Define aCOLLAPSED Model and use PUBLISH MODEL instead of PUBLISH TOPIC. (COLLAPSED means the Model doesn’t publish on its own — it only fires when something explicitly calls PUBLISH MODEL. See the Models reference for the full options.)
Optional: Deduplicate with State Tracking
If you don’t have a downstream notifier that deduplicates — or you want a clean audit trail of “alarm started” and “alarm cleared” events — track the previous state instate/ and only publish on transitions.
- The action reads three things: current value, threshold, and the previous alarm state stored in
state/co2_alarm. - If CO2 is over the threshold and the alarm wasn’t already active, it fires a “high” alert and marks the state active. Subsequent over-threshold readings while still active produce no extra alerts.
- If CO2 is back below threshold and the alarm was active, it fires a “normal” alert and marks the state normal.
state/ topic uses KEEP TOPIC (not PUBLISH TOPIC) so it’s internal to the alarm logic — retained on the broker, but not noise on the wire.
Optional: Send the Alarm by Email
For alarms that need to reach humans directly, add anEMAIL route that subscribes to your alert topics and sends a templated message via SMTP. The route does all the work — your Action just publishes to the alert topic as before. (Full reference: Data Pipeline Routes.)
- The threshold Action publishes a structured alarm to
alerts/co2_high(using the Model variant from above). - The email route is subscribed to that topic and fires automatically whenever a new alarm appears.
- Placeholders like
{value.json.value}pull fields out of the JSON payload to build the email subject and body.
ENV and SECRET (see Keeping Credentials Out of Your Code). Pair with the state tracking variant if you want only one email per alarm transition rather than one per reading.
Knowing When a Device or Route Goes Offline
Two different things can go silent in a Coreflux system, and you want to know about both. Devices are the sensors, machines, and gateways out in the world. They go offline when their network drops, their battery dies, or they crash. The signal that something’s wrong is the absence of incoming messages. Routes are the broker’s own connections to databases, cloud brokers, REST APIs, and other external systems. They go offline when credentials change, the remote system is unreachable, or the network between them breaks. The signal here is the absence of an outbound connection, which the broker tracks itself using SYS topics (the built-in SYS hierarchy). Both need monitoring. The data sources are different, so the patterns are different.When to Reach for This
Whenever uptime matters: critical infrastructure, paid telemetry, anything you’d want to dispatch a technician for. Skip it for opportunistic devices where occasional silence is normal (mobile phones, ad-hoc sensors). For routes, this is almost always worth doing — a silent integration is a silent data loss.Approach 1: Heartbeats for Devices
Each device publishes a timestamp to its own status topic at a regular interval. Then a scheduled Action checks for any device whose last timestamp is too old. If your devices already send data regularly, you can stamp the heartbeat directly from the Action that processes their readings:last_seen timestamp for that device. The wildcard means it covers every sensor automatically, and KEEP TOPIC retains the value internally without broadcasting it.
A scheduled Action then wakes up periodically, compares each timestamp to “now,” and publishes an alert for anything stale. Time arithmetic is awkward in LoT, so this is a natural place to call a small Python helper (see Running Python from a LoT Action):
state/+/last_seen topic, compares to the current time, and returns the count and list of devices whose last_seen is older than 300 seconds.
Approach 2: SYS topics for Routes
The broker exposes a live view of itself through SYS topics — a built-in dashboard in MQTT form. For monitoring route health, read the JSON array published on the topic below. It lists every client currently connected to the broker, with timestamps and connection details. Routes that maintain MQTT connections (bridges, REST endpoints in client mode, anything with a connected client identity) appear in this list. When one drops, it disappears from the array.- The expected route list lives in a config topic — for example, you’d publish
"DatabaseRoute,CloudBridge,WeatherAPI"toconfig/expected_routes. Operators can update it without redeploying anything. - The Action reads the live JSON from
GET TOPICon the path above and hands both lists to Python. - Python parses the connections, computes the set difference, and returns the count plus a comma-separated list of missing routes.
- If anything is missing, the Action publishes a critical alarm and a list of which routes are down.
Combining the Two Approaches
A complete monitoring layer runs both Actions side by side: heartbeats catch devices that have stopped reporting even though their network looks fine, and the SYS clients-topic check catches routes that have lost their integration to the outside world. Both publish into the samealerts/ branch, so a single subscriber — a dashboard, a notification rule, an email route — gives you a unified “what’s not working right now” view.
Pair either Action with the state tracking variant to avoid alert spam: one alert when something disappears, one when it comes back, silence in between.
Next Steps
Data Pipeline Routes
Email, MQTT bridge, and other event-driven pipeline routes.
SYS Topics
Built-in broker topics for monitoring clients and comms.

