1
0
Fork 0

Compare commits

..

No commits in common. "master" and "0.2" have entirely different histories.
master ... 0.2

2 changed files with 9 additions and 42 deletions

View File

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

View File

@ -1,9 +1,7 @@
import json import json
import logging import logging
import os import os
import select
import signal import signal
import threading
import time import time
from contextlib import closing from contextlib import closing
from types import FrameType from types import FrameType
@ -22,45 +20,30 @@ PORT = 8883
USERNAME = os.environ.get("MQTT_USERNAME", "") USERNAME = os.environ.get("MQTT_USERNAME", "")
PASSWORD = os.environ.get("MQTT_PASSWORD", "") PASSWORD = os.environ.get("MQTT_PASSWORD", "")
TOPIC = "homeassistant/sensor/thermostat" TOPIC = "homeassistant/sensor/thermostat"
AVAILABILITY_TOPIC = f"{TOPIC}/availability"
I2CPORT = 1 I2CPORT = 1
SENSOR_ADDR = 0x77 SENSOR_ADDR = 0x77
DEVICE = {
"manufacturer": "Dustin C. Hatch",
"name": "RPi Thermostat Display",
"model": "RPi Thermostat Display",
"identifiers": [
os.uname().nodename,
],
}
SENSOR_CONFIG = { SENSOR_CONFIG = {
"thermostat_temperature": { "thermostat_temperature": {
"device_class": "temperature", "device_class": "temperature",
"name": "Thermostat Temperature", "name": "Thermostat Temperature",
"device": DEVICE,
"state_topic": TOPIC, "state_topic": TOPIC,
"availability_topic": AVAILABILITY_TOPIC,
"unit_of_measurement": "°C", "unit_of_measurement": "°C",
"value_template": r"{{ value_json.temperature }}", "value_template": r"{{ value_json.temperature }}",
}, },
"thermostat_pressure": { "thermostat_pressure": {
"device_class": "pressure", "device_class": "pressure",
"name": "Thermostat Pressure", "name": "Thermostat Pressure",
"device": DEVICE,
"state_topic": TOPIC, "state_topic": TOPIC,
"availability_topic": AVAILABILITY_TOPIC,
"unit_of_measurement": "hPa", "unit_of_measurement": "hPa",
"value_template": r"{{ value_json.pressure }}", "value_template": r"{{ value_json.pressure }}",
}, },
"thermostat_humidity": { "thermostat_humidity": {
"device_class": "humidity", "device_class": "humidity",
"name": "Thermostat Humidity", "name": "Thermostat Humidity",
"device": DEVICE,
"state_topic": TOPIC, "state_topic": TOPIC,
"availability_topic": AVAILABILITY_TOPIC,
"unit_of_measurement": "%", "unit_of_measurement": "%",
"value_template": r"{{ value_json.humidity }}", "value_template": r"{{ value_json.humidity }}",
}, },
@ -69,20 +52,18 @@ SENSOR_CONFIG = {
class Daemon: class Daemon:
def __init__(self) -> None: def __init__(self) -> None:
self.quitpipe = os.pipe() self.running = True
self._ready = threading.Event()
def on_signal(self, signum: int, frame: FrameType) -> None: def on_signal(self, signum: int, frame: FrameType) -> None:
log.debug("Got signal %d at %s", signum, frame) log.debug("Got signal %d at %s", signum, frame)
log.info("Stopping") log.info("Stopping")
os.close(self.quitpipe[1]) self.running = False
def run(self): def run(self):
signal.signal(signal.SIGINT, self.on_signal) signal.signal(signal.SIGINT, self.on_signal)
signal.signal(signal.SIGTERM, self.on_signal) signal.signal(signal.SIGTERM, self.on_signal)
client = mqtt.Client() client = mqtt.Client()
client.will_set(AVAILABILITY_TOPIC, "offline", retain=True)
client.on_connect = self.on_connect client.on_connect = self.on_connect
client.on_message = self.on_message client.on_message = self.on_message
client.on_disconnect = self.on_disconnect client.on_disconnect = self.on_disconnect
@ -92,20 +73,15 @@ class Daemon:
client.loop_start() client.loop_start()
with closing(smbus2.SMBus(I2CPORT)) as bus: with closing(smbus2.SMBus(I2CPORT)) as bus:
params = bme280.load_calibration_params(bus, SENSOR_ADDR) params = bme280.load_calibration_params(bus, SENSOR_ADDR)
self._ready.wait() while self.running:
while 1:
data = bme280.sample(bus, SENSOR_ADDR, params) data = bme280.sample(bus, SENSOR_ADDR, params)
values = { values = {
"temperature": adj(data.temperature), "temperature": int(data.temperature),
"pressure": adj(data.pressure), "pressure": int(data.pressure),
"humidity": adj(data.humidity), "humidity": int(data.humidity),
} }
client.publish(TOPIC, json.dumps(values)) client.publish(TOPIC, json.dumps(values))
ready = select.select((self.quitpipe[0],), (), (), 10)[0] time.sleep(10)
if self.quitpipe[0] in ready:
os.close(self.quitpipe[0])
break
client.publish(AVAILABILITY_TOPIC, "offline", retain=True)
client.disconnect() client.disconnect()
client.loop_stop() client.loop_stop()
@ -118,14 +94,9 @@ class Daemon:
): ):
log.info("Successfully connected to MQTT broker") log.info("Successfully connected to MQTT broker")
for key, value in SENSOR_CONFIG.items(): for key, value in SENSOR_CONFIG.items():
value["unique_id"] = f"sensor.{key}"
client.publish( client.publish(
f"homeassistant/sensor/{key}/config", f"homeassistant/sensor/{key}/config", json.dumps(value)
json.dumps(value),
retain=True,
) )
client.publish(AVAILABILITY_TOPIC, "online", retain=True)
self._ready.set()
def on_disconnect(self, client, userdata, rc): def on_disconnect(self, client, userdata, rc):
log.error("Lost connection to MQTT broker") log.error("Lost connection to MQTT broker")
@ -142,10 +113,6 @@ class Daemon:
print("Message", client, userdata, msg) print("Message", client, userdata, msg)
def adj(value, p=10):
return int(value * p) / p
def main(): def main():
logging.basicConfig(level=logging.DEBUG) logging.basicConfig(level=logging.DEBUG)
daemon = Daemon() daemon = Daemon()