9 Commits
0.0.23 ... main

Author SHA1 Message Date
626b8edc88 feedback
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-11-24 15:58:51 +01:00
c5ed655399 feedback
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-11-24 15:56:18 +01:00
007ce16618 feedback
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-11-24 15:50:34 +01:00
12bcbfcca4 feedback
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-11-24 15:48:18 +01:00
da5506f432 add window sensor patty street
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-11-24 13:13:27 +01:00
f107f6b74c add window contact bad oben
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-11-24 12:53:45 +01:00
1b3ae9725e some devices migrated
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-11-19 14:58:05 +01:00
3a8377176f config adjusted
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-11-19 11:23:32 +01:00
d314ef37e4 fix
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-11-18 14:54:53 +01:00
5 changed files with 53 additions and 27 deletions

View File

@ -17,7 +17,8 @@ data:
{
"general_off": "heating/system/general_off",
"maintenance_mode": "heating/system/maintenance_mode",
"status": "heating/system/status"
"status": "heating/system/status",
"cmd": "heating/command/all"
}
STATUS_TOPIC: "heating/status"
CONTEXT_TOPIC_PREFIX: "heating/context/"
@ -30,32 +31,35 @@ data:
"patty": {
"windows": {
"garden_right": { "topic": "homegear/instance1/plain/18/1/STATE", "label": "Garten rechts", "converter": "max" },
"garden_left": { "topic": "homegear/instance1/plain/22/1/STATE", "label": "Garten links", "converter": "max" }
"garden_left": { "topic": "homegear/instance1/plain/22/1/STATE", "label": "Garten links", "converter": "max" },
"street": { "topic": "zigbee2mqtt/0x00158d000af457cf", "label": "Strasse", "converter": "aqara" }
},
"output_topic": "heating/homegear/instance1/set/39/1/SET_TEMPERATURE",
"output_topic": "homegear/instance1/set/39/1/SET_TEMPERATURE",
"output_converter": "max"
},
"kueche": {
"windows": {
"garden_window": { "topic": "homegear/instance1/plain/37/1/STATE", "label": "Garten Fenster", "converter": "max" },
"garden_door": { "topic": "homegear/instance1/plain/36/1/STATE", "label": "Garten Tuer", "converter": "max" },
"street_right": { "topic": "homegear/instance1/plain/38/1/STATE", "label": "Strasse rechts", "converter": "max" },
"street_left": { "topic": "homegear/instance1/plain/13/1/STATE", "label": "Strasse links", "converter": "max" }
"garden_window": { "topic": "zigbee2mqtt/0x00158d008b332785", "label": "Garten Fenster", "converter": "aqara" },
"garden_door": { "topic": "zigbee2mqtt/0x00158d008b332788", "label": "Garten Tuer", "converter": "aqara" },
"street_right": { "topic": "zigbee2mqtt/0x00158d008b151803", "label": "Strasse rechts", "converter": "aqara" },
"street_left": { "topic": "zigbee2mqtt/0x00158d008b331d0b", "label": "Strasse links", "converter": "aqara" }
},
"output_topic": "heating/homegear/instance1/set/40/1/SET_TEMPERATURE",
"output_converter": "max"
"output_topic": "zigbee2mqtt/0x94deb8fffe2e5c06/set",
"output_converter": "brennenstuhl"
},
"bad_oben": {
"windows": {
"street": { "topic": "zigbee2mqtt/0x00158d008b333aec", "label": "Strasse links", "converter": "aqara" }
},
"output_topic": "heating/homegear/instance1/set/41/1/SET_TEMPERATURE",
"output_topic": "homegear/instance1/set/41/1/SET_TEMPERATURE",
"output_converter": "max"
},
"schlafzimmer": {
"windows": {
"street": { "topic": "homegear/instance1/plain/52/1/STATE", "label": "Strasse", "converter": "max" }
},
"output_topic": "heating/homegear/instance1/set/42/1/SET_TEMPERATURE",
"output_topic": "homegear/instance1/set/42/1/SET_TEMPERATURE",
"feedback_topic": "homegear/instance1/jsonobj/42/1",
"output_converter": "max"
},
"wolfgang": {
@ -70,7 +74,7 @@ data:
"street_right": { "topic": "homegear/instance1/plain/26/1/STATE", "label": "Strasse rechts", "converter": "max" },
"street_left": { "topic": "homegear/instance1/plain/27/1/STATE", "label": "Strasse links", "converter": "max" }
},
"output_topic": "heating/homegear/instance1/set/45/1/SET_TEMPERATURE",
"output_topic": "homegear/instance1/set/45/1/SET_TEMPERATURE",
"output_converter": "max"
},
"wohnzimmer": {
@ -78,14 +82,14 @@ data:
"garden_right": { "topic": "homegear/instance1/plain/28/1/STATE", "label": "Garten rechts", "converter": "max" },
"garden_left": { "topic": "homegear/instance1/plain/29/1/STATE", "label": "Garten links", "converter": "max" }
},
"output_topic": "heating/homegear/instance1/set/46/1/SET_TEMPERATURE",
"output_topic": "homegear/instance1/set/46/1/SET_TEMPERATURE",
"output_converter": "max"
},
"bad_unten": {
"windows": {
"street": { "topic": "homegear/instance1/plain/44/1/STATE", "label": "Strasse", "converter": "max" }
},
"output_topic": "heating/homegear/instance1/set/48/1/SET_TEMPERATURE",
"output_topic": "homegear/instance1/set/48/1/SET_TEMPERATURE",
"output_converter": "max"
}
}

View File

@ -2,15 +2,15 @@ export MQTT_BROKER="172.23.1.102"
export MQTT_PORT=1883
export MQTT_CLIENT_PREFIX="MyMQTTClient"
export BOX_TOPIC_PREFIXES='{
"high_temp": "xheating/config/high_temp/",
"cmd": "xheating/command/"
"high_temp": "heating/config/high_temp/",
"cmd": "heating/command/"
}'
export CENTRAL_TOPICS='{
"general_off": "xheating/system/general_off",
"maintenance_mode": "xheating/system/maintenance_mode",
"status": "xheating/system/status"
"general_off": "heating/system/general_off",
"maintenance_mode": "heating/system/maintenance_mode",
"status": "heating/system/status"
}'
export CONTEXT_TOPIC_PREFIX='xheating/context/'
export CONTEXT_TOPIC_PREFIX='heating/context/'
export STATUS_TOPIC="heating/status"
export OFF_TEMPERATURE="5.0"
export LOW_TEMPERATURE="15.0"

View File

@ -10,6 +10,7 @@ class Context:
maintenance_mode: bool = field(default=False)
overwrite_window: bool = field(default=False)
window_state: dict = field(default_factory=dict)
feedback: dict = field(default_factory=dict)
mode: str = field(default='off')
output_temperature: str = field(default='0')
@ -24,6 +25,8 @@ class Box:
self.windows = box_config['windows']
self.output_converter = box_config['output_converter']
self.output_topic = box_config['output_topic']
# we use get here since this key is optional
self.feedback_topic = box_config.get('feedback_topic')
self.config = config
self.context = Context(high_temperature=config.DEFAULT_HIGH_TEMPERATURE,
@ -70,14 +73,16 @@ class Box:
try:
# match topic to find operation to be executed
send_command = True
match topic_key.split('/'):
case [ primary_key, sub_key ] if primary_key == 'window':
self.context.window_state[sub_key] = CONVERTERS["window_contact_input"][self.windows[sub_key]["converter"]](payload)
case [ primary_key ] if primary_key == 'high_temp':
self.context.high_temperature = payload
case [ primary_key ] if primary_key == 'cmd':
if payload in ('high', 'low', 'off'):
self.context.mode = payload
p = payload.lower()
if p in ('high', 'low', 'off'):
self.context.mode = p
else:
raise Exception(f"Invalid cmd '{payload}'")
case [ primary_key ] if primary_key == 'overwrite_window':
@ -87,7 +92,12 @@ class Box:
case [ primary_key ] if primary_key == 'maintenance_mode':
self.context.maintenance_mode = payload.lower() == 'true'
case [ primary_key ] if primary_key == 'status':
send_command = False
pass
case [ primary_key ] if primary_key == 'feedback':
# merge the both dicts
self.context.feedback |= json.loads(payload)
send_command = False
case _:
raise Error(f"Unexcepted topic_key: {topic_key}, {payload}")
@ -95,12 +105,14 @@ class Box:
self._calculate_output_temperature()
# publish output temperature
result_message = CONVERTERS["target_temperature_output"][self.output_converter](self.context.output_temperature)
publish_topic = self.output_topic
self.mqtt_client.publish(publish_topic, result_message)
logger.info(f"[Box {self.id}] Result published on '{publish_topic}': {result_message}")
if send_command:
# publish output temperature
result_message = CONVERTERS["target_temperature_output"][self.output_converter](self.context.output_temperature)
publish_topic = self.output_topic
self.mqtt_client.publish(publish_topic, result_message)
logger.info(f"[Box {self.id}] Result published on '{publish_topic}': {result_message}")
# send context in any case
context_topic = f"{self.config.CONTEXT_TOPIC_PREFIX}{self.id}"
self.mqtt_client.publish(context_topic, str(self.context))
except Exception as e:

View File

@ -1,3 +1,5 @@
import json
CONVERTERS = {
"target_temperature_output": {
"max": lambda x: x,

View File

@ -44,6 +44,14 @@ def on_connect(client, userdata, flags, reason_code, properties):
client.subscribe(topic)
topic_mapping[topic] = (box, topic_key)
logger.info(f"[{box.id}] Subscribed to '{topic}' (Key: '{topic_key}')")
# Subscribe feedback topic if one is available
if box.feedback_topic:
topic = box.feedback_topic
topic_key = "feedback"
client.subscribe(topic)
topic_mapping[topic] = (box, topic_key)
logger.info(f"[{box.id}] Subscribed to '{topic}' (Key: '{topic_key}')")
# Subscribe to central topics and create mappings
for central_key, central_topic in config.CENTRAL_TOPICS.items():