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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: modpoll
3
- Version: 1.3.3
3
+ Version: 1.4.0
4
4
  Summary: A New Command-line Tool for Modbus and MQTT
5
5
  Home-page: https://github.com/gavinying/modpoll
6
6
  Author: Ying Shaodong
@@ -39,8 +39,8 @@ def get_parser():
39
39
  parser.add_argument(
40
40
  "--interval",
41
41
  type=float,
42
- default=1.0,
43
- help="The time interval in seconds between two polling, Defaults to 1.0",
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 = 1.0,
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
- value = (
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
- payload[ref.name] = value
524
- if payload:
525
- if timestamp:
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)
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "modpoll"
3
- version = "v1.3.3"
3
+ version = "v1.4.0"
4
4
  description = "A New Command-line Tool for Modbus and MQTT"
5
5
  authors = ["Ying Shaodong <helloysd@gmail.com>"]
6
6
  repository = "https://github.com/gavinying/modpoll"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes