Skip to content

Commit

Permalink
feat: Publish MQTT message for each single reference.
Browse files Browse the repository at this point in the history
The topic contains reference name and the payload only contains reference value.
  • Loading branch information
gavinying committed Oct 17, 2024
1 parent b2c2753 commit adb869f
Showing 1 changed file with 25 additions and 7 deletions.
32 changes: 25 additions & 7 deletions modpoll/modbus_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ def __init__(
daemon: bool = False,
mqtt_publish_topic_pattern: Optional[str] = None,
mqtt_diagnostics_topic_pattern: Optional[str] = None,
mqtt_single_publish: bool = False,
):
self.modbus_client = modbus_client
self.config_file = config_file
Expand All @@ -277,6 +278,7 @@ def __init__(
self.daemon = daemon
self.mqtt_publish_topic_pattern = mqtt_publish_topic_pattern
self.mqtt_diagnostics_topic_pattern = mqtt_diagnostics_topic_pattern
self.mqtt_single_publish = mqtt_single_publish
self.connected = False
self.deviceList: List[Device] = []
self.logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -507,22 +509,37 @@ def print_results(self):
print(table)

def publish_data(self, timestamp=None, on_change=False):
if not self.mqtt_handler:
return
if not self.mqtt_publish_topic_pattern:
if not self.mqtt_handler or not self.mqtt_publish_topic_pattern:
return

for dev in self.deviceList:
if not dev.pollSuccess:
self.logger.debug(
f"Skip publishing for disconnected device: {dev.name}"
)
continue

payload = {}
for ref in dev.references.values():
if not on_change or ref.val != ref.last_val:
value = (
ref_val = (
round(ref.val, FLOAT_TYPE_PRECISION)
if isinstance(ref.val, float)
else ref.val
)
payload[ref.name] = value
if payload:
if timestamp:
key = f"{ref.name}|{ref.unit}" if ref.unit else ref.name
payload[key] = ref_val

if self.mqtt_single_publish:
topic = f"{self.mqtt_publish_topic_pattern.replace('{{device_name}}', dev.name)}/{ref.name}"
if isinstance(ref_val, list):
for i, entry in enumerate(ref_val):
self.mqtt_handler.publish(f"{topic}/{i}", entry)
else:
self.mqtt_handler.publish(topic, ref_val)

if payload and not self.mqtt_single_publish:
if timestamp is not None:
payload["timestamp"] = timestamp
topic = self.mqtt_publish_topic_pattern.replace(
"{{device_name}}", dev.name
Expand Down Expand Up @@ -581,6 +598,7 @@ def setup_modbus_handlers(args, mqtt_handler: Optional[MqttHandler] = None):
daemon=args.daemon,
mqtt_publish_topic_pattern=args.mqtt_publish_topic_pattern,
mqtt_diagnostics_topic_pattern=args.mqtt_diagnostics_topic_pattern,
mqtt_single_publish=args.mqtt_single,
)
if modbus_handler.load_config():
modbus_handlers.append(modbus_handler)
Expand Down

0 comments on commit adb869f

Please sign in to comment.