modpoll 1.3.3__tar.gz → 1.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {modpoll-1.3.3 → modpoll-1.4.0}/PKG-INFO +1 -1
- {modpoll-1.3.3 → modpoll-1.4.0}/modpoll/arg_parser.py +2 -2
- {modpoll-1.3.3 → modpoll-1.4.0}/modpoll/modbus_task.py +30 -12
- {modpoll-1.3.3 → modpoll-1.4.0}/pyproject.toml +1 -1
- {modpoll-1.3.3 → modpoll-1.4.0}/LICENSE +0 -0
- {modpoll-1.3.3 → modpoll-1.4.0}/README.md +0 -0
- {modpoll-1.3.3 → modpoll-1.4.0}/modpoll/__init__.py +0 -0
- {modpoll-1.3.3 → modpoll-1.4.0}/modpoll/__main__.py +0 -0
- {modpoll-1.3.3 → modpoll-1.4.0}/modpoll/main.py +0 -0
- {modpoll-1.3.3 → modpoll-1.4.0}/modpoll/mqtt_task.py +0 -0
- {modpoll-1.3.3 → modpoll-1.4.0}/modpoll/utils.py +0 -0
|
@@ -39,8 +39,8 @@ def get_parser():
|
|
|
39
39
|
parser.add_argument(
|
|
40
40
|
"--interval",
|
|
41
41
|
type=float,
|
|
42
|
-
default=
|
|
43
|
-
help="The time interval in seconds between two polling, Defaults to
|
|
42
|
+
default=0.5,
|
|
43
|
+
help="The time interval in seconds between two polling, Defaults to 0.5",
|
|
44
44
|
)
|
|
45
45
|
parser.add_argument(
|
|
46
46
|
"--tcp", help="Act as a Modbus TCP master, connecting to host TCP"
|
|
@@ -264,10 +264,11 @@ class ModbusHandler:
|
|
|
264
264
|
config_file: str,
|
|
265
265
|
mqtt_handler: Optional[MqttHandler] = None,
|
|
266
266
|
timeout: float = 3.0,
|
|
267
|
-
interval: float =
|
|
267
|
+
interval: float = 0.5,
|
|
268
268
|
daemon: bool = False,
|
|
269
269
|
mqtt_publish_topic_pattern: Optional[str] = None,
|
|
270
270
|
mqtt_diagnostics_topic_pattern: Optional[str] = None,
|
|
271
|
+
mqtt_single_publish: bool = False,
|
|
271
272
|
):
|
|
272
273
|
self.modbus_client = modbus_client
|
|
273
274
|
self.config_file = config_file
|
|
@@ -277,6 +278,7 @@ class ModbusHandler:
|
|
|
277
278
|
self.daemon = daemon
|
|
278
279
|
self.mqtt_publish_topic_pattern = mqtt_publish_topic_pattern
|
|
279
280
|
self.mqtt_diagnostics_topic_pattern = mqtt_diagnostics_topic_pattern
|
|
281
|
+
self.mqtt_single_publish = mqtt_single_publish
|
|
280
282
|
self.connected = False
|
|
281
283
|
self.deviceList: List[Device] = []
|
|
282
284
|
self.logger = logging.getLogger(__name__)
|
|
@@ -319,7 +321,7 @@ class ModbusHandler:
|
|
|
319
321
|
continue
|
|
320
322
|
device_name = row[1].strip()
|
|
321
323
|
try:
|
|
322
|
-
device_id = int(row[2])
|
|
324
|
+
device_id = int(row[2], 0)
|
|
323
325
|
except ValueError:
|
|
324
326
|
self.logger.error(f"Invalid device ID for {device_name}")
|
|
325
327
|
continue
|
|
@@ -357,8 +359,8 @@ class ModbusHandler:
|
|
|
357
359
|
return None
|
|
358
360
|
fc = row[1].lower()
|
|
359
361
|
try:
|
|
360
|
-
start_address = int(row[2])
|
|
361
|
-
size = int(row[3])
|
|
362
|
+
start_address = int(row[2], 0)
|
|
363
|
+
size = int(row[3], 0)
|
|
362
364
|
except ValueError:
|
|
363
365
|
self.logger.error("Invalid start address or size for poller")
|
|
364
366
|
return None
|
|
@@ -401,7 +403,7 @@ class ModbusHandler:
|
|
|
401
403
|
return None
|
|
402
404
|
ref_name = row[1].replace(" ", "_")
|
|
403
405
|
try:
|
|
404
|
-
address = int(row[2])
|
|
406
|
+
address = int(row[2], 0)
|
|
405
407
|
except ValueError:
|
|
406
408
|
self.logger.error(f"Invalid address for reference {ref_name}")
|
|
407
409
|
return None
|
|
@@ -507,22 +509,37 @@ class ModbusHandler:
|
|
|
507
509
|
print(table)
|
|
508
510
|
|
|
509
511
|
def publish_data(self, timestamp=None, on_change=False):
|
|
510
|
-
if not self.mqtt_handler:
|
|
511
|
-
return
|
|
512
|
-
if not self.mqtt_publish_topic_pattern:
|
|
512
|
+
if not self.mqtt_handler or not self.mqtt_publish_topic_pattern:
|
|
513
513
|
return
|
|
514
|
+
|
|
514
515
|
for dev in self.deviceList:
|
|
516
|
+
if not dev.pollSuccess:
|
|
517
|
+
self.logger.debug(
|
|
518
|
+
f"Skip publishing for disconnected device: {dev.name}"
|
|
519
|
+
)
|
|
520
|
+
continue
|
|
521
|
+
|
|
515
522
|
payload = {}
|
|
516
523
|
for ref in dev.references.values():
|
|
517
524
|
if not on_change or ref.val != ref.last_val:
|
|
518
|
-
|
|
525
|
+
ref_val = (
|
|
519
526
|
round(ref.val, FLOAT_TYPE_PRECISION)
|
|
520
527
|
if isinstance(ref.val, float)
|
|
521
528
|
else ref.val
|
|
522
529
|
)
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
530
|
+
key = f"{ref.name}|{ref.unit}" if ref.unit else ref.name
|
|
531
|
+
payload[key] = ref_val
|
|
532
|
+
|
|
533
|
+
if self.mqtt_single_publish:
|
|
534
|
+
topic = f"{self.mqtt_publish_topic_pattern.replace('{{device_name}}', dev.name)}/{ref.name}"
|
|
535
|
+
if isinstance(ref_val, list):
|
|
536
|
+
for i, entry in enumerate(ref_val):
|
|
537
|
+
self.mqtt_handler.publish(f"{topic}/{i}", entry)
|
|
538
|
+
else:
|
|
539
|
+
self.mqtt_handler.publish(topic, ref_val)
|
|
540
|
+
|
|
541
|
+
if payload and not self.mqtt_single_publish:
|
|
542
|
+
if timestamp is not None:
|
|
526
543
|
payload["timestamp"] = timestamp
|
|
527
544
|
topic = self.mqtt_publish_topic_pattern.replace(
|
|
528
545
|
"{{device_name}}", dev.name
|
|
@@ -581,6 +598,7 @@ def setup_modbus_handlers(args, mqtt_handler: Optional[MqttHandler] = None):
|
|
|
581
598
|
daemon=args.daemon,
|
|
582
599
|
mqtt_publish_topic_pattern=args.mqtt_publish_topic_pattern,
|
|
583
600
|
mqtt_diagnostics_topic_pattern=args.mqtt_diagnostics_topic_pattern,
|
|
601
|
+
mqtt_single_publish=args.mqtt_single,
|
|
584
602
|
)
|
|
585
603
|
if modbus_handler.load_config():
|
|
586
604
|
modbus_handlers.append(modbus_handler)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|