Skip to content

Commit

Permalink
Added ReadInputRegisters
Browse files Browse the repository at this point in the history
  • Loading branch information
retrodaredevil committed Feb 20, 2021
1 parent c91ce03 commit 899d6a4
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 70 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Hex | Dec | Function
0x01 | 1 | Read Coils
0x02 | 2 | Read Discrete Inputs
0x03 | 3 | Read Holding Registers
0x04 | 4 | Read Input Registers
0x05 | 5 | Write Single Coil
0x06 | 6 | Write Single Register
0x0F | 15 | Write Multiple Coils
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package me.retrodaredevil.io.modbus.handling;

import me.retrodaredevil.io.modbus.ModbusMessage;
import me.retrodaredevil.io.modbus.ModbusMessages;

import java.util.Objects;

import static me.retrodaredevil.io.modbus.ModbusMessages.get16BitDataFrom8BitArray;
import static me.retrodaredevil.io.modbus.ModbusMessages.get8BitDataFrom16BitArray;

public class BaseReadRegisters extends BaseStartingDataAddress implements MessageResponseCreator<int[]> {
private final int functionCode;
private final int numberOfRegisters;

/**
* @param startingDataAddress The starting register
* @param functionCode
* @param numberOfRegisters The number of registers to read. The array returned from {@link #handleResponse(ModbusMessage)} will have a length of this
*/
public BaseReadRegisters(int startingDataAddress, int functionCode, int numberOfRegisters) {
super(startingDataAddress);
this.functionCode = functionCode;
this.numberOfRegisters = numberOfRegisters;
}

public int getNumberOfRegisters() {
return numberOfRegisters;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
BaseReadRegisters that = (BaseReadRegisters) o;
return getStartingDataAddress() == that.getStartingDataAddress() &&
getNumberOfRegisters() == that.getNumberOfRegisters();
}

@Override
public int hashCode() {
return Objects.hash(getStartingDataAddress(), getNumberOfRegisters());
}

@Override
public ModbusMessage createRequest() {
return ModbusMessages.createMessage(functionCode, get8BitDataFrom16BitArray(getStartingDataAddress(), numberOfRegisters));
}

@Override
public int[] handleResponse(ModbusMessage response) {
int expectedLength = numberOfRegisters * 2 + 1;
HandleResponseHelper.checkResponse(response, functionCode, expectedLength);
int[] allData = response.getData();
int byteCount = allData[0];
if(byteCount != numberOfRegisters * 2){
throw new ParsedResponseException(response, "Inconsistent byte count! byteCount=" + byteCount + ". expected=" + (numberOfRegisters * 2));
}

int[] data = new int[allData.length - 1];
System.arraycopy(allData, 1, data, 0, data.length);
return get16BitDataFrom8BitArray(data);
}

@Override
public ModbusMessage createResponse(int[] data16Bit) {
if (data16Bit.length != numberOfRegisters) {
throw new IllegalArgumentException("The array of 16 bit integers passed was not the correct length! numberOfRegisters=" + numberOfRegisters + ". The passed data should have that length.");
}
int[] data = get8BitDataFrom16BitArray(data16Bit);
int byteCount = numberOfRegisters * 2;
if (data.length != byteCount) {
throw new AssertionError("We just checked this. This is a code problem.");
}
int[] allData = new int[data.length + 1];
allData[0] = byteCount;
System.arraycopy(data, 0, allData, 1, data.length);
return ModbusMessages.createMessage(functionCode, allData);
}
}
Original file line number Diff line number Diff line change
@@ -1,26 +1,11 @@
package me.retrodaredevil.io.modbus.handling;

import me.retrodaredevil.io.modbus.FunctionCode;
import me.retrodaredevil.io.modbus.ModbusMessage;
import me.retrodaredevil.io.modbus.ModbusMessages;
import me.retrodaredevil.io.modbus.parsing.MessageParseException;

import java.util.Objects;

import static me.retrodaredevil.io.modbus.ModbusMessages.get16BitDataFrom8BitArray;
import static me.retrodaredevil.io.modbus.ModbusMessages.get8BitDataFrom16BitArray;

public class ReadHoldingRegisters extends BaseStartingDataAddress implements MessageResponseCreator<int[]> {
private final int numberOfRegisters;

/**
*
* @param startingDataAddress The starting register
* @param numberOfRegisters The number of registers to read. The array returned from {@link #handleResponse(ModbusMessage)} will have a length of this
*/
public class ReadHoldingRegisters extends BaseReadRegisters {
public ReadHoldingRegisters(int startingDataAddress, int numberOfRegisters) {
super(startingDataAddress);
this.numberOfRegisters = numberOfRegisters;
super(startingDataAddress, FunctionCode.READ_HOLDING_REGISTERS, numberOfRegisters);
}
public static ReadHoldingRegisters parseFromRequestData(int[] data) throws MessageParseException {
if (data.length != 4) {
Expand All @@ -32,57 +17,4 @@ public static ReadHoldingRegisters parseFromRequestData(int[] data) throws Messa
);
}

public int getNumberOfRegisters() {
return numberOfRegisters;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ReadHoldingRegisters that = (ReadHoldingRegisters) o;
return getStartingDataAddress() == that.getStartingDataAddress() &&
getNumberOfRegisters() == that.getNumberOfRegisters();
}

@Override
public int hashCode() {
return Objects.hash(getStartingDataAddress(), getNumberOfRegisters());
}

@Override
public ModbusMessage createRequest() {
return ModbusMessages.createMessage(FunctionCode.READ_HOLDING_REGISTERS, get8BitDataFrom16BitArray(getStartingDataAddress(), numberOfRegisters));
}

@Override
public int[] handleResponse(ModbusMessage response) {
int expectedLength = numberOfRegisters * 2 + 1;
HandleResponseHelper.checkResponse(response, FunctionCode.READ_HOLDING_REGISTERS, expectedLength);
int[] allData = response.getData();
int byteCount = allData[0];
if(byteCount != numberOfRegisters * 2){
throw new ParsedResponseException(response, "Inconsistent byte count! byteCount=" + byteCount + ". expected=" + (numberOfRegisters * 2));
}

int[] data = new int[allData.length - 1];
System.arraycopy(allData, 1, data, 0, data.length);
return get16BitDataFrom8BitArray(data);
}

@Override
public ModbusMessage createResponse(int[] data16Bit) {
if (data16Bit.length != numberOfRegisters) {
throw new IllegalArgumentException("The array of 16 bit integers passed was not the correct length! numberOfRegisters=" + numberOfRegisters + ". The passed data should have that length.");
}
int[] data = get8BitDataFrom16BitArray(data16Bit);
int byteCount = numberOfRegisters * 2;
if (data.length != byteCount) {
throw new AssertionError("We just checked this. This is a code problem.");
}
int[] allData = new int[data.length + 1];
allData[0] = byteCount;
System.arraycopy(data, 0, allData, 1, data.length);
return ModbusMessages.createMessage(FunctionCode.READ_HOLDING_REGISTERS, allData);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package me.retrodaredevil.io.modbus.handling;

import me.retrodaredevil.io.modbus.FunctionCode;
import me.retrodaredevil.io.modbus.parsing.MessageParseException;

public class ReadInputRegisters extends BaseReadRegisters {
public ReadInputRegisters(int startingDataAddress, int numberOfRegisters) {
super(startingDataAddress, FunctionCode.READ_HOLDING_REGISTERS, numberOfRegisters);
}
public static ReadInputRegisters parseFromRequestData(int[] data) throws MessageParseException {
if (data.length != 4) {
throw new MessageParseException("data.length != 4! data.length=" + data.length);
}
return new ReadInputRegisters(
data[0] << 8 | data[1],
data[2] << 8 | data[3]
);
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ public MessageHandler<?> parseRequestMessage(ModbusMessage message) throws Messa
return ReadDiscreteInputs.parseFromRequestData(message.getData());
case FunctionCode.READ_HOLDING_REGISTERS:
return ReadHoldingRegisters.parseFromRequestData(message.getData());
case FunctionCode.READ_INPUT_REGISTERS:
return ReadInputRegisters.parseFromRequestData(message.getData());
case FunctionCode.WRITE_SINGLE_COIL:
return WriteSingleCoil.parseFromRequestData(message.getData());
case FunctionCode.WRITE_SINGLE_REGISTER:
Expand Down

0 comments on commit 899d6a4

Please sign in to comment.