Compare commits
9 Commits
class_base
...
0.0.26
Author | SHA1 | Date | |
---|---|---|---|
007ce16618
|
|||
12bcbfcca4
|
|||
da5506f432
|
|||
f107f6b74c
|
|||
1b3ae9725e
|
|||
3a8377176f
|
|||
d314ef37e4
|
|||
edb739764a
|
|||
21f49ae91b
|
10
Dockerfile
10
Dockerfile
@ -4,7 +4,9 @@ WORKDIR /app
|
||||
|
||||
COPY src/requirements.txt .
|
||||
COPY src/main.py .
|
||||
COPY src/message_processor.py .
|
||||
COPY src/converters.py .
|
||||
COPY src/config.py .
|
||||
COPY src/box.py .
|
||||
|
||||
RUN \
|
||||
addgroup -S appgroup && \
|
||||
@ -16,9 +18,9 @@ RUN \
|
||||
ENV MQTT_BROKER=""
|
||||
ENV MQTT_PORT=""
|
||||
ENV MQTT_CLIENT_PREFIX=""
|
||||
ENV MQTT_BOX_TOPIC_PREFIXES=""
|
||||
ENV MQTT_CENTRAL_TOPICS=""
|
||||
ENV MQTT_STATUS_TOPIC=""
|
||||
ENV BOX_TOPIC_PREFIXES=""
|
||||
ENV CENTRAL_TOPICS=""
|
||||
ENV STATUS_TOPIC=""
|
||||
ENV OFF_TEMPERATURE=""
|
||||
ENV LOW_TEMPERATURE=""
|
||||
ENV DEFAULT_HIGH_TEMPERATURE=""
|
||||
|
@ -7,20 +7,21 @@ data:
|
||||
MQTT_BROKER: "emqx01-anonymous-cluster-internal.broker.svc.cluster.local"
|
||||
MQTT_PORT: "1883"
|
||||
MQTT_CLIENT_PREFIX: "HeatingController"
|
||||
MQTT_BOX_TOPIC_PREFIXES: |
|
||||
BOX_TOPIC_PREFIXES: |
|
||||
{
|
||||
"high_temp": "heating/config/high_temp/",
|
||||
"overwrite_window": "heating/overwrite_window/",
|
||||
"cmd": "heating/command/"
|
||||
}
|
||||
MQTT_CENTRAL_TOPICS: |
|
||||
CENTRAL_TOPICS: |
|
||||
{
|
||||
"general_off": "heating/system/general_off",
|
||||
"maintenance_mode": "heating/system/maintenance_mode",
|
||||
"status": "heating/system/status"
|
||||
"status": "heating/system/status",
|
||||
"cmd": "heating/command/all"
|
||||
}
|
||||
MQTT_STATUS_TOPIC: "heating/status"
|
||||
MQTT_CONTEXT_TOPIC_PREFIX: "heating/context/"
|
||||
STATUS_TOPIC: "heating/status"
|
||||
CONTEXT_TOPIC_PREFIX: "heating/context/"
|
||||
OFF_TEMPERATURE: "5.0"
|
||||
LOW_TEMPERATURE: "15.0"
|
||||
DEFAULT_HIGH_TEMPERATURE: "21.0"
|
||||
@ -28,72 +29,67 @@ data:
|
||||
BOXES: |
|
||||
{
|
||||
"patty": {
|
||||
"label": "patty",
|
||||
"windows": [
|
||||
{ "topic": "homegear/instance1/plain/18/1/STATE", "label": "Garten rechts", "converter": "max" },
|
||||
{ "topic": "homegear/instance1/plain/22/1/STATE", "label": "Garten links", "converter": "max" }
|
||||
],
|
||||
"output_topic": "heating/homegear/instance1/set/39/1/SET_TEMPERATURE",
|
||||
"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" },
|
||||
"street": { "topic": "zigbee2mqtt/0x00158d000af457cf", "label": "Strasse", "converter": "aqara" }
|
||||
},
|
||||
"output_topic": "homegear/instance1/set/39/1/SET_TEMPERATURE",
|
||||
"output_converter": "max"
|
||||
},
|
||||
"kueche": {
|
||||
"label": "kueche",
|
||||
"windows": [
|
||||
{ "topic": "homegear/instance1/plain/37/1/STATE", "label": "Garten Fenster", "converter": "max" },
|
||||
{ "topic": "homegear/instance1/plain/36/1/STATE", "label": "Garten Tuer", "converter": "max" },
|
||||
{ "topic": "homegear/instance1/plain/38/1/STATE", "label": "Strasse rechts", "converter": "max" },
|
||||
{ "topic": "homegear/instance1/plain/13/1/STATE", "label": "Strasse links", "converter": "max" }
|
||||
],
|
||||
"output_topic": "heating/homegear/instance1/set/40/1/SET_TEMPERATURE",
|
||||
"output_converter": "max"
|
||||
"windows": {
|
||||
"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": "zigbee2mqtt/0x94deb8fffe2e5c06/set",
|
||||
"output_converter": "brennenstuhl"
|
||||
},
|
||||
"bad_oben": {
|
||||
"label": "bad_oben",
|
||||
"windows": [
|
||||
],
|
||||
"output_topic": "heating/homegear/instance1/set/41/1/SET_TEMPERATURE",
|
||||
"windows": {
|
||||
"street": { "topic": "zigbee2mqtt/0x00158d008b333aec", "label": "Strasse links", "converter": "aqara" }
|
||||
},
|
||||
"output_topic": "homegear/instance1/set/41/1/SET_TEMPERATURE",
|
||||
"output_converter": "max"
|
||||
},
|
||||
"schlafzimmer": {
|
||||
"label": "schlafzimmer",
|
||||
"windows": [
|
||||
{ "topic": "homegear/instance1/plain/52/1/STATE", "label": "Strasse", "converter": "max" }
|
||||
],
|
||||
"output_topic": "heating/homegear/instance1/set/42/1/SET_TEMPERATURE",
|
||||
"windows": {
|
||||
"street": { "topic": "homegear/instance1/plain/52/1/STATE", "label": "Strasse", "converter": "max" }
|
||||
},
|
||||
"output_topic": "homegear/instance1/set/42/1/SET_TEMPERATURE",
|
||||
"feedback_topic": "homegear/instance1/jsonobj/42/1",
|
||||
"output_converter": "max"
|
||||
},
|
||||
"wolfgang": {
|
||||
"label": "wolfgang",
|
||||
"windows": [
|
||||
{ "topic": "zigbee2mqtt/0x00158d008b3328da", "label": "Garten", "converter": "aqara" }
|
||||
],
|
||||
"windows": {
|
||||
"garden": { "topic": "zigbee2mqtt/0x00158d008b3328da", "label": "Garten", "converter": "aqara" }
|
||||
},
|
||||
"output_topic": "zigbee2mqtt/0x540f57fffe7e3cfe/set",
|
||||
"output_converter": "brennenstuhl"
|
||||
},
|
||||
"esszimmer": {
|
||||
"label": "esszimmer",
|
||||
"windows": [
|
||||
{ "topic": "homegear/instance1/plain/26/1/STATE", "label": "Strasse rechts", "converter": "max" },
|
||||
{ "topic": "homegear/instance1/plain/27/1/STATE", "label": "Strasse links", "converter": "max" }
|
||||
],
|
||||
"output_topic": "heating/homegear/instance1/set/45/1/SET_TEMPERATURE",
|
||||
"windows": {
|
||||
"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": "homegear/instance1/set/45/1/SET_TEMPERATURE",
|
||||
"output_converter": "max"
|
||||
},
|
||||
"wohnzimmer": {
|
||||
"label": "wohnzimmer",
|
||||
"windows": [
|
||||
{ "topic": "homegear/instance1/plain/28/1/STATE", "label": "Garten rechts", "converter": "max" },
|
||||
{ "topic": "homegear/instance1/plain/29/1/STATE", "label": "Garten links", "converter": "max" }
|
||||
],
|
||||
"output_topic": "heating/homegear/instance1/set/46/1/SET_TEMPERATURE",
|
||||
"windows": {
|
||||
"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": "homegear/instance1/set/46/1/SET_TEMPERATURE",
|
||||
"output_converter": "max"
|
||||
},
|
||||
"bad_unten": {
|
||||
"label": "bad_unten",
|
||||
"windows": [
|
||||
{ "topic": "homegear/instance1/plain/44/1/STATE", "label": "Strasse", "converter": "max" }
|
||||
],
|
||||
"output_topic": "heating/homegear/instance1/set/48/1/SET_TEMPERATURE",
|
||||
"windows": {
|
||||
"street": { "topic": "homegear/instance1/plain/44/1/STATE", "label": "Strasse", "converter": "max" }
|
||||
},
|
||||
"output_topic": "homegear/instance1/set/48/1/SET_TEMPERATURE",
|
||||
"output_converter": "max"
|
||||
}
|
||||
}
|
||||
|
6
env
6
env
@ -17,6 +17,12 @@ export LOW_TEMPERATURE="15.0"
|
||||
export DEFAULT_HIGH_TEMPERATURE="21.0"
|
||||
export MAINTENANCE_TEMPERATURE="30.0"
|
||||
export BOXES='{
|
||||
"bla": {
|
||||
"windows": {
|
||||
},
|
||||
"output_converter": "max",
|
||||
"output_topic": "xoutput/bla"
|
||||
},
|
||||
"living_room": {
|
||||
"windows": {
|
||||
"street_side": { "topic": "window/living_room/street_side", "converter": "max" },
|
||||
|
81
env-test
Normal file
81
env-test
Normal file
@ -0,0 +1,81 @@
|
||||
export MQTT_BROKER="172.23.1.102"
|
||||
export MQTT_PORT=1883
|
||||
export MQTT_CLIENT_PREFIX="MyMQTTClient"
|
||||
export BOX_TOPIC_PREFIXES='{
|
||||
"high_temp": "heating/config/high_temp/",
|
||||
"cmd": "heating/command/"
|
||||
}'
|
||||
export CENTRAL_TOPICS='{
|
||||
"general_off": "heating/system/general_off",
|
||||
"maintenance_mode": "heating/system/maintenance_mode",
|
||||
"status": "heating/system/status"
|
||||
}'
|
||||
export CONTEXT_TOPIC_PREFIX='heating/context/'
|
||||
export STATUS_TOPIC="heating/status"
|
||||
export OFF_TEMPERATURE="5.0"
|
||||
export LOW_TEMPERATURE="15.0"
|
||||
export DEFAULT_HIGH_TEMPERATURE="21.0"
|
||||
export MAINTENANCE_TEMPERATURE="30.0"
|
||||
export BOXES='{
|
||||
"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" }
|
||||
},
|
||||
"output_topic": "heating/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" }
|
||||
},
|
||||
"output_topic": "heating/homegear/instance1/set/40/1/SET_TEMPERATURE",
|
||||
"output_converter": "max"
|
||||
},
|
||||
"bad_oben": {
|
||||
"windows": {
|
||||
},
|
||||
"output_topic": "heating/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_converter": "max"
|
||||
},
|
||||
"wolfgang": {
|
||||
"windows": {
|
||||
"garden": { "topic": "zigbee2mqtt/0x00158d008b3328da", "label": "Garten", "converter": "aqara" }
|
||||
},
|
||||
"output_topic": "zigbee2mqtt/0x540f57fffe7e3cfe/set",
|
||||
"output_converter": "brennenstuhl"
|
||||
},
|
||||
"esszimmer": {
|
||||
"windows": {
|
||||
"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_converter": "max"
|
||||
},
|
||||
"wohnzimmer": {
|
||||
"windows": {
|
||||
"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_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_converter": "max"
|
||||
}
|
||||
}'
|
10
src/box.py
10
src/box.py
@ -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,
|
||||
@ -76,8 +79,9 @@ class Box:
|
||||
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':
|
||||
@ -88,6 +92,8 @@ class Box:
|
||||
self.context.maintenance_mode = payload.lower() == 'true'
|
||||
case [ primary_key ] if primary_key == 'status':
|
||||
pass
|
||||
case [ primary_key ] if primary_key == 'feedback':
|
||||
self.context.feedback = json.loads(payload)
|
||||
case _:
|
||||
raise Error(f"Unexcepted topic_key: {topic_key}, {payload}")
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
import json
|
||||
|
||||
CONVERTERS = {
|
||||
"target_temperature_output": {
|
||||
"max": lambda x: x,
|
||||
|
@ -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():
|
||||
|
Reference in New Issue
Block a user