Right now if you use the MQTT Alarm integration, when it starts up it’s in the ‘unknown’ state (or the last known state if retain is used). But neither of these are correct.
Instead when it starts up it should issue a MQTT message that a refresh is necessary to get the current state, and a response can be given to this request that gives the current state of the alarm system.
The broker only sends messages to clients subscribed to a topic when a message is published to the topic on the broker.
If retain is set for a message sent to a topic then clients will receive an update from this topic as soon as they connect.
There is no “refresh” command that the broker can issue to force clients to send updated messages. It’s all client side driven.
If you are using retain, the last state reported to the broker should be the correct state that can be sent out to clients that connect. So I am confused by your statement:
My HA server is also the MQTT broker via the integration, so I was under the assumption when I restart the server it’s losing the last value.
However even if that isn’t the case it doesn’t mean it’s accurate. If HA (and MQTT go down) and while they’re down the alarm system arms, how would it know when it starts back up?
Doesn’t it need to send a message to ask for the latest state otherwise there’s no guarantee it’s in the latest state after an outage.
The broker runs in it’s own container. So you should be able to restart home assistant while the broker keeps running.
If you turn off the host machine or reboot that will affect everything on the machine. You should never have to do this.
If the broker goes down there are no guarantees it’s data is not stale. It should be run in a highly reliable environment with battery backup if you have important systems relying on it like alarm systems.
Just to be clear: my alarm system is on battery backup, so it never usually goes down.
But sometimes the HA Pi goes down for a variety of reasons (or the router does bringing down the LAN) and yes it’s running the MQTT add-on.
While I’d love to have 99% uptime at home for a machine and LAN, that’s not very realistic is it lol. If I really wanted that uptime I wouldn’t use HA at all, I’d use an actual alarm monitor company or an enterprise automation solution…
The alarm system always knows its state, all I need for the alarm system is to push the state when required. It already pushes it’s state out when it starts up (if it ever goes down for some reason). Is there any way to detect the broker coming back? Maybe my client could check if the connection is re-established?
The MQTT Alarm and Control Panel integration subscribes to a state_topic. Whatever device you have that is publishing to that topic should be publishing its payloads as retained messages.
Retained messages are stored on the MQTT broker. When Home Assistant restarts, it connects to the broker and subscribes to whatever topic is specified in state_topic. If that topic has a retained message, Home Assistant will receive it immediately. It’s that simple.
I’m getting pretty close to 52 weeks uptime for my host machine. Can’t remember if my local network has ever been down except for planned firmware upgrades. It is entirely realistic. You need to apply the same regime you have for your alarm system to all system components that depend on it if you want it to be reliable. That means a UPS and reliable network components (not an all in one router/modem/wifi), regular offsite backups etc…
As a software developer, even if someone told me something is going to be up 99.9% of the time I still plan for the 0.1%. So either way I’m going to address this issue where it can get out of sync :).
But I’m glad you’ve got such great uptime! It’s not realistic for my location and setup unfortunately.
Sure, and I set retain in my code which is doing the MQTT client communication from the concord4 superbus. I committed it, along with the reconnection refresh in the commit here which you can take a look at.
If you read my comments above, my concern isn’t solely about retain. It’s also about the HA machine (and the MQTT broker plug-in along side it) going down. While down, the alarm panel issues messages that don’t go anywhere. Doors opening, the system being armed / disarmed, etc.
Worse, if the LAN goes down paho-mqtt, the standard Python library for doing MQTT, throws a socket exception if you use publish. It doesn’t even store the message for re-broadcast on reconnect.
In any case I think we can all agree this isn’t a valid FR for HA and that’s my mistake, but rather a discussion for MQTT itself since it’s rather sloppy, imo, to assume a stateful server is always available 100% of the time, especially when handling stateful devices. Perhaps that’s partially behind the rise of REST.
And for the record I don’t personally agree with statements like “it should never go down” because that inevitably leads to “well that wasn’t supposed to happen.” Anyone who’s worked on a software or IT project knows the woes of the 2am production server that is supposed to never go down, going down. Part of life, why not plan for it? Didn’t think I’d meet so much disagreement over that.
In any case, thanks for the discussion, led to me realizing what I needed to do.
Last Will and Testament (LWT) is MQTT’s means of reporting disconnections to all subscribed clients (i.e. Home Assistant loses connection with the broker). Once apprised, publishers can take whatever action is deemed appropriate. However, even if informed via LWT that Home Assistant is no longer listening, I’m not sure what would be the security system’s “Plan B”. So what would your security system’s response be upon learning that Home Assistant was no longer listening to it?
Do you have a means to poke the alarm system to provoke it to publish its current state? Perhaps you could define an automation that looks for a homeassistant start event.
I do this to publish some MQTT messages to provoke various Tasmota devices to publish current sensor state. And also to notify me in the even the restart wasn’t planned…
- alias: "Tasmota State refresh on HA start-up"
trigger:
platform: homeassistant
event: start
action:
- service: notify.pushover_louie
data:
title: "HASS"
message: "Home Assistant start event at {{ now().strftime('%Y-%m-%d %H:%M:%S') }}"
# force a state publish
- service: mqtt.publish
data:
topic: "19916/cmnd/sonoffs/state"
payload: ""
# force a publish of the current power state
- service: mqtt.publish
data:
topic: "19916/cmnd/sonoffs/power"
payload: ""