use of org.eclipse.smarthome.binding.mqtt.generic.internal.generic.ChannelState in project smarthome by eclipse.
the class AbstractMQTTThingHandler method handleCommand.
@Override
public void handleCommand(ChannelUID channelUID, Command command) {
if (connection == null) {
return;
}
@Nullable final ChannelState data = getChannelState(channelUID);
if (data == null) {
logger.warn("Channel {} not supported", channelUID.getId());
if (command instanceof RefreshType) {
updateState(channelUID.getId(), UnDefType.UNDEF);
}
return;
}
if (command instanceof RefreshType || data.isReadOnly()) {
updateState(channelUID.getId(), data.getCache().getChannelState());
return;
}
final CompletableFuture<@Nullable Void> future = data.publishValue(command);
future.exceptionally(e -> {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getLocalizedMessage());
return null;
}).thenRun(() -> logger.debug("Successfully published value {} to topic {}", command, data.getStateTopic()));
}
use of org.eclipse.smarthome.binding.mqtt.generic.internal.generic.ChannelState in project smarthome by eclipse.
the class GenericThingHandler method createChannelState.
/**
* For every Thing channel there exists a corresponding {@link ChannelState}. It consists of the MQTT state
* and MQTT command topic, the ChannelUID and a value state.
*
* @param channelConfig The channel configuration that contains MQTT state and command topic and multiple other
* configurations.
* @param channelUID The channel UID
* @param valueState The channel value state
* @return
*/
protected ChannelState createChannelState(ChannelConfig channelConfig, ChannelUID channelUID, Value valueState) {
ChannelState state = new ChannelState(channelConfig, channelUID, valueState, this);
String[] transformations;
// Incoming value transformations
transformations = channelConfig.transformationPattern.split("∩");
Stream.of(transformations).filter(t -> StringUtils.isNotBlank(t)).map(t -> new ChannelStateTransformation(t, transformationServiceProvider)).forEach(t -> state.addTransformation(t));
// Outgoing value transformations
transformations = channelConfig.transformationPatternOut.split("∩");
Stream.of(transformations).filter(t -> StringUtils.isNotBlank(t)).map(t -> new ChannelStateTransformation(t, transformationServiceProvider)).forEach(t -> state.addTransformationOut(t));
return state;
}
use of org.eclipse.smarthome.binding.mqtt.generic.internal.generic.ChannelState in project smarthome by eclipse.
the class Property method startChannel.
/**
* Subscribes to the state topic on the given connection and informs about updates on the given listener.
*
* @param connection A broker connection
* @param scheduler A scheduler to realize the timeout
* @param timeout A timeout in milliseconds. Can be 0 to disable the timeout and let the future return earlier.
* @param channelStateUpdateListener An update listener
* @return A future that completes with true if the subscribing worked and false and/or exceptionally otherwise.
*/
public CompletableFuture<@Nullable Void> startChannel(MqttBrokerConnection connection, ScheduledExecutorService scheduler, int timeout) {
final ChannelState channelState = this.channelState;
if (channelState == null) {
CompletableFuture<@Nullable Void> f = new CompletableFuture<>();
f.completeExceptionally(new IllegalStateException("Attributes not yet received!"));
return f;
}
return channelState.start(connection, scheduler, timeout);
}
use of org.eclipse.smarthome.binding.mqtt.generic.internal.generic.ChannelState in project smarthome by eclipse.
the class HomieThingHandlerTests method handleCommandUpdate.
@SuppressWarnings("null")
@Test
public void handleCommandUpdate() {
// Create mocked homie device tree with one node and one writable property
Node node = thingHandler.device.createNode("node", spy(new NodeAttributes()));
doReturn(future).when(node.attributes).subscribeAndReceive(any(), any(), anyString(), any(), anyInt());
doReturn(future).when(node.attributes).unsubscribe();
node.attributes.name = "testnode";
Property property = node.createProperty("property", spy(new PropertyAttributes()));
doReturn(future).when(property.attributes).subscribeAndReceive(any(), any(), anyString(), any(), anyInt());
doReturn(future).when(property.attributes).unsubscribe();
property.attributes.name = "testprop";
property.attributes.datatype = DataTypeEnum.string_;
property.attributes.settable = true;
property.attributesReceived();
node.properties.put(property.propertyID, property);
thingHandler.device.nodes.put(node.nodeID, node);
ChannelState channelState = property.getChannelState();
assertNotNull(channelState);
// Pretend we called start()
ChannelStateHelper.setConnection(channelState, connection);
thingHandler.connection = connection;
StringType updateValue = new StringType("UPDATE");
thingHandler.handleCommand(property.channelUID, updateValue);
assertThat(property.getChannelState().getCache().getChannelState().toString(), is("UPDATE"));
verify(connection, times(1)).publish(any(), any(), anyInt(), anyBoolean());
// Check non writable property
property.attributes.settable = false;
property.attributesReceived();
// Assign old value
Value value = property.getChannelState().getCache();
Command command = TypeParser.parseCommand(value.getSupportedCommandTypes(), "OLDVALUE");
property.getChannelState().getCache().update(command);
// Try to update with new value
updateValue = new StringType("SOMETHINGNEW");
thingHandler.handleCommand(property.channelUID, updateValue);
// Expect old value and no MQTT publish
assertThat(property.getChannelState().getCache().getChannelState().toString(), is("OLDVALUE"));
verify(connection, times(1)).publish(any(), any(), anyInt(), anyBoolean());
}
use of org.eclipse.smarthome.binding.mqtt.generic.internal.generic.ChannelState in project smarthome by eclipse.
the class GenericThingHandlerTests method initialize.
@Test
public void initialize() {
thingHandler.initialize();
verify(thingHandler).bridgeStatusChanged(any());
verify(thingHandler).start(any());
assertThat(thingHandler.connection, is(connection));
ChannelState channelConfig = thingHandler.channelStateByChannelUID.get(textChannelUID);
assertThat(channelConfig.getStateTopic(), is("test/state"));
assertThat(channelConfig.getCommandTopic(), is("test/command"));
verify(connection).subscribe(eq(channelConfig.getStateTopic()), eq(channelConfig));
verify(callback).statusUpdated(eq(thing), argThat((arg) -> arg.getStatus().equals(ThingStatus.ONLINE) && arg.getStatusDetail().equals(ThingStatusDetail.NONE)));
}
Aggregations