use of org.openhab.core.io.transport.modbus.ModbusReadFunctionCode 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();
}
use of org.openhab.core.io.transport.modbus.ModbusReadFunctionCode in project openhab-addons by openhab.
the class ModbusPollerThingHandler method registerPollTask.
/**
* Register poll task
*
* @throws EndpointNotInitializedException in case the bridge initialization is not complete. This should only
* happen in transient conditions, for example, when bridge is initializing.
*/
@SuppressWarnings("null")
private synchronized void registerPollTask() throws EndpointNotInitializedException {
logger.trace("registerPollTask()");
if (pollTask != null) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR);
logger.debug("pollTask should be unregistered before registering a new one!");
return;
}
ModbusEndpointThingHandler slaveEndpointThingHandler = getEndpointThingHandler();
if (slaveEndpointThingHandler == null) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE, String.format("Bridge '%s' is offline", Optional.ofNullable(getBridge()).map(b -> b.getLabel()).orElse("<null>")));
logger.debug("No bridge handler available -- aborting init for {}", this);
return;
}
ModbusCommunicationInterface localComms = slaveEndpointThingHandler.getCommunicationInterface();
if (localComms == null) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE, String.format("Bridge '%s' not completely initialized", Optional.ofNullable(getBridge()).map(b -> b.getLabel())));
logger.debug("Bridge not initialized fully (no communication interface) -- aborting init for {}", this);
return;
}
this.comms = localComms;
ModbusReadFunctionCode localFunctionCode = functionCode;
if (localFunctionCode == null) {
return;
}
ModbusReadRequestBlueprint localRequest = new ModbusReadRequestBlueprint(slaveEndpointThingHandler.getSlaveId(), localFunctionCode, config.getStart(), config.getLength(), config.getMaxTries());
this.request = localRequest;
if (config.getRefresh() <= 0L) {
logger.debug("Not registering polling with ModbusManager since refresh disabled");
updateStatus(ThingStatus.ONLINE, ThingStatusDetail.NONE, "Not polling");
} else {
logger.debug("Registering polling with ModbusManager");
pollTask = localComms.registerRegularPoll(localRequest, config.getRefresh(), 0, callbackDelegator, callbackDelegator);
assert pollTask != null;
updateStatus(ThingStatus.ONLINE);
}
}
use of org.openhab.core.io.transport.modbus.ModbusReadFunctionCode in project openhab-addons by openhab.
the class ModbusDataHandlerTest method testRefreshOnData.
@Test
public void testRefreshOnData() throws InterruptedException {
ModbusReadFunctionCode functionCode = ModbusReadFunctionCode.READ_COILS;
ModbusSlaveEndpoint endpoint = new ModbusTCPSlaveEndpoint("thisishost", 502, false);
int pollLength = 3;
// Minimally mocked request
ModbusReadRequestBlueprint request = Mockito.mock(ModbusReadRequestBlueprint.class);
doReturn(pollLength).when(request).getDataLength();
doReturn(functionCode).when(request).getFunctionCode();
PollTask task = Mockito.mock(PollTask.class);
doReturn(endpoint).when(task).getEndpoint();
doReturn(request).when(task).getRequest();
Bridge poller = createPollerMock("poller1", task);
Configuration dataConfig = new Configuration();
dataConfig.put("readStart", "0");
dataConfig.put("readTransform", "default");
dataConfig.put("readValueType", "bit");
String thingId = "read1";
ModbusDataThingHandler dataHandler = createDataHandler(thingId, poller, builder -> builder.withConfiguration(dataConfig), bundleContext);
assertThat(dataHandler.getThing().getStatus(), is(equalTo(ThingStatus.ONLINE)));
verify(comms, never()).submitOneTimePoll(eq(request), notNull(), notNull());
// Wait for all channels to receive the REFRESH command (initiated by the core)
waitForAssert(() -> verify((ModbusPollerThingHandler) poller.getHandler(), times(CHANNEL_TO_ACCEPTED_TYPE.size())).refresh());
// Reset the mock
reset(poller.getHandler());
// Issue REFRESH command and verify the results
dataHandler.handleCommand(Mockito.mock(ChannelUID.class), RefreshType.REFRESH);
// data handler asynchronously calls the poller.refresh() -- it might take some time
// We check that refresh is finally called
waitForAssert(() -> verify((ModbusPollerThingHandler) poller.getHandler()).refresh());
}
Aggregations