@@ -21,6 +21,7 @@ public class EasyModbus2Mqtt
2121 public bool AutomaticReconnect { get ; set ; } = true ;
2222 public string MqttUserName { get ; set ; }
2323 public string MqttPassword { get ; set ; }
24+ public bool RetainMessages { get ; set ; }
2425
2526
2627 public EasyModbus2Mqtt ( )
@@ -37,6 +38,15 @@ public void AddReadOrder(ReadOrder readOrder)
3738 if ( readOrder . Topic != null )
3839 if ( readOrder . Topic . Length != readOrder . Quantity )
3940 throw new ArgumentOutOfRangeException ( "Size of the Topic array must mach with quantity" ) ;
41+ if ( readOrder . Retain != null )
42+ if ( readOrder . Retain . Length != readOrder . Quantity )
43+ throw new ArgumentOutOfRangeException ( "Size of the Retain array must mach with quantity" ) ;
44+ if ( readOrder . Hysteresis != null )
45+ if ( readOrder . Hysteresis . Length != readOrder . Quantity )
46+ throw new ArgumentOutOfRangeException ( "Size of the Hysteresis array must mach with quantity" ) ;
47+ if ( readOrder . Scale != null )
48+ if ( readOrder . Scale . Length != readOrder . Quantity )
49+ throw new ArgumentOutOfRangeException ( "Size of the Scale array must mach with quantity" ) ;
4050 if ( readOrder . CylceTime == 0 )
4151 readOrder . CylceTime = 500 ;
4252 if ( readOrder . Topic == null )
@@ -78,6 +88,7 @@ public void AddReadOrder(FunctionCode functionCode, int quantity, int startingAd
7888 readOrder . Quantity = quantity ;
7989 readOrder . StartingAddress = startingAddress ;
8090 readOrder . Topic = new string [ quantity ] ;
91+ readOrder . Retain = new bool [ quantity ] ;
8192 readOrder . oldvalue = new object [ quantity ] ;
8293 for ( int i = 0 ; i < quantity ; i ++ )
8394 {
@@ -169,6 +180,27 @@ public void publish(string[] topic, string[] payload, string mqttBrokerAddress)
169180
170181 }
171182
183+ public void publish ( string topic , string payload , string mqttBrokerAddress )
184+ {
185+ if ( mqttClient != null )
186+ if ( ! mqttBrokerAddress . Equals ( this . MqttBrokerAddressPublish ) & mqttClient . IsConnected )
187+ mqttClient . Disconnect ( ) ;
188+ mqttClient = new uPLibrary . Networking . M2Mqtt . MqttClient ( mqttBrokerAddress , mqttBrokerPort , false , null , null , uPLibrary . Networking . M2Mqtt . MqttSslProtocols . None ) ;
189+ string clientID = Guid . NewGuid ( ) . ToString ( ) ;
190+ if ( ! mqttClient . IsConnected )
191+ {
192+ if ( MqttUserName == null || MqttPassword == null )
193+ mqttClient . Connect ( clientID ) ;
194+ else
195+ mqttClient . Connect ( clientID , MqttUserName , MqttPassword ) ;
196+ }
197+
198+ if ( payload != null )
199+ mqttClient . Publish ( topic , Encoding . UTF8 . GetBytes ( payload ) , MqttMsgBase . QOS_LEVEL_EXACTLY_ONCE , RetainMessages ) ;
200+ else
201+ mqttClient . Publish ( topic , null , MqttMsgBase . QOS_LEVEL_EXACTLY_ONCE , RetainMessages ) ;
202+ }
203+
172204 public void Disconnect ( )
173205 {
174206 mqttClient . Disconnect ( ) ;
@@ -216,9 +248,9 @@ private void ProcessData(object param)
216248 for ( int i = 0 ; i < value . Length ; i ++ )
217249 {
218250 if ( readOrder . oldvalue [ i ] == null )
219- mqttClient . Publish ( readOrder . Topic [ i ] , Encoding . UTF8 . GetBytes ( value [ i ] . ToString ( ) ) , MqttMsgBase . QOS_LEVEL_EXACTLY_ONCE , false ) ;
251+ mqttClient . Publish ( readOrder . Topic [ i ] , Encoding . UTF8 . GetBytes ( value [ i ] . ToString ( ) ) , MqttMsgBase . QOS_LEVEL_EXACTLY_ONCE , readOrder . Retain [ i ] ) ;
220252 else if ( ( bool ) readOrder . oldvalue [ i ] != value [ i ] )
221- mqttClient . Publish ( readOrder . Topic [ i ] , Encoding . UTF8 . GetBytes ( value [ i ] . ToString ( ) ) , MqttMsgBase . QOS_LEVEL_EXACTLY_ONCE , false ) ;
253+ mqttClient . Publish ( readOrder . Topic [ i ] , Encoding . UTF8 . GetBytes ( value [ i ] . ToString ( ) ) , MqttMsgBase . QOS_LEVEL_EXACTLY_ONCE , readOrder . Retain [ i ] ) ;
222254 readOrder . oldvalue [ i ] = value [ i ] ;
223255 }
224256
@@ -229,9 +261,9 @@ private void ProcessData(object param)
229261 for ( int i = 0 ; i < value . Length ; i ++ )
230262 {
231263 if ( readOrder . oldvalue [ i ] == null )
232- mqttClient . Publish ( readOrder . Topic [ i ] , Encoding . UTF8 . GetBytes ( value [ i ] . ToString ( ) ) , MqttMsgBase . QOS_LEVEL_EXACTLY_ONCE , false ) ;
264+ mqttClient . Publish ( readOrder . Topic [ i ] , Encoding . UTF8 . GetBytes ( value [ i ] . ToString ( ) ) , MqttMsgBase . QOS_LEVEL_EXACTLY_ONCE , readOrder . Retain [ i ] ) ;
233265 else if ( ( bool ) readOrder . oldvalue [ i ] != value [ i ] )
234- mqttClient . Publish ( readOrder . Topic [ i ] , Encoding . UTF8 . GetBytes ( value [ i ] . ToString ( ) ) , MqttMsgBase . QOS_LEVEL_EXACTLY_ONCE , false ) ;
266+ mqttClient . Publish ( readOrder . Topic [ i ] , Encoding . UTF8 . GetBytes ( value [ i ] . ToString ( ) ) , MqttMsgBase . QOS_LEVEL_EXACTLY_ONCE , readOrder . Retain [ i ] ) ;
235267 readOrder . oldvalue [ i ] = value [ i ] ;
236268 }
237269 }
@@ -243,12 +275,12 @@ private void ProcessData(object param)
243275 float scale = readOrder . Scale != null ? ( readOrder . Scale [ i ] == 0 ) ? 1 : readOrder . Scale [ i ] : 1 ;
244276 if ( readOrder . oldvalue [ i ] == null )
245277 {
246- mqttClient . Publish ( readOrder . Topic [ i ] , ( readOrder . Unit == null ? Encoding . UTF8 . GetBytes ( ( ( float ) value [ i ] * scale ) . ToString ( ) ) : Encoding . UTF8 . GetBytes ( ( ( float ) value [ i ] * scale ) + " " + readOrder . Unit [ i ] ) ) , MqttMsgBase . QOS_LEVEL_EXACTLY_ONCE , false ) ;
278+ mqttClient . Publish ( readOrder . Topic [ i ] , ( readOrder . Unit == null ? Encoding . UTF8 . GetBytes ( ( ( float ) value [ i ] * scale ) . ToString ( ) ) : Encoding . UTF8 . GetBytes ( ( ( float ) value [ i ] * scale ) + " " + readOrder . Unit [ i ] ) ) , MqttMsgBase . QOS_LEVEL_EXACTLY_ONCE , readOrder . Retain [ i ] ) ;
247279 readOrder . oldvalue [ i ] = value [ i ] ;
248280 }
249281 else if ( ( ( int ) readOrder . oldvalue [ i ] != value [ i ] ) && ( readOrder . Hysteresis != null ? ( ( value [ i ] < ( int ) readOrder . oldvalue [ i ] - ( int ) readOrder . Hysteresis [ i ] ) | ( value [ i ] > ( int ) readOrder . oldvalue [ i ] + ( int ) readOrder . Hysteresis [ i ] ) ) : true ) )
250282 {
251- mqttClient . Publish ( readOrder . Topic [ i ] , ( readOrder . Unit == null ? Encoding . UTF8 . GetBytes ( ( ( float ) value [ i ] * scale ) . ToString ( ) ) : Encoding . UTF8 . GetBytes ( ( ( float ) value [ i ] * scale ) . ToString ( ) + " " + readOrder . Unit [ i ] ) ) , MqttMsgBase . QOS_LEVEL_EXACTLY_ONCE , false ) ;
283+ mqttClient . Publish ( readOrder . Topic [ i ] , ( readOrder . Unit == null ? Encoding . UTF8 . GetBytes ( ( ( float ) value [ i ] * scale ) . ToString ( ) ) : Encoding . UTF8 . GetBytes ( ( ( float ) value [ i ] * scale ) . ToString ( ) + " " + readOrder . Unit [ i ] ) ) , MqttMsgBase . QOS_LEVEL_EXACTLY_ONCE , readOrder . Retain [ i ] ) ;
252284 readOrder . oldvalue [ i ] = value [ i ] ;
253285 }
254286 }
@@ -262,12 +294,12 @@ private void ProcessData(object param)
262294 float scale = readOrder . Scale != null ? ( readOrder . Scale [ i ] == 0 ) ? 1 : readOrder . Scale [ i ] : 1 ;
263295 if ( readOrder . oldvalue [ i ] == null )
264296 {
265- mqttClient . Publish ( readOrder . Topic [ i ] , ( readOrder . Unit == null ? Encoding . UTF8 . GetBytes ( ( ( float ) value [ i ] * scale ) . ToString ( ) ) : Encoding . UTF8 . GetBytes ( ( ( float ) value [ i ] * scale ) . ToString ( ) + " " + readOrder . Unit [ i ] ) ) , MqttMsgBase . QOS_LEVEL_EXACTLY_ONCE , false ) ;
297+ mqttClient . Publish ( readOrder . Topic [ i ] , ( readOrder . Unit == null ? Encoding . UTF8 . GetBytes ( ( ( float ) value [ i ] * scale ) . ToString ( ) ) : Encoding . UTF8 . GetBytes ( ( ( float ) value [ i ] * scale ) . ToString ( ) + " " + readOrder . Unit [ i ] ) ) , MqttMsgBase . QOS_LEVEL_EXACTLY_ONCE , readOrder . Retain [ i ] ) ;
266298 readOrder . oldvalue [ i ] = value [ i ] ;
267299 }
268300 else if ( ( ( int ) readOrder . oldvalue [ i ] != value [ i ] ) && ( readOrder . Hysteresis != null ? ( ( value [ i ] < ( int ) readOrder . oldvalue [ i ] - ( int ) readOrder . Hysteresis [ i ] ) | ( value [ i ] > ( int ) readOrder . oldvalue [ i ] + ( int ) readOrder . Hysteresis [ i ] ) ) : true ) )
269301 {
270- mqttClient . Publish ( readOrder . Topic [ i ] , ( readOrder . Unit == null ? Encoding . UTF8 . GetBytes ( ( ( float ) value [ i ] * scale ) . ToString ( ) ) : Encoding . UTF8 . GetBytes ( ( ( float ) value [ i ] * scale ) . ToString ( ) + " " + readOrder . Unit [ i ] ) ) , MqttMsgBase . QOS_LEVEL_EXACTLY_ONCE , false ) ;
302+ mqttClient . Publish ( readOrder . Topic [ i ] , ( readOrder . Unit == null ? Encoding . UTF8 . GetBytes ( ( ( float ) value [ i ] * scale ) . ToString ( ) ) : Encoding . UTF8 . GetBytes ( ( ( float ) value [ i ] * scale ) . ToString ( ) + " " + readOrder . Unit [ i ] ) ) , MqttMsgBase . QOS_LEVEL_EXACTLY_ONCE , readOrder . Retain [ i ] ) ;
271303 readOrder . oldvalue [ i ] = value [ i ] ;
272304 }
273305 }
@@ -491,7 +523,8 @@ public class ReadOrder
491523 public string [ ] Topic ; //Symbolnames can by replaced, by default we Push to the topic e.g. for Coils: /modbusclient/coils/1
492524 public int [ ] Hysteresis ; //Values for 16-Bit Registers will be published of the dieffreence is greater than Hysteresis
493525 public string [ ] Unit ; //Unit for Analog Values (Holding Registers and Input Registers)
494- public float [ ] Scale ; //Scale for Analog Values (Holding Registers and Input Registers)
526+ public float [ ] Scale ; //Scale for Analog Values (Holding Registers and Input Registers)
527+ public bool [ ] Retain ; //Retain last Value in Broker
495528 internal System . Threading . Thread thread ;
496529 internal object [ ] oldvalue ;
497530 }
0 commit comments