1
0
Fork 0

sensor: Add availability messages

Home Assistant can mark MQTT-based sensors as "unavailable" when it
receives a special message (`offline`) on a designated topic.  We send
an `online` message when the sensor process starts, and `offline` when
the process shuts down.  Additionally, we set the last will and
testament message to `offline` as well, so that Home Assistant will
still get the notification, even if the sensor does not shut down
cleanly.
master
Dustin 2021-05-01 15:57:03 -05:00
parent 205989aefd
commit e30e8aaedc
2 changed files with 12 additions and 1 deletions

View File

@ -1,6 +1,6 @@
[tool.poetry]
name = "thermostat"
version = "0.3.0dev1"
version = "0.3.0dev2"
description = ""
authors = ["Dustin C. Hatch <dustin@hatch.name>"]

View File

@ -3,6 +3,7 @@ import logging
import os
import select
import signal
import threading
import time
from contextlib import closing
from types import FrameType
@ -21,6 +22,7 @@ PORT = 8883
USERNAME = os.environ.get("MQTT_USERNAME", "")
PASSWORD = os.environ.get("MQTT_PASSWORD", "")
TOPIC = "homeassistant/sensor/thermostat"
AVAILABILITY_TOPIC = f"{TOPIC}/availability"
I2CPORT = 1
SENSOR_ADDR = 0x77
@ -31,6 +33,7 @@ SENSOR_CONFIG = {
"device_class": "temperature",
"name": "Thermostat Temperature",
"state_topic": TOPIC,
"availability_topic": AVAILABILITY_TOPIC,
"unit_of_measurement": "°C",
"value_template": r"{{ value_json.temperature }}",
},
@ -38,6 +41,7 @@ SENSOR_CONFIG = {
"device_class": "pressure",
"name": "Thermostat Pressure",
"state_topic": TOPIC,
"availability_topic": AVAILABILITY_TOPIC,
"unit_of_measurement": "hPa",
"value_template": r"{{ value_json.pressure }}",
},
@ -45,6 +49,7 @@ SENSOR_CONFIG = {
"device_class": "humidity",
"name": "Thermostat Humidity",
"state_topic": TOPIC,
"availability_topic": AVAILABILITY_TOPIC,
"unit_of_measurement": "%",
"value_template": r"{{ value_json.humidity }}",
},
@ -54,6 +59,7 @@ SENSOR_CONFIG = {
class Daemon:
def __init__(self) -> None:
self.quitpipe = os.pipe()
self._ready = threading.Event()
def on_signal(self, signum: int, frame: FrameType) -> None:
log.debug("Got signal %d at %s", signum, frame)
@ -65,6 +71,7 @@ class Daemon:
signal.signal(signal.SIGTERM, self.on_signal)
client = mqtt.Client()
client.will_set(AVAILABILITY_TOPIC, "offline")
client.on_connect = self.on_connect
client.on_message = self.on_message
client.on_disconnect = self.on_disconnect
@ -74,6 +81,7 @@ class Daemon:
client.loop_start()
with closing(smbus2.SMBus(I2CPORT)) as bus:
params = bme280.load_calibration_params(bus, SENSOR_ADDR)
self._ready.wait()
while 1:
data = bme280.sample(bus, SENSOR_ADDR, params)
values = {
@ -86,6 +94,7 @@ class Daemon:
if self.quitpipe[0] in ready:
os.close(self.quitpipe[0])
break
client.publish(AVAILABILITY_TOPIC, "offline")
client.disconnect()
client.loop_stop()
@ -101,6 +110,8 @@ class Daemon:
client.publish(
f"homeassistant/sensor/{key}/config", json.dumps(value)
)
client.publish(AVAILABILITY_TOPIC, "online")
self._ready.set()
def on_disconnect(self, client, userdata, rc):
log.error("Lost connection to MQTT broker")