1616package com .hivemq .edge .adapters .modbus ;
1717
1818import com .hivemq .adapter .sdk .api .ProtocolAdapterInformation ;
19- import com .hivemq .adapter .sdk .api .config .PollingContext ;
2019import com .hivemq .adapter .sdk .api .data .DataPoint ;
2120import com .hivemq .adapter .sdk .api .discovery .NodeTree ;
2221import com .hivemq .adapter .sdk .api .discovery .NodeType ;
3433import com .hivemq .adapter .sdk .api .state .ProtocolAdapterState ;
3534import com .hivemq .edge .adapters .modbus .config .AddressRange ;
3635import com .hivemq .edge .adapters .modbus .config .ModbusAdapterConfig ;
36+ import com .hivemq .edge .adapters .modbus .config .ModbusAdu ;
37+ import com .hivemq .edge .adapters .modbus .config .ModbusDataType ;
3738import com .hivemq .edge .adapters .modbus .config .ModbusToMqttMapping ;
3839import com .hivemq .edge .adapters .modbus .impl .ModbusClient ;
3940import com .hivemq .edge .adapters .modbus .model .ModBusData ;
5051import java .util .concurrent .CompletableFuture ;
5152
5253import static com .hivemq .adapter .sdk .api .state .ProtocolAdapterState .ConnectionStatus .CONNECTED ;
54+ import static com .hivemq .adapter .sdk .api .state .ProtocolAdapterState .ConnectionStatus .DISCONNECTED ;
5355
5456public class ModbusProtocolAdapter implements PollingProtocolAdapter <ModbusToMqttMapping > {
5557 private static final Logger log = LoggerFactory .getLogger (ModbusProtocolAdapter .class );
56- private final @ NotNull Object lock = new Object ();
5758 private final @ NotNull ProtocolAdapterInformation adapterInformation ;
5859 private final @ NotNull ModbusAdapterConfig adapterConfig ;
5960 private final @ NotNull ProtocolAdapterState protocolAdapterState ;
6061 private final @ NotNull AdapterFactories adapterFactories ;
6162
62- private volatile @ Nullable ModbusClient modbusClient ;
63+ private final @ Nullable ModbusClient modbusClient ;
6364 private final @ NotNull Map <ModbusToMqttMapping , List <DataPoint >> lastSamples = new HashMap <>();
6465
6566 public ModbusProtocolAdapter (
@@ -70,31 +71,35 @@ public ModbusProtocolAdapter(
7071 this .adapterConfig = adapterConfig ;
7172 this .protocolAdapterState = input .getProtocolAdapterState ();
7273 this .adapterFactories = input .adapterFactories ();
74+ this .modbusClient = new ModbusClient (adapterConfig , adapterFactories .dataPointFactory ());
7375 }
7476
7577 @ Override
76- public void start (
77- @ NotNull final ProtocolAdapterStartInput input , @ NotNull final ProtocolAdapterStartOutput output ) {
78- try {
79- initConnection ();
80- output .startedSuccessfully ();
81- } catch (final Exception e ) {
82- output .failStart (e , "Exception during setup of Modbus client." );
83- }
84-
78+ public void start (@ NotNull final ProtocolAdapterStartInput input , @ NotNull final ProtocolAdapterStartOutput output ) {
79+ modbusClient
80+ .connect ()
81+ .whenComplete ((unused , throwable ) -> {
82+ if (throwable == null ) {
83+ output .startedSuccessfully ();
84+ protocolAdapterState .setConnectionStatus (CONNECTED );
85+ } else {
86+ output .failStart (throwable , "Exception during setup of Modbus client." );
87+ }});
8588 }
8689
8790 @ Override
8891 public void stop (@ NotNull final ProtocolAdapterStopInput input , @ NotNull final ProtocolAdapterStopOutput output ) {
89- try {
90- if (modbusClient != null ) {
91- modbusClient .disconnect ();
92- }
93- } catch (final Exception e ) {
94- output .failStop (e , "Error encountered closing connection to Modbus device." );
95- return ;
96- }
97- output .stoppedSuccessfully ();
92+ modbusClient
93+ .disconnect ()
94+ .whenComplete ((unused ,t ) -> {
95+ if (t == null ) {
96+ output .stoppedSuccessfully ();
97+ protocolAdapterState .setConnectionStatus (DISCONNECTED );
98+ } else {
99+ output .failStop (t , "Error encountered closing connection to Modbus device." );
100+ }
101+ }
102+ );
98103 }
99104
100105 @ Override
@@ -103,25 +108,15 @@ public void poll(
103108
104109 //-- If a previously linked job has terminally disconnected the client
105110 //-- we need to ensure any orphaned jobs tidy themselves up properly
106- try {
107- if (modbusClient != null ) {
108- if (!modbusClient .isConnected ()) {
109- modbusClient .connect ().thenRun (() -> protocolAdapterState .setConnectionStatus (CONNECTED )).get ();
111+
112+ readRegisters (pollingInput .getPollingContext (), modbusClient )
113+ .whenComplete ((modbusdata , throwable ) -> {
114+ if (throwable != null ) {
115+ pollingOutput .fail (throwable , null );
116+ } else {
117+ this .captureDataSample (modbusdata , pollingOutput );
110118 }
111- CompletableFuture .supplyAsync (() -> readRegisters (pollingInput .getPollingContext ()))
112- .whenComplete ((modbusdata , throwable ) -> {
113- if (throwable != null ) {
114- pollingOutput .fail (throwable , null );
115- } else {
116- this .captureDataSample (modbusdata , pollingOutput );
117- }
118- });
119- } else {
120- pollingOutput .fail (new IllegalStateException ("client not initialised" ),"The client is not initialised." );
121- }
122- } catch (final Exception e ) {
123- pollingOutput .fail (e , null );
124- }
119+ });
125120 }
126121
127122 @ Override
@@ -139,21 +134,6 @@ public int getMaxPollingErrorsBeforeRemoval() {
139134 return adapterConfig .getModbusToMQTTConfig ().getMaxPollingErrorsBeforeRemoval ();
140135 }
141136
142-
143- private @ NotNull ModbusClient initConnection () {
144- if (modbusClient == null ) {
145- synchronized (lock ) {
146- if (modbusClient == null ) {
147- if (log .isTraceEnabled ()) {
148- log .trace ("Creating new instance of Modbus Client with {}." , adapterConfig );
149- }
150- modbusClient = new ModbusClient (adapterConfig , adapterFactories .dataPointFactory ());
151- }
152- }
153- }
154- return modbusClient ;
155- }
156-
157137 @ Override
158138 public @ NotNull String getId () {
159139 return adapterConfig .getId ();
@@ -218,21 +198,62 @@ private void calculateDelta(@NotNull final ModBusData modBusData, @NotNull final
218198 }
219199 }
220200
221- protected @ NotNull ModBusData readRegisters (final @ NotNull ModbusToMqttMapping modbusToMqttMapping ) {
222- try {
223- final AddressRange addressRange = modbusToMqttMapping .getAddressRange ();
224- final DataPoint dataPoint = modbusClient .readHoldingRegisters (addressRange .startIdx ,
225- addressRange .nrRegistersToRead , modbusToMqttMapping .getDataType ());
226- final ModBusData data = new ModBusData (modbusToMqttMapping );
227- data .addDataPoint (dataPoint );
228- return data ;
229- } catch (final Exception e ) {
230- throw new RuntimeException (e );
201+ protected static @ NotNull CompletableFuture <ModBusData > readRegisters (
202+ final @ NotNull ModbusToMqttMapping modbusToMqttMapping ,
203+ final @ NotNull ModbusClient modbusClient ) {
204+ final AddressRange addressRange = modbusToMqttMapping .getAddressRange ();
205+
206+ return doRead (addressRange .startIdx , addressRange .unitId , addressRange .flipRegisters , modbusToMqttMapping .getDataType (), addressRange .readType , modbusClient )
207+ .thenApply (dataPoint -> {
208+ final ModBusData data = new ModBusData (modbusToMqttMapping );
209+ data .addDataPoint (dataPoint );
210+ return data ;
211+ });
212+ }
213+
214+ protected static CompletableFuture <DataPoint > doRead (
215+ final int startIdx ,
216+ final int unitId ,
217+ final boolean flipRegisters ,
218+ final @ NotNull ModbusDataType dataType ,
219+ final @ NotNull ModbusAdu readType ,
220+ final @ NotNull ModbusClient modbusClient ) {
221+ switch (readType ) {
222+ case HOLDING_REGISTERS :
223+ return modbusClient
224+ .readHoldingRegisters (
225+ startIdx ,
226+ dataType ,
227+ unitId ,
228+ flipRegisters );
229+ case INPUT_REGISTERS :
230+ return modbusClient
231+ .readInputRegisters (
232+ startIdx ,
233+ dataType ,
234+ unitId ,
235+ flipRegisters );
236+ case COILS :
237+ return modbusClient
238+ .readCoils (
239+ startIdx ,
240+ unitId );
241+ case DISCRETE_INPUT :
242+ return modbusClient
243+ .readDiscreteInput (
244+ startIdx ,
245+ unitId );
246+ default :
247+ return CompletableFuture .failedFuture (new Exception ("Unknown read type " + readType ));
231248 }
232249 }
233250
234251 private static void addAddresses (
235- @ NotNull final NodeTree tree , @ NotNull final String parent , final int startIdx , final int count , final int groupIdx ) {
252+ @ NotNull final NodeTree tree ,
253+ @ NotNull final String parent ,
254+ final int startIdx ,
255+ final int count ,
256+ final int groupIdx ) {
236257
237258 String parentNode = parent ;
238259 if (groupIdx < count ) {
0 commit comments