Search in sources :

Example 6 with ChannelState

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()));
}
Also used : NonNullByDefault(org.eclipse.jdt.annotation.NonNullByDefault) Logger(org.slf4j.Logger) MqttBrokerConnection(org.eclipse.smarthome.io.transport.mqtt.MqttBrokerConnection) Bridge(org.eclipse.smarthome.core.thing.Bridge) RefreshType(org.eclipse.smarthome.core.types.RefreshType) LoggerFactory(org.slf4j.LoggerFactory) TimeoutException(java.util.concurrent.TimeoutException) UnDefType(org.eclipse.smarthome.core.types.UnDefType) CompletableFuture(java.util.concurrent.CompletableFuture) ThingStatusInfo(org.eclipse.smarthome.core.thing.ThingStatusInfo) ChannelState(org.eclipse.smarthome.binding.mqtt.generic.internal.generic.ChannelState) BaseThingHandler(org.eclipse.smarthome.core.thing.binding.BaseThingHandler) Command(org.eclipse.smarthome.core.types.Command) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) AbstractBrokerHandler(org.eclipse.smarthome.binding.mqtt.handler.AbstractBrokerHandler) ChannelUID(org.eclipse.smarthome.core.thing.ChannelUID) Nullable(org.eclipse.jdt.annotation.Nullable) ThingStatusDetail(org.eclipse.smarthome.core.thing.ThingStatusDetail) Thing(org.eclipse.smarthome.core.thing.Thing) ChannelStateUpdateListener(org.eclipse.smarthome.binding.mqtt.generic.internal.generic.ChannelStateUpdateListener) State(org.eclipse.smarthome.core.types.State) ThingStatus(org.eclipse.smarthome.core.thing.ThingStatus) ChannelState(org.eclipse.smarthome.binding.mqtt.generic.internal.generic.ChannelState) RefreshType(org.eclipse.smarthome.core.types.RefreshType) Nullable(org.eclipse.jdt.annotation.Nullable)

Example 7 with ChannelState

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;
}
Also used : Channel(org.eclipse.smarthome.core.thing.Channel) StringUtils(org.apache.commons.lang.StringUtils) MqttChannelStateDescriptionProvider(org.eclipse.smarthome.binding.mqtt.generic.internal.generic.MqttChannelStateDescriptionProvider) LoggerFactory(org.slf4j.LoggerFactory) TimeoutException(java.util.concurrent.TimeoutException) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) ChannelState(org.eclipse.smarthome.binding.mqtt.generic.internal.generic.ChannelState) TransformationServiceProvider(org.eclipse.smarthome.binding.mqtt.generic.internal.generic.TransformationServiceProvider) ChannelConfig(org.eclipse.smarthome.binding.mqtt.generic.internal.generic.ChannelConfig) ArrayList(java.util.ArrayList) ChannelUID(org.eclipse.smarthome.core.thing.ChannelUID) Nullable(org.eclipse.jdt.annotation.Nullable) Map(java.util.Map) Thing(org.eclipse.smarthome.core.thing.Thing) ChannelStateUpdateListener(org.eclipse.smarthome.binding.mqtt.generic.internal.generic.ChannelStateUpdateListener) Value(org.eclipse.smarthome.binding.mqtt.generic.internal.values.Value) NonNullByDefault(org.eclipse.jdt.annotation.NonNullByDefault) Logger(org.slf4j.Logger) ValueFactory(org.eclipse.smarthome.binding.mqtt.generic.internal.values.ValueFactory) MqttBrokerConnection(org.eclipse.smarthome.io.transport.mqtt.MqttBrokerConnection) ChannelStateTransformation(org.eclipse.smarthome.binding.mqtt.generic.internal.generic.ChannelStateTransformation) Collectors(java.util.stream.Collectors) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) List(java.util.List) ChannelTypeUID(org.eclipse.smarthome.core.thing.type.ChannelTypeUID) Stream(java.util.stream.Stream) ThingStatusDetail(org.eclipse.smarthome.core.thing.ThingStatusDetail) StateDescription(org.eclipse.smarthome.core.types.StateDescription) ThingStatus(org.eclipse.smarthome.core.thing.ThingStatus) ChannelStateTransformation(org.eclipse.smarthome.binding.mqtt.generic.internal.generic.ChannelStateTransformation) ChannelState(org.eclipse.smarthome.binding.mqtt.generic.internal.generic.ChannelState)

Example 8 with ChannelState

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);
}
Also used : ChannelState(org.eclipse.smarthome.binding.mqtt.generic.internal.generic.ChannelState) CompletableFuture(java.util.concurrent.CompletableFuture)

Example 9 with ChannelState

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());
}
Also used : ChannelState(org.eclipse.smarthome.binding.mqtt.generic.internal.generic.ChannelState) PropertyAttributes(org.eclipse.smarthome.binding.mqtt.generic.internal.convention.homie300.PropertyAttributes) StringType(org.eclipse.smarthome.core.library.types.StringType) Command(org.eclipse.smarthome.core.types.Command) Node(org.eclipse.smarthome.binding.mqtt.generic.internal.convention.homie300.Node) NodeAttributes(org.eclipse.smarthome.binding.mqtt.generic.internal.convention.homie300.NodeAttributes) Value(org.eclipse.smarthome.binding.mqtt.generic.internal.values.Value) Property(org.eclipse.smarthome.binding.mqtt.generic.internal.convention.homie300.Property) Test(org.junit.Test)

Example 10 with ChannelState

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)));
}
Also used : CoreMatchers.is(org.hamcrest.CoreMatchers.is) ArgumentMatchers(org.mockito.ArgumentMatchers) Mock(org.mockito.Mock) MqttChannelStateDescriptionProvider(org.eclipse.smarthome.binding.mqtt.generic.internal.generic.MqttChannelStateDescriptionProvider) OnOffType(org.eclipse.smarthome.core.library.types.OnOffType) CompletableFuture(java.util.concurrent.CompletableFuture) ChannelState(org.eclipse.smarthome.binding.mqtt.generic.internal.generic.ChannelState) TransformationServiceProvider(org.eclipse.smarthome.binding.mqtt.generic.internal.generic.TransformationServiceProvider) ChannelConfig(org.eclipse.smarthome.binding.mqtt.generic.internal.generic.ChannelConfig) Assert.assertThat(org.junit.Assert.assertThat) AbstractBrokerHandler(org.eclipse.smarthome.binding.mqtt.handler.AbstractBrokerHandler) ChannelUID(org.eclipse.smarthome.core.thing.ChannelUID) MockitoAnnotations(org.mockito.MockitoAnnotations) Thing(org.eclipse.smarthome.core.thing.Thing) ChannelConfigBuilder(org.eclipse.smarthome.binding.mqtt.generic.internal.generic.ChannelConfigBuilder) StringType(org.eclipse.smarthome.core.library.types.StringType) Configuration(org.eclipse.smarthome.config.core.Configuration) Before(org.junit.Before) ThingHandlerCallback(org.eclipse.smarthome.core.thing.binding.ThingHandlerCallback) ThingChannelConstants(org.eclipse.smarthome.binding.mqtt.generic.internal.handler.ThingChannelConstants) ValueFactory(org.eclipse.smarthome.binding.mqtt.generic.internal.values.ValueFactory) MqttBrokerConnection(org.eclipse.smarthome.io.transport.mqtt.MqttBrokerConnection) OnOffValue(org.eclipse.smarthome.binding.mqtt.generic.internal.values.OnOffValue) RefreshType(org.eclipse.smarthome.core.types.RefreshType) ThingStatusInfo(org.eclipse.smarthome.core.thing.ThingStatusInfo) Test(org.junit.Test) Mockito(org.mockito.Mockito) TextValue(org.eclipse.smarthome.binding.mqtt.generic.internal.values.TextValue) ThingStatusDetail(org.eclipse.smarthome.core.thing.ThingStatusDetail) ThingStatus(org.eclipse.smarthome.core.thing.ThingStatus) ChannelState(org.eclipse.smarthome.binding.mqtt.generic.internal.generic.ChannelState) Test(org.junit.Test)

Aggregations

ChannelState (org.eclipse.smarthome.binding.mqtt.generic.internal.generic.ChannelState)12 Test (org.junit.Test)7 CompletableFuture (java.util.concurrent.CompletableFuture)6 TextValue (org.eclipse.smarthome.binding.mqtt.generic.internal.values.TextValue)5 StringType (org.eclipse.smarthome.core.library.types.StringType)5 ChannelUID (org.eclipse.smarthome.core.thing.ChannelUID)5 Thing (org.eclipse.smarthome.core.thing.Thing)5 ThingStatus (org.eclipse.smarthome.core.thing.ThingStatus)5 ThingStatusDetail (org.eclipse.smarthome.core.thing.ThingStatusDetail)5 MqttBrokerConnection (org.eclipse.smarthome.io.transport.mqtt.MqttBrokerConnection)5 ChannelConfig (org.eclipse.smarthome.binding.mqtt.generic.internal.generic.ChannelConfig)4 MqttChannelStateDescriptionProvider (org.eclipse.smarthome.binding.mqtt.generic.internal.generic.MqttChannelStateDescriptionProvider)4 TransformationServiceProvider (org.eclipse.smarthome.binding.mqtt.generic.internal.generic.TransformationServiceProvider)4 OnOffValue (org.eclipse.smarthome.binding.mqtt.generic.internal.values.OnOffValue)4 ValueFactory (org.eclipse.smarthome.binding.mqtt.generic.internal.values.ValueFactory)4 ExecutionException (java.util.concurrent.ExecutionException)3 TimeUnit (java.util.concurrent.TimeUnit)3 TimeoutException (java.util.concurrent.TimeoutException)3 NonNullByDefault (org.eclipse.jdt.annotation.NonNullByDefault)3 Nullable (org.eclipse.jdt.annotation.Nullable)3