Search in sources :

Example 1 with ModbusWriteCoilRequestBlueprint

use of org.openhab.core.io.transport.modbus.ModbusWriteCoilRequestBlueprint 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)));
}
Also used : ModbusDataThingHandler(org.openhab.binding.modbus.internal.handler.ModbusDataThingHandler) ModbusWriteRequestBlueprint(org.openhab.core.io.transport.modbus.ModbusWriteRequestBlueprint) DecimalType(org.openhab.core.library.types.DecimalType) ModbusWriteCoilRequestBlueprint(org.openhab.core.io.transport.modbus.ModbusWriteCoilRequestBlueprint) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 2 with ModbusWriteCoilRequestBlueprint

use of org.openhab.core.io.transport.modbus.ModbusWriteCoilRequestBlueprint 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)));
}
Also used : ModbusDataThingHandler(org.openhab.binding.modbus.internal.handler.ModbusDataThingHandler) TransformationException(org.openhab.core.transform.TransformationException) ModbusWriteRequestBlueprint(org.openhab.core.io.transport.modbus.ModbusWriteRequestBlueprint) DecimalType(org.openhab.core.library.types.DecimalType) TransformationService(org.openhab.core.transform.TransformationService) ModbusWriteCoilRequestBlueprint(org.openhab.core.io.transport.modbus.ModbusWriteCoilRequestBlueprint) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 3 with ModbusWriteCoilRequestBlueprint

use of org.openhab.core.io.transport.modbus.ModbusWriteCoilRequestBlueprint 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;
}
Also used : ModbusBindingConstantsInternal(org.openhab.binding.modbus.internal.ModbusBindingConstantsInternal) LoggerFactory(org.slf4j.LoggerFactory) OnOffType(org.openhab.core.library.types.OnOffType) DateTimeType(org.openhab.core.library.types.DateTimeType) ModbusConstants(org.openhab.core.io.transport.modbus.ModbusConstants) BitArray(org.openhab.core.io.transport.modbus.BitArray) DateTimeItem(org.openhab.core.library.items.DateTimeItem) HexUtils(org.openhab.core.util.HexUtils) BigDecimal(java.math.BigDecimal) Nullable(org.eclipse.jdt.annotation.Nullable) ModbusWriteCoilRequestBlueprint(org.openhab.core.io.transport.modbus.ModbusWriteCoilRequestBlueprint) ThingHandlerCallback(org.openhab.core.thing.binding.ThingHandlerCallback) Duration(java.time.Duration) Map(java.util.Map) ModbusCommunicationInterface(org.openhab.core.io.transport.modbus.ModbusCommunicationInterface) NumberItem(org.openhab.core.library.items.NumberItem) EndpointNotInitializedException(org.openhab.binding.modbus.handler.EndpointNotInitializedException) NonNullByDefault(org.eclipse.jdt.annotation.NonNullByDefault) Collection(java.util.Collection) UnDefType(org.openhab.core.types.UnDefType) BaseThingHandler(org.openhab.core.thing.binding.BaseThingHandler) BridgeHandler(org.openhab.core.thing.binding.BridgeHandler) ModbusReadFunctionCode(org.openhab.core.io.transport.modbus.ModbusReadFunctionCode) CascadedValueTransformationImpl(org.openhab.binding.modbus.internal.CascadedValueTransformationImpl) ModbusTransportException(org.openhab.core.io.transport.modbus.exception.ModbusTransportException) BundleContext(org.osgi.framework.BundleContext) Objects(java.util.Objects) List(java.util.List) ValueType(org.openhab.core.io.transport.modbus.ModbusConstants.ValueType) AsyncModbusWriteResult(org.openhab.core.io.transport.modbus.AsyncModbusWriteResult) Optional(java.util.Optional) ModbusPollerThingHandler(org.openhab.binding.modbus.handler.ModbusPollerThingHandler) ModbusReadRequestBlueprint(org.openhab.core.io.transport.modbus.ModbusReadRequestBlueprint) OpenClosedType(org.openhab.core.library.types.OpenClosedType) DimmerItem(org.openhab.core.library.items.DimmerItem) AsyncModbusFailure(org.openhab.core.io.transport.modbus.AsyncModbusFailure) ModbusRegisterArray(org.openhab.core.io.transport.modbus.ModbusRegisterArray) ModbusWriteRequestBlueprint(org.openhab.core.io.transport.modbus.ModbusWriteRequestBlueprint) SwitchItem(org.openhab.core.library.items.SwitchItem) LocalDateTime(java.time.LocalDateTime) ValueTransformation(org.openhab.binding.modbus.internal.ValueTransformation) HashMap(java.util.HashMap) AtomicReference(java.util.concurrent.atomic.AtomicReference) ModbusDataConfiguration(org.openhab.binding.modbus.internal.config.ModbusDataConfiguration) ModbusBitUtilities(org.openhab.core.io.transport.modbus.ModbusBitUtilities) ModbusWriteRegisterRequestBlueprint(org.openhab.core.io.transport.modbus.ModbusWriteRegisterRequestBlueprint) Thing(org.openhab.core.thing.Thing) ChannelUID(org.openhab.core.thing.ChannelUID) ThingStatusInfo(org.openhab.core.thing.ThingStatusInfo) WriteRequestJsonUtilities(org.openhab.core.io.transport.modbus.json.WriteRequestJsonUtilities) DecimalType(org.openhab.core.library.types.DecimalType) ModbusConnectionException(org.openhab.core.io.transport.modbus.exception.ModbusConnectionException) ModbusConfigurationException(org.openhab.binding.modbus.internal.ModbusConfigurationException) ThingStatus(org.openhab.core.thing.ThingStatus) Command(org.openhab.core.types.Command) Logger(org.slf4j.Logger) RollershutterItem(org.openhab.core.library.items.RollershutterItem) State(org.openhab.core.types.State) RefreshType(org.openhab.core.types.RefreshType) ThingStatusDetail(org.openhab.core.thing.ThingStatusDetail) TimeUnit(java.util.concurrent.TimeUnit) ModbusEndpointThingHandler(org.openhab.binding.modbus.handler.ModbusEndpointThingHandler) StringItem(org.openhab.core.library.items.StringItem) ContactItem(org.openhab.core.library.items.ContactItem) AsyncModbusReadResult(org.openhab.core.io.transport.modbus.AsyncModbusReadResult) SingleValueTransformation(org.openhab.binding.modbus.internal.SingleValueTransformation) Collections(java.util.Collections) FrameworkUtil(org.osgi.framework.FrameworkUtil) Bridge(org.openhab.core.thing.Bridge) ModbusRegisterArray(org.openhab.core.io.transport.modbus.ModbusRegisterArray) ModbusWriteRequestBlueprint(org.openhab.core.io.transport.modbus.ModbusWriteRequestBlueprint) Optional(java.util.Optional) ValueType(org.openhab.core.io.transport.modbus.ModbusConstants.ValueType) AtomicReference(java.util.concurrent.atomic.AtomicReference) ModbusPollerThingHandler(org.openhab.binding.modbus.handler.ModbusPollerThingHandler) ModbusWriteRegisterRequestBlueprint(org.openhab.core.io.transport.modbus.ModbusWriteRegisterRequestBlueprint) Nullable(org.eclipse.jdt.annotation.Nullable) ModbusWriteCoilRequestBlueprint(org.openhab.core.io.transport.modbus.ModbusWriteCoilRequestBlueprint) Nullable(org.eclipse.jdt.annotation.Nullable)

Example 4 with ModbusWriteCoilRequestBlueprint

use of org.openhab.core.io.transport.modbus.ModbusWriteCoilRequestBlueprint in project openhab-core by openhab.

the class SmokeTest method testOneOffWriteMultipleCoil.

/**
 * @throws Exception
 */
@Test
public void testOneOffWriteMultipleCoil() throws Exception {
    LoggerFactory.getLogger(this.getClass()).error("STARTING MULTIPLE");
    generateData();
    ModbusSlaveEndpoint endpoint = getEndpoint();
    AtomicInteger unexpectedCount = new AtomicInteger();
    AtomicReference<Object> lastData = new AtomicReference<>();
    BitArray bits = new BitArray(true, true, false, false, true, true);
    try (ModbusCommunicationInterface comms = modbusManager.newModbusCommunicationInterface(endpoint, null)) {
        comms.submitOneTimeWrite(new ModbusWriteCoilRequestBlueprint(SLAVE_UNIT_ID, 3, bits, true, 1), result -> {
            lastData.set(result.getResponse());
        }, failure -> {
            unexpectedCount.incrementAndGet();
        });
        waitForAssert(() -> {
            assertThat(unexpectedCount.get(), is(equalTo(0)));
            assertThat(lastData.get(), is(notNullValue()));
            ModbusResponse response = (ModbusResponse) lastData.get();
            assertThat(response.getFunctionCode(), is(equalTo(15)));
            assertThat(modbustRequestCaptor.getAllReturnValues().size(), is(equalTo(1)));
            ModbusRequest request = modbustRequestCaptor.getAllReturnValues().get(0);
            assertThat(request.getFunctionCode(), is(equalTo(15)));
            assertThat(((WriteMultipleCoilsRequest) request).getReference(), is(equalTo(3)));
            assertThat(((WriteMultipleCoilsRequest) request).getBitCount(), is(equalTo(bits.size())));
            BitVector writeRequestCoils = ((WriteMultipleCoilsRequest) request).getCoils();
            BitArray writtenBits = new BitArray(BitSet.valueOf(writeRequestCoils.getBytes()), bits.size());
            assertThat(writtenBits, is(equalTo(bits)));
        }, 6000, 10);
    }
    LoggerFactory.getLogger(this.getClass()).error("ENDINGMULTIPLE");
}
Also used : BitVector(net.wimpi.modbus.util.BitVector) ModbusSlaveEndpoint(org.openhab.core.io.transport.modbus.endpoint.ModbusSlaveEndpoint) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) WriteMultipleCoilsRequest(net.wimpi.modbus.msg.WriteMultipleCoilsRequest) ModbusCommunicationInterface(org.openhab.core.io.transport.modbus.ModbusCommunicationInterface) ModbusResponse(org.openhab.core.io.transport.modbus.ModbusResponse) ModbusRequest(net.wimpi.modbus.msg.ModbusRequest) AtomicReference(java.util.concurrent.atomic.AtomicReference) BitArray(org.openhab.core.io.transport.modbus.BitArray) ModbusWriteCoilRequestBlueprint(org.openhab.core.io.transport.modbus.ModbusWriteCoilRequestBlueprint) Test(org.junit.jupiter.api.Test)

Example 5 with ModbusWriteCoilRequestBlueprint

use of org.openhab.core.io.transport.modbus.ModbusWriteCoilRequestBlueprint in project openhab-core by openhab.

the class SmokeTest method testOneOffWriteMultipleCoilError.

/**
 * Write is out-of-bounds, slave should return error
 *
 * @throws Exception
 */
@Test
public void testOneOffWriteMultipleCoilError() throws Exception {
    generateData();
    ModbusSlaveEndpoint endpoint = getEndpoint();
    AtomicInteger unexpectedCount = new AtomicInteger();
    CountDownLatch callbackCalled = new CountDownLatch(1);
    AtomicReference<Exception> lastError = new AtomicReference<>();
    BitArray bits = new BitArray(500);
    try (ModbusCommunicationInterface comms = modbusManager.newModbusCommunicationInterface(endpoint, null)) {
        comms.submitOneTimeWrite(new ModbusWriteCoilRequestBlueprint(SLAVE_UNIT_ID, 3, bits, true, 1), result -> {
            unexpectedCount.incrementAndGet();
            callbackCalled.countDown();
        }, failure -> {
            lastError.set(failure.getCause());
            callbackCalled.countDown();
        });
        assertTrue(callbackCalled.await(60, TimeUnit.SECONDS));
        assertThat(unexpectedCount.get(), is(equalTo(0)));
        assertTrue(lastError.get() instanceof ModbusSlaveErrorResponseException, lastError.toString());
        assertThat(modbustRequestCaptor.getAllReturnValues().size(), is(equalTo(1)));
        ModbusRequest request = modbustRequestCaptor.getAllReturnValues().get(0);
        assertThat(request.getFunctionCode(), is(equalTo(15)));
        assertThat(((WriteMultipleCoilsRequest) request).getReference(), is(equalTo(3)));
        assertThat(((WriteMultipleCoilsRequest) request).getBitCount(), is(equalTo(bits.size())));
        BitVector writeRequestCoils = ((WriteMultipleCoilsRequest) request).getCoils();
        BitArray writtenBits = new BitArray(BitSet.valueOf(writeRequestCoils.getBytes()), bits.size());
        assertThat(writtenBits, is(equalTo(bits)));
    }
}
Also used : BitVector(net.wimpi.modbus.util.BitVector) ModbusSlaveEndpoint(org.openhab.core.io.transport.modbus.endpoint.ModbusSlaveEndpoint) WriteMultipleCoilsRequest(net.wimpi.modbus.msg.WriteMultipleCoilsRequest) ModbusCommunicationInterface(org.openhab.core.io.transport.modbus.ModbusCommunicationInterface) ModbusRequest(net.wimpi.modbus.msg.ModbusRequest) AtomicReference(java.util.concurrent.atomic.AtomicReference) CountDownLatch(java.util.concurrent.CountDownLatch) ModbusConnectionException(org.openhab.core.io.transport.modbus.exception.ModbusConnectionException) IOException(java.io.IOException) ModbusSlaveErrorResponseException(org.openhab.core.io.transport.modbus.exception.ModbusSlaveErrorResponseException) InvocationTargetException(java.lang.reflect.InvocationTargetException) ModbusSlaveIOException(org.openhab.core.io.transport.modbus.exception.ModbusSlaveIOException) ModbusSlaveErrorResponseException(org.openhab.core.io.transport.modbus.exception.ModbusSlaveErrorResponseException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) BitArray(org.openhab.core.io.transport.modbus.BitArray) ModbusWriteCoilRequestBlueprint(org.openhab.core.io.transport.modbus.ModbusWriteCoilRequestBlueprint) Test(org.junit.jupiter.api.Test)

Aggregations

ModbusWriteCoilRequestBlueprint (org.openhab.core.io.transport.modbus.ModbusWriteCoilRequestBlueprint)10 Test (org.junit.jupiter.api.Test)7 BitArray (org.openhab.core.io.transport.modbus.BitArray)7 AtomicReference (java.util.concurrent.atomic.AtomicReference)6 ModbusRequest (net.wimpi.modbus.msg.ModbusRequest)5 ModbusCommunicationInterface (org.openhab.core.io.transport.modbus.ModbusCommunicationInterface)5 ModbusWriteRequestBlueprint (org.openhab.core.io.transport.modbus.ModbusWriteRequestBlueprint)5 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)4 ModbusSlaveEndpoint (org.openhab.core.io.transport.modbus.endpoint.ModbusSlaveEndpoint)4 DecimalType (org.openhab.core.library.types.DecimalType)4 CountDownLatch (java.util.concurrent.CountDownLatch)3 WriteMultipleCoilsRequest (net.wimpi.modbus.msg.WriteMultipleCoilsRequest)3 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)3 ModbusDataThingHandler (org.openhab.binding.modbus.internal.handler.ModbusDataThingHandler)3 ModbusConnectionException (org.openhab.core.io.transport.modbus.exception.ModbusConnectionException)3 IOException (java.io.IOException)2 InvocationTargetException (java.lang.reflect.InvocationTargetException)2 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)2 BitVector (net.wimpi.modbus.util.BitVector)2 ModbusWriteRegisterRequestBlueprint (org.openhab.core.io.transport.modbus.ModbusWriteRegisterRequestBlueprint)2