@@ -94,15 +94,15 @@ def publish(self, topic: str, value: str, retain: bool = True):
9494 return True
9595
9696 def rpc_subscribe (self , src ):
97- t = src .topic_prefix
97+ t = src .control_topic
9898 if self .topic_prefix is not None :
9999 t = self .topic_prefix + '/' + t
100100 self .subscribers [t .lower () + '/rpc' ] = src
101101 log .info (f"Subscribing to rpc topic { t } /rpc." )
102102 self .client .subscribe (t + '/rpc' , 0 )
103103
104104 def rpc_unsubscribe (self , src ):
105- t = src .topic_prefix
105+ t = src .control_topic
106106 if self .topic_prefix is not None :
107107 t = self .topic_prefix + '/' + t
108108 if self .subscribers .get (t .lower () + '/rpc' , None ) is not None :
@@ -237,13 +237,15 @@ class HoldingRegister(Register):
237237 # 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)
238238
239239 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 ,
241241 format : str = "integer" , byteorder : str = "big" , wordorder : str = "big" ,
242242 decimals : int = 0 , signed : bool = False , unitid : int = None , ** kvargs ):
243243 super ().__init__ (name , topic , register , length , mode , unitid = unitid )
244244 self .divide = divide
245245 self .decimals = decimals
246246 self .substract = substract
247+ self .minvalue = min
248+ self .maxvalue = max
247249 self .signed = signed
248250 self .typereg = typereg
249251 self .format = "float" if format .lower () == "float" else "integer"
@@ -292,6 +294,9 @@ def get_value(self, src):
292294 val = float (fmt .format ((float (val ) - float (self .substract )) / float (self .divide )))
293295 else :
294296 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
295300 return val
296301
297302 if self .signed and int (val ) >= 32768 :
@@ -303,6 +308,9 @@ def get_value(self, src):
303308 else :
304309 val = int (((int (val ) - float (self .substract )) / float (self .divide )))
305310
311+ if (self .maxvalue and val > self .maxvalue ) or (self .minvalue and val < self .minvalue ):
312+ return None
313+
306314 return val
307315
308316
@@ -317,6 +325,7 @@ class ModbusSource:
317325
318326 def __init__ (self , name : str , broker : MqttBroker , host : str , port : int ,
319327 schema : Schema , unitid : int = 1 , topic_prefix : str = None ,
328+ control_topic : str = None ,
320329 pollms : int = 100 , enabled : bool = True ):
321330 self .mqtt = broker
322331 self .host = host
@@ -341,10 +350,13 @@ def __init__(self, name: str, broker: MqttBroker, host: str, port: int,
341350 self .pollms = pollms
342351 self .is_online = False
343352 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
346358 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 ())
348360
349361 self .mqtt .rpc_subscribe (self )
350362
@@ -370,6 +382,8 @@ def poller_thread(self):
370382
371383 try :
372384 val = r .get_value (self )
385+ if val is None :
386+ continue
373387 except ModbusException as e :
374388 log .error (f"Received exception({ e } ) while trying to read from modbus slave." )
375389 self .is_online = False
@@ -415,7 +429,7 @@ def poller_thread(self):
415429 finally :
416430 try :
417431 self .client .close ()
418- topic = self .topic_prefix + '/online'
432+ topic = self .control_topic + '/online'
419433 if self .mqtt .is_connected :
420434 self .mqtt .publish (topic , str (False ).lower ())
421435 self .mqtt .rpc_unsubscribe (self )
@@ -427,7 +441,7 @@ def publish_changes(self):
427441 return
428442
429443 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'
431445 if self .mqtt .publish (topic , str (True ).lower ()):
432446 self .was_online = self .is_online
433447
@@ -436,12 +450,17 @@ def publish_changes(self):
436450 rid = id (r )
437451 if not self .track .get (rid , False ):
438452 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+
440458 val = None
441459 if isinstance (self .cache [rid ], dict ):
442460 val = json .dumps (self .cache [rid ])
443461 else :
444462 val = str (self .cache [rid ])
463+
445464 if self .mqtt .publish (topic , val ):
446465 self .track [rid ] = False
447466 else :
@@ -500,6 +519,7 @@ def main(argv):
500519 int (source .get ("unitid" , 1 )),
501520 pollms = int (source .get ("pollms" , 1000 )),
502521 topic_prefix = source .get ("topic_prefix" , None ),
522+ control_topic = source .get ("control_topic" , None ),
503523 enabled = bool (source .get ("enabled" , True ))
504524 )
505525 )
0 commit comments