use of org.openhab.core.io.transport.modbus.ModbusWriteRequestBlueprint in project openhab-addons by openhab.
the class ModbusDataHandlerTest method testWriteRealTransformation5.
@Test
public void testWriteRealTransformation5() throws InvalidSyntaxException {
captureModbusWrites();
mockTransformation("PLUS", new TransformationService() {
@Override
public String transform(String arg, String source) throws TransformationException {
return String.valueOf(Integer.parseInt(arg) + Integer.parseInt(source));
}
});
mockTransformation("CONCAT", new TransformationService() {
@Override
public String transform(String function, String source) throws TransformationException {
return source + function;
}
});
mockTransformation("MULTIPLY", new MultiplyTransformation());
ModbusDataThingHandler dataHandler = testWriteHandlingGeneric("50", "MULTIPLY:3∩PLUS(2)∩CONCAT(0)", ModbusConstants.ValueType.INT16, "holding", ModbusWriteFunctionCode.WRITE_SINGLE_REGISTER, "number", new DecimalType("2"), null, bundleContext);
assertSingleStateUpdate(dataHandler, CHANNEL_LAST_WRITE_SUCCESS, is(notNullValue(State.class)));
assertSingleStateUpdate(dataHandler, CHANNEL_LAST_WRITE_ERROR, is(nullValue(State.class)));
assertThat(writeRequests.size(), is(equalTo(1)));
ModbusWriteRequestBlueprint writeRequest = writeRequests.get(0);
assertThat(writeRequest.getFunctionCode(), is(equalTo(ModbusWriteFunctionCode.WRITE_SINGLE_REGISTER)));
assertThat(writeRequest.getReference(), is(equalTo(50)));
assertThat(((ModbusWriteRegisterRequestBlueprint) writeRequest).getRegisters().size(), is(equalTo(1)));
assertThat(((ModbusWriteRegisterRequestBlueprint) writeRequest).getRegisters().getRegister(0), is(equalTo(/* (2*3 + 2) + '0' */
80)));
}
use of org.openhab.core.io.transport.modbus.ModbusWriteRequestBlueprint in project openhab-addons by openhab.
the class ModbusDataHandlerTest method testWriteRealTransformation3.
@Test
public void testWriteRealTransformation3() throws InvalidSyntaxException {
captureModbusWrites();
mockTransformation("RANDOM", new TransformationService() {
@Override
public String transform(String function, String source) throws TransformationException {
return "5";
}
});
ModbusDataThingHandler dataHandler = testWriteHandlingGeneric("50", "RANDOM(foobar)", ModbusConstants.ValueType.INT16, "holding", ModbusWriteFunctionCode.WRITE_SINGLE_REGISTER, "number", new DecimalType("2"), null, bundleContext);
assertSingleStateUpdate(dataHandler, CHANNEL_LAST_WRITE_SUCCESS, is(notNullValue(State.class)));
assertSingleStateUpdate(dataHandler, CHANNEL_LAST_WRITE_ERROR, is(nullValue(State.class)));
assertThat(writeRequests.size(), is(equalTo(1)));
ModbusWriteRequestBlueprint writeRequest = writeRequests.get(0);
assertThat(writeRequest.getFunctionCode(), is(equalTo(ModbusWriteFunctionCode.WRITE_SINGLE_REGISTER)));
assertThat(writeRequest.getReference(), is(equalTo(50)));
assertThat(((ModbusWriteRegisterRequestBlueprint) writeRequest).getRegisters().size(), is(equalTo(1)));
assertThat(((ModbusWriteRegisterRequestBlueprint) writeRequest).getRegisters().getRegister(0), is(equalTo(5)));
}
use of org.openhab.core.io.transport.modbus.ModbusWriteRequestBlueprint in project openhab-addons by openhab.
the class ModbusDataHandlerTest method testWriteRealTransformation.
@Test
public void testWriteRealTransformation() throws InvalidSyntaxException {
captureModbusWrites();
mockTransformation("MULTIPLY", new MultiplyTransformation());
ModbusDataThingHandler dataHandler = testWriteHandlingGeneric("50", "MULTIPLY(10)", ModbusConstants.ValueType.BIT, "coil", ModbusWriteFunctionCode.WRITE_COIL, "number", new DecimalType("2"), null, bundleContext);
assertSingleStateUpdate(dataHandler, CHANNEL_LAST_WRITE_SUCCESS, is(notNullValue(State.class)));
assertSingleStateUpdate(dataHandler, CHANNEL_LAST_WRITE_ERROR, is(nullValue(State.class)));
assertThat(writeRequests.size(), is(equalTo(1)));
ModbusWriteRequestBlueprint writeRequest = writeRequests.get(0);
assertThat(writeRequest.getFunctionCode(), is(equalTo(ModbusWriteFunctionCode.WRITE_COIL)));
assertThat(writeRequest.getReference(), is(equalTo(50)));
assertThat(((ModbusWriteCoilRequestBlueprint) writeRequest).getCoils().size(), is(equalTo(1)));
// Since transform output is non-zero, it is mapped as "true"
assertThat(((ModbusWriteCoilRequestBlueprint) writeRequest).getCoils().getBit(0), is(equalTo(true)));
}
use of org.openhab.core.io.transport.modbus.ModbusWriteRequestBlueprint in project openhab-addons by openhab.
the class ModbusDataHandlerTest method testWriteRealTransformation2.
@Test
public void testWriteRealTransformation2() throws InvalidSyntaxException {
captureModbusWrites();
mockTransformation("ZERO", new TransformationService() {
@Override
public String transform(String function, String source) throws TransformationException {
return "0";
}
});
ModbusDataThingHandler dataHandler = testWriteHandlingGeneric("50", "ZERO(foobar)", ModbusConstants.ValueType.BIT, "coil", ModbusWriteFunctionCode.WRITE_COIL, "number", new DecimalType("2"), null, bundleContext);
assertSingleStateUpdate(dataHandler, CHANNEL_LAST_WRITE_SUCCESS, is(notNullValue(State.class)));
assertSingleStateUpdate(dataHandler, CHANNEL_LAST_WRITE_ERROR, is(nullValue(State.class)));
assertThat(writeRequests.size(), is(equalTo(1)));
ModbusWriteRequestBlueprint writeRequest = writeRequests.get(0);
assertThat(writeRequest.getFunctionCode(), is(equalTo(ModbusWriteFunctionCode.WRITE_COIL)));
assertThat(writeRequest.getReference(), is(equalTo(50)));
assertThat(((ModbusWriteCoilRequestBlueprint) writeRequest).getCoils().size(), is(equalTo(1)));
// Since transform output is zero, it is mapped as "false"
assertThat(((ModbusWriteCoilRequestBlueprint) writeRequest).getCoils().getBit(0), is(equalTo(false)));
}
use of org.openhab.core.io.transport.modbus.ModbusWriteRequestBlueprint in project openhab-addons by openhab.
the class ModbusDataThingHandler method requestFromCommand.
@Nullable
private ModbusWriteRequestBlueprint requestFromCommand(ChannelUID channelUID, Command origCommand, ModbusDataConfiguration config, Command transformedCommand, Integer writeStart) {
ModbusWriteRequestBlueprint request;
boolean writeMultiple = config.isWriteMultipleEvenWithSingleRegisterOrCoil();
String writeType = config.getWriteType();
ModbusPollerThingHandler pollerHandler = this.pollerHandler;
if (writeType == null) {
// disposed thing
return null;
}
if (writeType.equals(WRITE_TYPE_COIL)) {
Optional<Boolean> commandAsBoolean = ModbusBitUtilities.translateCommand2Boolean(transformedCommand);
if (!commandAsBoolean.isPresent()) {
logger.warn("Cannot process command {} with channel {} since command is not OnOffType, OpenClosedType or Decimal trying to write to coil. Do not know how to convert to 0/1. Transformed command was '{}'", origCommand, channelUID, transformedCommand);
return null;
}
boolean data = commandAsBoolean.get();
request = new ModbusWriteCoilRequestBlueprint(slaveId, writeStart, data, writeMultiple, config.getWriteMaxTries());
} else if (writeType.equals(WRITE_TYPE_HOLDING)) {
ValueType writeValueType = this.writeValueType;
if (writeValueType == null) {
// Should not happen in practice, since we are not in configuration error (checked above)
// This will make compiler happy anyways with the null checks
logger.warn("Received command but write value type not set! Ignoring command");
return null;
}
final ModbusRegisterArray data;
if (writeValueType.equals(ValueType.BIT)) {
if (writeSubIndex.isEmpty()) {
// Should not happen! should be in configuration error
logger.error("Bug: sub index not present but writeValueType=BIT. Should be in configuration error");
return null;
}
Optional<Boolean> commandBool = ModbusBitUtilities.translateCommand2Boolean(transformedCommand);
if (commandBool.isEmpty()) {
logger.warn("Data thing is configured to write individual bit but we received command that is not convertible to 0/1 bit. Ignoring.");
return null;
} else if (pollerHandler == null) {
logger.warn("Bug: sub index present but not child of poller. Should be in configuration erro");
return null;
}
// writing bit of an individual register. Using cache from poller
AtomicReference<@Nullable ModbusRegisterArray> cachedRegistersRef = pollerHandler.getLastPolledDataCache();
ModbusRegisterArray mutatedRegisters = cachedRegistersRef.updateAndGet(cachedRegisters -> cachedRegisters == null ? null : combineCommandWithRegisters(cachedRegisters, writeStart, writeSubIndex.get(), commandBool.get()));
if (mutatedRegisters == null) {
logger.warn("Received command to thing with writeValueType=bit (pointing to individual bit of a holding register) but internal cache not yet populated. Ignoring command");
return null;
}
// extract register (first byte index = register index * 2)
byte[] allMutatedBytes = mutatedRegisters.getBytes();
int writeStartRelative = writeStart - pollStart;
data = new ModbusRegisterArray(allMutatedBytes[writeStartRelative * 2], allMutatedBytes[writeStartRelative * 2 + 1]);
} else {
data = ModbusBitUtilities.commandToRegisters(transformedCommand, writeValueType);
}
writeMultiple = writeMultiple || data.size() > 1;
request = new ModbusWriteRegisterRequestBlueprint(slaveId, writeStart, data, writeMultiple, config.getWriteMaxTries());
} else {
// We keep this here for future-proofing the code (new writeType values)
throw new IllegalStateException(String.format("writeType does not equal %s or %s and thus configuration is invalid. Should not end up this far with configuration error.", WRITE_TYPE_COIL, WRITE_TYPE_HOLDING));
}
return request;
}
Aggregations