]> git.basschouten.com Git - openhab-addons.git/commitdiff
[remoteopenhab] Listen to the new ChannelDescriptionChangedEvent events to update...
authorlolodomo <lg.hc@free.fr>
Tue, 22 Jun 2021 19:19:45 +0000 (21:19 +0200)
committerGitHub <noreply@github.com>
Tue, 22 Jun 2021 19:19:45 +0000 (21:19 +0200)
Also handle dynamic command options

Signed-off-by: Laurent Garnier <lg.hc@free.fr>
bundles/org.openhab.binding.remoteopenhab/src/main/java/org/openhab/binding/remoteopenhab/internal/RemoteopenhabCommandDescriptionOptionProvider.java [new file with mode: 0644]
bundles/org.openhab.binding.remoteopenhab/src/main/java/org/openhab/binding/remoteopenhab/internal/RemoteopenhabHandlerFactory.java
bundles/org.openhab.binding.remoteopenhab/src/main/java/org/openhab/binding/remoteopenhab/internal/data/RemoteopenhabChannelDescriptionChangedEvent.java [new file with mode: 0644]
bundles/org.openhab.binding.remoteopenhab/src/main/java/org/openhab/binding/remoteopenhab/internal/data/RemoteopenhabCommandDescription.java [new file with mode: 0644]
bundles/org.openhab.binding.remoteopenhab/src/main/java/org/openhab/binding/remoteopenhab/internal/data/RemoteopenhabCommandOption.java [new file with mode: 0644]
bundles/org.openhab.binding.remoteopenhab/src/main/java/org/openhab/binding/remoteopenhab/internal/data/RemoteopenhabCommandOptions.java [new file with mode: 0644]
bundles/org.openhab.binding.remoteopenhab/src/main/java/org/openhab/binding/remoteopenhab/internal/data/RemoteopenhabItem.java
bundles/org.openhab.binding.remoteopenhab/src/main/java/org/openhab/binding/remoteopenhab/internal/data/RemoteopenhabStateOptions.java [new file with mode: 0644]
bundles/org.openhab.binding.remoteopenhab/src/main/java/org/openhab/binding/remoteopenhab/internal/handler/RemoteopenhabBridgeHandler.java
bundles/org.openhab.binding.remoteopenhab/src/main/java/org/openhab/binding/remoteopenhab/internal/listener/RemoteopenhabItemsDataListener.java
bundles/org.openhab.binding.remoteopenhab/src/main/java/org/openhab/binding/remoteopenhab/internal/rest/RemoteopenhabRestClient.java

diff --git a/bundles/org.openhab.binding.remoteopenhab/src/main/java/org/openhab/binding/remoteopenhab/internal/RemoteopenhabCommandDescriptionOptionProvider.java b/bundles/org.openhab.binding.remoteopenhab/src/main/java/org/openhab/binding/remoteopenhab/internal/RemoteopenhabCommandDescriptionOptionProvider.java
new file mode 100644 (file)
index 0000000..35394ea
--- /dev/null
@@ -0,0 +1,42 @@
+/**
+ * Copyright (c) 2010-2021 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.remoteopenhab.internal;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.core.events.EventPublisher;
+import org.openhab.core.thing.binding.BaseDynamicCommandDescriptionProvider;
+import org.openhab.core.thing.i18n.ChannelTypeI18nLocalizationService;
+import org.openhab.core.thing.link.ItemChannelLinkRegistry;
+import org.openhab.core.thing.type.DynamicCommandDescriptionProvider;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+
+/**
+ * Dynamic provider of command options
+ *
+ * @author Laurent Garnier - Initial contribution
+ */
+@Component(service = { DynamicCommandDescriptionProvider.class, RemoteopenhabCommandDescriptionOptionProvider.class })
+@NonNullByDefault
+public class RemoteopenhabCommandDescriptionOptionProvider extends BaseDynamicCommandDescriptionProvider {
+
+    @Activate
+    public RemoteopenhabCommandDescriptionOptionProvider(final @Reference EventPublisher eventPublisher, //
+            final @Reference ItemChannelLinkRegistry itemChannelLinkRegistry, //
+            final @Reference ChannelTypeI18nLocalizationService channelTypeI18nLocalizationService) {
+        this.eventPublisher = eventPublisher;
+        this.itemChannelLinkRegistry = itemChannelLinkRegistry;
+        this.channelTypeI18nLocalizationService = channelTypeI18nLocalizationService;
+    }
+}
index 6c332add640c56abc8894b674f1361e628d73dbd..93e3177c738ac3283d244f2dc1f79b116563f43d 100644 (file)
@@ -75,6 +75,7 @@ public class RemoteopenhabHandlerFactory extends BaseThingHandlerFactory {
     private final SseEventSourceFactory eventSourceFactory;
     private final RemoteopenhabChannelTypeProvider channelTypeProvider;
     private final RemoteopenhabStateDescriptionOptionProvider stateDescriptionProvider;
+    private final RemoteopenhabCommandDescriptionOptionProvider commandDescriptionProvider;
     private final Gson jsonParser;
 
     private HttpClient httpClientTrustingCert;
@@ -83,13 +84,15 @@ public class RemoteopenhabHandlerFactory extends BaseThingHandlerFactory {
     public RemoteopenhabHandlerFactory(final @Reference HttpClientFactory httpClientFactory,
             final @Reference ClientBuilder clientBuilder, final @Reference SseEventSourceFactory eventSourceFactory,
             final @Reference RemoteopenhabChannelTypeProvider channelTypeProvider,
-            final @Reference RemoteopenhabStateDescriptionOptionProvider stateDescriptionProvider) {
+            final @Reference RemoteopenhabStateDescriptionOptionProvider stateDescriptionProvider,
+            final @Reference RemoteopenhabCommandDescriptionOptionProvider commandDescriptionProvider) {
         this.httpClient = httpClientFactory.getCommonHttpClient();
         this.httpClientTrustingCert = httpClientFactory.createHttpClient(RemoteopenhabBindingConstants.BINDING_ID);
         this.clientBuilder = clientBuilder;
         this.eventSourceFactory = eventSourceFactory;
         this.channelTypeProvider = channelTypeProvider;
         this.stateDescriptionProvider = stateDescriptionProvider;
+        this.commandDescriptionProvider = commandDescriptionProvider;
         this.jsonParser = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.IDENTITY).create();
 
         try {
@@ -196,7 +199,8 @@ public class RemoteopenhabHandlerFactory extends BaseThingHandlerFactory {
         ThingTypeUID thingTypeUID = thing.getThingTypeUID();
         if (thingTypeUID.equals(RemoteopenhabBindingConstants.BRIDGE_TYPE_SERVER)) {
             return new RemoteopenhabBridgeHandler((Bridge) thing, httpClient, httpClientTrustingCert, clientBuilder,
-                    eventSourceFactory, channelTypeProvider, stateDescriptionProvider, jsonParser);
+                    eventSourceFactory, channelTypeProvider, stateDescriptionProvider, commandDescriptionProvider,
+                    jsonParser);
         } else if (RemoteopenhabBindingConstants.SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID)) {
             return new RemoteopenhabThingHandler(thing);
         }
diff --git a/bundles/org.openhab.binding.remoteopenhab/src/main/java/org/openhab/binding/remoteopenhab/internal/data/RemoteopenhabChannelDescriptionChangedEvent.java b/bundles/org.openhab.binding.remoteopenhab/src/main/java/org/openhab/binding/remoteopenhab/internal/data/RemoteopenhabChannelDescriptionChangedEvent.java
new file mode 100644 (file)
index 0000000..8a78985
--- /dev/null
@@ -0,0 +1,33 @@
+/**
+ * Copyright (c) 2010-2021 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.remoteopenhab.internal.data;
+
+import java.util.Set;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
+/**
+ * Payload from ChannelDescriptionChangedEvent events received through the SSE connection.
+ *
+ * @author Laurent Garnier - Initial contribution
+ */
+@NonNullByDefault
+public class RemoteopenhabChannelDescriptionChangedEvent {
+
+    public String field = "";
+    public String channelUID = "";
+    public Set<String> linkedItemNames = Set.of();
+    public String value = "";
+    public @Nullable String oldValue = "";
+}
diff --git a/bundles/org.openhab.binding.remoteopenhab/src/main/java/org/openhab/binding/remoteopenhab/internal/data/RemoteopenhabCommandDescription.java b/bundles/org.openhab.binding.remoteopenhab/src/main/java/org/openhab/binding/remoteopenhab/internal/data/RemoteopenhabCommandDescription.java
new file mode 100644 (file)
index 0000000..b57b4e9
--- /dev/null
@@ -0,0 +1,29 @@
+/**
+ * Copyright (c) 2010-2021 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.remoteopenhab.internal.data;
+
+import java.util.List;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
+/**
+ * Part of {@link RemoteopenhabItem} containing the command description
+ *
+ * @author Laurent Garnier - Initial contribution
+ */
+@NonNullByDefault
+public class RemoteopenhabCommandDescription {
+
+    public @Nullable List<RemoteopenhabCommandOption> commandOptions;
+}
diff --git a/bundles/org.openhab.binding.remoteopenhab/src/main/java/org/openhab/binding/remoteopenhab/internal/data/RemoteopenhabCommandOption.java b/bundles/org.openhab.binding.remoteopenhab/src/main/java/org/openhab/binding/remoteopenhab/internal/data/RemoteopenhabCommandOption.java
new file mode 100644 (file)
index 0000000..ebf6d57
--- /dev/null
@@ -0,0 +1,27 @@
+/**
+ * Copyright (c) 2010-2021 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.remoteopenhab.internal.data;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * Part of {@link RemoteopenhabCommandDescription} containing one command option
+ *
+ * @author Laurent Garnier - Initial contribution
+ */
+@NonNullByDefault
+public class RemoteopenhabCommandOption {
+
+    public String command = "";
+    public String label = "";
+}
diff --git a/bundles/org.openhab.binding.remoteopenhab/src/main/java/org/openhab/binding/remoteopenhab/internal/data/RemoteopenhabCommandOptions.java b/bundles/org.openhab.binding.remoteopenhab/src/main/java/org/openhab/binding/remoteopenhab/internal/data/RemoteopenhabCommandOptions.java
new file mode 100644 (file)
index 0000000..ff0cb18
--- /dev/null
@@ -0,0 +1,29 @@
+/**
+ * Copyright (c) 2010-2021 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.remoteopenhab.internal.data;
+
+import java.util.List;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * Match content of field value from {@link RemoteopenhabChannelDescriptionChangedEvent) event payload when event is for
+ * COMMAND_OPTIONS
+ *
+ * @author Laurent Garnier - Initial contribution
+ */
+@NonNullByDefault
+public class RemoteopenhabCommandOptions {
+
+    public List<RemoteopenhabCommandOption> options = List.of();
+}
index ba63479c3a5d6e9b5471a6e8b03588c9741c0213..5293a75343fe17ef26704fdfe3448a09e1b23550 100644 (file)
@@ -29,4 +29,5 @@ public class RemoteopenhabItem {
     public String state = "";
     public String groupType = "";
     public @Nullable RemoteopenhabStateDescription stateDescription;
+    public @Nullable RemoteopenhabCommandDescription commandDescription;
 }
diff --git a/bundles/org.openhab.binding.remoteopenhab/src/main/java/org/openhab/binding/remoteopenhab/internal/data/RemoteopenhabStateOptions.java b/bundles/org.openhab.binding.remoteopenhab/src/main/java/org/openhab/binding/remoteopenhab/internal/data/RemoteopenhabStateOptions.java
new file mode 100644 (file)
index 0000000..4f8e04b
--- /dev/null
@@ -0,0 +1,29 @@
+/**
+ * Copyright (c) 2010-2021 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.remoteopenhab.internal.data;
+
+import java.util.List;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * Match content of field value from {@link RemoteopenhabChannelDescriptionChangedEvent) event payload when event is for
+ * STATE_OPTIONS
+ *
+ * @author Laurent Garnier - Initial contribution
+ */
+@NonNullByDefault
+public class RemoteopenhabStateOptions {
+
+    public List<RemoteopenhabStateOption> options = List.of();
+}
index a47f233d040cebb432f5e4ba6ad217c69f5cd457..93d0c6bb817fcd285391d4296cb2a11c70e1897a 100644 (file)
@@ -32,8 +32,11 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.jetty.client.HttpClient;
 import org.openhab.binding.remoteopenhab.internal.RemoteopenhabChannelTypeProvider;
+import org.openhab.binding.remoteopenhab.internal.RemoteopenhabCommandDescriptionOptionProvider;
 import org.openhab.binding.remoteopenhab.internal.RemoteopenhabStateDescriptionOptionProvider;
 import org.openhab.binding.remoteopenhab.internal.config.RemoteopenhabServerConfiguration;
+import org.openhab.binding.remoteopenhab.internal.data.RemoteopenhabCommandDescription;
+import org.openhab.binding.remoteopenhab.internal.data.RemoteopenhabCommandOption;
 import org.openhab.binding.remoteopenhab.internal.data.RemoteopenhabItem;
 import org.openhab.binding.remoteopenhab.internal.data.RemoteopenhabStateDescription;
 import org.openhab.binding.remoteopenhab.internal.data.RemoteopenhabStateOption;
@@ -69,6 +72,7 @@ import org.openhab.core.thing.type.ChannelType;
 import org.openhab.core.thing.type.ChannelTypeBuilder;
 import org.openhab.core.thing.type.ChannelTypeUID;
 import org.openhab.core.types.Command;
+import org.openhab.core.types.CommandOption;
 import org.openhab.core.types.RefreshType;
 import org.openhab.core.types.State;
 import org.openhab.core.types.StateDescriptionFragmentBuilder;
@@ -101,6 +105,7 @@ public class RemoteopenhabBridgeHandler extends BaseBridgeHandler
     private final HttpClient httpClientTrustingCert;
     private final RemoteopenhabChannelTypeProvider channelTypeProvider;
     private final RemoteopenhabStateDescriptionOptionProvider stateDescriptionProvider;
+    private final RemoteopenhabCommandDescriptionOptionProvider commandDescriptionProvider;
 
     private final Object updateThingLock = new Object();
 
@@ -114,11 +119,13 @@ public class RemoteopenhabBridgeHandler extends BaseBridgeHandler
     public RemoteopenhabBridgeHandler(Bridge bridge, HttpClient httpClient, HttpClient httpClientTrustingCert,
             ClientBuilder clientBuilder, SseEventSourceFactory eventSourceFactory,
             RemoteopenhabChannelTypeProvider channelTypeProvider,
-            RemoteopenhabStateDescriptionOptionProvider stateDescriptionProvider, final Gson jsonParser) {
+            RemoteopenhabStateDescriptionOptionProvider stateDescriptionProvider,
+            RemoteopenhabCommandDescriptionOptionProvider commandDescriptionProvider, final Gson jsonParser) {
         super(bridge);
         this.httpClientTrustingCert = httpClientTrustingCert;
         this.channelTypeProvider = channelTypeProvider;
         this.stateDescriptionProvider = stateDescriptionProvider;
+        this.commandDescriptionProvider = commandDescriptionProvider;
         this.restClient = new RemoteopenhabRestClient(httpClient, clientBuilder, eventSourceFactory, jsonParser);
     }
 
@@ -314,18 +321,31 @@ public class RemoteopenhabBridgeHandler extends BaseBridgeHandler
         }
     }
 
-    private void setStateOptions(List<RemoteopenhabItem> items) {
+    private void setDynamicOptions(List<RemoteopenhabItem> items) {
         for (RemoteopenhabItem item : items) {
             Channel channel = getThing().getChannel(item.name);
-            RemoteopenhabStateDescription descr = item.stateDescription;
-            List<RemoteopenhabStateOption> options = descr == null ? null : descr.options;
-            if (channel != null && options != null && !options.isEmpty()) {
-                List<StateOption> stateOptions = new ArrayList<>();
-                for (RemoteopenhabStateOption option : options) {
-                    stateOptions.add(new StateOption(option.value, option.label));
+            if (channel == null) {
+                continue;
+            }
+            RemoteopenhabStateDescription stateDescr = item.stateDescription;
+            List<RemoteopenhabStateOption> stateOptions = stateDescr == null ? null : stateDescr.options;
+            if (stateOptions != null && !stateOptions.isEmpty()) {
+                List<StateOption> options = new ArrayList<>();
+                for (RemoteopenhabStateOption option : stateOptions) {
+                    options.add(new StateOption(option.value, option.label));
+                }
+                stateDescriptionProvider.setStateOptions(channel.getUID(), options);
+                logger.trace("{} state options set for the channel {}", options.size(), channel.getUID());
+            }
+            RemoteopenhabCommandDescription commandDescr = item.commandDescription;
+            List<RemoteopenhabCommandOption> commandOptions = commandDescr == null ? null : commandDescr.commandOptions;
+            if (commandOptions != null && !commandOptions.isEmpty()) {
+                List<CommandOption> options = new ArrayList<>();
+                for (RemoteopenhabCommandOption option : commandOptions) {
+                    options.add(new CommandOption(option.command, option.label));
                 }
-                stateDescriptionProvider.setStateOptions(channel.getUID(), stateOptions);
-                logger.trace("{} options set for the channel {}", options.size(), channel.getUID());
+                commandDescriptionProvider.setCommandOptions(channel.getUID(), options);
+                logger.trace("{} command options set for the channel {}", options.size(), channel.getUID());
             }
         }
     }
@@ -341,7 +361,7 @@ public class RemoteopenhabBridgeHandler extends BaseBridgeHandler
                 List<RemoteopenhabItem> items = restClient.getRemoteItems("name,type,groupType,state,stateDescription");
 
                 if (createChannels(items, true)) {
-                    setStateOptions(items);
+                    setDynamicOptions(items);
                     for (RemoteopenhabItem item : items) {
                         updateChannelState(item.name, null, item.state, false);
                     }
@@ -467,6 +487,11 @@ public class RemoteopenhabBridgeHandler extends BaseBridgeHandler
         }
     }
 
+    @Override
+    public void onItemOptionsUpdatedd(RemoteopenhabItem item) {
+        setDynamicOptions(List.of(item));
+    }
+
     private void updateChannelState(String itemName, @Nullable String stateType, String state,
             boolean onlyIfStateChanged) {
         Channel channel = getThing().getChannel(itemName);
index 902cce4b33fda726daac1393e0861a6e80960ac4..7540b6cad09d5ebc65b3e3ea2784b300c48caba5 100644 (file)
@@ -43,4 +43,9 @@ public interface RemoteopenhabItemsDataListener {
      * A new ItemUpdatedEvent was published.
      */
     void onItemUpdated(RemoteopenhabItem newItem, RemoteopenhabItem oldItem);
+
+    /**
+     * A new ChannelDescriptionChangedEvent with updated state options or updated command options was published.
+     */
+    void onItemOptionsUpdatedd(RemoteopenhabItem item);
 }
index f43becaf11c1dac559c8af7aeec9e44ea2cb8233..1b40d12f85ed6071e0be84d4ceec5cd92d35d4df 100644 (file)
@@ -46,11 +46,16 @@ import org.eclipse.jetty.client.util.InputStreamResponseListener;
 import org.eclipse.jetty.client.util.StringContentProvider;
 import org.eclipse.jetty.http.HttpMethod;
 import org.eclipse.jetty.http.HttpStatus;
+import org.openhab.binding.remoteopenhab.internal.data.RemoteopenhabChannelDescriptionChangedEvent;
 import org.openhab.binding.remoteopenhab.internal.data.RemoteopenhabChannelTriggerEvent;
+import org.openhab.binding.remoteopenhab.internal.data.RemoteopenhabCommandDescription;
+import org.openhab.binding.remoteopenhab.internal.data.RemoteopenhabCommandOptions;
 import org.openhab.binding.remoteopenhab.internal.data.RemoteopenhabEvent;
 import org.openhab.binding.remoteopenhab.internal.data.RemoteopenhabEventPayload;
 import org.openhab.binding.remoteopenhab.internal.data.RemoteopenhabItem;
 import org.openhab.binding.remoteopenhab.internal.data.RemoteopenhabRestApi;
+import org.openhab.binding.remoteopenhab.internal.data.RemoteopenhabStateDescription;
+import org.openhab.binding.remoteopenhab.internal.data.RemoteopenhabStateOptions;
 import org.openhab.binding.remoteopenhab.internal.data.RemoteopenhabStatusInfo;
 import org.openhab.binding.remoteopenhab.internal.data.RemoteopenhabThing;
 import org.openhab.binding.remoteopenhab.internal.exceptions.RemoteopenhabException;
@@ -321,8 +326,9 @@ public class RemoteopenhabRestClient {
 
         String url;
         try {
-            url = String.format("%s?topics=%s/items/*/*,%s/things/*/*,%s/channels/*/triggered", getRestApiUrl("events"),
-                    getTopicNamespace(), getTopicNamespace(), getTopicNamespace());
+            url = String.format(
+                    "%s?topics=%s/items/*/*,%s/things/*/*,%s/channels/*/triggered,openhab/channels/*/descriptionchanged",
+                    getRestApiUrl("events"), getTopicNamespace(), getTopicNamespace(), getTopicNamespace());
         } catch (RemoteopenhabException e) {
             logger.debug("{}", e.getMessage());
             return;
@@ -383,7 +389,7 @@ public class RemoteopenhabRestClient {
     private void onEvent(InboundSseEvent inboundEvent) {
         String name = inboundEvent.getName();
         String data = inboundEvent.readData();
-        logger.trace("Received event name {} date {}", name, data);
+        logger.trace("Received event name {} data {}", name, data);
 
         lastEventTimestamp = System.currentTimeMillis();
         if (!connected) {
@@ -468,6 +474,35 @@ public class RemoteopenhabRestClient {
                     thingsListeners
                             .forEach(listener -> listener.onChannelTriggered(triggerEvent.channel, triggerEvent.event));
                     break;
+                case "ChannelDescriptionChangedEvent":
+                    RemoteopenhabStateDescription stateDescription = new RemoteopenhabStateDescription();
+                    RemoteopenhabCommandDescription commandDescription = new RemoteopenhabCommandDescription();
+                    RemoteopenhabChannelDescriptionChangedEvent descriptionChanged = Objects.requireNonNull(
+                            jsonParser.fromJson(event.payload, RemoteopenhabChannelDescriptionChangedEvent.class));
+                    switch (descriptionChanged.field) {
+                        case "STATE_OPTIONS":
+                            RemoteopenhabStateOptions stateOptions = Objects.requireNonNull(
+                                    jsonParser.fromJson(descriptionChanged.value, RemoteopenhabStateOptions.class));
+                            stateDescription.options = stateOptions.options;
+                            break;
+                        case "COMMAND_OPTIONS":
+                            RemoteopenhabCommandOptions commandOptions = Objects.requireNonNull(
+                                    jsonParser.fromJson(descriptionChanged.value, RemoteopenhabCommandOptions.class));
+                            commandDescription.commandOptions = commandOptions.options;
+                            break;
+                        default:
+                            break;
+                    }
+                    if (stateDescription.options != null || commandDescription.commandOptions != null) {
+                        descriptionChanged.linkedItemNames.forEach(linkedItemName -> {
+                            RemoteopenhabItem item1 = new RemoteopenhabItem();
+                            item1.name = linkedItemName;
+                            item1.stateDescription = stateDescription;
+                            item1.commandDescription = commandDescription;
+                            itemsListeners.forEach(listener -> listener.onItemOptionsUpdatedd(item1));
+                        });
+                    }
+                    break;
                 case "ItemStatePredictedEvent":
                 case "ItemCommandEvent":
                 case "ThingStatusInfoEvent":