changeset 5:8390d5d0d512

one mqtt message can convert to multiple measurements
author drewp@bigasterisk.com
date Sat, 10 Aug 2024 23:02:51 -0700
parents cd1b8d7bda78
children bc2a93b306e9
files convert.py mqtt_metrics.py
diffstat 2 files changed, 17 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/convert.py	Sat Aug 10 21:16:19 2024 -0700
+++ b/convert.py	Sat Aug 10 23:02:51 2024 -0700
@@ -4,6 +4,10 @@
 converters = []
 
 
+def f_from_c(c):
+    return (c * 9 / 5) + 32
+
+
 def topic(topic_pattern: str):
 
     def decorator(func):
@@ -15,8 +19,8 @@
 
 
 @topic(r'([^-]+)-air-quality/sensor/particulate_matter__10_0__m_concentration/state')
-def pm(message, topicGroups: tuple[str]):
-    return {
+def pm(message, topicGroups: tuple[str]) -> list[dict]:
+    return [{
         'name': 'air_quality_pm',
         'labels': [{
             'labelName': 'location',
@@ -26,16 +30,16 @@
             'labelValue': '10',
         }],
         'value': float(message['payload']),
-    }
+    }]
 
 
 @topic(r'([^-]+)-air-quality/sensor/air_temperature_c/state')
-def air_temp(message, topicGroups: tuple[str]):
-    return {
+def air_temp(message, topicGroups: tuple[str]) -> list[dict]:
+    return [{
         'name': 'air_temperature_f',
         'labels': [{
             'labelName': 'location',
             'labelValue': topicGroups[0],
         }],
-        'value': (float(message['payload']) * 9 / 5) + 32,
-    }
+        'value': f_from_c(float(message['payload'])),
+    }]
--- a/mqtt_metrics.py	Sat Aug 10 21:16:19 2024 -0700
+++ b/mqtt_metrics.py	Sat Aug 10 23:02:51 2024 -0700
@@ -77,21 +77,21 @@
 def onMqttMessage(metrics, mqttMessage):
     message = simplifyMqttMessage(mqttMessage)
 
-    metricEvent = tryConverters(message)
-    if metricEvent:
+    metricEvents = tryConverters(message)
+    for metricEvent in metricEvents:
         metrics.write(message['t'], metricEvent)
         broadcastToDebugListeners({'message': message, 'metricEvent': metricEvent})
 
 
-def tryConverters(message) -> dict | None:
-    metricEvent = None
+def tryConverters(message) -> list[dict]:
+    metricEvents: list[dict] = []
     matchedPats = []
     for converter in converters:
         if not (m := re.search(converter.topic_pattern, message['topic'])):
             continue
         if not matchedPats:
             try:
-                metricEvent = converter(message, cast(tuple[str], m.groups()))
+                metricEvents.extend(converter(message, cast(tuple[str], m.groups())))
             except Exception:
                 log.error("Error converting mqtt message: topic pattern = %r", converter.topic_pattern, exc_info=True)
             matchedPats.append(converter.topic_pattern)
@@ -99,7 +99,7 @@
     if len(matchedPats) > 1:
         log.warning("Multiple patterns matched: %s", ", ".join(matchedPats))
 
-    return metricEvent
+    return metricEvents
 
 
 def main():