@@ -94,15 +94,15 @@ def publish(self, topic: str, value: str, retain: bool = True):
94
94
return True
95
95
96
96
def rpc_subscribe (self , src ):
97
- t = src .topic_prefix
97
+ t = src .control_topic
98
98
if self .topic_prefix is not None :
99
99
t = self .topic_prefix + '/' + t
100
100
self .subscribers [t .lower () + '/rpc' ] = src
101
101
log .info (f"Subscribing to rpc topic { t } /rpc." )
102
102
self .client .subscribe (t + '/rpc' , 0 )
103
103
104
104
def rpc_unsubscribe (self , src ):
105
- t = src .topic_prefix
105
+ t = src .control_topic
106
106
if self .topic_prefix is not None :
107
107
t = self .topic_prefix + '/' + t
108
108
if self .subscribers .get (t .lower () + '/rpc' , None ) is not None :
@@ -237,13 +237,15 @@ class HoldingRegister(Register):
237
237
# pass the parameter "littleendian" with the value False or true (little endian) to define the endianness of the register to read. (Solax use little endian)
238
238
239
239
def __init__ (self , name : str , topic : str , register : int , typereg : str = "holding" , littleendian : bool = False , length : int = 1 ,
240
- mode : str = "r" , substract : float = 0 , divide : float = 1 ,
240
+ mode : str = "r" , substract : float = 0 , divide : float = 1 , min : float = None , max : float = None ,
241
241
format : str = "integer" , byteorder : str = "big" , wordorder : str = "big" ,
242
242
decimals : int = 0 , signed : bool = False , unitid : int = None , ** kvargs ):
243
243
super ().__init__ (name , topic , register , length , mode , unitid = unitid )
244
244
self .divide = divide
245
245
self .decimals = decimals
246
246
self .substract = substract
247
+ self .minvalue = min
248
+ self .maxvalue = max
247
249
self .signed = signed
248
250
self .typereg = typereg
249
251
self .format = "float" if format .lower () == "float" else "integer"
@@ -292,6 +294,9 @@ def get_value(self, src):
292
294
val = float (fmt .format ((float (val ) - float (self .substract )) / float (self .divide )))
293
295
else :
294
296
val = int (((float (val ) - float (self .substract )) / float (self .divide )))
297
+
298
+ if (self .maxvalue and val > self .maxvalue ) or (self .minvalue and val < self .minvalue ):
299
+ return None
295
300
return val
296
301
297
302
if self .signed and int (val ) >= 32768 :
@@ -303,6 +308,9 @@ def get_value(self, src):
303
308
else :
304
309
val = int (((int (val ) - float (self .substract )) / float (self .divide )))
305
310
311
+ if (self .maxvalue and val > self .maxvalue ) or (self .minvalue and val < self .minvalue ):
312
+ return None
313
+
306
314
return val
307
315
308
316
@@ -317,6 +325,7 @@ class ModbusSource:
317
325
318
326
def __init__ (self , name : str , broker : MqttBroker , host : str , port : int ,
319
327
schema : Schema , unitid : int = 1 , topic_prefix : str = None ,
328
+ control_topic : str = None ,
320
329
pollms : int = 100 , enabled : bool = True ):
321
330
self .mqtt = broker
322
331
self .host = host
@@ -341,10 +350,13 @@ def __init__(self, name: str, broker: MqttBroker, host: str, port: int,
341
350
self .pollms = pollms
342
351
self .is_online = False
343
352
self .was_online = None
344
- if topic_prefix :
345
- self .topic_prefix = topic_prefix
353
+ self .topic_prefix = topic_prefix
354
+ if control_topic :
355
+ self .control_topic = control_topic
356
+ elif self .topic_prefix :
357
+ self .control_topic = self .topic_prefix
346
358
else :
347
- self .topic_prefix = re .sub (r'/\s\s+/g' , '_' , self .name .strip ().lower ())
359
+ self .control_topic = re .sub (r'/\s\s+/g' , '_' , self .name .strip ().lower ())
348
360
349
361
self .mqtt .rpc_subscribe (self )
350
362
@@ -370,6 +382,8 @@ def poller_thread(self):
370
382
371
383
try :
372
384
val = r .get_value (self )
385
+ if val is None :
386
+ continue
373
387
except ModbusException as e :
374
388
log .error (f"Received exception({ e } ) while trying to read from modbus slave." )
375
389
self .is_online = False
@@ -415,7 +429,7 @@ def poller_thread(self):
415
429
finally :
416
430
try :
417
431
self .client .close ()
418
- topic = self .topic_prefix + '/online'
432
+ topic = self .control_topic + '/online'
419
433
if self .mqtt .is_connected :
420
434
self .mqtt .publish (topic , str (False ).lower ())
421
435
self .mqtt .rpc_unsubscribe (self )
@@ -427,7 +441,7 @@ def publish_changes(self):
427
441
return
428
442
429
443
if self .was_online is None or self .was_online != self .is_online :
430
- topic = self .topic_prefix + '/online'
444
+ topic = self .control_topic + '/online'
431
445
if self .mqtt .publish (topic , str (True ).lower ()):
432
446
self .was_online = self .is_online
433
447
@@ -436,12 +450,17 @@ def publish_changes(self):
436
450
rid = id (r )
437
451
if not self .track .get (rid , False ):
438
452
continue
439
- topic = self .topic_prefix + '/' + r .topic
453
+
454
+ topic = r .topic
455
+ if self .topic_prefix :
456
+ topic = self .topic_prefix + '/' + topic
457
+
440
458
val = None
441
459
if isinstance (self .cache [rid ], dict ):
442
460
val = json .dumps (self .cache [rid ])
443
461
else :
444
462
val = str (self .cache [rid ])
463
+
445
464
if self .mqtt .publish (topic , val ):
446
465
self .track [rid ] = False
447
466
else :
@@ -500,6 +519,7 @@ def main(argv):
500
519
int (source .get ("unitid" , 1 )),
501
520
pollms = int (source .get ("pollms" , 1000 )),
502
521
topic_prefix = source .get ("topic_prefix" , None ),
522
+ control_topic = source .get ("control_topic" , None ),
503
523
enabled = bool (source .get ("enabled" , True ))
504
524
)
505
525
)
0 commit comments