Search in sources :

Example 1 with ModbusConfigurationException

use of org.openhab.binding.modbus.internal.ModbusConfigurationException in project openhab-addons by openhab.

the class ModbusDataThingHandler method validateAndParseReadParameters.

private void validateAndParseReadParameters(ModbusDataConfiguration config) throws ModbusConfigurationException {
    ModbusReadFunctionCode functionCode = this.functionCode;
    boolean readingDiscreteOrCoil = functionCode == ModbusReadFunctionCode.READ_COILS || functionCode == ModbusReadFunctionCode.READ_INPUT_DISCRETES;
    boolean readStartMissing = config.getReadStart() == null || config.getReadStart().isBlank();
    boolean readValueTypeMissing = config.getReadValueType() == null || config.getReadValueType().isBlank();
    if (childOfEndpoint && readRequest == null) {
        if (!readStartMissing || !readValueTypeMissing) {
            String errmsg = String.format("Thing %s readStart=%s, and readValueType=%s were specified even though the data thing is child of endpoint (that is, write-only)!", getThing().getUID(), config.getReadStart(), config.getReadValueType());
            throw new ModbusConfigurationException(errmsg);
        }
    }
    // we assume readValueType=bit by default if it is missing
    boolean allMissingOrAllPresent = (readStartMissing && readValueTypeMissing) || (!readStartMissing && (!readValueTypeMissing || readingDiscreteOrCoil));
    if (!allMissingOrAllPresent) {
        String errmsg = String.format("Thing %s readStart=%s, and readValueType=%s should be all present or all missing!", getThing().getUID(), config.getReadStart(), config.getReadValueType());
        throw new ModbusConfigurationException(errmsg);
    } else if (!readStartMissing) {
        // all read values are present
        isReadEnabled = true;
        if (readingDiscreteOrCoil && readValueTypeMissing) {
            readValueType = ModbusConstants.ValueType.BIT;
        } else {
            try {
                readValueType = ValueType.fromConfigValue(config.getReadValueType());
            } catch (IllegalArgumentException e) {
                String errmsg = String.format("Thing %s readValueType=%s is invalid!", getThing().getUID(), config.getReadValueType());
                throw new ModbusConfigurationException(errmsg);
            }
        }
        if (readingDiscreteOrCoil && !ModbusConstants.ValueType.BIT.equals(readValueType)) {
            String errmsg = String.format("Thing %s invalid readValueType: Only readValueType='%s' (or undefined) supported with coils or discrete inputs. Value type was: %s", getThing().getUID(), ModbusConstants.ValueType.BIT, config.getReadValueType());
            throw new ModbusConfigurationException(errmsg);
        }
    } else {
        isReadEnabled = false;
    }
    if (isReadEnabled) {
        String readStart = config.getReadStart();
        if (readStart == null) {
            throw new ModbusConfigurationException(String.format("Thing %s invalid readStart: %s", getThing().getUID(), config.getReadStart()));
        }
        String[] readParts = readStart.split("\\.", 2);
        try {
            readIndex = Optional.of(Integer.parseInt(readParts[0]));
            if (readParts.length == 2) {
                readSubIndex = Optional.of(Integer.parseInt(readParts[1]));
            } else {
                readSubIndex = Optional.empty();
            }
        } catch (IllegalArgumentException e) {
            String errmsg = String.format("Thing %s invalid readStart: %s", getThing().getUID(), config.getReadStart());
            throw new ModbusConfigurationException(errmsg);
        }
    }
    readTransformation = new CascadedValueTransformationImpl(config.getReadTransform());
    validateReadIndex();
}
Also used : CascadedValueTransformationImpl(org.openhab.binding.modbus.internal.CascadedValueTransformationImpl) ModbusConfigurationException(org.openhab.binding.modbus.internal.ModbusConfigurationException) ModbusReadFunctionCode(org.openhab.core.io.transport.modbus.ModbusReadFunctionCode)

Example 2 with ModbusConfigurationException

use of org.openhab.binding.modbus.internal.ModbusConfigurationException in project openhab-addons by openhab.

the class ModbusDataThingHandler method validateReadIndex.

private void validateReadIndex() throws ModbusConfigurationException {
    @Nullable ModbusReadRequestBlueprint readRequest = this.readRequest;
    ValueType readValueType = this.readValueType;
    if (!readIndex.isPresent() || readRequest == null) {
        return;
    }
    assert readValueType != null;
    // bits represented by the value type, e.g. int32 -> 32
    int valueTypeBitCount = readValueType.getBits();
    int dataElementBits;
    switch(readRequest.getFunctionCode()) {
        case READ_INPUT_REGISTERS:
        case READ_MULTIPLE_REGISTERS:
            dataElementBits = 16;
            break;
        case READ_COILS:
        case READ_INPUT_DISCRETES:
            dataElementBits = 1;
            break;
        default:
            throw new IllegalStateException(readRequest.getFunctionCode().toString());
    }
    boolean bitQuery = dataElementBits == 1;
    if (bitQuery && readSubIndex.isPresent()) {
        String errmsg = String.format("readStart=X.Y is not allowed to be used with coils or discrete inputs!");
        throw new ModbusConfigurationException(errmsg);
    }
    if (valueTypeBitCount >= 16 && readSubIndex.isPresent()) {
        String errmsg = String.format("readStart=X.Y notation is not allowed to be used with value types larger than 16bit! Use readStart=X instead.");
        throw new ModbusConfigurationException(errmsg);
    } else if (!bitQuery && valueTypeBitCount < 16 && !readSubIndex.isPresent()) {
        // User has specified value type which is less than register width (16 bits).
        // readStart=X.Y notation must be used to define which data to extract from the 16 bit register.
        String errmsg = String.format("readStart=X.Y must be used with value types (readValueType) less than 16bit!");
        throw new ModbusConfigurationException(errmsg);
    } else if (readSubIndex.isPresent() && (readSubIndex.get() + 1) * valueTypeBitCount > 16) {
        // the sub index Y (in X.Y) is above the register limits
        String errmsg = String.format("readStart=X.Y, the value Y is too large");
        throw new ModbusConfigurationException(errmsg);
    }
    // Determine bit positions polled, both start and end inclusive
    int pollStartBitIndex = readRequest.getReference() * dataElementBits;
    int pollEndBitIndex = pollStartBitIndex + readRequest.getDataLength() * dataElementBits - 1;
    // Determine bit positions read, both start and end inclusive
    int readStartBitIndex = readIndex.get() * dataElementBits + readSubIndex.orElse(0) * valueTypeBitCount;
    int readEndBitIndex = readStartBitIndex + valueTypeBitCount - 1;
    if (readStartBitIndex < pollStartBitIndex || readEndBitIndex > pollEndBitIndex) {
        String errmsg = String.format("Out-of-bounds: Poller is reading from index %d to %d (inclusive) but this thing configured to read '%s' starting from element %d. Exceeds polled data bounds.", pollStartBitIndex / dataElementBits, pollEndBitIndex / dataElementBits, readValueType, readIndex.get());
        throw new ModbusConfigurationException(errmsg);
    }
}
Also used : ValueType(org.openhab.core.io.transport.modbus.ModbusConstants.ValueType) ModbusReadRequestBlueprint(org.openhab.core.io.transport.modbus.ModbusReadRequestBlueprint) ModbusConfigurationException(org.openhab.binding.modbus.internal.ModbusConfigurationException) Nullable(org.eclipse.jdt.annotation.Nullable) ModbusWriteCoilRequestBlueprint(org.openhab.core.io.transport.modbus.ModbusWriteCoilRequestBlueprint) ModbusReadRequestBlueprint(org.openhab.core.io.transport.modbus.ModbusReadRequestBlueprint) ModbusWriteRequestBlueprint(org.openhab.core.io.transport.modbus.ModbusWriteRequestBlueprint) ModbusWriteRegisterRequestBlueprint(org.openhab.core.io.transport.modbus.ModbusWriteRegisterRequestBlueprint)

Example 3 with ModbusConfigurationException

use of org.openhab.binding.modbus.internal.ModbusConfigurationException in project openhab-addons by openhab.

the class ModbusDataThingHandler method validateWriteIndex.

private void validateWriteIndex() throws ModbusConfigurationException {
    @Nullable ModbusReadRequestBlueprint readRequest = this.readRequest;
    if (!writeStart.isPresent() || !writeSubIndex.isPresent()) {
        // 
        return;
    } else if (readRequest == null) {
        // should not happen, already validated
        throw new ModbusConfigurationException("Must poll data with writeStart=X.Y");
    }
    if (writeSubIndex.isPresent() && (writeSubIndex.get() + 1) > 16) {
        // the sub index Y (in X.Y) is above the register limits
        String errmsg = String.format("readStart=X.Y, the value Y is too large");
        throw new ModbusConfigurationException(errmsg);
    }
    // Determine bit positions polled, both start and end inclusive
    int pollStartBitIndex = readRequest.getReference() * 16;
    int pollEndBitIndex = pollStartBitIndex + readRequest.getDataLength() * 16 - 1;
    // Determine bit positions read, both start and end inclusive
    int writeStartBitIndex = writeStart.get() * 16 + readSubIndex.orElse(0);
    int writeEndBitIndex = writeStartBitIndex - 1;
    if (writeStartBitIndex < pollStartBitIndex || writeEndBitIndex > pollEndBitIndex) {
        String errmsg = String.format("Out-of-bounds: Poller is reading from index %d to %d (inclusive) but this thing configured to write  starting from element %d. Must write within polled limits", pollStartBitIndex / 16, pollEndBitIndex / 16, writeStart.get());
        throw new ModbusConfigurationException(errmsg);
    }
}
Also used : ModbusReadRequestBlueprint(org.openhab.core.io.transport.modbus.ModbusReadRequestBlueprint) ModbusConfigurationException(org.openhab.binding.modbus.internal.ModbusConfigurationException) Nullable(org.eclipse.jdt.annotation.Nullable) ModbusWriteCoilRequestBlueprint(org.openhab.core.io.transport.modbus.ModbusWriteCoilRequestBlueprint) ModbusReadRequestBlueprint(org.openhab.core.io.transport.modbus.ModbusReadRequestBlueprint) ModbusWriteRequestBlueprint(org.openhab.core.io.transport.modbus.ModbusWriteRequestBlueprint) ModbusWriteRegisterRequestBlueprint(org.openhab.core.io.transport.modbus.ModbusWriteRegisterRequestBlueprint)

Example 4 with ModbusConfigurationException

use of org.openhab.binding.modbus.internal.ModbusConfigurationException in project openhab-addons by openhab.

the class ModbusDataThingHandler method initialize.

@Override
public synchronized void initialize() {
    // Long running initialization should be done asynchronously in background.
    try {
        logger.trace("initialize() of thing {} '{}' starting", thing.getUID(), thing.getLabel());
        ModbusDataConfiguration localConfig = config = getConfigAs(ModbusDataConfiguration.class);
        updateUnchangedValuesEveryMillis = localConfig.getUpdateUnchangedValuesEveryMillis();
        Bridge bridge = getBridge();
        if (bridge == null || !bridge.getStatus().equals(ThingStatus.ONLINE)) {
            logger.debug("Thing {} '{}' has no bridge or it is not online", getThing().getUID(), getThing().getLabel());
            updateStatusIfChanged(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE, "No online bridge");
            return;
        }
        BridgeHandler bridgeHandler = bridge.getHandler();
        if (bridgeHandler == null) {
            logger.warn("Bridge {} '{}' has no handler.", bridge.getUID(), bridge.getLabel());
            String errmsg = String.format("Bridge %s '%s' configuration incomplete or with errors", bridge.getUID(), bridge.getLabel());
            throw new ModbusConfigurationException(errmsg);
        }
        if (bridgeHandler instanceof ModbusEndpointThingHandler) {
            // Write-only thing, parent is endpoint
            ModbusEndpointThingHandler endpointHandler = (ModbusEndpointThingHandler) bridgeHandler;
            slaveId = endpointHandler.getSlaveId();
            comms = endpointHandler.getCommunicationInterface();
            childOfEndpoint = true;
            functionCode = null;
            readRequest = null;
        } else {
            ModbusPollerThingHandler localPollerHandler = (ModbusPollerThingHandler) bridgeHandler;
            pollerHandler = localPollerHandler;
            ModbusReadRequestBlueprint localReadRequest = localPollerHandler.getRequest();
            if (localReadRequest == null) {
                logger.debug("Poller {} '{}' has no read request -- configuration is changing or bridge having invalid configuration?", bridge.getUID(), bridge.getLabel());
                updateStatusIfChanged(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE, String.format("Poller %s '%s' has no poll task", bridge.getUID(), bridge.getLabel()));
                return;
            }
            readRequest = localReadRequest;
            slaveId = localReadRequest.getUnitID();
            functionCode = localReadRequest.getFunctionCode();
            comms = localPollerHandler.getCommunicationInterface();
            pollStart = localReadRequest.getReference();
            childOfEndpoint = false;
        }
        validateAndParseReadParameters(localConfig);
        validateAndParseWriteParameters(localConfig);
        validateMustReadOrWrite();
        updateStatusIfChanged(ThingStatus.ONLINE);
    } catch (ModbusConfigurationException | EndpointNotInitializedException e) {
        logger.debug("Thing {} '{}' initialization error: {}", getThing().getUID(), getThing().getLabel(), e.getMessage());
        updateStatusIfChanged(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getMessage());
    } finally {
        logger.trace("initialize() of thing {} '{}' finished", thing.getUID(), thing.getLabel());
    }
}
Also used : ModbusDataConfiguration(org.openhab.binding.modbus.internal.config.ModbusDataConfiguration) ModbusEndpointThingHandler(org.openhab.binding.modbus.handler.ModbusEndpointThingHandler) BridgeHandler(org.openhab.core.thing.binding.BridgeHandler) ModbusConfigurationException(org.openhab.binding.modbus.internal.ModbusConfigurationException) ModbusReadRequestBlueprint(org.openhab.core.io.transport.modbus.ModbusReadRequestBlueprint) ModbusPollerThingHandler(org.openhab.binding.modbus.handler.ModbusPollerThingHandler) EndpointNotInitializedException(org.openhab.binding.modbus.handler.EndpointNotInitializedException) Bridge(org.openhab.core.thing.Bridge)

Example 5 with ModbusConfigurationException

use of org.openhab.binding.modbus.internal.ModbusConfigurationException in project openhab-addons by openhab.

the class ModbusSerialThingHandler method configure.

@Override
protected void configure() throws ModbusConfigurationException {
    ModbusSerialConfiguration config = getConfigAs(ModbusSerialConfiguration.class);
    String port = config.getPort();
    int baud = config.getBaud();
    String flowControlIn = config.getFlowControlIn();
    String flowControlOut = config.getFlowControlOut();
    String stopBits = config.getStopBits();
    String parity = config.getParity();
    String encoding = config.getEncoding();
    if (port == null || flowControlIn == null || flowControlOut == null || stopBits == null || parity == null || encoding == null) {
        throw new ModbusConfigurationException("port, baud, flowControlIn, flowControlOut, stopBits, parity, encoding all must be non-null!");
    }
    this.config = config;
    EndpointPoolConfiguration poolConfiguration = new EndpointPoolConfiguration();
    this.poolConfiguration = poolConfiguration;
    poolConfiguration.setConnectMaxTries(config.getConnectMaxTries());
    poolConfiguration.setConnectTimeoutMillis(config.getConnectTimeoutMillis());
    poolConfiguration.setInterTransactionDelayMillis(config.getTimeBetweenTransactionsMillis());
    // Never reconnect serial connections "automatically"
    poolConfiguration.setInterConnectDelayMillis(1000);
    poolConfiguration.setReconnectAfterMillis(-1);
    endpoint = new ModbusSerialSlaveEndpoint(port, baud, flowControlIn, flowControlOut, config.getDataBits(), stopBits, parity, encoding, config.isEcho(), config.getReceiveTimeoutMillis());
}
Also used : ModbusSerialSlaveEndpoint(org.openhab.core.io.transport.modbus.endpoint.ModbusSerialSlaveEndpoint) EndpointPoolConfiguration(org.openhab.core.io.transport.modbus.endpoint.EndpointPoolConfiguration) ModbusConfigurationException(org.openhab.binding.modbus.internal.ModbusConfigurationException) ModbusSerialConfiguration(org.openhab.binding.modbus.internal.config.ModbusSerialConfiguration) ModbusSerialSlaveEndpoint(org.openhab.core.io.transport.modbus.endpoint.ModbusSerialSlaveEndpoint)

Aggregations

ModbusConfigurationException (org.openhab.binding.modbus.internal.ModbusConfigurationException)7 ModbusReadRequestBlueprint (org.openhab.core.io.transport.modbus.ModbusReadRequestBlueprint)4 Nullable (org.eclipse.jdt.annotation.Nullable)2 CascadedValueTransformationImpl (org.openhab.binding.modbus.internal.CascadedValueTransformationImpl)2 ValueType (org.openhab.core.io.transport.modbus.ModbusConstants.ValueType)2 ModbusWriteCoilRequestBlueprint (org.openhab.core.io.transport.modbus.ModbusWriteCoilRequestBlueprint)2 ModbusWriteRegisterRequestBlueprint (org.openhab.core.io.transport.modbus.ModbusWriteRegisterRequestBlueprint)2 ModbusWriteRequestBlueprint (org.openhab.core.io.transport.modbus.ModbusWriteRequestBlueprint)2 EndpointPoolConfiguration (org.openhab.core.io.transport.modbus.endpoint.EndpointPoolConfiguration)2 EndpointNotInitializedException (org.openhab.binding.modbus.handler.EndpointNotInitializedException)1 ModbusEndpointThingHandler (org.openhab.binding.modbus.handler.ModbusEndpointThingHandler)1 ModbusPollerThingHandler (org.openhab.binding.modbus.handler.ModbusPollerThingHandler)1 ModbusDataConfiguration (org.openhab.binding.modbus.internal.config.ModbusDataConfiguration)1 ModbusSerialConfiguration (org.openhab.binding.modbus.internal.config.ModbusSerialConfiguration)1 ModbusTcpConfiguration (org.openhab.binding.modbus.internal.config.ModbusTcpConfiguration)1 ModbusReadFunctionCode (org.openhab.core.io.transport.modbus.ModbusReadFunctionCode)1 ModbusSerialSlaveEndpoint (org.openhab.core.io.transport.modbus.endpoint.ModbusSerialSlaveEndpoint)1 ModbusTCPSlaveEndpoint (org.openhab.core.io.transport.modbus.endpoint.ModbusTCPSlaveEndpoint)1 Bridge (org.openhab.core.thing.Bridge)1 BridgeHandler (org.openhab.core.thing.binding.BridgeHandler)1