123 lines
4.1 KiB
Python
123 lines
4.1 KiB
Python
#!/usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
#
|
|
""" Communication (MQTT)
|
|
|
|
brennenstuhl_heatingvalve {
|
|
| "away_mode": ["ON", "OFF"]
|
|
| "battery": [0...100] %
|
|
| "child_lock": ["LOCK", "UNLOCK"]
|
|
| "current_heating_setpoint": [5...30] °C
|
|
| "linkquality": [0...255] lqi
|
|
| "local_temperature": [numeric] °C
|
|
| "preset": ["manual", ...]
|
|
| "system_mode": ["heat", ...]
|
|
| "valve_detection": ["ON", "OFF"]
|
|
| "window_detection": ["ON", "OFF"]
|
|
| }
|
|
+- set {
|
|
"away_mode": ["ON", "OFF", "TOGGLE"]
|
|
"child_lock": ["LOCK", "UNLOCK"]
|
|
"current_heating_setpoint": [5...30] °C
|
|
"preset": ["manual", ...]
|
|
"system_mode": ["heat", ...]
|
|
"valve_detection": ["ON", "OFF", "TOGGLE"]
|
|
"window_detection": ["ON", "OFF", "TOGGLE"]
|
|
}
|
|
"""
|
|
|
|
from devices.base import base
|
|
import json
|
|
import task
|
|
import time
|
|
|
|
""" ANSWER of a device:
|
|
{
|
|
"away_mode":"OFF",
|
|
"battery":5,
|
|
"child_lock":"UNLOCK",
|
|
"current_heating_setpoint":21,
|
|
"linkquality":196,
|
|
"local_temperature":21.2,
|
|
"preset":"manual",
|
|
"system_mode":"heat",
|
|
"valve_detection":"ON",
|
|
"window_detection":"ON"
|
|
}
|
|
"""
|
|
|
|
|
|
class vlv(base):
|
|
"""A tradfri device with switching functionality
|
|
|
|
Args:
|
|
mqtt_client (mqtt.mqtt_client): A MQTT Client instance
|
|
topic (str): the base topic for this device
|
|
"""
|
|
PROPERTIES = [
|
|
"away_mode",
|
|
"battery",
|
|
"child_lock",
|
|
"current_heating_setpoint",
|
|
"linkquality",
|
|
"local_temperature",
|
|
"preset",
|
|
"system_mode",
|
|
"valve_detection",
|
|
"window_detection"
|
|
]
|
|
|
|
def __init__(self, mqtt_client, topic, **kwargs):
|
|
super().__init__(mqtt_client, topic, **kwargs)
|
|
self["away_mode"] = "OFF"
|
|
self["battery"] = 87
|
|
self["child_lock"] = "UNLOCK"
|
|
self["current_heating_setpoint"] = 21
|
|
self["linkquality"] = 196
|
|
self["local_temperature"] = 21.2
|
|
self["preset"] = "manual"
|
|
self["system_mode"] = "heat"
|
|
self["valve_detection"] = "ON"
|
|
self["window_detection"] = "ON"
|
|
#
|
|
self.mqtt_client.add_callback(self.topic + '/set', self.__rx_set__)
|
|
#
|
|
self.tq = task.threaded_queue()
|
|
self.tq.run()
|
|
#
|
|
cmd_base = self.topic.replace('/', '.') + '.'
|
|
self.user_cmds = {
|
|
cmd_base + 'setpoint': self.__ui_setpoint__,
|
|
}
|
|
|
|
def set_state(self, value):
|
|
self.__set__("state", "on" if value else "off")
|
|
self.send_device_status()
|
|
|
|
def __rx_set__(self, client, userdata, message):
|
|
data = json.loads(message.payload)
|
|
self.logger.info("Received set data: %s", repr(data))
|
|
for key in data:
|
|
self.__set__(key, data[key])
|
|
self.tq.enqueue(1, self.send_device_status, data)
|
|
|
|
def send_device_status(self, rt, data):
|
|
for i in range(0, 75):
|
|
time.sleep(0.01)
|
|
if self.tq.qsize() >= 3:
|
|
return
|
|
for key in self:
|
|
if key not in data:
|
|
data[key] = self[key]
|
|
self.logger.info("Sending status: %s", repr(data))
|
|
self.mqtt_client.send(self.topic, json.dumps(data))
|
|
|
|
def __ui_setpoint__(self, *args):
|
|
try:
|
|
value = float(args[0].replace(',', '.'))
|
|
except (ValueError, IndexError):
|
|
print("You need to give a numeric value as first argument.")
|
|
else:
|
|
self.__set__("current_heating_setpoint", value)
|
|
self.tq.enqueue(1, self.send_device_status, self)
|