@@ -169,7 +169,13 @@ protected PlcReadResponse processReadResponses(PlcReadRequest readRequest, Map<P
169169 if (!responses .containsKey (tagType )) {
170170 responses .put (tagType , new ArrayList <>());
171171 }
172- responses .get (tagType ).add (new Response (modbusTag .getAddress (), optimizedReadResponse .getPlcValue (tagName ).getRaw ()));
172+ PlcResponseCode responseCode = optimizedReadResponse .getResponseCode (tagName );
173+ int startingAddress = modbusTag .getAddress ();
174+ int endingAddressRegister = modbusTag .getAddress () + modbusTag .getNumberOfElements ();
175+ int endingAddressCoil = modbusTag .getAddress () + modbusTag .getNumberOfElements ();
176+ byte [] responseData = (responseCode == PlcResponseCode .OK ) ? optimizedReadResponse .getPlcValue (tagName ).getRaw () : null ;
177+ responses .get (tagType ).add (new Response (responseCode , startingAddress ,
178+ endingAddressRegister , endingAddressCoil , responseData ));
173179 }
174180
175181 // Now go through the original requests and try to answer them by using the raw data we now have.
@@ -185,6 +191,16 @@ protected PlcReadResponse processReadResponses(PlcReadRequest readRequest, Map<P
185191 for (Response response : responses .get (tagType )) {
186192 if (modbusTag instanceof ModbusTagCoil ) {
187193 if (response .matchesCoil (modbusTag )) {
194+ // If this response was invalid, return all associated addresses as equally invalid.
195+ // TODO: Possibly it would be worth doing a single item request for each of these
196+ // tags in order to find out which ones are actually invalid as if one item in the
197+ // current request exceeds the address range, all items in this chunk will fail, even
198+ // if only one element was invalid.
199+ if (response .getResponseCode () != PlcResponseCode .OK ) {
200+ values .put (tagName , new ResponseItem <>(response .getResponseCode (), null ));
201+ break ;
202+ }
203+
188204 // Coils are read completely different from registers.
189205 ModbusTagCoil coilTag = (ModbusTagCoil ) modbusTag ;
190206
@@ -200,6 +216,16 @@ protected PlcReadResponse processReadResponses(PlcReadRequest readRequest, Map<P
200216 }
201217 // Read a normal register.
202218 else if (response .matchesRegister (modbusTag )) {
219+ // If this response was invalid, return all associated addresses as equally invalid.
220+ // TODO: Possibly it would be worth doing a single item request for each of these
221+ // tags in order to find out which ones are actually invalid as if one item in the
222+ // current request exceeds the address range, all items in this chunk will fail, even
223+ // if only one element was invalid.
224+ if (response .getResponseCode () != PlcResponseCode .OK ) {
225+ values .put (tagName , new ResponseItem <>(response .getResponseCode (), null ));
226+ break ;
227+ }
228+
203229 byte [] responseData = response .getResponseDataForTag (modbusTag );
204230 ReadBuffer readBuffer = getReadBuffer (responseData , modbusContext .getByteOrder ());
205231 try {
@@ -340,18 +366,20 @@ protected List<PlcReadRequest> processRegisterRequests(TreeSet<ModbusTag> tags,
340366 }
341367
342368 protected static class Response {
369+ private final PlcResponseCode responseCode ;
343370 private final int startingAddress ;
344371 private final int endingAddressCoil ;
345372 private final int endingAddressRegister ;
346373 private final byte [] responseData ;
347374
348- public Response (int startingAddress , byte [] responseData ) {
375+ public Response (PlcResponseCode responseCode , int startingAddress , int endingAddressRegister , int endingAddressCoil , byte [] responseData ) {
376+ this .responseCode = responseCode ;
349377 this .startingAddress = startingAddress ;
350378 this .responseData = responseData ;
351- this .endingAddressCoil = startingAddress + responseData . length * 8 ;
379+ this .endingAddressCoil = endingAddressRegister ;
352380 // In general a "Celil(responseData.length / 2)" would have been more correct,
353381 // but the data returned from the device should already be an even number.
354- this .endingAddressRegister = startingAddress + ( responseData . length / 2 ) ;
382+ this .endingAddressRegister = endingAddressCoil ;
355383 }
356384
357385 public boolean matchesCoil (ModbusTag modbusTag ) {
@@ -366,6 +394,10 @@ public boolean matchesRegister(ModbusTag modbusTag) {
366394 return ((tagStartingAddress >= this .startingAddress ) && (tagEndingAddress <= this .endingAddressRegister ));
367395 }
368396
397+ public PlcResponseCode getResponseCode () {
398+ return responseCode ;
399+ }
400+
369401 public byte [] getResponseData () {
370402 return responseData ;
371403 }
0 commit comments