<< Previous |
Alarms Monitor and design decisions
Alarms monitor is the one of the main components. It listens to alarms, sends notifications and commands. It relies on MQTT broker for communication. MQTT protocol allows fine tune communication depending on specific context. Here are several design decision that I've made to configure it for my connected smoke detector.
Quality of Service (QoS)
MQTT protocol supports three types of QoS.
- QoS 0 : at most once : The packet is sent once, so if it lost - nobody will know.
- QoS 1 : at least once : The packet is sent until it gets confirmation from the broker. But it may generate duplicates, which is a bit difficult to handle.
- QoS 2 : exactly once : In this case client and broker have a longer negotiation, bit the message will be delivered exactly once with no duplicates.
For the connected smoke alarm I've decided to use "exactly once". It provides the highest possible level of consistency (so I will not loose alarm notifications). There is a small trade-off. To achieve higher consistency it is using a bit more packets, which is not very important for a local network. MQTT client and broker must support selected QoS. MQTT.js and Mosquitto supports all MQTT QoS options.
Keep Alive
Keep Alive timer is how long the connection will be kept alive until the server will disconnect the client. The Keep Alive timer for the connected smoke sensor is very important, as it provides status of the alarm availability. At the same time I will assume that in case of fire it will send alarm before detector gets destroyed.So I'll set it to quite a big number 5 minutes (300 seconds) for the sensor, which mean I'll get alert once it stopped working with a 5 minutes delay. On other side, I'll keep default 10 seconds value for the monitor itself. The frequent communication is acceptable as MQTT broker and the monitor are collocated on the same Intel Edison board.
Last Will and Testament (LWT)
In addition to Keep Alive, there is a Last Will and Testament (LWT). It allows MQTT client request the broker to publish a message to a specified topic when connection gets unexpectedly lost after a timeout defined by Keep Alive parameter. Here is a good description when it gets triggered:
- An I/O error or network failure is detected by the server.
- The client fails to communicate within the Keep Alive time.
- The client closes the network connection without sending a DISCONNECT packet first.
- The server closes the network connection because of a protocol error.
Message Retention
I'd like to know last reported alert and connection state of alarms, even if monitor or broker gets restarted. It can be achieved by setting retain parameter to true. The downside of it that they can be reported twice - once at time of report and second time after restart of the monitor.
MQTT.js client and connection parameters
It all comes together when the monitor opens MQTT connection, creates subscriptions and report its own status
const monitor_topic = 'home/alarm/monitor/connected'; const client = mqtt.connect(mqtt_url,{ keepalive: 10, // after 10 second time-out the broker will publish a message if the monitor dies will: { topic: monitor_topic, payload: 'false', qos: 2, //Exactly once retain: true }}); client.on('connect', () => { //subscription to smoke detector alarms and connection states from any location client.subscribe('+/alarm/smoke/+', {qos: 2}) //subscription to alarms monitors connection states from any location //this subscription is useful for logging/testing client.subscribe('+/alarm/monitor/+', {qos: 2}) // publish a message to a topic - "The home alarm monitor is connected" //Mosquitto conf /etc/mosquitto/mosquitto.conf should be configured to support retained messages //persistence true //persistence_location /var/lib/mosquitto/ client.publish(monitor_topic, 'true', {qos: 2, retain: true}, function() { console.log("Home alarms monitor connected"); }); })
Node.js Environment Parameters
It is a good practice to keep environment related parameters like broker URL, Slack channel and API keys outside from the code. So far I defined MQTT_BROKER_URL, SLACK_API_TOKEN and SLACK_CHANNEL.
Top Comments