Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
adcc5a86f8
|
|||
39adf907b1
|
|||
7abec12620
|
|||
046430d1d1
|
|||
000510202e
|
90
deployment/configmap.yml
Normal file
90
deployment/configmap.yml
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: heating-controller-config
|
||||||
|
namespace: homea
|
||||||
|
data:
|
||||||
|
MQTT_BROKER: "emqx01-anonymous-cluster-internal.broker.svc.cluster.local"
|
||||||
|
MQTT_PORT: "1883"
|
||||||
|
MQTT_CLIENT_PREFIX: "HeatingController"
|
||||||
|
MQTT_BOX_TOPIC_PREFIXES: |
|
||||||
|
{
|
||||||
|
"high_temp": "heating/config/high_temp/",
|
||||||
|
"cmd": "heating/command/"
|
||||||
|
}
|
||||||
|
MQTT_CENTRAL_TOPICS: |
|
||||||
|
{
|
||||||
|
"general_off": "heating/system/general_off",
|
||||||
|
"maintenance_mode": "heating/system/maintenance_mode",
|
||||||
|
"status": "heating/system/status"
|
||||||
|
}
|
||||||
|
MQTT_STATUS_TOPIC: "heating/status"
|
||||||
|
OFF_TEMPERATURE: "5.0"
|
||||||
|
LOW_TEMPERATURE: "15.0"
|
||||||
|
DEFAULT_HIGH_TEMPERATURE: "21.0"
|
||||||
|
MAINTENANCE_TEMPERATURE: "30.0"
|
||||||
|
BOXES: |
|
||||||
|
{
|
||||||
|
"box1": {
|
||||||
|
"label": "patty",
|
||||||
|
"windows": [
|
||||||
|
{ "topic": "homegear/instance1/plain/18/1/STATE", "label": "Garten rechts" },
|
||||||
|
{ "topic": "homegear/instance1/plain/22/1/STATE", "label": "Garten links" }
|
||||||
|
],
|
||||||
|
"output_topic": "heating/homegear/instance1/set/39/1/SET_TEMPERATURE"
|
||||||
|
},
|
||||||
|
"box2": {
|
||||||
|
"label": "kueche",
|
||||||
|
"windows": [
|
||||||
|
{ "topic": "homegear/instance1/plain/37/1/STATE", "label": "Garten Fenster" },
|
||||||
|
{ "topic": "homegear/instance1/plain/36/1/STATE", "label": "Garten Tuer" },
|
||||||
|
{ "topic": "homegear/instance1/plain/38/1/STATE", "label": "Strasse rechts" },
|
||||||
|
{ "topic": "homegear/instance1/plain/13/1/STATE", "label": "Strasse links" }
|
||||||
|
],
|
||||||
|
"output_topic": "heating/homegear/instance1/set/40/1/SET_TEMPERATURE"
|
||||||
|
},
|
||||||
|
"box3": {
|
||||||
|
"label": "bad_oben",
|
||||||
|
"windows": [
|
||||||
|
],
|
||||||
|
"output_topic": "heating/homegear/instance1/set/41/1/SET_TEMPERATURE"
|
||||||
|
},
|
||||||
|
"box4": {
|
||||||
|
"label": "schlafzimmer",
|
||||||
|
"windows": [
|
||||||
|
{ "topic": "homegear/instance1/plain/52/1/STATE", "label": "Strasse" }
|
||||||
|
],
|
||||||
|
"output_topic": "heating/homegear/instance1/set/42/1/SET_TEMPERATURE"
|
||||||
|
},
|
||||||
|
"box5": {
|
||||||
|
"label": "wolfgang",
|
||||||
|
"windows": [
|
||||||
|
{ "topic": "homegear/instance1/plain/24/1/STATE", "label": "Garten" }
|
||||||
|
],
|
||||||
|
"output_topic": "heating/homegear/instance1/set/43/1/SET_TEMPERATURE"
|
||||||
|
},
|
||||||
|
"box6": {
|
||||||
|
"label": "esszimmer",
|
||||||
|
"windows": [
|
||||||
|
{ "topic": "homegear/instance1/plain/26/1/STATE", "label": "Strasse rechts" },
|
||||||
|
{ "topic": "homegear/instance1/plain/27/1/STATE", "label": "Strasse links" }
|
||||||
|
],
|
||||||
|
"output_topic": "heating/homegear/instance1/set/45/1/SET_TEMPERATURE"
|
||||||
|
},
|
||||||
|
"box7": {
|
||||||
|
"label": "wohnzimmer",
|
||||||
|
"windows": [
|
||||||
|
{ "topic": "homegear/instance1/plain/28/1/STATE", "label": "Garten rechts" },
|
||||||
|
{ "topic": "homegear/instance1/plain/29/1/STATE", "label": "Garten links" }
|
||||||
|
],
|
||||||
|
"output_topic": "heating/homegear/instance1/set/46/1/SET_TEMPERATURE"
|
||||||
|
},
|
||||||
|
"box8": {
|
||||||
|
"label": "bad_unten",
|
||||||
|
"windows": [
|
||||||
|
{ "topic": "homegear/instance1/plain/44/1/STATE", "label": "Strasse" }
|
||||||
|
],
|
||||||
|
"output_topic": "heating/homegear/instance1/set/48/1/SET_TEMPERATURE"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,52 +1,9 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: ConfigMap
|
|
||||||
metadata:
|
|
||||||
name: heating-controller-config
|
|
||||||
data:
|
|
||||||
MQTT_BROKER: "emqx01-anonymous-cluster-internal.broker.svc.cluster.local"
|
|
||||||
MQTT_PORT: "1883"
|
|
||||||
MQTT_CLIENT_PREFIX: "HeatingController"
|
|
||||||
MQTT_BOX_TOPIC_PREFIXES: |
|
|
||||||
{
|
|
||||||
"high_temp": "heating/config/high_temp/",
|
|
||||||
"cmd": "heating/command/"
|
|
||||||
}
|
|
||||||
MQTT_CENTRAL_TOPICS: |
|
|
||||||
{
|
|
||||||
"general_off": "heating/system/general_off",
|
|
||||||
"maintenance_mode": "heating/system/maintenance_mode",
|
|
||||||
"status": "heating/system/status"
|
|
||||||
}
|
|
||||||
MQTT_STATUS_TOPIC: "heating/status"
|
|
||||||
OFF_TEMPERATURE: "5.0"
|
|
||||||
LOW_TEMPERATURE: "15.0"
|
|
||||||
DEFAULT_HIGH_TEMPERATURE: "21.0"
|
|
||||||
MAINTENANCE_TEMPERATURE: "30.0"
|
|
||||||
BOXES: |
|
|
||||||
{
|
|
||||||
"box1": {
|
|
||||||
"label": "living_room",
|
|
||||||
"windows": [
|
|
||||||
{ "topic": "window/living_room/street_side", "label": "street_side" },
|
|
||||||
{ "topic": "window/living_room/garden_side", "label": "garden_side" }
|
|
||||||
],
|
|
||||||
"output_topic": "output/living_room"
|
|
||||||
},
|
|
||||||
"box2": {
|
|
||||||
"label": "kitchen",
|
|
||||||
"windows": [
|
|
||||||
{ "topic": "window/kitchen/street_side", "label": "street_side" },
|
|
||||||
{ "topic": "window/kitchen/garden_side", "label": "garden_side" },
|
|
||||||
{ "topic": "window/kitchen/garden_door", "label": "garden_door" }
|
|
||||||
],
|
|
||||||
"output_topic": "output/kitchen"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
---
|
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
name: heating-controller
|
name: heating-controller
|
||||||
|
annotations:
|
||||||
|
configmap.reloader.stakater.com/reload: "heating-controller-config"
|
||||||
spec:
|
spec:
|
||||||
replicas: 1
|
replicas: 1
|
||||||
selector:
|
selector:
|
||||||
|
@ -16,6 +16,8 @@ kubectl create namespace $NAMESPACE \
|
|||||||
-o yaml | \
|
-o yaml | \
|
||||||
kubectl -f - apply
|
kubectl -f - apply
|
||||||
|
|
||||||
|
kubectl apply -f $DEPLOYMENT_DIR/configmap.yml -n $NAMESPACE
|
||||||
|
|
||||||
cat $DEPLOYMENT_DIR/deploy-yml.tmpl | \
|
cat $DEPLOYMENT_DIR/deploy-yml.tmpl | \
|
||||||
sed -e 's,%IMAGE%,'$IMAGE_NAME':'$IMAGE_TAG','g | \
|
sed -e 's,%IMAGE%,'$IMAGE_NAME':'$IMAGE_TAG','g | \
|
||||||
kubectl apply -f - -n $NAMESPACE
|
kubectl apply -f - -n $NAMESPACE
|
||||||
|
12
src/main.py
12
src/main.py
@ -91,8 +91,8 @@ CLIENT_ID = f"{CLIENT_PREFIX}_{uuid.uuid4()}"
|
|||||||
topic_mapping = {}
|
topic_mapping = {}
|
||||||
|
|
||||||
# Callback function for successful connection to the broker
|
# Callback function for successful connection to the broker
|
||||||
def on_connect(client, userdata, flags, rc):
|
def on_connect(client, userdata, flags, reason_code, properties):
|
||||||
if rc == 0:
|
if reason_code == 0:
|
||||||
logger.info("Connected to the broker")
|
logger.info("Connected to the broker")
|
||||||
|
|
||||||
# Subscribe to dynamically generated topics for each box and create mappings
|
# Subscribe to dynamically generated topics for each box and create mappings
|
||||||
@ -125,7 +125,7 @@ def on_connect(client, userdata, flags, rc):
|
|||||||
topic_mapping[central_topic] = ("__central__", central_key)
|
topic_mapping[central_topic] = ("__central__", central_key)
|
||||||
logger.info(f"Subscribed to central topic '{central_topic}' (Key: '{central_key}')")
|
logger.info(f"Subscribed to central topic '{central_topic}' (Key: '{central_key}')")
|
||||||
else:
|
else:
|
||||||
logger.error(f"Connection error with code {rc}")
|
logger.error(f"Connection error with code {reason_code}")
|
||||||
|
|
||||||
# Callback function for received messages
|
# Callback function for received messages
|
||||||
def on_message(client, userdata, msg):
|
def on_message(client, userdata, msg):
|
||||||
@ -149,8 +149,8 @@ def on_message(client, userdata, msg):
|
|||||||
logger.error(f"Error processing message from '{msg.topic}': {e}")
|
logger.error(f"Error processing message from '{msg.topic}': {e}")
|
||||||
|
|
||||||
# Callback function for disconnection
|
# Callback function for disconnection
|
||||||
def on_disconnect(client, userdata, rc):
|
def on_disconnect(client, userdata, flags, reason_code, properties):
|
||||||
if rc != 0:
|
if reason_code != 0:
|
||||||
logger.warning("Unexpected disconnection, attempting to reconnect...")
|
logger.warning("Unexpected disconnection, attempting to reconnect...")
|
||||||
else:
|
else:
|
||||||
logger.info("Disconnected from the broker.")
|
logger.info("Disconnected from the broker.")
|
||||||
@ -161,7 +161,7 @@ def handle_exit_signal(signum, frame):
|
|||||||
client.disconnect() # Disconnects from the broker and stops loop_forever()
|
client.disconnect() # Disconnects from the broker and stops loop_forever()
|
||||||
|
|
||||||
# Initialize the MQTT client and configure callbacks
|
# Initialize the MQTT client and configure callbacks
|
||||||
client = mqtt.Client(client_id=CLIENT_ID)
|
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=CLIENT_ID, )
|
||||||
|
|
||||||
context['client'] = client
|
context['client'] = client
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ def process_message(box_name, topic_key, payload, context):
|
|||||||
try:
|
try:
|
||||||
box = context['boxes'][box_name]
|
box = context['boxes'][box_name]
|
||||||
local_context = box['context']
|
local_context = box['context']
|
||||||
logger.info(f"{local_context=}")
|
logger.info(f"Local context before: {local_context}")
|
||||||
logger.info(f"[{box_name}, {box['label']}] Processing message for '{topic_key}': {payload}")
|
logger.info(f"[{box_name}, {box['label']}] Processing message for '{topic_key}': {payload}")
|
||||||
|
|
||||||
match topic_key.split('/'):
|
match topic_key.split('/'):
|
||||||
@ -59,6 +59,8 @@ def process_message(box_name, topic_key, payload, context):
|
|||||||
publish_topic = box["output_topic"] if not status else context['status_topic']
|
publish_topic = box["output_topic"] if not status else context['status_topic']
|
||||||
context['client'].publish(publish_topic, result_message)
|
context['client'].publish(publish_topic, result_message)
|
||||||
logger.info(f"[{box_name}] Result published on '{publish_topic}': {status} {result_message}")
|
logger.info(f"[{box_name}] Result published on '{publish_topic}': {status} {result_message}")
|
||||||
|
|
||||||
|
logger.info(f"Local context after: {local_context}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"[{box_name}] Error processing '{topic_key}': {e}")
|
logger.error(f"[{box_name}] Error processing '{topic_key}': {e}")
|
||||||
|
|
||||||
@ -117,7 +119,7 @@ def process_high_temp(box_name, context, local_context, payload):
|
|||||||
return (local_context['output_temperature'], False)
|
return (local_context['output_temperature'], False)
|
||||||
|
|
||||||
def process_window(box_name, context, local_context, sub_key, payload):
|
def process_window(box_name, context, local_context, sub_key, payload):
|
||||||
local_context['window_state'][sub_key] = 'closed' if (payload.lower() in ('true', 'close', 'closed')) else 'open'
|
local_context['window_state'][sub_key] = 'closed' if (payload.lower() in ('false', 'close', 'closed')) else 'open'
|
||||||
_calculate_output_temperature(local_context)
|
_calculate_output_temperature(local_context)
|
||||||
return (local_context['output_temperature'], False)
|
return (local_context['output_temperature'], False)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user