diff --git a/bom/openhab-addons/pom.xml b/bom/openhab-addons/pom.xml
index 8a317a327595..86b68fc6ca4c 100644
--- a/bom/openhab-addons/pom.xml
+++ b/bom/openhab-addons/pom.xml
@@ -741,11 +741,13 @@
org.openhab.binding.lifx${project.version}
-
+
org.openhab.addons.bundlesorg.openhab.binding.linuxinput
@@ -1476,6 +1478,11 @@
org.openhab.binding.tradfri${project.version}
+
+ org.openhab.addons.bundles
+ org.openhab.binding.twitter
+ ${project.version}
+ org.openhab.addons.bundlesorg.openhab.binding.unifi
diff --git a/bundles/org.openhab.automation.groovyscripting/README.md b/bundles/org.openhab.automation.groovyscripting/README.md
index 6f1f78721554..4cfb17e86607 100644
--- a/bundles/org.openhab.automation.groovyscripting/README.md
+++ b/bundles/org.openhab.automation.groovyscripting/README.md
@@ -1,6 +1,6 @@
# Groovy Scripting
-This add-on provides support for [Groovy](https://groovy-lang.org/) 3.0.8 that can be used as a scripting language within automation rules and which eliminates the need to manually install Groovy.
+This add-on provides support for [Groovy](https://groovy-lang.org/) 3.0.9 that can be used as a scripting language within automation rules and which eliminates the need to manually install Groovy.
## Creating Groovy Scripts
diff --git a/bundles/org.openhab.automation.groovyscripting/pom.xml b/bundles/org.openhab.automation.groovyscripting/pom.xml
index 008e2b30b6bc..14472d023c51 100644
--- a/bundles/org.openhab.automation.groovyscripting/pom.xml
+++ b/bundles/org.openhab.automation.groovyscripting/pom.xml
@@ -16,7 +16,7 @@
com.ibm.icu.*;resolution:=optional,groovy.runtime.metaclass;resolution:=optional,groovyjarjarantlr4.stringtemplate;resolution:=optional,org.abego.treelayout.*;resolution:=optional,org.apache.ivy.*;resolution:=optional,org.stringtemplate.v4.*;resolution:=optional
- 3.0.8
+ 3.0.9
diff --git a/bundles/org.openhab.binding.bsblan/src/main/resources/OH-INF/thing/bridge.xml b/bundles/org.openhab.binding.bsblan/src/main/resources/OH-INF/thing/bridge.xml
index 81583d1f8bab..73b6aa29e601 100644
--- a/bundles/org.openhab.binding.bsblan/src/main/resources/OH-INF/thing/bridge.xml
+++ b/bundles/org.openhab.binding.bsblan/src/main/resources/OH-INF/thing/bridge.xml
@@ -7,7 +7,12 @@
A bridge to connect a BSB-LAN device
+
+
+
+
+
network-address
diff --git a/bundles/org.openhab.binding.bsblan/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.bsblan/src/main/resources/OH-INF/thing/thing-types.xml
index 9703981f6953..46af28828ac3 100644
--- a/bundles/org.openhab.binding.bsblan/src/main/resources/OH-INF/thing/thing-types.xml
+++ b/bundles/org.openhab.binding.bsblan/src/main/resources/OH-INF/thing/thing-types.xml
@@ -23,16 +23,20 @@
+
+
+
+
Specific parameter identifier
-
+ Parameter identifier used for change requests. Defaults to the value of Parameter IDtrue
-
+ Message type used for change requests. Defaults to SET.SET
diff --git a/bundles/org.openhab.binding.doorbird/README.md b/bundles/org.openhab.binding.doorbird/README.md
index b0fd966ff128..52aa88eefa8f 100644
--- a/bundles/org.openhab.binding.doorbird/README.md
+++ b/bundles/org.openhab.binding.doorbird/README.md
@@ -38,6 +38,7 @@ The following configuration parameters are available on the Doorbird A1081 Contr
| Hostname | doorbirdHost | Required | The hostname or IP address of the Doorbird device. |
| User ID | userId | Required | User Id of a Doorbird user that has permissions to access the API. The User ID and Password must be created using the Doorbird smart phone application. |
| Password | userPassword | Required | Password of a Doorbird user. |
+| Controller Id | controllerId | Optional | Doorbird Id of the controller to reliable target the relays of this device. E.g. "gggaaa" |
## Discovery
diff --git a/bundles/org.openhab.binding.doorbird/src/main/java/org/openhab/binding/doorbird/internal/api/DoorbirdInfo.java b/bundles/org.openhab.binding.doorbird/src/main/java/org/openhab/binding/doorbird/internal/api/DoorbirdInfo.java
index 26dbec9d5134..0edb0d43c440 100644
--- a/bundles/org.openhab.binding.doorbird/src/main/java/org/openhab/binding/doorbird/internal/api/DoorbirdInfo.java
+++ b/bundles/org.openhab.binding.doorbird/src/main/java/org/openhab/binding/doorbird/internal/api/DoorbirdInfo.java
@@ -13,6 +13,7 @@
package org.openhab.binding.doorbird.internal.api;
import java.util.ArrayList;
+import java.util.Arrays;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
@@ -35,7 +36,6 @@ public class DoorbirdInfo {
private @Nullable String primaryMacAddress;
private @Nullable String wifiMacAddress;
private @Nullable String deviceType;
- private @Nullable String controllerId;
private ArrayList relays = new ArrayList<>();
@SuppressWarnings("null")
@@ -51,13 +51,7 @@ public DoorbirdInfo(String infoJson) throws JsonSyntaxException {
primaryMacAddress = doorbirdInfo.primaryMacAddress;
wifiMacAddress = doorbirdInfo.wifiMacAddress;
deviceType = doorbirdInfo.deviceType;
- for (String relay : doorbirdInfo.relays) {
- relays.add(relay);
- String[] parts = relay.split("@");
- if (parts.length == 2) {
- controllerId = parts[0];
- }
- }
+ relays.addAll(Arrays.asList(doorbirdInfo.relays));
}
}
}
@@ -86,15 +80,12 @@ public DoorbirdInfo(String infoJson) throws JsonSyntaxException {
return deviceType;
}
- public @Nullable String getControllerId() {
- return controllerId;
+ public @Nullable String getControllerId(@Nullable String configId) {
+ return relays.stream().map(relay -> relay.split("@")).filter(parts -> parts.length == 2).map(parts -> parts[0])
+ .filter(id -> configId == null || id.equals(configId)).reduce((first, second) -> second).orElse(null);
}
public ArrayList getRelays() {
return relays;
}
-
- public void addRelay(String relay) {
- relays.add(relay);
- }
}
diff --git a/bundles/org.openhab.binding.doorbird/src/main/java/org/openhab/binding/doorbird/internal/config/ControllerConfiguration.java b/bundles/org.openhab.binding.doorbird/src/main/java/org/openhab/binding/doorbird/internal/config/ControllerConfiguration.java
index 3c172607faae..bddab107014d 100644
--- a/bundles/org.openhab.binding.doorbird/src/main/java/org/openhab/binding/doorbird/internal/config/ControllerConfiguration.java
+++ b/bundles/org.openhab.binding.doorbird/src/main/java/org/openhab/binding/doorbird/internal/config/ControllerConfiguration.java
@@ -37,4 +37,9 @@ public class ControllerConfiguration {
* Password of the Doorbird doorbell to which the controller is assigned
*/
public @Nullable String userPassword;
+
+ /**
+ * Id of the Doorbird device
+ */
+ public @Nullable String controllerId;
}
diff --git a/bundles/org.openhab.binding.doorbird/src/main/java/org/openhab/binding/doorbird/internal/handler/ControllerHandler.java b/bundles/org.openhab.binding.doorbird/src/main/java/org/openhab/binding/doorbird/internal/handler/ControllerHandler.java
index dd8869145062..f9780b352e65 100644
--- a/bundles/org.openhab.binding.doorbird/src/main/java/org/openhab/binding/doorbird/internal/handler/ControllerHandler.java
+++ b/bundles/org.openhab.binding.doorbird/src/main/java/org/openhab/binding/doorbird/internal/handler/ControllerHandler.java
@@ -68,7 +68,7 @@ public void initialize() {
api.setAuthorization(host, user, password);
// Get the Id of the controller for use in the open door API
- controllerId = getControllerId();
+ controllerId = getControllerId(config.controllerId);
if (controllerId != null) {
updateStatus(ThingStatus.ONLINE);
} else {
@@ -105,8 +105,8 @@ private void handleOpenDoor(Command command, String doorNumber) {
}
}
- private @Nullable String getControllerId() {
+ private @Nullable String getControllerId(@Nullable String configId) {
DoorbirdInfo info = api.getDoorbirdInfo();
- return info == null ? null : info.getControllerId();
+ return info == null ? null : info.getControllerId(configId);
}
}
diff --git a/bundles/org.openhab.binding.doorbird/src/test/java/org/openhab/binding/doorbird/internal/DoorbirdInfoTest.java b/bundles/org.openhab.binding.doorbird/src/test/java/org/openhab/binding/doorbird/internal/DoorbirdInfoTest.java
index 7397eaa94d9e..3941578acf39 100644
--- a/bundles/org.openhab.binding.doorbird/src/test/java/org/openhab/binding/doorbird/internal/DoorbirdInfoTest.java
+++ b/bundles/org.openhab.binding.doorbird/src/test/java/org/openhab/binding/doorbird/internal/DoorbirdInfoTest.java
@@ -81,7 +81,7 @@ public void testParsingWithoutControllerId() {
public void testGetControllerId() {
DoorbirdInfo info = new DoorbirdInfo(infoWithControllerId);
- assertEquals("gggaaa", info.getControllerId());
+ assertEquals("gggaaa", info.getControllerId(null));
assertTrue(info.getRelays().contains("gggaaa@1"));
assertTrue(info.getRelays().contains("gggaaa@2"));
@@ -92,6 +92,6 @@ public void testGetControllerId() {
public void testControllerIdIsNull() {
DoorbirdInfo info = new DoorbirdInfo(infoWithoutControllerId);
- assertNull(info.getControllerId());
+ assertNull(info.getControllerId(null));
}
}
diff --git a/bundles/org.openhab.binding.hdpowerview/README.md b/bundles/org.openhab.binding.hdpowerview/README.md
index ab9fe8f76f07..d387c46160d5 100644
--- a/bundles/org.openhab.binding.hdpowerview/README.md
+++ b/bundles/org.openhab.binding.hdpowerview/README.md
@@ -44,6 +44,7 @@ If in the future, you add additional shades or scenes to your system, the bindin
| host | The host name or IP address of the hub on your network. |
| refresh | The number of milli-seconds between fetches of the PowerView hub's shade state (default 60'000 one minute). |
| hardRefresh | The number of minutes between hard refreshes of the PowerView hub's shade state (default 180 three hours). See [Refreshing the PowerView Hub Cache](#Refreshing-the-PowerView-Hub-Cache). |
+| hardRefreshBatteryLevel | The number of hours between hard refreshes of battery levels from the PowerView Hub (or 0 to disable, defaulting to weekly). See [Refreshing the PowerView Hub Cache](#Refreshing-the-PowerView-Hub-Cache). |
### Thing Configuration for PowerView Shades
@@ -74,11 +75,12 @@ If it is a dual action (top-down plus bottom-up) shade, there is also a roller s
All of these channels appear in the binding, but only those which have a physical implementation in the shade, will have any physical effect.
| Channel | Item Type | Description |
-|----------------|--------------------------|------------|
+|----------------|--------------------------|-------------|
| position | Rollershutter | The vertical position of the shade's rail -- see [next chapter](#Roller-Shutter-Up/Down-Position-vs.-Open/Close-State). Up/Down commands will move the rail completely up or completely down. Percentage commands will move the rail to an intermediate position. Stop commands will halt any current movement of the rail. |
| secondary | Rollershutter | The vertical position of the secondary rail (if any). Its function is basically identical to the `position` channel above -- but see [next chapter](#Roller-Shutter-Up/Down-Position-vs.-Open/Close-State). |
| vane | Dimmer | The degree of opening of the slats or vanes. Setting this to a non-zero value will first move the shade `position` fully down, since the slats or vanes can only have a defined state if the shade is in its down position -- see [Interdependency between Channel positions](#Interdependency-between-Channel-positions). |
| lowBattery | Switch | Indicates ON when the battery level of the shade is low, as determined by the hub's internal rules. |
+| batteryLevel | Number | Battery level (10% = low, 50% = medium, 100% = high)
| batteryVoltage | Number:ElectricPotential | Battery voltage reported by the shade. |
| signalStrength | Number | Signal strength (0 for no or unknown signal, 1 for weak, 2 for average, 3 for good or 4 for excellent) |
@@ -134,6 +136,10 @@ The hub periodically does a _**"hard refresh"**_ in order to overcome this issue
The time interval between hard refreshes is set in the `hardRefresh` configuration parameter.
To disable periodic hard refreshes, set `hardRefresh` to zero.
+Similarly, the battery level is transient and is only updated automatically by the hub once a week.
+To change this interval, set `hardRefreshBatteryLevel` to number of hours between refreshes.
+To use default hub behavior (weekly updates), set `hardRefreshBatteryLevel` to zero.
+
Note: You can also force the hub to refresh itself by sending a `REFRESH` command in a rule to an item that is connected to a channel in the hub as follows:
```
diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/HDPowerViewBindingConstants.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/HDPowerViewBindingConstants.java
index 1b710cb277a7..da235dd22c8d 100644
--- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/HDPowerViewBindingConstants.java
+++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/HDPowerViewBindingConstants.java
@@ -41,6 +41,7 @@ public class HDPowerViewBindingConstants {
public static final String CHANNEL_SHADE_SECONDARY_POSITION = "secondary";
public static final String CHANNEL_SHADE_VANE = "vane";
public static final String CHANNEL_SHADE_LOW_BATTERY = "lowBattery";
+ public static final String CHANNEL_SHADE_BATTERY_LEVEL = "batteryLevel";
public static final String CHANNEL_SHADE_BATTERY_VOLTAGE = "batteryVoltage";
public static final String CHANNEL_SHADE_SIGNAL_STRENGTH = "signalStrength";
diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/HDPowerViewWebTargets.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/HDPowerViewWebTargets.java
index 4d40d9927bee..eaa17cfbfe3a 100644
--- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/HDPowerViewWebTargets.java
+++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/HDPowerViewWebTargets.java
@@ -234,8 +234,8 @@ private synchronized String invoke(HttpMethod method, String url, @Nullable Quer
/**
* Instructs the hub to do a hard refresh (discovery on the hubs RF network) on
- * a specific shade; fetches a JSON package that describes that shade, and wraps
- * it in a Shade class instance
+ * a specific shade's position; fetches a JSON package that describes that shade,
+ * and wraps it in a Shade class instance
*
* @param shadeId id of the shade to be refreshed
* @return Shade class instance
@@ -243,13 +243,31 @@ private synchronized String invoke(HttpMethod method, String url, @Nullable Quer
* @throws HubProcessingException if there is any processing error
* @throws HubMaintenanceException if the hub is down for maintenance
*/
- public @Nullable Shade refreshShade(int shadeId)
+ public @Nullable Shade refreshShadePosition(int shadeId)
throws JsonParseException, HubProcessingException, HubMaintenanceException {
String json = invoke(HttpMethod.GET, shades + Integer.toString(shadeId),
Query.of("refresh", Boolean.toString(true)), null);
return gson.fromJson(json, Shade.class);
}
+ /**
+ * Instructs the hub to do a hard refresh (discovery on the hubs RF network) on
+ * a specific shade's battery level; fetches a JSON package that describes that shade,
+ * and wraps it in a Shade class instance
+ *
+ * @param shadeId id of the shade to be refreshed
+ * @return Shade class instance
+ * @throws JsonParseException if there is a JSON parsing error
+ * @throws HubProcessingException if there is any processing error
+ * @throws HubMaintenanceException if the hub is down for maintenance
+ */
+ public @Nullable Shade refreshShadeBatteryLevel(int shadeId)
+ throws JsonParseException, HubProcessingException, HubMaintenanceException {
+ String json = invoke(HttpMethod.GET, shades + Integer.toString(shadeId),
+ Query.of("updateBatteryLevel", Boolean.toString(true)), null);
+ return gson.fromJson(json, Shade.class);
+ }
+
/**
* Tells the hub to stop movement of a specific shade
*
diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/config/HDPowerViewHubConfiguration.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/config/HDPowerViewHubConfiguration.java
index c93df90aeec4..dd599c3265ca 100644
--- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/config/HDPowerViewHubConfiguration.java
+++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/config/HDPowerViewHubConfiguration.java
@@ -29,4 +29,5 @@ public class HDPowerViewHubConfiguration {
public long refresh;
public long hardRefresh;
+ public long hardRefreshBatteryLevel;
}
diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewHubHandler.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewHubHandler.java
index 0827a682e31e..d617bb06cfbe 100644
--- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewHubHandler.java
+++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewHubHandler.java
@@ -67,11 +67,13 @@ public class HDPowerViewHubHandler extends BaseBridgeHandler {
private final HttpClient httpClient;
private long refreshInterval;
- private long hardRefreshInterval;
+ private long hardRefreshPositionInterval;
+ private long hardRefreshBatteryLevelInterval;
private @Nullable HDPowerViewWebTargets webTargets;
private @Nullable ScheduledFuture> pollFuture;
- private @Nullable ScheduledFuture> hardRefreshFuture;
+ private @Nullable ScheduledFuture> hardRefreshPositionFuture;
+ private @Nullable ScheduledFuture> hardRefreshBatteryLevelFuture;
private final ChannelTypeUID sceneChannelTypeUID = new ChannelTypeUID(HDPowerViewBindingConstants.BINDING_ID,
HDPowerViewBindingConstants.CHANNELTYPE_SCENE_ACTIVATE);
@@ -84,7 +86,7 @@ public HDPowerViewHubHandler(Bridge bridge, HttpClient httpClient) {
@Override
public void handleCommand(ChannelUID channelUID, Command command) {
if (RefreshType.REFRESH.equals(command)) {
- requestRefreshShades();
+ requestRefreshShadePositions();
return;
}
@@ -119,7 +121,8 @@ public void initialize() {
webTargets = new HDPowerViewWebTargets(httpClient, host);
refreshInterval = config.refresh;
- hardRefreshInterval = config.hardRefresh;
+ hardRefreshPositionInterval = config.hardRefresh;
+ hardRefreshBatteryLevelInterval = config.hardRefreshBatteryLevel;
schedulePoll();
}
@@ -147,14 +150,24 @@ private void schedulePoll() {
logger.debug("Scheduling poll for 5000ms out, then every {}ms", refreshInterval);
this.pollFuture = scheduler.scheduleWithFixedDelay(this::poll, 5000, refreshInterval, TimeUnit.MILLISECONDS);
- future = this.hardRefreshFuture;
+ future = this.hardRefreshPositionFuture;
if (future != null) {
future.cancel(false);
}
- if (hardRefreshInterval > 0) {
- logger.debug("Scheduling hard refresh every {}minutes", hardRefreshInterval);
- this.hardRefreshFuture = scheduler.scheduleWithFixedDelay(this::requestRefreshShades, 1,
- hardRefreshInterval, TimeUnit.MINUTES);
+ if (hardRefreshPositionInterval > 0) {
+ logger.debug("Scheduling hard position refresh every {} minutes", hardRefreshPositionInterval);
+ this.hardRefreshPositionFuture = scheduler.scheduleWithFixedDelay(this::requestRefreshShadePositions, 1,
+ hardRefreshPositionInterval, TimeUnit.MINUTES);
+ }
+
+ future = this.hardRefreshBatteryLevelFuture;
+ if (future != null) {
+ future.cancel(false);
+ }
+ if (hardRefreshBatteryLevelInterval > 0) {
+ logger.debug("Scheduling hard battery level refresh every {} hours", hardRefreshBatteryLevelInterval);
+ this.hardRefreshBatteryLevelFuture = scheduler.scheduleWithFixedDelay(
+ this::requestRefreshShadeBatteryLevels, 1, hardRefreshBatteryLevelInterval, TimeUnit.HOURS);
}
}
@@ -165,11 +178,17 @@ private synchronized void stopPoll() {
}
this.pollFuture = null;
- future = this.hardRefreshFuture;
+ future = this.hardRefreshPositionFuture;
if (future != null) {
future.cancel(true);
}
- this.hardRefreshFuture = null;
+ this.hardRefreshPositionFuture = null;
+
+ future = this.hardRefreshBatteryLevelFuture;
+ if (future != null) {
+ future.cancel(true);
+ }
+ this.hardRefreshBatteryLevelFuture = null;
}
private synchronized void poll() {
@@ -304,13 +323,27 @@ private Map getIdChannelMap() {
return ret;
}
- private void requestRefreshShades() {
+ private void requestRefreshShadePositions() {
+ Map thingIdMap = getThingIdMap();
+ for (Entry item : thingIdMap.entrySet()) {
+ Thing thing = item.getKey();
+ ThingHandler handler = thing.getHandler();
+ if (handler instanceof HDPowerViewShadeHandler) {
+ ((HDPowerViewShadeHandler) handler).requestRefreshShadePosition();
+ } else {
+ String shadeId = item.getValue();
+ logger.debug("Shade '{}' handler not initialized", shadeId);
+ }
+ }
+ }
+
+ private void requestRefreshShadeBatteryLevels() {
Map thingIdMap = getThingIdMap();
for (Entry item : thingIdMap.entrySet()) {
Thing thing = item.getKey();
ThingHandler handler = thing.getHandler();
if (handler instanceof HDPowerViewShadeHandler) {
- ((HDPowerViewShadeHandler) handler).requestRefreshShade();
+ ((HDPowerViewShadeHandler) handler).requestRefreshShadeBatteryLevel();
} else {
String shadeId = item.getValue();
logger.debug("Shade '{}' handler not initialized", shadeId);
diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewShadeHandler.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewShadeHandler.java
index 960d182fddd7..42514597bafb 100644
--- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewShadeHandler.java
+++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewShadeHandler.java
@@ -19,6 +19,8 @@
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
+import javax.ws.rs.NotSupportedException;
+
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.hdpowerview.internal.HDPowerViewWebTargets;
@@ -57,10 +59,16 @@
@NonNullByDefault
public class HDPowerViewShadeHandler extends AbstractHubbedThingHandler {
+ private enum RefreshKind {
+ POSITION,
+ BATTERY_LEVEL
+ }
+
private final Logger logger = LoggerFactory.getLogger(HDPowerViewShadeHandler.class);
private static final int REFRESH_DELAY_SEC = 10;
- private @Nullable ScheduledFuture> refreshFuture = null;
+ private @Nullable ScheduledFuture> refreshPositionFuture = null;
+ private @Nullable ScheduledFuture> refreshBatteryLevelFuture = null;
public HDPowerViewShadeHandler(Thing thing) {
super(thing);
@@ -85,7 +93,7 @@ public void initialize() {
@Override
public void handleCommand(ChannelUID channelUID, Command command) {
if (RefreshType.REFRESH.equals(command)) {
- requestRefreshShade();
+ requestRefreshShadePosition();
return;
}
@@ -137,8 +145,10 @@ protected void onReceiveUpdate(@Nullable ShadeData shadeData) {
if (shadeData != null) {
updateStatus(ThingStatus.ONLINE);
updateBindingStates(shadeData.positions);
- updateState(CHANNEL_SHADE_LOW_BATTERY, shadeData.batteryStatus == 1 ? OnOffType.ON : OnOffType.OFF);
- updateState(CHANNEL_SHADE_BATTERY_VOLTAGE, new QuantityType<>(shadeData.batteryStrength / 10, Units.VOLT));
+ updateBatteryLevel(shadeData.batteryStatus);
+ updateState(CHANNEL_SHADE_BATTERY_VOLTAGE,
+ shadeData.batteryStrength > 0 ? new QuantityType<>(shadeData.batteryStrength / 10, Units.VOLT)
+ : UnDefType.UNDEF);
updateState(CHANNEL_SHADE_SIGNAL_STRENGTH, new DecimalType(shadeData.signalStrength));
} else {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
@@ -157,6 +167,28 @@ private void updateBindingStates(@Nullable ShadePosition shadePos) {
}
}
+ private void updateBatteryLevel(int batteryStatus) {
+ int mappedValue;
+ switch (batteryStatus) {
+ case 1: // Low
+ mappedValue = 10;
+ break;
+ case 2: // Medium
+ mappedValue = 50;
+ break;
+ case 3: // High
+ case 4: // Plugged in
+ mappedValue = 100;
+ break;
+ default: // No status available (0) or invalid
+ updateState(CHANNEL_SHADE_LOW_BATTERY, UnDefType.UNDEF);
+ updateState(CHANNEL_SHADE_BATTERY_LEVEL, UnDefType.UNDEF);
+ return;
+ }
+ updateState(CHANNEL_SHADE_LOW_BATTERY, batteryStatus == 1 ? OnOffType.ON : OnOffType.OFF);
+ updateState(CHANNEL_SHADE_BATTERY_LEVEL, new DecimalType(mappedValue));
+ }
+
private void moveShade(ActuatorClass actuatorClass, CoordinateSystem coordSys, int newPercent) {
try {
HDPowerViewHubHandler bridge;
@@ -223,7 +255,7 @@ private void stopShade() {
}
int shadeId = getShadeId();
webTargets.stopShade(shadeId);
- requestRefreshShade();
+ requestRefreshShadePosition();
} catch (HubProcessingException | NumberFormatException e) {
logger.warn("Unexpected error: {}", e.getMessage());
return;
@@ -234,15 +266,36 @@ private void stopShade() {
}
/**
- * Request that the shade shall undergo a 'hard' refresh
+ * Request that the shade shall undergo a 'hard' refresh for querying its current position
*/
- protected synchronized void requestRefreshShade() {
- if (refreshFuture == null) {
- refreshFuture = scheduler.schedule(this::doRefreshShade, REFRESH_DELAY_SEC, TimeUnit.SECONDS);
+ protected synchronized void requestRefreshShadePosition() {
+ if (refreshPositionFuture == null) {
+ refreshPositionFuture = scheduler.schedule(this::doRefreshShadePosition, REFRESH_DELAY_SEC,
+ TimeUnit.SECONDS);
}
}
- private void doRefreshShade() {
+ /**
+ * Request that the shade shall undergo a 'hard' refresh for querying its battery level state
+ */
+ protected synchronized void requestRefreshShadeBatteryLevel() {
+ if (refreshBatteryLevelFuture == null) {
+ refreshBatteryLevelFuture = scheduler.schedule(this::doRefreshShadeBatteryLevel, REFRESH_DELAY_SEC,
+ TimeUnit.SECONDS);
+ }
+ }
+
+ private void doRefreshShadePosition() {
+ this.doRefreshShade(RefreshKind.POSITION);
+ refreshPositionFuture = null;
+ }
+
+ private void doRefreshShadeBatteryLevel() {
+ this.doRefreshShade(RefreshKind.BATTERY_LEVEL);
+ refreshBatteryLevelFuture = null;
+ }
+
+ private void doRefreshShade(RefreshKind kind) {
try {
HDPowerViewHubHandler bridge;
if ((bridge = getBridgeHandler()) == null) {
@@ -253,7 +306,17 @@ private void doRefreshShade() {
throw new HubProcessingException("Web targets not initialized");
}
int shadeId = getShadeId();
- Shade shade = webTargets.refreshShade(shadeId);
+ Shade shade;
+ switch (kind) {
+ case POSITION:
+ shade = webTargets.refreshShadePosition(shadeId);
+ break;
+ case BATTERY_LEVEL:
+ shade = webTargets.refreshShadeBatteryLevel(shadeId);
+ break;
+ default:
+ throw new NotSupportedException("Unsupported refresh kind " + kind.toString());
+ }
if (shade != null) {
ShadeData shadeData = shade.shade;
if (shadeData != null) {
@@ -267,6 +330,5 @@ private void doRefreshShade() {
} catch (HubMaintenanceException e) {
// exceptions are logged in HDPowerViewWebTargets
}
- refreshFuture = null;
}
}
diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.hdpowerview/src/main/resources/OH-INF/thing/thing-types.xml
index 19e8e9a8a18f..c852a49b7529 100644
--- a/bundles/org.openhab.binding.hdpowerview/src/main/resources/OH-INF/thing/thing-types.xml
+++ b/bundles/org.openhab.binding.hdpowerview/src/main/resources/OH-INF/thing/thing-types.xml
@@ -26,10 +26,17 @@
60000
-
- The number of minutes between hard refreshes of the PowerView Hub (or 0 to disable)
+
+ The number of minutes between hard refreshes of positions from the PowerView Hub (or 0 to disable)180
+
+
+ The number of hours between hard refreshes of battery levels from the PowerView Hub (or 0 to disable,
+ default is weekly)
+ true
+ 0
+
@@ -48,6 +55,7 @@
+
diff --git a/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/HDPowerViewJUnitTests.java b/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/HDPowerViewJUnitTests.java
index 75a56d610295..46240065fbaf 100644
--- a/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/HDPowerViewJUnitTests.java
+++ b/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/HDPowerViewJUnitTests.java
@@ -218,7 +218,7 @@ public void testOnlineCommunication() {
Shade shade = null;
try {
assertNotEquals(0, shadeId);
- shade = webTargets.refreshShade(shadeId);
+ shade = webTargets.refreshShadePosition(shadeId);
assertNotNull(shade);
} catch (HubProcessingException | HubMaintenanceException e) {
fail(e.getMessage());
@@ -356,6 +356,8 @@ public void testOfflineJsonParsing() {
pos = shadePos.getState(PRIMARY_ACTUATOR, VANE_COORDS);
assertEquals(UnDefType.class, pos.getClass());
+ assertEquals(3, shadeData.batteryStatus);
+
assertEquals(4, shadeData.signalStrength);
} catch (JsonParseException e) {
fail(e.getMessage());
diff --git a/bundles/org.openhab.binding.hdpowerview/src/test/resources/duette.json b/bundles/org.openhab.binding.hdpowerview/src/test/resources/duette.json
index 4e0e8a7d5291..ff4e03e01c00 100644
--- a/bundles/org.openhab.binding.hdpowerview/src/test/resources/duette.json
+++ b/bundles/org.openhab.binding.hdpowerview/src/test/resources/duette.json
@@ -6,8 +6,8 @@
{
"id": 63778,
"type": 8,
- "batteryStatus": 0,
- "batteryStrength": 0,
+ "batteryStatus": 3,
+ "batteryStrength": 168,
"roomId": 891,
"firmware": {
"revision": 1,
diff --git a/bundles/org.openhab.binding.homematic/README.md b/bundles/org.openhab.binding.homematic/README.md
index c923afcfc843..1dd7842f7fc8 100644
--- a/bundles/org.openhab.binding.homematic/README.md
+++ b/bundles/org.openhab.binding.homematic/README.md
@@ -343,16 +343,17 @@ A virtual datapoint (String) to simulate a key press, available on all channels
Available values:
-- `SHORT_PRESS`: triggered on a short key press
-- `LONG_PRESS`: triggered on a key press longer than `LONG_PRESS_TIME` (variable configuration per key, default is 0.4 s)
-- `DOUBLE_PRESS`: triggered on a short key press but only if the latest `SHORT_PRESS` or `DOUBLE_PRESS` event is not older than 2.0 s (not related to `DBL_PRESS_TIME` configuration, which is more like a key lock because if it is other than `0.0` single presses are not notified anymore)
+- `SHORT_PRESSED`: triggered on a short key press
+- `LONG_PRESSED`: triggered on a key press longer than `LONG_PRESS_TIME` (variable configuration per key, default is 0.4 s)
+- `LONG_REPEATED`: triggered on long key press repetition, that is, in `LONG_PRESS_TIME` intervals as long as key is held
+- `LONG_RELEASED`: triggered when a key is released after being long pressed
**Example:** to capture a short key press on the 19 button remote control in a rule
```javascript
rule "example trigger rule"
when
- Channel 'homematic:HM-RC-19-B:ccu:KEQ0012345:1#BUTTON' triggered SHORT_PRESS
+ Channel 'homematic:HM-RC-19-B:ccu:KEQ0012345:1#BUTTON' triggered SHORT_PRESSED
then
...
end
diff --git a/bundles/org.openhab.binding.homematic/src/main/java/org/openhab/binding/homematic/internal/communicator/virtual/ButtonVirtualDatapointHandler.java b/bundles/org.openhab.binding.homematic/src/main/java/org/openhab/binding/homematic/internal/communicator/virtual/ButtonVirtualDatapointHandler.java
index b4feca685fad..db121ccb13cb 100644
--- a/bundles/org.openhab.binding.homematic/src/main/java/org/openhab/binding/homematic/internal/communicator/virtual/ButtonVirtualDatapointHandler.java
+++ b/bundles/org.openhab.binding.homematic/src/main/java/org/openhab/binding/homematic/internal/communicator/virtual/ButtonVirtualDatapointHandler.java
@@ -33,6 +33,9 @@
public class ButtonVirtualDatapointHandler extends AbstractVirtualDatapointHandler {
private final Logger logger = LoggerFactory.getLogger(ButtonVirtualDatapointHandler.class);
+ private static final String LONG_REPEATED_EVENT = "LONG_REPEATED";
+ private static final String LONG_RELEASED_EVENT = "LONG_RELEASED";
+
@Override
public String getName() {
return VIRTUAL_DATAPOINT_NAME_BUTTON;
@@ -45,7 +48,7 @@ public void initialize(HmDevice device) {
HmDatapoint dp = addDatapoint(device, channel.getNumber(), getName(), HmValueType.STRING, null, false);
dp.setTrigger(true);
dp.setOptions(new String[] { CommonTriggerEvents.SHORT_PRESSED, CommonTriggerEvents.LONG_PRESSED,
- CommonTriggerEvents.DOUBLE_PRESSED });
+ LONG_REPEATED_EVENT, LONG_RELEASED_EVENT });
}
}
}
@@ -57,33 +60,59 @@ public boolean canHandleEvent(HmDatapoint dp) {
@Override
public void handleEvent(VirtualGateway gateway, HmDatapoint dp) {
- HmDatapoint vdp = getVirtualDatapoint(dp.getChannel());
+ HmChannel channel = dp.getChannel();
+ HmDatapoint vdp = getVirtualDatapoint(channel);
+ int usPos = dp.getName().indexOf("_");
+ String pressType = usPos == -1 ? dp.getName() : dp.getName().substring(usPos + 1);
+ boolean isLongPressActive = CommonTriggerEvents.LONG_PRESSED.equals(vdp.getValue())
+ || LONG_REPEATED_EVENT.equals(vdp.getValue());
if (MiscUtils.isTrueValue(dp.getValue())) {
- int usPos = dp.getName().indexOf("_");
- String pressType = usPos == -1 ? dp.getName() : dp.getName().substring(usPos + 1);
switch (pressType) {
- case "SHORT":
- if (dp.getValue() == null || !dp.getValue().equals(dp.getPreviousValue())) {
- vdp.setValue(CommonTriggerEvents.SHORT_PRESSED);
- } else {
- // two (or more) PRESS_SHORT events were received
- // within AbstractHomematicGateway#DEFAULT_DISABLE_DELAY seconds
- vdp.setValue(CommonTriggerEvents.DOUBLE_PRESSED);
- }
+ case "SHORT": {
+ vdp.setValue(null); // Force sending new event
+ vdp.setValue(CommonTriggerEvents.SHORT_PRESSED);
break;
+ }
case "LONG":
- vdp.setValue(CommonTriggerEvents.LONG_PRESSED);
+ if (LONG_REPEATED_EVENT.equals(vdp.getValue())) {
+ // Suppress long press events during an ongoing long press
+ vdp.setValue(LONG_REPEATED_EVENT);
+ } else {
+ vdp.setValue(CommonTriggerEvents.LONG_PRESSED);
+ }
break;
case "LONG_RELEASE":
+ // Only send release events if we sent a pressed event before
+ vdp.setValue(isLongPressActive ? LONG_RELEASED_EVENT : null);
+ break;
case "CONT":
+ // Clear previous value to force re-triggering of repetition
vdp.setValue(null);
+ // Only send repetitions if there was a pressed event before
+ // (a CONT might arrive simultaneously with the initial LONG event)
+ if (isLongPressActive) {
+ vdp.setValue(LONG_REPEATED_EVENT);
+ }
break;
default:
vdp.setValue(null);
logger.warn("Unexpected vaule '{}' for PRESS virtual datapoint", pressType);
}
} else {
- vdp.setValue(null);
+ if ("LONG".equals(pressType) && LONG_REPEATED_EVENT.equals(vdp.getValue())) {
+ // If we're currently processing a repeated long-press event, don't let the initial LONG
+ // event time out the repetitions, the CONT delay handler will take care of it
+ vdp.setValue(LONG_REPEATED_EVENT);
+ } else if (isLongPressActive) {
+ // We seemingly missed an event (either a CONT or the final LONG_RELEASE),
+ // so end the long press cycle now
+ vdp.setValue(LONG_RELEASED_EVENT);
+ } else {
+ vdp.setValue(null);
+ }
}
+ logger.debug("Handled virtual button event on {}:{}: press type {}, value {}, button state {} -> {}",
+ channel.getDevice().getAddress(), channel.getNumber(), pressType, dp.getValue(), vdp.getPreviousValue(),
+ vdp.getValue());
}
}
diff --git a/bundles/org.openhab.binding.homematic/src/main/java/org/openhab/binding/homematic/internal/handler/HomematicThingHandler.java b/bundles/org.openhab.binding.homematic/src/main/java/org/openhab/binding/homematic/internal/handler/HomematicThingHandler.java
index 39899a5d652c..204e29dc458f 100644
--- a/bundles/org.openhab.binding.homematic/src/main/java/org/openhab/binding/homematic/internal/handler/HomematicThingHandler.java
+++ b/bundles/org.openhab.binding.homematic/src/main/java/org/openhab/binding/homematic/internal/handler/HomematicThingHandler.java
@@ -384,8 +384,9 @@ protected void updateDatapointState(HmDatapoint dp) {
private void updateChannelState(final HmDatapoint dp, Channel channel)
throws IOException, GatewayNotAvailableException, ConverterException {
if (dp.isTrigger()) {
- if (dp.getValue() != null) {
- triggerChannel(channel.getUID(), dp.getValue() == null ? "" : dp.getValue().toString());
+ final Object value = dp.getValue();
+ if (value != null && !value.equals(dp.getPreviousValue())) {
+ triggerChannel(channel.getUID(), value.toString());
}
} else if (isLinked(channel)) {
loadHomematicChannelValues(dp.getChannel());
diff --git a/bundles/org.openhab.binding.homematic/src/test/java/org/openhab/binding/homematic/internal/communicator/virtual/ButtonDatapointTest.java b/bundles/org.openhab.binding.homematic/src/test/java/org/openhab/binding/homematic/internal/communicator/virtual/ButtonDatapointTest.java
index be58072c3b20..02ac032cdca6 100644
--- a/bundles/org.openhab.binding.homematic/src/test/java/org/openhab/binding/homematic/internal/communicator/virtual/ButtonDatapointTest.java
+++ b/bundles/org.openhab.binding.homematic/src/test/java/org/openhab/binding/homematic/internal/communicator/virtual/ButtonDatapointTest.java
@@ -17,7 +17,6 @@
import java.io.IOException;
-import org.junit.Ignore;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openhab.binding.homematic.internal.misc.HomematicClientException;
@@ -66,8 +65,15 @@ public void testLongPress() throws IOException, HomematicClientException {
HmDatapoint buttonVirtualDatapoint = getButtonVirtualDatapoint(longPressDp);
mockEventReceiver.eventReceived(longPressDp);
-
assertThat(buttonVirtualDatapoint.getValue(), is(CommonTriggerEvents.LONG_PRESSED));
+
+ HmDatapoint contPressDp = createPressDatapointFrom(longPressDp, "PRESS_CONT", Boolean.TRUE);
+ mockEventReceiver.eventReceived(contPressDp);
+ assertThat(buttonVirtualDatapoint.getValue(), is("LONG_REPEATED"));
+
+ HmDatapoint releaseDp = createPressDatapointFrom(longPressDp, "PRESS_LONG_RELEASE", Boolean.TRUE);
+ mockEventReceiver.eventReceived(releaseDp);
+ assertThat(buttonVirtualDatapoint.getValue(), is("LONG_RELEASED"));
}
@Test
@@ -83,35 +89,14 @@ public void testUnsupportedEvents() throws IOException, HomematicClientException
mockEventReceiver.eventReceived(releaseDp);
HmDatapoint crapDp = createPressDatapoint("CRAP", Boolean.TRUE);
- HmDatapoint crapButtonVirtualDatapoint = getButtonVirtualDatapoint(releaseDp);
+ HmDatapoint crapButtonVirtualDatapoint = getButtonVirtualDatapoint(crapDp);
mockEventReceiver.eventReceived(crapDp);
+ // CONT and LONG_RELEASE events without previous LONG event are supposed to yield no trigger
assertThat(contButtonVirtualDatapoint.getValue(), nullValue());
assertThat(releaseButtonVirtualDatapoint.getValue(), nullValue());
- assertThat(crapButtonVirtualDatapoint.getValue(), nullValue());
- }
-
- @Test
- @Ignore(value = "Test is unstable see #10753")
- public void testDoublePress() throws IOException, HomematicClientException, InterruptedException {
- HmDatapoint shortPressDp = createPressDatapoint("PRESS_SHORT", Boolean.TRUE);
- HmDatapoint buttonVirtualDatapoint = getButtonVirtualDatapoint(shortPressDp);
-
- mockEventReceiver.eventReceived(shortPressDp);
- assertThat(buttonVirtualDatapoint.getValue(), is(CommonTriggerEvents.SHORT_PRESSED));
-
- Thread.sleep(DISABLE_DATAPOINT_DELAY / 2);
-
- shortPressDp.setValue(Boolean.TRUE);
- mockEventReceiver.eventReceived(shortPressDp);
- assertThat(buttonVirtualDatapoint.getValue(), is(CommonTriggerEvents.DOUBLE_PRESSED));
-
- Thread.sleep(DISABLE_DATAPOINT_DELAY * 2);
-
- shortPressDp.setValue(Boolean.TRUE);
- mockEventReceiver.eventReceived(shortPressDp);
- assertThat(buttonVirtualDatapoint.getValue(), is(CommonTriggerEvents.SHORT_PRESSED));
+ assertThat(crapButtonVirtualDatapoint, nullValue());
}
private HmDatapoint createPressDatapoint(String channelName, Object value) {
@@ -127,6 +112,15 @@ private HmDatapoint createPressDatapoint(String channelName, Object value) {
return pressDp;
}
+ private HmDatapoint createPressDatapointFrom(HmDatapoint originalDatapoint, String channelName, Object value) {
+ HmDatapoint pressDp = new HmDatapoint(channelName, "", HmValueType.ACTION, value, true, HmParamsetType.VALUES);
+ HmChannel hmChannel = originalDatapoint.getChannel();
+ hmChannel.addDatapoint(pressDp);
+ pressDp.setChannel(hmChannel);
+
+ return pressDp;
+ }
+
private HmDatapoint getButtonVirtualDatapoint(HmDatapoint originalDatapoint) {
return originalDatapoint.getChannel().getDatapoints().stream()
.filter(dp -> HomematicConstants.VIRTUAL_DATAPOINT_NAME_BUTTON.equals(dp.getName())).findFirst()
diff --git a/bundles/org.openhab.binding.icalendar/pom.xml b/bundles/org.openhab.binding.icalendar/pom.xml
index 0c12afd983a6..768f07224abf 100644
--- a/bundles/org.openhab.binding.icalendar/pom.xml
+++ b/bundles/org.openhab.binding.icalendar/pom.xml
@@ -17,12 +17,12 @@
net.sf.biweeklybiweekly
- 0.6.4
+ 0.6.6compilecom.fasterxml.jackson.core
- *
+ jackson-databind
@@ -39,12 +39,6 @@
${jackson.version}compile
-
- com.fasterxml.jackson.core
- jackson-annotations
- ${jackson.version}
- compile
- com.fasterxml.jackson.corejackson-databind
diff --git a/bundles/org.openhab.binding.icalendar/src/main/java/org/openhab/binding/icalendar/internal/logic/BiweeklyPresentableCalendar.java b/bundles/org.openhab.binding.icalendar/src/main/java/org/openhab/binding/icalendar/internal/logic/BiweeklyPresentableCalendar.java
index 61d2f9a25184..d38e9e4454ef 100644
--- a/bundles/org.openhab.binding.icalendar/src/main/java/org/openhab/binding/icalendar/internal/logic/BiweeklyPresentableCalendar.java
+++ b/bundles/org.openhab.binding.icalendar/src/main/java/org/openhab/binding/icalendar/internal/logic/BiweeklyPresentableCalendar.java
@@ -88,55 +88,14 @@ class BiweeklyPresentableCalendar extends AbstractPresentableCalendar {
@Override
public List getJustBegunEvents(Instant frameBegin, Instant frameEnd) {
- final List eventList = new ArrayList<>();
- // process all the events in the iCalendar
- for (final VEvent event : usedCalendar.getEvents()) {
- // iterate over all begin dates
- final DateIterator begDates = getRecurredEventDateIterator(event);
- while (begDates.hasNext()) {
- final Instant begInst = begDates.next().toInstant();
- if (begInst.isBefore(frameBegin)) {
- continue;
- } else if (begInst.isAfter(frameEnd)) {
- break;
- }
- // fall through => means we are within the time frame
- Duration duration = getEventLength(event);
- if (duration == null) {
- duration = Duration.ofMinutes(1);
- }
- eventList.add(new VEventWPeriod(event, begInst, begInst.plus(duration)).toEvent());
- break;
- }
- }
- return eventList;
+ return this.getVEventWPeriodsBetween(frameBegin, frameEnd, 0).stream().map(e -> e.toEvent())
+ .collect(Collectors.toList());
}
@Override
public List getJustEndedEvents(Instant frameBegin, Instant frameEnd) {
- final List eventList = new ArrayList<>();
- // process all the events in the iCalendar
- for (final VEvent event : usedCalendar.getEvents()) {
- final Duration duration = getEventLength(event);
- if (duration == null) {
- continue;
- }
- // iterate over all begin dates
- final DateIterator begDates = getRecurredEventDateIterator(event);
- while (begDates.hasNext()) {
- final Instant begInst = begDates.next().toInstant();
- final Instant endInst = begInst.plus(duration);
- if (endInst.isBefore(frameBegin)) {
- continue;
- } else if (endInst.isAfter(frameEnd)) {
- break;
- }
- // fall through => means we are within the time frame
- eventList.add(new VEventWPeriod(event, begInst, endInst).toEvent());
- break;
- }
- }
- return eventList;
+ return this.getVEventWPeriodsBetween(frameBegin, frameEnd, 0, true).stream().map(e -> e.toEvent())
+ .collect(Collectors.toList());
}
@Override
@@ -247,6 +206,20 @@ public List getFilteredEventsBetween(Instant begin, Instant end, @Nullabl
* @return All events which begin in the time frame.
*/
private List getVEventWPeriodsBetween(Instant frameBegin, Instant frameEnd, int maximumPerSeries) {
+ return this.getVEventWPeriodsBetween(frameBegin, frameEnd, maximumPerSeries, false);
+ }
+
+ /**
+ * Finds events which begin in the given frame by end time and date
+ *
+ * @param frameBegin Begin of the frame where to search events.
+ * @param frameEnd End of the time frame where to search events. The Instant is inclusive when searchByEnd is true.
+ * @param maximumPerSeries Limit the results per series. Set to 0 for no limit.
+ * @param searchByEnd Whether to search by begin of the event or by end.
+ * @return All events which begin in the time frame.
+ */
+ private List getVEventWPeriodsBetween(Instant frameBegin, Instant frameEnd, int maximumPerSeries,
+ boolean searchByEnd) {
final List positiveEvents = new ArrayList<>();
final List negativeEvents = new ArrayList<>();
classifyEvents(positiveEvents, negativeEvents);
@@ -254,16 +227,22 @@ private List getVEventWPeriodsBetween(Instant frameBegin, Instant
final List eventList = new ArrayList<>();
for (final VEvent positiveEvent : positiveEvents) {
final DateIterator positiveBeginDates = getRecurredEventDateIterator(positiveEvent);
- positiveBeginDates.advanceTo(Date.from(frameBegin));
+ Duration duration = getEventLength(positiveEvent);
+ if (duration == null) {
+ duration = Duration.ZERO;
+ }
+ positiveBeginDates.advanceTo(Date.from(frameBegin.minus(searchByEnd ? duration : Duration.ZERO)));
int foundInSeries = 0;
while (positiveBeginDates.hasNext()) {
final Instant begInst = positiveBeginDates.next().toInstant();
- if (begInst.isAfter(frameEnd) || begInst.equals(frameEnd)) {
+ if ((!searchByEnd && (begInst.isAfter(frameEnd) || begInst.equals(frameEnd)))
+ || (searchByEnd && begInst.plus(duration).isAfter(frameEnd))) {
break;
}
- Duration duration = getEventLength(positiveEvent);
- if (duration == null) {
- duration = Duration.ZERO;
+ // biweekly is not as precise as java.time. An exact check is required.
+ if ((!searchByEnd && begInst.isBefore(frameBegin))
+ || (searchByEnd && begInst.plus(duration).isBefore(frameBegin))) {
+ continue;
}
final VEventWPeriod resultingVEWP = new VEventWPeriod(positiveEvent, begInst, begInst.plus(duration));
diff --git a/bundles/org.openhab.binding.icalendar/src/test/java/org/openhab/binding/icalendar/internal/logic/BiweeklyPresentableCalendarTest.java b/bundles/org.openhab.binding.icalendar/src/test/java/org/openhab/binding/icalendar/internal/logic/BiweeklyPresentableCalendarTest.java
index 7c60c4fb68f3..c4857336c7da 100644
--- a/bundles/org.openhab.binding.icalendar/src/test/java/org/openhab/binding/icalendar/internal/logic/BiweeklyPresentableCalendarTest.java
+++ b/bundles/org.openhab.binding.icalendar/src/test/java/org/openhab/binding/icalendar/internal/logic/BiweeklyPresentableCalendarTest.java
@@ -49,6 +49,7 @@ public class BiweeklyPresentableCalendarTest {
private AbstractPresentableCalendar calendar3;
private AbstractPresentableCalendar calendar_issue9647;
private AbstractPresentableCalendar calendar_issue10808;
+ private AbstractPresentableCalendar calendar_issue11084;
@BeforeEach
public void setUp() throws IOException, CalendarException {
@@ -59,6 +60,8 @@ public void setUp() throws IOException, CalendarException {
new FileInputStream("src/test/resources/test-issue9647.ics"));
calendar_issue10808 = new BiweeklyPresentableCalendar(
new FileInputStream("src/test/resources/test-issue10808.ics"));
+ calendar_issue11084 = new BiweeklyPresentableCalendar(
+ new FileInputStream("src/test/resources/test-issue11084.ics"));
}
/**
@@ -132,6 +135,13 @@ public void testGetCurrentEvent() {
Event currentEvent4 = calendar_issue10808.getCurrentEvent(Instant.parse("2021-06-05T17:18:05Z"));
assertNotNull(currentEvent4);
assertTrue("Test event 1".contentEquals(currentEvent4.title));
+
+ Event currentEvent5 = calendar_issue11084.getCurrentEvent(Instant.parse("2021-08-16T16:30:05Z"));
+ assertNull(currentEvent5);
+
+ Event currentEvent6 = calendar_issue11084.getCurrentEvent(Instant.parse("2021-08-16T16:45:05Z"));
+ assertNotNull(currentEvent6);
+ assertTrue("TEST_REPEATING_EVENT_3".contentEquals(currentEvent6.title));
}
/**
@@ -563,6 +573,17 @@ public void testCommandTagCode() {
cmd7 = cmdTags.get(7).getCommand();
assertNotNull(cmd7);
assertEquals(DecimalType.class, cmd7.getClass());
+
+ // issue 11084: Command tags from moved events are also executed
+ List events2 = calendar_issue11084.getJustBegunEvents(Instant.parse("2021-08-16T16:29:55Z"),
+ Instant.parse("2021-08-16T17:00:05Z"));
+ assertEquals(1, events2.size());
+ assertEquals(Instant.parse("2021-08-16T16:45:00Z"), events2.get(0).start);
+
+ List events3 = calendar_issue11084.getJustEndedEvents(Instant.parse("2021-08-16T16:29:55Z"),
+ Instant.parse("2021-08-16T17:00:05Z"));
+ assertEquals(1, events3.size());
+ assertEquals(Instant.parse("2021-08-16T17:00:00Z"), events3.get(0).end);
}
@SuppressWarnings("null")
@@ -621,5 +642,9 @@ public void testGetFilteredEventsBetween() {
LocalDate.parse("2021-01-04").atStartOfDay(ZoneId.systemDefault()).toInstant(),
LocalDate.parse("2021-01-05").atStartOfDay(ZoneId.systemDefault()).toInstant(), null, 3);
assertArrayEquals(expectedFilteredEvents8, realFilteredEvents8.toArray(new Event[] {}));
+
+ List realFilteredEvents9 = calendar_issue11084.getFilteredEventsBetween(
+ Instant.parse("2021-08-16T16:45:00.123456Z"), Instant.parse("2021-08-16T16:46:00.768643Z"), null, 3);
+ assertEquals(0, realFilteredEvents9.size());
}
}
diff --git a/bundles/org.openhab.binding.icalendar/src/test/resources/test-issue11084.ics b/bundles/org.openhab.binding.icalendar/src/test/resources/test-issue11084.ics
new file mode 100644
index 000000000000..38c208b09ea0
--- /dev/null
+++ b/bundles/org.openhab.binding.icalendar/src/test/resources/test-issue11084.ics
@@ -0,0 +1,56 @@
+BEGIN:VCALENDAR
+PRODID:-//Google Inc//Google Calendar 70.9054//EN
+VERSION:2.0
+CALSCALE:GREGORIAN
+METHOD:PUBLISH
+X-WR-CALNAME:ohtest
+X-WR-TIMEZONE:UTC
+BEGIN:VTIMEZONE
+TZID:Europe/Brussels
+X-LIC-LOCATION:Europe/Brussels
+BEGIN:DAYLIGHT
+TZOFFSETFROM:+0100
+TZOFFSETTO:+0200
+TZNAME:CEST
+DTSTART:19700329T020000
+RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
+END:DAYLIGHT
+BEGIN:STANDARD
+TZOFFSETFROM:+0200
+TZOFFSETTO:+0100
+TZNAME:CET
+DTSTART:19701025T030000
+RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTART;TZID=Europe/Brussels:20210816T184500
+DTEND;TZID=Europe/Brussels:20210816T190000
+DTSTAMP:20210816T174418Z
+UID:pseudo7346893o7r8328zheh@google.com
+RECURRENCE-ID;TZID=Europe/Brussels:20210816T183000
+CREATED:20210816T161602Z
+DESCRIPTION:BEGIN:E_Test_Cal:ON
+LAST-MODIFIED:20210816T162009Z
+LOCATION:
+SEQUENCE:1
+STATUS:CONFIRMED
+SUMMARY:TEST_REPEATING_EVENT_3
+TRANSP:OPAQUE
+END:VEVENT
+BEGIN:VEVENT
+DTSTART;TZID=Europe/Brussels:20210816T183000
+DTEND;TZID=Europe/Brussels:20210816T184500
+RRULE:FREQ=DAILY
+DTSTAMP:20210816T174418Z
+UID:pseudo7346893o7r8328zheh@google.com
+CREATED:20210816T161602Z
+DESCRIPTION:BEGIN:E_Test_Cal:ON
+LAST-MODIFIED:20210816T162009Z
+LOCATION:
+SEQUENCE:0
+STATUS:CONFIRMED
+SUMMARY:TEST_REPEATING_EVENT_3
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
diff --git a/bundles/org.openhab.binding.kaleidescape/README.md b/bundles/org.openhab.binding.kaleidescape/README.md
index cb6dbaeb4ef4..29b00a059b7f 100644
--- a/bundles/org.openhab.binding.kaleidescape/README.md
+++ b/bundles/org.openhab.binding.kaleidescape/README.md
@@ -32,9 +32,8 @@ The supported thing types are:
## Discovery
-Manually initiated Auto-discovery is supported if Kaleidescape components are accessible on the same IP subnet of the openHAB server.
-Since discovery involves scanning all IP addresses in the subnet range for an open socket, the discovery must be initiated by the user.
-In the Inbox, select Search For Things and then choose the Kaleidescape System Binding to initiate discovery.
+Manually initiated Auto-discovery will locate all suported Kaleidescape components if they are on the same IP subnet of the openHAB server.
+In the Inbox, select Search For Things and then choose the Kaleidescape System Binding to initiate a discovery scan.
## Binding Configuration
@@ -45,14 +44,16 @@ All settings are through thing configuration parameters.
The thing has the following configuration parameters:
-| Parameter Label | Parameter ID | Description | Accepted values |
-|------------------------|---------------|------------------------------------------------------------------------------------|------------------------------------------------------|
-| Address | host | Host name or IP address of the Kaleidescape component | A host name or IP address |
-| Port | port | Communication port of the IP connection | 10000 (default - should not need to change) |
-| Serial Port | serialPort | Serial port for connecting directly a component | Serial port name (optional) |
-| Update Period | updatePeriod | Tells the component how often time status updates should be sent (see notes below) | 0 or 1 are the currently accepted values (default 0) |
-| Volume Control Enabled | volumeEnabled | Enable the volume and mute controls in the K iPad & phone apps | Boolean (default false) |
-| Initial Volume Setting | initialVolume | Initial volume level set when the binding starts up | 0 to 75 (default 25) |
+| Parameter Label | Parameter ID | Description | Accepted values |
+|--------------------------|------------------------|--------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------|
+| Address | host | Host name or IP address of the Kaleidescape component | A host name or IP address |
+| Port | port | Communication port of the IP connection | 10000 (default - should not need to change) |
+| Serial Port | serialPort | Serial port for connecting directly a component | Serial port name (optional) |
+| Update Period | updatePeriod | Tells the component how often time status updates should be sent (see notes below) | 0 or 1 are the currently accepted values (default 0) |
+| Volume Control Enabled | volumeEnabled | Enable the volume and mute controls in the K iPad & phone apps | Boolean (default false) |
+| Initial Volume Setting | initialVolume | Initial volume level set when the binding starts up | 0 to 75 (default 25) |
+| Load Highlighted Details | loadHighlightedDetails | When enabled the binding will automatically load the the metadata channels when the selected item in the UI (Movie or Album) changes | Boolean (default false) |
+| Load Album Details | loadAlbumDetails | When enabled the binding will automatically load the metadata channels for the currently playing Album | Boolean (default false) N/A for Alto and Strato |
Some notes:
@@ -152,14 +153,16 @@ The following channels are available:
kaleidescape.things:
-```java
-kaleidescape:player:myzone1 "M500 Living Rm" [host="192.168.1.10", updatePeriod=0, volumeEnabled=true, initialVolume=20]
-kaleidescape:cinemaone:myzone2 "My Cinema One" [host="192.168.1.11", updatePeriod=0, volumeEnabled=true, initialVolume=20]
+```
+kaleidescape:player:myzone1 "M500 Living Rm" [ host="192.168.1.10", updatePeriod=0, loadHighlightedDetails=true, loadAlbumDetails=true ]
+kaleidescape:cinemaone:myzone2 "My Cinema One" [ host="192.168.1.11", updatePeriod=0, loadHighlightedDetails=true, loadAlbumDetails=true ]
+kaleidescape:strato:myzone3 "Strato Theater Rm" [ host="192.168.1.12", updatePeriod=0, loadHighlightedDetails=true ]
+
```
kaleidescape.items:
-```java
+```
// Virtual switch to send a command, see sitemap and rules below
Switch z1_GoMovieCovers "Go to Movie Covers"
@@ -239,11 +242,12 @@ String z1_Detail_ColorDescription "Color Description: [%s]" { channel="kaleidesc
String z1_Detail_Country "Country: [%s]" { channel="kaleidescape:player:myzone1:detail#country" }
String z1_Detail_AspectRatio "Aspect Ratio: [%s]" { channel="kaleidescape:player:myzone1:detail#aspect_ratio" }
String z1_Detail_DiscLocation "Disc Location: [%s]" { channel="kaleidescape:player:myzone1:detail#disc_location" }
+
```
ksecondsformat.js:
-```java
+```
(function(totalSeconds) {
if (isNaN(totalSeconds)) {
return '-';
@@ -265,7 +269,7 @@ ksecondsformat.js:
kaleidescape.sitemap:
-```perl
+```
sitemap kaleidescape label="Kaleidescape" {
Frame label="Zone 1" {
Image item=z1_Detail_CoverArt
@@ -351,7 +355,7 @@ sitemap kaleidescape label="Kaleidescape" {
kaleidescape.rules:
-```java
+```
var int lightPercent
val kactions = getActions("kaleidescape","kaleidescape:player:myzone1")
@@ -360,7 +364,7 @@ rule "Go to Movie Covers"
when
Item z1_GoMovieCovers received command
then
- if(null === kactions) {
+ if (null === kactions) {
logInfo("kactions", "Actions not found, check thing ID")
return
}
@@ -372,7 +376,7 @@ rule "Play Script - Great Vistas"
when
Item z1_PlayScript received command
then
- if(null === kactions) {
+ if (null === kactions) {
logInfo("kactions", "Actions not found, check thing ID")
return
}
@@ -389,28 +393,6 @@ then
}
end
-rule "Load selected item Metadata"
-when
- Item z1_Ui_HighlightedSelection changed
-then
- if(null === kactions) {
- logInfo("kactions", "Actions not found, check thing ID")
- return
- }
- kactions.sendKCommand("GET_CONTENT_DETAILS:" + z1_Ui_HighlightedSelection.state.toString + ":")
-end
-
-rule "Load Metadata for currently playing album"
-when
- Item z1_Music_AlbumHandle changed
-then
- if(null === kactions) {
- logInfo("kactions", "Actions not found, check thing ID")
- return
- }
- kactions.sendKCommand("GET_CONTENT_DETAILS:" + z1_Music_AlbumHandle.state.toString + ":")
-end
-
rule "Bring up Lights when movie is over"
when
Item z1_Ui_MovieLocation changed from "Main content" to "End Credits"
@@ -420,7 +402,7 @@ then
while (lightPercent < 100) {
lightPercent = lightPercent + 5
logInfo("k rules", "lights at " + lightPercent.toString + " percent")
- //myLightItem.sendCommand(lightPercent)
+ // myLightItem.sendCommand(lightPercent)
Thread::sleep(5000)
}
end
@@ -429,7 +411,7 @@ rule "Bring up Lights at 20 percent during intermission"
when
Item z1_Ui_MovieLocation changed from "Main content" to "Intermission"
then
- //myLightItem.sendCommand(20)
+ // myLightItem.sendCommand(20)
logInfo("k rules", "intermission started")
end
@@ -437,7 +419,32 @@ rule "Turn lights back off when intermission over"
when
Item z1_Ui_MovieLocation changed from "Intermission" to "Main content"
then
- //myLightItem.sendCommand(OFF)
+ // myLightItem.sendCommand(OFF)
logInfo("k rules", "intermission over")
end
+
+// The following are no longer required since the thing configuration will enable automatic loading of metatdata.
+// However the examples are still valid for advanced use cases where retrieving metadata from an arbitrary content handle is desired.
+
+rule "Load selected item Metadata"
+when
+ Item z1_Ui_HighlightedSelection changed
+then
+ if (null === kactions) {
+ logInfo("kactions", "Actions not found, check thing ID")
+ return
+ }
+ kactions.sendKCommand("GET_CONTENT_DETAILS:" + z1_Ui_HighlightedSelection.state.toString + ":")
+end
+
+rule "Load Metadata for currently playing album"
+when
+ Item z1_Music_AlbumHandle changed
+then
+ if (null === kactions) {
+ logInfo("kactions", "Actions not found, check thing ID")
+ return
+ }
+ kactions.sendKCommand("GET_CONTENT_DETAILS:" + z1_Music_AlbumHandle.state.toString + ":")
+end
```
diff --git a/bundles/org.openhab.binding.kaleidescape/src/main/java/org/openhab/binding/kaleidescape/internal/KaleidescapeBindingConstants.java b/bundles/org.openhab.binding.kaleidescape/src/main/java/org/openhab/binding/kaleidescape/internal/KaleidescapeBindingConstants.java
index 6b327fa42391..cb95ab3df1ab 100644
--- a/bundles/org.openhab.binding.kaleidescape/src/main/java/org/openhab/binding/kaleidescape/internal/KaleidescapeBindingConstants.java
+++ b/bundles/org.openhab.binding.kaleidescape/src/main/java/org/openhab/binding/kaleidescape/internal/KaleidescapeBindingConstants.java
@@ -166,6 +166,7 @@ public class KaleidescapeBindingConstants {
public static final String GET_CONTENT_COLOR = "GET_CONTENT_COLOR";
public static final String SET_STATUS_CUE_PERIOD_1 = "SET_STATUS_CUE_PERIOD:1";
public static final String GET_TIME = "GET_TIME";
+ public static final String GET_CONTENT_DETAILS = "GET_CONTENT_DETAILS:";
public static final String LEAVE_STANDBY = "LEAVE_STANDBY";
public static final String ENTER_STANDBY = "ENTER_STANDBY";
diff --git a/bundles/org.openhab.binding.kaleidescape/src/main/java/org/openhab/binding/kaleidescape/internal/communication/KaleidescapeConnector.java b/bundles/org.openhab.binding.kaleidescape/src/main/java/org/openhab/binding/kaleidescape/internal/communication/KaleidescapeConnector.java
index 6f6b5188770f..73100f4cb55d 100644
--- a/bundles/org.openhab.binding.kaleidescape/src/main/java/org/openhab/binding/kaleidescape/internal/communication/KaleidescapeConnector.java
+++ b/bundles/org.openhab.binding.kaleidescape/src/main/java/org/openhab/binding/kaleidescape/internal/communication/KaleidescapeConnector.java
@@ -185,7 +185,7 @@ public void sendCommand(@Nullable String cmd) throws KaleidescapeException {
*/
public void sendCommand(@Nullable String cmd, @Nullable String cachedMessage) throws KaleidescapeException {
// if sent a cachedMessage, just send out an event with the data so KaleidescapeMessageHandler will process it
- if (cachedMessage != null) {
+ if (cmd != null && cachedMessage != null) {
logger.debug("Command: '{}' returning cached value: '{}'", cmd, cachedMessage);
// change GET_SOMETHING into SOMETHING and special case GET_PLAYING_TITLE_NAME into TITLE_NAME
dispatchKeyValue(cmd.replace("GET_", "").replace("PLAYING_TITLE_NAME", "TITLE_NAME"), cachedMessage, true);
diff --git a/bundles/org.openhab.binding.kaleidescape/src/main/java/org/openhab/binding/kaleidescape/internal/communication/KaleidescapeFormatter.java b/bundles/org.openhab.binding.kaleidescape/src/main/java/org/openhab/binding/kaleidescape/internal/communication/KaleidescapeFormatter.java
index 0dbe8727f53e..627c675d7459 100644
--- a/bundles/org.openhab.binding.kaleidescape/src/main/java/org/openhab/binding/kaleidescape/internal/communication/KaleidescapeFormatter.java
+++ b/bundles/org.openhab.binding.kaleidescape/src/main/java/org/openhab/binding/kaleidescape/internal/communication/KaleidescapeFormatter.java
@@ -12,6 +12,8 @@
*/
package org.openhab.binding.kaleidescape.internal.communication;
+import static org.openhab.binding.kaleidescape.internal.KaleidescapeBindingConstants.*;
+
import org.apache.commons.lang3.StringEscapeUtils;
import org.eclipse.jdt.annotation.NonNullByDefault;
@@ -23,7 +25,7 @@
@NonNullByDefault
public class KaleidescapeFormatter {
public static String formatString(String input) {
- if (!input.equals("")) {
+ if (!EMPTY.equals(input)) {
// convert || back to :
input = input.replace("||", ":");
diff --git a/bundles/org.openhab.binding.kaleidescape/src/main/java/org/openhab/binding/kaleidescape/internal/configuration/KaleidescapeThingConfiguration.java b/bundles/org.openhab.binding.kaleidescape/src/main/java/org/openhab/binding/kaleidescape/internal/configuration/KaleidescapeThingConfiguration.java
index 20e8e2f1f8d8..8b7ee83a9994 100644
--- a/bundles/org.openhab.binding.kaleidescape/src/main/java/org/openhab/binding/kaleidescape/internal/configuration/KaleidescapeThingConfiguration.java
+++ b/bundles/org.openhab.binding.kaleidescape/src/main/java/org/openhab/binding/kaleidescape/internal/configuration/KaleidescapeThingConfiguration.java
@@ -28,4 +28,6 @@ public class KaleidescapeThingConfiguration {
public @Nullable Integer updatePeriod;
public boolean volumeEnabled;
public Integer initialVolume = 0;
+ public boolean loadHighlightedDetails;
+ public boolean loadAlbumDetails;
}
diff --git a/bundles/org.openhab.binding.kaleidescape/src/main/java/org/openhab/binding/kaleidescape/internal/discovery/KaleidescapeDiscoveryJob.java b/bundles/org.openhab.binding.kaleidescape/src/main/java/org/openhab/binding/kaleidescape/internal/discovery/KaleidescapeDiscoveryJob.java
deleted file mode 100644
index f9f5b6130e90..000000000000
--- a/bundles/org.openhab.binding.kaleidescape/src/main/java/org/openhab/binding/kaleidescape/internal/discovery/KaleidescapeDiscoveryJob.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/**
- * 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.kaleidescape.internal.discovery;
-
-import static org.openhab.binding.kaleidescape.internal.KaleidescapeBindingConstants.*;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.net.UnknownHostException;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.openhab.core.thing.ThingTypeUID;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The {@link KaleidescapeDiscoveryJob} class allow manual discovery of
- * Kaleidescape components for a single IP address. This is used
- * for threading to make discovery faster.
- *
- * @author Chris Graham - Initial contribution
- * @author Michael Lobstein - Adapted for the Kaleidescape binding
- *
- */
-@NonNullByDefault
-public class KaleidescapeDiscoveryJob implements Runnable {
- private final Logger logger = LoggerFactory.getLogger(KaleidescapeDiscoveryJob.class);
-
- // Component Types
- private static final String PLAYER = "Player";
- private static final String CINEMA_ONE = "Cinema One";
- private static final String ALTO = "Alto";
- private static final String STRATO = "Strato";
- private static final String STRATO_S = "Strato S";
- private static final String DISC_VAULT = "Disc Vault";
-
- private static final Set ALLOWED_DEVICES = new HashSet(
- Arrays.asList(PLAYER, CINEMA_ONE, ALTO, STRATO, STRATO_S, DISC_VAULT));
-
- private KaleidescapeDiscoveryService discoveryClass;
-
- private ThingTypeUID thingTypeUid = THING_TYPE_PLAYER;
- private String ipAddress = EMPTY;
- private String friendlyName = EMPTY;
- private String serialNumber = EMPTY;
-
- public KaleidescapeDiscoveryJob(KaleidescapeDiscoveryService service, String ip) {
- this.discoveryClass = service;
- this.ipAddress = ip;
- }
-
- @Override
- public void run() {
- if (hasKaleidescapeDevice(this.ipAddress)) {
- discoveryClass.submitDiscoveryResults(this.thingTypeUid, this.ipAddress, this.friendlyName,
- this.serialNumber);
- }
- }
-
- /**
- * Determines if a Kaleidescape component with a movie player zone is available at a given IP address.
- *
- * @param ip IP address of the Kaleidescape component as a string.
- * @return True if a component is found, false if not.
- */
- private boolean hasKaleidescapeDevice(String ip) {
- try {
- InetAddress address = InetAddress.getByName(ip);
-
- if (isKaleidescapeDevice(address, DEFAULT_API_PORT)) {
- return true;
- } else {
- logger.debug("No Kaleidescape component found at IP address ({})", ip);
- return false;
- }
- } catch (UnknownHostException e) {
- logger.debug("Unknown host: {} - {}", ip, e.getMessage());
- return false;
- }
- }
-
- /**
- * Tries to establish a connection to a hostname and port and then interrogate the component
- *
- * @param host Hostname or IP address to connect to.
- * @param port Port to attempt to connect to.
- * @return True if the component found is one the binding supports
- */
- private boolean isKaleidescapeDevice(InetAddress host, int port) {
- try (Socket socket = new Socket()) {
- socket.connect(new InetSocketAddress(host, port), DISCOVERY_DEFAULT_IP_TIMEOUT_RATE_MS);
-
- OutputStream output = socket.getOutputStream();
- PrintWriter writer = new PrintWriter(output, true);
-
- // query the component to see if it has video zones, the device type, friendly name, and serial number
- writer.println("01/1/GET_NUM_ZONES:");
- writer.println("01/1/GET_DEVICE_TYPE_NAME:");
- writer.println("01/1/GET_FRIENDLY_NAME:");
- writer.println("01/1/GET_DEVICE_INFO:");
-
- InputStream input = socket.getInputStream();
-
- BufferedReader reader = new BufferedReader(new InputStreamReader(input));
-
- String componentType = EMPTY;
- String line;
- String videoZone = null;
- String audioZone = null;
- int lineCount = 0;
-
- while ((line = reader.readLine()) != null) {
- String[] strArr = line.split(":");
-
- if (strArr.length >= 4) {
- switch (strArr[1]) {
- case "NUM_ZONES":
- videoZone = strArr[2];
- audioZone = strArr[3];
- break;
- case "DEVICE_TYPE_NAME":
- componentType = strArr[2];
- break;
- case "FRIENDLY_NAME":
- friendlyName = strArr[2];
- break;
- case "DEVICE_INFO":
- serialNumber = strArr[3].trim(); // take off leading zeros
- break;
- }
- } else {
- logger.debug("isKaleidescapeDevice() - Unable to process line: {}", line);
- }
-
- lineCount++;
-
- // stop after reading four lines
- if (lineCount > 3) {
- break;
- }
- }
-
- // see if we have a video zone
- if ("01".equals(videoZone)) {
- // now check if we are one of the allowed types
- if (ALLOWED_DEVICES.contains(componentType)) {
- if (STRATO_S.equals(componentType) || STRATO.equals(componentType)) {
- thingTypeUid = THING_TYPE_STRATO;
- return true;
- }
-
- // A 'Player' without an audio zone is really a Strato C
- // does not work yet, Strato C erroneously reports "01" for audio zones
- // so we are unable to differentiate a Strato C from a Premiere player
- if ("00".equals(audioZone) && PLAYER.equals(componentType)) {
- thingTypeUid = THING_TYPE_STRATO;
- return true;
- }
-
- // Alto
- if (ALTO.equals(componentType)) {
- thingTypeUid = THING_TYPE_ALTO;
- return true;
- }
-
- // Cinema One
- if (CINEMA_ONE.equals(componentType)) {
- thingTypeUid = THING_TYPE_CINEMA_ONE;
- return true;
- }
-
- // A Disc Vault with a video zone (the M700 vault), just call it a THING_TYPE_PLAYER
- if (DISC_VAULT.equals(componentType)) {
- thingTypeUid = THING_TYPE_PLAYER;
- return true;
- }
-
- // default returns THING_TYPE_PLAYER
- return true;
- }
- }
- } catch (IOException e) {
- logger.debug("isKaleidescapeDevice() IOException: {}", e.getMessage());
- return false;
- }
-
- return false;
- }
-}
diff --git a/bundles/org.openhab.binding.kaleidescape/src/main/java/org/openhab/binding/kaleidescape/internal/discovery/KaleidescapeDiscoveryService.java b/bundles/org.openhab.binding.kaleidescape/src/main/java/org/openhab/binding/kaleidescape/internal/discovery/KaleidescapeDiscoveryService.java
index 2505e7fd4fef..8bb2388bbc85 100644
--- a/bundles/org.openhab.binding.kaleidescape/src/main/java/org/openhab/binding/kaleidescape/internal/discovery/KaleidescapeDiscoveryService.java
+++ b/bundles/org.openhab.binding.kaleidescape/src/main/java/org/openhab/binding/kaleidescape/internal/discovery/KaleidescapeDiscoveryService.java
@@ -14,26 +14,30 @@
import static org.openhab.binding.kaleidescape.internal.KaleidescapeBindingConstants.*;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.InterfaceAddress;
-import java.net.NetworkInterface;
-import java.net.SocketException;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketTimeoutException;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
-import java.util.List;
+import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
-import org.apache.commons.net.util.SubnetUtils;
import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.common.NamedThreadFactory;
import org.openhab.core.config.discovery.AbstractDiscoveryService;
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
@@ -50,7 +54,7 @@
*
* @author Chris Graham - Initial contribution
* @author Michael Lobstein - Adapted for the Kaleidescape binding
- *
+ *
*/
@NonNullByDefault
@Component(service = DiscoveryService.class, configurationPid = "discovery.kaleidescape")
@@ -60,6 +64,29 @@ public class KaleidescapeDiscoveryService extends AbstractDiscoveryService {
.unmodifiableSet(Stream.of(THING_TYPE_PLAYER, THING_TYPE_CINEMA_ONE, THING_TYPE_ALTO, THING_TYPE_STRATO)
.collect(Collectors.toSet()));
+ private static final int K_HEARTBEAT_PORT = 1443;
+
+ // Component Types
+ private static final String PLAYER = "Player";
+ private static final String CINEMA_ONE = "Cinema One";
+ private static final String ALTO = "Alto";
+ private static final String STRATO = "Strato";
+ private static final String STRATO_S = "Strato S";
+ private static final String DISC_VAULT = "Disc Vault";
+
+ private static final Set ALLOWED_DEVICES = new HashSet(
+ Arrays.asList(PLAYER, CINEMA_ONE, ALTO, STRATO, STRATO_S, DISC_VAULT));
+
+ @Nullable
+ private ExecutorService executorService = null;
+
+ /**
+ * Whether we are currently scanning or not
+ */
+ private boolean scanning;
+
+ private Set foundIPs = new HashSet();
+
@Activate
public KaleidescapeDiscoveryService() {
super(SUPPORTED_THING_TYPES_UIDS, DISCOVERY_DEFAULT_TIMEOUT_RATE_MS, DISCOVERY_DEFAULT_AUTO_DISCOVER);
@@ -70,83 +97,214 @@ public Set getSupportedThingTypes() {
return SUPPORTED_THING_TYPES_UIDS;
}
+ /**
+ * {@inheritDoc}
+ *
+ * Starts the scan. This discovery will:
+ *
+ *
Create a listening thread that opens up a broadcast {@link DatagramSocket} on port {@link #K_HEARTBEAT_PORT}
+ * and will receive any {@link DatagramPacket} that comes in
+ *
The source IP address of the {@link DatagramPacket} is interrogated to verify it is a Kaleidescape component
+ * and will create a new thing from it
+ *
+ * The process will continue until {@link #stopScan()} is called.
+ */
@Override
protected void startScan() {
logger.debug("Starting discovery of Kaleidescape components.");
- try {
- List ipList = getIpAddressScanList();
+ if (executorService != null) {
+ stopScan();
+ }
- ExecutorService discoverySearchPool = Executors.newFixedThreadPool(DISCOVERY_THREAD_POOL_SIZE,
- new NamedThreadFactory("OH-binding-discovery.kaleidescape", true));
+ final ExecutorService service = Executors.newFixedThreadPool(DISCOVERY_THREAD_POOL_SIZE,
+ new NamedThreadFactory("OH-binding-discovery.kaleidescape", true));
+ executorService = service;
- for (String ip : ipList) {
- discoverySearchPool.execute(new KaleidescapeDiscoveryJob(this, ip));
- }
+ scanning = true;
+ foundIPs.clear();
- discoverySearchPool.shutdown();
- } catch (Exception exp) {
- logger.debug("Kaleidescape discovery service encountered an error while scanning for components: {}",
- exp.getMessage());
- }
+ service.execute(() -> {
+ try {
+ DatagramSocket dSocket = new DatagramSocket(K_HEARTBEAT_PORT);
+ dSocket.setSoTimeout(DISCOVERY_DEFAULT_TIMEOUT_RATE_MS);
+ dSocket.setBroadcast(true);
- logger.debug("Completed discovery of Kaleidescape components.");
+ while (scanning) {
+ DatagramPacket receivePacket = new DatagramPacket(new byte[1], 1);
+ try {
+ dSocket.receive(receivePacket);
+
+ if (!foundIPs.contains(receivePacket.getAddress().getHostAddress())) {
+ String foundIp = receivePacket.getAddress().getHostAddress();
+ logger.debug("RECEIVED Kaleidescape packet from: {}", foundIp);
+ foundIPs.add(foundIp);
+ isKaleidescapeDevice(foundIp);
+ }
+ } catch (SocketTimeoutException e) {
+ // ignore
+ continue;
+ }
+ }
+
+ dSocket.close();
+ } catch (IOException e) {
+ logger.debug("KaleidescapeDiscoveryService IOException: {}", e.getMessage(), e);
+ }
+ });
}
/**
- * Create a new Thing with an IP address and Component type given. Uses default port.
+ * {@inheritDoc}
*
- * @param thingTypeUid ThingTypeUID of detected Kaleidescape component.
- * @param ip IP address of the Kaleidescape component as a string.
- * @param friendlyName Name of Kaleidescape component as a string.
- * @param serialNumber Serial Number of Kaleidescape component as a string.
+ * Stops the discovery scan. We set {@link #scanning} to false (allowing the listening thread to end naturally
+ * within {@link #TIMEOUT) * 5 time then shutdown the {@link #executorService}
*/
- public void submitDiscoveryResults(ThingTypeUID thingTypeUid, String ip, String friendlyName, String serialNumber) {
- ThingUID uid = new ThingUID(thingTypeUid, serialNumber);
-
- HashMap properties = new HashMap<>();
+ @Override
+ protected synchronized void stopScan() {
+ super.stopScan();
+ ExecutorService service = executorService;
+ if (service == null) {
+ return;
+ }
- properties.put("host", ip);
- properties.put("port", DEFAULT_API_PORT);
+ scanning = false;
- thingDiscovered(DiscoveryResultBuilder.create(uid).withProperties(properties).withRepresentationProperty("host")
- .withLabel(friendlyName).build());
+ try {
+ service.awaitTermination(DISCOVERY_DEFAULT_TIMEOUT_RATE_MS * 5, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ }
+ service.shutdown();
+ executorService = null;
}
/**
- * Provide a string list of all the IP addresses associated with the network interfaces on
- * this machine.
+ * Tries to establish a connection to the specified ip address and then interrogate the component,
+ * creates a discovery result if a valid component is found.
*
- * @return String list of IP addresses.
- * @throws UnknownHostException
- * @throws SocketException
+ * @param ipAddress IP address to connect to
*/
- private List getIpAddressScanList() throws UnknownHostException, SocketException {
- List results = new ArrayList<>();
+ private void isKaleidescapeDevice(String ipAddress) {
+ try (Socket socket = new Socket()) {
+ socket.connect(new InetSocketAddress(ipAddress, DEFAULT_API_PORT), DISCOVERY_DEFAULT_IP_TIMEOUT_RATE_MS);
+
+ OutputStream output = socket.getOutputStream();
+ PrintWriter writer = new PrintWriter(output, true);
+
+ // query the component to see if it has video zones, the device type, friendly name, and serial number
+ writer.println("01/1/GET_NUM_ZONES:");
+ writer.println("01/1/GET_DEVICE_TYPE_NAME:");
+ writer.println("01/1/GET_FRIENDLY_NAME:");
+ writer.println("01/1/GET_DEVICE_INFO:");
+
+ InputStream input = socket.getInputStream();
+
+ BufferedReader reader = new BufferedReader(new InputStreamReader(input));
+
+ ThingTypeUID thingTypeUid = THING_TYPE_PLAYER;
+ String friendlyName = EMPTY;
+ String serialNumber = EMPTY;
+ String componentType = EMPTY;
+ String line;
+ String videoZone = null;
+ String audioZone = null;
+ int lineCount = 0;
- InetAddress localHost = InetAddress.getLocalHost();
- NetworkInterface networkInterface = NetworkInterface.getByInetAddress(localHost);
+ while ((line = reader.readLine()) != null) {
+ String[] strArr = line.split(":");
- for (InterfaceAddress address : networkInterface.getInterfaceAddresses()) {
- InetAddress ipAddress = address.getAddress();
+ if (strArr.length >= 4) {
+ switch (strArr[1]) {
+ case "NUM_ZONES":
+ videoZone = strArr[2];
+ audioZone = strArr[3];
+ break;
+ case "DEVICE_TYPE_NAME":
+ componentType = strArr[2];
+ break;
+ case "FRIENDLY_NAME":
+ friendlyName = strArr[2];
+ break;
+ case "DEVICE_INFO":
+ serialNumber = strArr[3].trim(); // take off leading zeros
+ break;
+ }
+ } else {
+ logger.debug("isKaleidescapeDevice() - Unable to process line: {}", line);
+ }
- String cidrSubnet = ipAddress.getHostAddress() + "/" + address.getNetworkPrefixLength();
+ lineCount++;
- /* Apache Subnet Utils only supports IP v4 for creating string list of IP's */
- if (ipAddress instanceof Inet4Address) {
- logger.debug("Found interface IPv4 address to scan: {}", cidrSubnet);
+ // stop after reading four lines
+ if (lineCount > 3) {
+ break;
+ }
+ }
+
+ // see if we have a video zone
+ if ("01".equals(videoZone)) {
+ // now check if we are one of the allowed types
+ if (ALLOWED_DEVICES.contains(componentType)) {
+ if (STRATO_S.equals(componentType) || STRATO.equals(componentType)) {
+ thingTypeUid = THING_TYPE_STRATO;
+ }
+
+ // A 'Player' without an audio zone is really a Strato C
+ // does not work yet, Strato C erroneously reports "01" for audio zones
+ // so we are unable to differentiate a Strato C from a Premiere player
+ if ("00".equals(audioZone) && PLAYER.equals(componentType)) {
+ thingTypeUid = THING_TYPE_STRATO;
+ }
+
+ // Alto
+ if (ALTO.equals(componentType)) {
+ thingTypeUid = THING_TYPE_ALTO;
+ }
- SubnetUtils utils = new SubnetUtils(cidrSubnet);
+ // Cinema One
+ if (CINEMA_ONE.equals(componentType)) {
+ thingTypeUid = THING_TYPE_CINEMA_ONE;
+ }
- results.addAll(Arrays.asList(utils.getInfo().getAllAddresses())); // not sure how to do this without the
- // Apache libraries
- } else if (ipAddress instanceof Inet6Address) {
- logger.debug("Found interface IPv6 address to scan: {}, ignoring", cidrSubnet);
+ // A Disc Vault with a video zone (the M700 vault), just call it a THING_TYPE_PLAYER
+ if (DISC_VAULT.equals(componentType)) {
+ thingTypeUid = THING_TYPE_PLAYER;
+ }
+
+ // default THING_TYPE_PLAYER
+ submitDiscoveryResults(thingTypeUid, ipAddress, friendlyName, serialNumber);
+ }
} else {
- logger.debug("Found interface unknown IP type address to scan: {}", cidrSubnet);
+ logger.debug("No Suitable Kaleidescape component found at IP address ({})", ipAddress);
}
+ reader.close();
+ input.close();
+ writer.close();
+ output.close();
+ socket.close();
+ } catch (IOException e) {
+ logger.debug("isKaleidescapeDevice() IOException: {}", e.getMessage());
}
+ }
- return results;
+ /**
+ * Create a new Thing with an IP address and Component type given. Uses default port.
+ *
+ * @param thingTypeUid ThingTypeUID of detected Kaleidescape component.
+ * @param ip IP address of the Kaleidescape component as a string.
+ * @param friendlyName Name of Kaleidescape component as a string.
+ * @param serialNumber Serial Number of Kaleidescape component as a string.
+ */
+ private void submitDiscoveryResults(ThingTypeUID thingTypeUid, String ip, String friendlyName,
+ String serialNumber) {
+ ThingUID uid = new ThingUID(thingTypeUid, serialNumber);
+
+ HashMap properties = new HashMap<>();
+
+ properties.put("host", ip);
+ properties.put("port", DEFAULT_API_PORT);
+
+ thingDiscovered(DiscoveryResultBuilder.create(uid).withProperties(properties).withRepresentationProperty("host")
+ .withLabel(friendlyName).build());
}
}
diff --git a/bundles/org.openhab.binding.kaleidescape/src/main/java/org/openhab/binding/kaleidescape/internal/handler/KaleidescapeHandler.java b/bundles/org.openhab.binding.kaleidescape/src/main/java/org/openhab/binding/kaleidescape/internal/handler/KaleidescapeHandler.java
index 2cbcc821d068..8d8a87fccce1 100644
--- a/bundles/org.openhab.binding.kaleidescape/src/main/java/org/openhab/binding/kaleidescape/internal/handler/KaleidescapeHandler.java
+++ b/bundles/org.openhab.binding.kaleidescape/src/main/java/org/openhab/binding/kaleidescape/internal/handler/KaleidescapeHandler.java
@@ -90,6 +90,8 @@ public class KaleidescapeHandler extends BaseThingHandler implements Kaleidescap
protected int volume = 0;
protected boolean volumeEnabled = false;
protected boolean isMuted = false;
+ protected boolean isLoadHighlightedDetails = false;
+ protected boolean isLoadAlbumDetails = false;
protected String friendlyName = EMPTY;
protected Object sequenceLock = new Object();
@@ -124,6 +126,8 @@ public void initialize() {
final String host = config.host;
final Integer port = config.port;
final Integer updatePeriod = config.updatePeriod;
+ this.isLoadHighlightedDetails = config.loadHighlightedDetails;
+ this.isLoadAlbumDetails = config.loadAlbumDetails;
if ((serialPort == null || serialPort.isEmpty()) && (host == null || host.isEmpty())) {
configError = "undefined serialPort and host configuration settings; please set one of them";
@@ -166,10 +170,10 @@ public void initialize() {
return;
}
+ updateStatus(ThingStatus.UNKNOWN);
+
scheduleReconnectJob();
schedulePollingJob();
-
- updateStatus(ThingStatus.UNKNOWN);
}
@Override
diff --git a/bundles/org.openhab.binding.kaleidescape/src/main/java/org/openhab/binding/kaleidescape/internal/handler/KaleidescapeMessageHandler.java b/bundles/org.openhab.binding.kaleidescape/src/main/java/org/openhab/binding/kaleidescape/internal/handler/KaleidescapeMessageHandler.java
index 2469d65d2d2a..22f26dd3d050 100644
--- a/bundles/org.openhab.binding.kaleidescape/src/main/java/org/openhab/binding/kaleidescape/internal/handler/KaleidescapeMessageHandler.java
+++ b/bundles/org.openhab.binding.kaleidescape/src/main/java/org/openhab/binding/kaleidescape/internal/handler/KaleidescapeMessageHandler.java
@@ -57,9 +57,19 @@ public void handleMessage(String message, KaleidescapeHandler handler) {
}
},
HIGHLIGHTED_SELECTION {
+ private final Logger logger = LoggerFactory.getLogger(KaleidescapeMessageHandler.class);
+
@Override
public void handleMessage(String message, KaleidescapeHandler handler) {
handler.updateChannel(KaleidescapeBindingConstants.HIGHLIGHTED_SELECTION, new StringType(message));
+
+ if (handler.isLoadHighlightedDetails) {
+ try {
+ handler.connector.sendCommand(GET_CONTENT_DETAILS + message + ":");
+ } catch (KaleidescapeException e) {
+ logger.debug("GET_CONTENT_DETAILS - exception loading content details for handle: {}", message);
+ }
+ }
}
},
DEVICE_POWER_STATE {
@@ -273,6 +283,15 @@ public void handleMessage(String message, KaleidescapeHandler handler) {
handler.updateChannel(MUSIC_ALBUM_HANDLE, new StringType(matcher.group(5)));
handler.updateChannel(MUSIC_NOWPLAY_HANDLE, new StringType(matcher.group(6)));
+
+ if (handler.isLoadAlbumDetails) {
+ try {
+ handler.connector.sendCommand(GET_CONTENT_DETAILS + matcher.group(5) + ":");
+ } catch (KaleidescapeException e) {
+ logger.debug("GET_CONTENT_DETAILS - exception loading album details for handle: {}",
+ matcher.group(5));
+ }
+ }
} else {
logger.debug("MUSIC_TITLE - no match on message: {}", message);
}
diff --git a/bundles/org.openhab.binding.kaleidescape/src/main/resources/OH-INF/config/config.xml b/bundles/org.openhab.binding.kaleidescape/src/main/resources/OH-INF/config/config.xml
index 8b4a294ba426..0d851f32c07d 100644
--- a/bundles/org.openhab.binding.kaleidescape/src/main/resources/OH-INF/config/config.xml
+++ b/bundles/org.openhab.binding.kaleidescape/src/main/resources/OH-INF/config/config.xml
@@ -42,5 +42,17 @@
When the binding starts up, set the Inital Volume level to this value (Default 25).25
+
+
+ When enabled the binding will automatically load the metadata channels when the selected item in the UI
+ (Movie or Album) changes.
+ false
+
+
+
+ When enabled the binding will automatically load the metadata channels for the currently playing Album.
+ Not applicable for Alto and Strato components.
+ false
+
diff --git a/bundles/org.openhab.binding.kodi/README.md b/bundles/org.openhab.binding.kodi/README.md
index 5cf912208ef5..35653967854a 100644
--- a/bundles/org.openhab.binding.kodi/README.md
+++ b/bundles/org.openhab.binding.kodi/README.md
@@ -83,6 +83,7 @@ The Kodi thing supports the following channels:
| input | String | Sends a key stroke to Kodi to navigate in the UI. Valid commands are: `Back`, `ContextMenu`, `Down`, `Home`, `Info`, `Left`, `Right`, `Select`, `ShowCodec`, `ShowOSD`, `ShowPlayerProcessInfo` and `Up`. `ExecuteAction` and `SendText` should be used with the dedicated channels `inputaction` and `inputtext`. |
| inputtext | String | Sends a generic input (unicode) text to Kodi. |
| inputaction | String | Sends a predefined action to Kodi to control the UI and/or perform other tasks. Valid commands are: `left`, `right`, `up`, `down`, `pageup`, `pagedown`, `select`, `highlight`, `parentdir`, `parentfolder`, `back`, `menu`, `previousmenu`, `info`, `pause`, `stop`, `skipnext`, `skipprevious`, `fullscreen`, `aspectratio`, `stepforward`, `stepback`, `bigstepforward`, `bigstepback`, `chapterorbigstepforward`, `chapterorbigstepback`, `osd`, `showsubtitles`, `nextsubtitle`, `cyclesubtitle`, `playerdebug`, `codecinfo`, `playerprocessinfo`, `nextpicture`, `previouspicture`, `zoomout`, `zoomin`, `playlist`, `queue`, `zoomnormal`, `zoomlevel1`, `zoomlevel2`, `zoomlevel3`, `zoomlevel4`, `zoomlevel5`, `zoomlevel6`, `zoomlevel7`, `zoomlevel8`, `zoomlevel9`, `nextcalibration`, `resetcalibration`, `analogmove`, `analogmovex`, `analogmovey`, `rotate`, `rotateccw`, `close`, `subtitledelayminus`, `subtitledelay`, `subtitledelayplus`, `audiodelayminus`, `audiodelay`, `audiodelayplus`, `subtitleshiftup`, `subtitleshiftdown`, `subtitlealign`, `audionextlanguage`, `verticalshiftup`, `verticalshiftdown`, `nextresolution`, `audiotoggledigital`, `number0`, `number1`, `number2`, `number3`, `number4`, `number5`, `number6`, `number7`, `number8`, `number9`, `smallstepback`, `fastforward`, `rewind`, `play`, `playpause`, `switchplayer`, `delete`, `copy`, `move`, `screenshot`, `rename`, `togglewatched`, `scanitem`, `reloadkeymaps`, `volumeup`, `volumedown`, `mute`, `backspace`, `scrollup`, `scrolldown`, `analogfastforward`, `analogrewind`, `moveitemup`, `moveitemdown`, `contextmenu`, `shift`, `symbols`, `cursorleft`, `cursorright`, `showtime`, `analogseekforward`, `analogseekback`, `showpreset`, `nextpreset`, `previouspreset`, `lockpreset`, `randompreset`, `increasevisrating`, `decreasevisrating`, `showvideomenu`, `enter`, `increaserating`, `decreaserating`, `setrating`, `togglefullscreen`, `nextscene`, `previousscene`, `nextletter`, `prevletter`, `jumpsms2`, `jumpsms3`, `jumpsms4`, `jumpsms5`, `jumpsms6`, `jumpsms7`, `jumpsms8`, `jumpsms9`, `filter`, `filterclear`, `filtersms2`, `filtersms3`, `filtersms4`, `filtersms5`, `filtersms6`, `filtersms7`, `filtersms8`, `filtersms9`, `firstpage`, `lastpage`, `guiprofile`, `red`, `green`, `yellow`, `blue`, `increasepar`, `decreasepar`, `volampup`, `volampdown`, `volumeamplification`, `createbookmark`, `createepisodebookmark`, `settingsreset`, `settingslevelchange`, `stereomode`, `nextstereomode`, `previousstereomode`, `togglestereomode`, `stereomodetomono`, `channelup`, `channeldown`, `previouschannelgroup`, `nextchannelgroup`, `playpvr`, `playpvrtv`, `playpvrradio`, `record`, `togglecommskip`, `showtimerrule`, `leftclick`, `rightclick`, `middleclick`, `doubleclick`, `longclick`, `wheelup`, `wheeldown`, `mousedrag`, `mousemove`, `tap`, `longpress`, `pangesture`, `zoomgesture`, `rotategesture`, `swipeleft`, `swiperight`, `swipeup`, `swipedown`, `error`, `noop`. |
+| inputbuttonevent | String | Send a button press event. The parameter can have the format "`
+
+ io.dropwizard.metrics
+ metrics-jmx
+ 4.0.7
+ compile
+
+
+ io.micrometer
+ micrometer-registry-jmx
+ ${micrometer.version}
+ compile
+ io.micrometermicrometer-registry-prometheus
diff --git a/bundles/org.openhab.io.metrics/src/main/java/org/openhab/io/metrics/MetricsConfiguration.java b/bundles/org.openhab.io.metrics/src/main/java/org/openhab/io/metrics/MetricsConfiguration.java
index 08daf12192bf..b40ce1d6c363 100644
--- a/bundles/org.openhab.io.metrics/src/main/java/org/openhab/io/metrics/MetricsConfiguration.java
+++ b/bundles/org.openhab.io.metrics/src/main/java/org/openhab/io/metrics/MetricsConfiguration.java
@@ -25,15 +25,17 @@ public class MetricsConfiguration {
public boolean influxMetricsEnabled = false;
public String influxURL = "http://localhost:8086";
public String influxDB = "openhab";
- public @Nullable String influxPassword = null;
- public @Nullable String influxUsername = null;
+ public @Nullable String influxPassword;
+ public @Nullable String influxUsername;
public Integer influxUpdateIntervalInSeconds = 300;
+ public boolean jmxMetricsEnabled = false;
+
@Override
public String toString() {
return "MetricsConfiguration{" + "influxMetricsEnabled=" + influxMetricsEnabled + ", influxURL='" + influxURL
+ '\'' + ", influxDB='" + influxDB + '\'' + ", influxPassword='" + influxPassword + '\''
+ ", influxUsername='" + influxUsername + '\'' + ", influxUpdateIntervalInSeconds="
- + influxUpdateIntervalInSeconds + '}';
+ + influxUpdateIntervalInSeconds + ", jmxMetricsEnabled=" + jmxMetricsEnabled + '}';
}
}
diff --git a/bundles/org.openhab.io.metrics/src/main/java/org/openhab/io/metrics/MetricsExporter.java b/bundles/org.openhab.io.metrics/src/main/java/org/openhab/io/metrics/MetricsExporter.java
index cc1c644d8f6c..6d6acad131ad 100644
--- a/bundles/org.openhab.io.metrics/src/main/java/org/openhab/io/metrics/MetricsExporter.java
+++ b/bundles/org.openhab.io.metrics/src/main/java/org/openhab/io/metrics/MetricsExporter.java
@@ -31,8 +31,8 @@ public abstract class MetricsExporter {
private final Logger logger = LoggerFactory.getLogger(MetricsExporter.class);
private boolean active = false;
- protected @Nullable CompositeMeterRegistry meterRegistry = null;
- protected @Nullable MetricsConfiguration config = null;
+ protected @Nullable CompositeMeterRegistry meterRegistry;
+ protected @Nullable MetricsConfiguration config;
protected abstract void start(CompositeMeterRegistry meterRegistry, MetricsConfiguration metricsConfiguration);
diff --git a/bundles/org.openhab.io.metrics/src/main/java/org/openhab/io/metrics/MetricsRestController.java b/bundles/org.openhab.io.metrics/src/main/java/org/openhab/io/metrics/MetricsRestController.java
index b13b73ca435d..6d42edd5bbf3 100644
--- a/bundles/org.openhab.io.metrics/src/main/java/org/openhab/io/metrics/MetricsRestController.java
+++ b/bundles/org.openhab.io.metrics/src/main/java/org/openhab/io/metrics/MetricsRestController.java
@@ -14,7 +14,6 @@
import java.util.HashSet;
import java.util.Map;
-import java.util.Objects;
import java.util.Set;
import javax.annotation.security.RolesAllowed;
@@ -31,6 +30,7 @@
import org.openhab.core.io.monitor.MeterRegistryProvider;
import org.openhab.core.io.rest.RESTConstants;
import org.openhab.io.metrics.exporters.InfluxMetricsExporter;
+import org.openhab.io.metrics.exporters.JmxMetricsExporter;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Modified;
@@ -68,7 +68,7 @@
public class MetricsRestController {
private final Logger logger = LoggerFactory.getLogger(MetricsRestController.class);
public static final String PATH_METRICS = "metrics";
- private @Nullable CompositeMeterRegistry meterRegistry = null;
+ private @Nullable CompositeMeterRegistry meterRegistry;
private final PrometheusMeterRegistry prometheusMeterRegistry = new PrometheusMeterRegistry(
PrometheusConfig.DEFAULT);
private final Set metricsExporters = new HashSet<>();
@@ -85,11 +85,13 @@ public String getPrometheusMetrics() {
@Reference
public void setMeterRegistryProvider(MeterRegistryProvider meterRegistryProvider) {
+ CompositeMeterRegistry meterRegistry = this.meterRegistry;
if (meterRegistry != null) {
- Objects.requireNonNull(meterRegistry).remove(prometheusMeterRegistry);
+ meterRegistry.remove(prometheusMeterRegistry);
}
meterRegistry = meterRegistryProvider.getOHMeterRegistry();
- Objects.requireNonNull(meterRegistry).add(prometheusMeterRegistry);
+ meterRegistry.add(prometheusMeterRegistry);
+ this.meterRegistry = meterRegistry;
logger.debug("Core metrics registry retrieved and Prometheus registry added successfully.");
updateMeterRegistry();
}
@@ -98,6 +100,7 @@ public void setMeterRegistryProvider(MeterRegistryProvider meterRegistryProvider
protected void activate(Map<@Nullable String, @Nullable Object> configuration) {
logger.info("Metrics service activated, serving the following URL(s): /rest/metrics/prometheus");
metricsExporters.add(new InfluxMetricsExporter());
+ metricsExporters.add(new JmxMetricsExporter());
updateConfig(configuration);
updateMeterRegistry();
}
diff --git a/bundles/org.openhab.io.metrics/src/main/java/org/openhab/io/metrics/exporters/InfluxMetricsExporter.java b/bundles/org.openhab.io.metrics/src/main/java/org/openhab/io/metrics/exporters/InfluxMetricsExporter.java
index 8b02eac05e30..24e710408862 100644
--- a/bundles/org.openhab.io.metrics/src/main/java/org/openhab/io/metrics/exporters/InfluxMetricsExporter.java
+++ b/bundles/org.openhab.io.metrics/src/main/java/org/openhab/io/metrics/exporters/InfluxMetricsExporter.java
@@ -13,7 +13,6 @@
package org.openhab.io.metrics.exporters;
import java.time.Duration;
-import java.util.Objects;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
@@ -26,15 +25,15 @@
import io.micrometer.influx.InfluxMeterRegistry;
/**
- * The {@link InfluxMetricsExporter} class implements a MetricsExporter for InfluxDB
+ * The {@link InfluxMetricsExporter} class implements a MetricsExporter for InfluxDB.
*
* @author Robert Bach - Initial contribution
*/
@NonNullByDefault
public class InfluxMetricsExporter extends MetricsExporter {
- private @Nullable InfluxMeterRegistry influxMeterRegistry = null;
- private @Nullable CompositeMeterRegistry meterRegistry = null;
+ private @Nullable InfluxMeterRegistry influxMeterRegistry;
+ private @Nullable CompositeMeterRegistry meterRegistry;
@Override
public void start(CompositeMeterRegistry meterRegistry, MetricsConfiguration metricsConfiguration) {
@@ -44,14 +43,17 @@ public void start(CompositeMeterRegistry meterRegistry, MetricsConfiguration met
@Override
public void shutdown() {
+ InfluxMeterRegistry influxMeterRegistry = this.influxMeterRegistry;
if (influxMeterRegistry != null) {
- Objects.requireNonNull(influxMeterRegistry).stop();
+ influxMeterRegistry.stop();
+ this.influxMeterRegistry = null;
}
+
+ CompositeMeterRegistry meterRegistry = this.meterRegistry;
if (meterRegistry != null) {
- Objects.requireNonNull(meterRegistry).remove(influxMeterRegistry);
- meterRegistry = null;
+ meterRegistry.remove(influxMeterRegistry);
+ this.meterRegistry = null;
}
- influxMeterRegistry = null;
}
private InfluxConfig getInfluxConfig(MetricsConfiguration metricsConfiguration) {
diff --git a/bundles/org.openhab.io.metrics/src/main/java/org/openhab/io/metrics/exporters/JmxMetricsExporter.java b/bundles/org.openhab.io.metrics/src/main/java/org/openhab/io/metrics/exporters/JmxMetricsExporter.java
new file mode 100644
index 000000000000..8644a1946b3a
--- /dev/null
+++ b/bundles/org.openhab.io.metrics/src/main/java/org/openhab/io/metrics/exporters/JmxMetricsExporter.java
@@ -0,0 +1,72 @@
+/**
+ * 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.io.metrics.exporters;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.io.metrics.MetricsConfiguration;
+import org.openhab.io.metrics.MetricsExporter;
+
+import io.micrometer.core.instrument.Clock;
+import io.micrometer.core.instrument.composite.CompositeMeterRegistry;
+import io.micrometer.jmx.JmxConfig;
+import io.micrometer.jmx.JmxMeterRegistry;
+
+/**
+ * The {@link JmxMetricsExporter} class implements a MetricsExporter for Java Management Extensions (JMX).
+ *
+ * @author Wouter Born - Initial contribution
+ */
+@NonNullByDefault
+public class JmxMetricsExporter extends MetricsExporter {
+
+ private @Nullable JmxMeterRegistry jmxMeterRegistry;
+ private @Nullable CompositeMeterRegistry meterRegistry;
+
+ @Override
+ public void start(CompositeMeterRegistry meterRegistry, MetricsConfiguration metricsConfiguration) {
+ jmxMeterRegistry = new JmxMeterRegistry(getJmxConfig(), Clock.SYSTEM);
+ meterRegistry.add(jmxMeterRegistry);
+ }
+
+ @Override
+ public void shutdown() {
+ JmxMeterRegistry jmxMeterRegistry = this.jmxMeterRegistry;
+ if (jmxMeterRegistry != null) {
+ jmxMeterRegistry.stop();
+ this.jmxMeterRegistry = null;
+ }
+
+ CompositeMeterRegistry meterRegistry = this.meterRegistry;
+ if (meterRegistry != null) {
+ meterRegistry.remove(jmxMeterRegistry);
+ this.meterRegistry = null;
+ }
+ }
+
+ private JmxConfig getJmxConfig() {
+ return new JmxConfig() {
+ @Override
+ @io.micrometer.core.lang.Nullable
+ @Nullable
+ public String get(@Nullable String k) {
+ return null; // accept the rest of the defaults
+ }
+ };
+ }
+
+ @Override
+ protected boolean isEnabled(MetricsConfiguration config) {
+ return config.jmxMetricsEnabled;
+ }
+}
diff --git a/bundles/org.openhab.io.metrics/src/main/resources/OH-INF/config/config.xml b/bundles/org.openhab.io.metrics/src/main/resources/OH-INF/config/config.xml
index dd30657702bf..9d32dd65d096 100644
--- a/bundles/org.openhab.io.metrics/src/main/resources/OH-INF/config/config.xml
+++ b/bundles/org.openhab.io.metrics/src/main/resources/OH-INF/config/config.xml
@@ -5,35 +5,48 @@
xsi:schemaLocation="https://openhab.org/schemas/config-description/v1.0.0
https://openhab.org/schemas/config-description-1.0.0.xsd">
-
+
+
+
+
+
+
+
+
Enable the Influx (www.influxdata.com) Metrics. Further Configuration of the InfluxDB Instance
Necessary.false
-
-
+
+
The URL of the InfluxDB Instance. Defaults to http://localhost:8086http://localhost:8086
-
-
+
+
The Name of the Database to Use. Defaults to "openhab".openhab
-
-
+
+
The InfluxDB User Name (No Default).
-
-
+
+
The InfluxDB Password (No Default).password
-
-
+
+
Controls How Often Metrics Are Exported to InfluxDB (in Seconds). Defaults to 300300
+
+
+
+ Enable the Java Management Extensions (JMX) Metrics.
+ false
+
diff --git a/bundles/org.openhab.persistence.influxdb/pom.xml b/bundles/org.openhab.persistence.influxdb/pom.xml
index dcacb2b1b25c..3d8e8fe9a48c 100644
--- a/bundles/org.openhab.persistence.influxdb/pom.xml
+++ b/bundles/org.openhab.persistence.influxdb/pom.xml
@@ -71,7 +71,7 @@
okhttpcom.squareup.okhttp3
- 3.14.4
+ ${okhttp.version}retrofit
@@ -86,7 +86,7 @@
logging-interceptorcom.squareup.okhttp3
- 3.14.4
+ ${okhttp.version}rxjava
diff --git a/bundles/pom.xml b/bundles/pom.xml
index 9d865277c3c8..3ff122bea712 100644
--- a/bundles/pom.xml
+++ b/bundles/pom.xml
@@ -183,7 +183,9 @@
org.openhab.binding.lgtvserialorg.openhab.binding.lgwebosorg.openhab.binding.lifx
- org.openhab.binding.linky
+
org.openhab.binding.linuxinputorg.openhab.binding.lircorg.openhab.binding.logreader
diff --git a/itests/org.openhab.binding.astro.tests/itest.bndrun b/itests/org.openhab.binding.astro.tests/itest.bndrun
index 40d6daa8ded3..5578055b1511 100644
--- a/itests/org.openhab.binding.astro.tests/itest.bndrun
+++ b/itests/org.openhab.binding.astro.tests/itest.bndrun
@@ -29,7 +29,6 @@ Fragment-Host: org.openhab.binding.astro
biz.aQute.tester.junit-platform;version='[5.3.0,5.3.1)',\
com.google.gson;version='[2.8.6,2.8.7)',\
org.apache.commons.lang3;version='[3.12.0,3.12.1)',\
- org.apache.felix.scr;version='[2.1.26,2.1.27)',\
org.osgi.util.function;version='[1.1.0,1.1.1)',\
org.osgi.util.promise;version='[1.1.1,1.1.2)',\
jakarta.annotation-api;version='[2.0.0,2.0.1)',\
@@ -43,7 +42,6 @@ Fragment-Host: org.openhab.binding.astro
tech.units.indriya;version='[2.1.2,2.1.3)',\
uom-lib-common;version='[2.1.0,2.1.1)',\
org.apache.felix.configadmin;version='[1.9.22,1.9.23)',\
- org.ops4j.pax.logging.pax-logging-api;version='[2.0.9,2.0.10)',\
org.openhab.binding.astro;version='[3.2.0,3.2.1)',\
org.openhab.binding.astro.tests;version='[3.2.0,3.2.1)',\
org.openhab.core;version='[3.2.0,3.2.1)',\
@@ -51,4 +49,6 @@ Fragment-Host: org.openhab.binding.astro
org.openhab.core.config.discovery;version='[3.2.0,3.2.1)',\
org.openhab.core.io.console;version='[3.2.0,3.2.1)',\
org.openhab.core.storage.json;version='[3.2.0,3.2.1)',\
- org.openhab.core.thing;version='[3.2.0,3.2.1)'
+ org.openhab.core.thing;version='[3.2.0,3.2.1)',\
+ org.apache.felix.scr;version='[2.1.28,2.1.29)',\
+ org.ops4j.pax.logging.pax-logging-api;version='[2.0.10,2.0.11)'
diff --git a/itests/org.openhab.binding.avmfritz.tests/itest.bndrun b/itests/org.openhab.binding.avmfritz.tests/itest.bndrun
index ba539c17ff2f..7d7e205d3af0 100644
--- a/itests/org.openhab.binding.avmfritz.tests/itest.bndrun
+++ b/itests/org.openhab.binding.avmfritz.tests/itest.bndrun
@@ -34,7 +34,6 @@ Fragment-Host: org.openhab.binding.avmfritz
org.glassfish.hk2.osgi-resource-locator;version='[1.0.3,1.0.4)',\
biz.aQute.tester.junit-platform;version='[5.3.0,5.3.1)',\
com.google.gson;version='[2.8.6,2.8.7)',\
- org.apache.felix.scr;version='[2.1.26,2.1.27)',\
org.osgi.util.function;version='[1.1.0,1.1.1)',\
org.osgi.util.promise;version='[1.1.1,1.1.2)',\
org.objectweb.asm;version='[9.1.0,9.1.1)',\
@@ -53,19 +52,6 @@ Fragment-Host: org.openhab.binding.avmfritz
org.apache.felix.configadmin;version='[1.9.22,1.9.23)',\
org.apache.xbean.bundleutils;version='[4.19.0,4.19.1)',\
org.apache.xbean.finder;version='[4.19.0,4.19.1)',\
- org.eclipse.jetty.client;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.http;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.io;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.security;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.server;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.servlet;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.util;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.util.ajax;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.websocket.api;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.websocket.client;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.websocket.common;version='[9.4.40,9.4.41)',\
- org.ops4j.pax.logging.pax-logging-api;version='[2.0.9,2.0.10)',\
- org.ops4j.pax.web.pax-web-api;version='[7.3.16,7.3.17)',\
org.openhab.binding.avmfritz;version='[3.2.0,3.2.1)',\
org.openhab.binding.avmfritz.tests;version='[3.2.0,3.2.1)',\
org.openhab.core;version='[3.2.0,3.2.1)',\
@@ -75,4 +61,18 @@ Fragment-Host: org.openhab.binding.avmfritz
org.openhab.core.io.console;version='[3.2.0,3.2.1)',\
org.openhab.core.io.net;version='[3.2.0,3.2.1)',\
org.openhab.core.test;version='[3.2.0,3.2.1)',\
- org.openhab.core.thing;version='[3.2.0,3.2.1)'
+ org.openhab.core.thing;version='[3.2.0,3.2.1)',\
+ org.apache.felix.scr;version='[2.1.28,2.1.29)',\
+ org.eclipse.jetty.client;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.http;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.io;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.security;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.server;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.servlet;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.util;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.util.ajax;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.websocket.api;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.websocket.client;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.websocket.common;version='[9.4.43,9.4.44)',\
+ org.ops4j.pax.logging.pax-logging-api;version='[2.0.10,2.0.11)',\
+ org.ops4j.pax.web.pax-web-api;version='[7.3.19,7.3.20)'
diff --git a/itests/org.openhab.binding.feed.tests/itest.bndrun b/itests/org.openhab.binding.feed.tests/itest.bndrun
index d0113e2cf996..0428c2d19bb6 100644
--- a/itests/org.openhab.binding.feed.tests/itest.bndrun
+++ b/itests/org.openhab.binding.feed.tests/itest.bndrun
@@ -36,7 +36,6 @@ Fragment-Host: org.openhab.binding.feed
org.glassfish.hk2.osgi-resource-locator;version='[1.0.3,1.0.4)',\
biz.aQute.tester.junit-platform;version='[5.3.0,5.3.1)',\
com.google.gson;version='[2.8.6,2.8.7)',\
- org.apache.felix.scr;version='[2.1.26,2.1.27)',\
org.osgi.util.function;version='[1.1.0,1.1.1)',\
org.osgi.util.promise;version='[1.1.1,1.1.2)',\
org.objectweb.asm;version='[9.1.0,9.1.1)',\
@@ -54,20 +53,7 @@ Fragment-Host: org.openhab.binding.feed
org.apache.felix.configadmin;version='[1.9.22,1.9.23)',\
org.apache.xbean.bundleutils;version='[4.19.0,4.19.1)',\
org.apache.xbean.finder;version='[4.19.0,4.19.1)',\
- org.eclipse.jetty.http;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.io;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.security;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.server;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.servlet;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.util;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.util.ajax;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.xml;version='[9.4.40,9.4.41)',\
- org.ops4j.pax.logging.pax-logging-api;version='[2.0.9,2.0.10)',\
- org.ops4j.pax.web.pax-web-api;version='[7.3.16,7.3.17)',\
- org.ops4j.pax.web.pax-web-jetty;version='[7.3.16,7.3.17)',\
- org.ops4j.pax.web.pax-web-runtime;version='[7.3.16,7.3.17)',\
- org.ops4j.pax.web.pax-web-spi;version='[7.3.16,7.3.17)',\
- xstream;version='[1.4.17,1.4.18)',\
+ xstream;version='[1.4.18,1.4.19)',\
org.openhab.binding.feed;version='[3.2.0,3.2.1)',\
org.openhab.binding.feed.tests;version='[3.2.0,3.2.1)',\
org.openhab.core;version='[3.2.0,3.2.1)',\
@@ -77,4 +63,18 @@ Fragment-Host: org.openhab.binding.feed
org.openhab.core.io.console;version='[3.2.0,3.2.1)',\
org.openhab.core.test;version='[3.2.0,3.2.1)',\
org.openhab.core.thing;version='[3.2.0,3.2.1)',\
- org.openhab.core.thing.xml;version='[3.2.0,3.2.1)'
+ org.openhab.core.thing.xml;version='[3.2.0,3.2.1)',\
+ org.apache.felix.scr;version='[2.1.28,2.1.29)',\
+ org.eclipse.jetty.http;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.io;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.security;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.server;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.servlet;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.util;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.util.ajax;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.xml;version='[9.4.43,9.4.44)',\
+ org.ops4j.pax.logging.pax-logging-api;version='[2.0.10,2.0.11)',\
+ org.ops4j.pax.web.pax-web-api;version='[7.3.19,7.3.20)',\
+ org.ops4j.pax.web.pax-web-jetty;version='[7.3.19,7.3.20)',\
+ org.ops4j.pax.web.pax-web-runtime;version='[7.3.19,7.3.20)',\
+ org.ops4j.pax.web.pax-web-spi;version='[7.3.19,7.3.20)'
diff --git a/itests/org.openhab.binding.hue.tests/itest.bndrun b/itests/org.openhab.binding.hue.tests/itest.bndrun
index 384bb1803a24..0e7f76ea9042 100644
--- a/itests/org.openhab.binding.hue.tests/itest.bndrun
+++ b/itests/org.openhab.binding.hue.tests/itest.bndrun
@@ -34,7 +34,6 @@ Fragment-Host: org.openhab.binding.hue
org.glassfish.hk2.osgi-resource-locator;version='[1.0.3,1.0.4)',\
biz.aQute.tester.junit-platform;version='[5.3.0,5.3.1)',\
com.google.gson;version='[2.8.6,2.8.7)',\
- org.apache.felix.scr;version='[2.1.26,2.1.27)',\
org.osgi.util.function;version='[1.1.0,1.1.1)',\
org.osgi.util.promise;version='[1.1.1,1.1.2)',\
org.objectweb.asm;version='[9.1.0,9.1.1)',\
@@ -53,20 +52,7 @@ Fragment-Host: org.openhab.binding.hue
org.apache.felix.configadmin;version='[1.9.22,1.9.23)',\
org.apache.xbean.bundleutils;version='[4.19.0,4.19.1)',\
org.apache.xbean.finder;version='[4.19.0,4.19.1)',\
- org.eclipse.jetty.client;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.http;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.io;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.security;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.server;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.servlet;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.util;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.util.ajax;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.websocket.api;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.websocket.client;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.websocket.common;version='[9.4.40,9.4.41)',\
- org.ops4j.pax.logging.pax-logging-api;version='[2.0.9,2.0.10)',\
- org.ops4j.pax.web.pax-web-api;version='[7.3.16,7.3.17)',\
- xstream;version='[1.4.17,1.4.18)',\
+ xstream;version='[1.4.18,1.4.19)',\
org.openhab.binding.hue;version='[3.2.0,3.2.1)',\
org.openhab.binding.hue.tests;version='[3.2.0,3.2.1)',\
org.openhab.core;version='[3.2.0,3.2.1)',\
@@ -79,4 +65,18 @@ Fragment-Host: org.openhab.binding.hue
org.openhab.core.io.net;version='[3.2.0,3.2.1)',\
org.openhab.core.test;version='[3.2.0,3.2.1)',\
org.openhab.core.thing;version='[3.2.0,3.2.1)',\
- org.openhab.core.thing.xml;version='[3.2.0,3.2.1)'
+ org.openhab.core.thing.xml;version='[3.2.0,3.2.1)',\
+ org.apache.felix.scr;version='[2.1.28,2.1.29)',\
+ org.eclipse.jetty.client;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.http;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.io;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.security;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.server;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.servlet;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.util;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.util.ajax;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.websocket.api;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.websocket.client;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.websocket.common;version='[9.4.43,9.4.44)',\
+ org.ops4j.pax.logging.pax-logging-api;version='[2.0.10,2.0.11)',\
+ org.ops4j.pax.web.pax-web-api;version='[7.3.19,7.3.20)'
diff --git a/itests/org.openhab.binding.max.tests/itest.bndrun b/itests/org.openhab.binding.max.tests/itest.bndrun
index ea166c44f30c..82a0731d6c6f 100644
--- a/itests/org.openhab.binding.max.tests/itest.bndrun
+++ b/itests/org.openhab.binding.max.tests/itest.bndrun
@@ -33,7 +33,6 @@ Fragment-Host: org.openhab.binding.max
biz.aQute.tester.junit-platform;version='[5.3.0,5.3.1)',\
com.google.gson;version='[2.8.6,2.8.7)',\
org.apache.commons.lang3;version='[3.12.0,3.12.1)',\
- org.apache.felix.scr;version='[2.1.26,2.1.27)',\
org.osgi.util.function;version='[1.1.0,1.1.1)',\
org.osgi.util.promise;version='[1.1.1,1.1.2)',\
jakarta.annotation-api;version='[2.0.0,2.0.1)',\
@@ -47,15 +46,7 @@ Fragment-Host: org.openhab.binding.max
tech.units.indriya;version='[2.1.2,2.1.3)',\
uom-lib-common;version='[2.1.0,2.1.1)',\
org.apache.felix.configadmin;version='[1.9.22,1.9.23)',\
- org.eclipse.jetty.http;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.io;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.security;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.server;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.servlet;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.util;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.util.ajax;version='[9.4.40,9.4.41)',\
- org.ops4j.pax.logging.pax-logging-api;version='[2.0.9,2.0.10)',\
- xstream;version='[1.4.17,1.4.18)',\
+ xstream;version='[1.4.18,1.4.19)',\
org.openhab.binding.max;version='[3.2.0,3.2.1)',\
org.openhab.binding.max.tests;version='[3.2.0,3.2.1)',\
org.openhab.core;version='[3.2.0,3.2.1)',\
@@ -66,4 +57,13 @@ Fragment-Host: org.openhab.binding.max
org.openhab.core.io.console;version='[3.2.0,3.2.1)',\
org.openhab.core.test;version='[3.2.0,3.2.1)',\
org.openhab.core.thing;version='[3.2.0,3.2.1)',\
- org.openhab.core.thing.xml;version='[3.2.0,3.2.1)'
+ org.openhab.core.thing.xml;version='[3.2.0,3.2.1)',\
+ org.apache.felix.scr;version='[2.1.28,2.1.29)',\
+ org.eclipse.jetty.http;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.io;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.security;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.server;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.servlet;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.util;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.util.ajax;version='[9.4.43,9.4.44)',\
+ org.ops4j.pax.logging.pax-logging-api;version='[2.0.10,2.0.11)'
diff --git a/itests/org.openhab.binding.mielecloud.tests/itest.bndrun b/itests/org.openhab.binding.mielecloud.tests/itest.bndrun
index 1ce00c4c1c9c..ae7a0069fb26 100644
--- a/itests/org.openhab.binding.mielecloud.tests/itest.bndrun
+++ b/itests/org.openhab.binding.mielecloud.tests/itest.bndrun
@@ -36,7 +36,6 @@ Fragment-Host: org.openhab.binding.mielecloud
org.objenesis;version='[3.1.0,3.1.1)',\
biz.aQute.tester.junit-platform;version='[5.3.0,5.3.1)',\
com.google.gson;version='[2.8.6,2.8.7)',\
- org.apache.felix.scr;version='[2.1.26,2.1.27)',\
org.objectweb.asm;version='[9.1.0,9.1.1)',\
org.objectweb.asm.commons;version='[9.0.0,9.0.1)',\
org.objectweb.asm.tree;version='[9.0.0,9.0.1)',\
@@ -48,31 +47,14 @@ Fragment-Host: org.openhab.binding.mielecloud
org.apache.felix.configadmin;version='[1.9.22,1.9.23)',\
org.apache.xbean.bundleutils;version='[4.19.0,4.19.1)',\
org.apache.xbean.finder;version='[4.19.0,4.19.1)',\
- org.eclipse.jetty.client;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.http;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.io;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.security;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.server;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.servlet;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.util;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.util.ajax;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.websocket.api;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.websocket.client;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.websocket.common;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.xml;version='[9.4.40,9.4.41)',\
org.glassfish.hk2.external.javax.inject;version='[2.4.0,2.4.1)',\
org.jsr-305;version='[3.0.2,3.0.3)',\
- org.ops4j.pax.web.pax-web-api;version='[7.3.16,7.3.17)',\
- org.ops4j.pax.web.pax-web-jetty;version='[7.3.16,7.3.17)',\
- org.ops4j.pax.web.pax-web-runtime;version='[7.3.16,7.3.17)',\
- org.ops4j.pax.web.pax-web-spi;version='[7.3.16,7.3.17)',\
org.osgi.service.cm;version='[1.6.0,1.6.1)',\
si-units;version='[2.0.1,2.0.2)',\
si.uom.si-quantity;version='[2.0.1,2.0.2)',\
tech.units.indriya;version='[2.1.2,2.1.3)',\
uom-lib-common;version='[2.1.0,2.1.1)',\
- xstream;version='[1.4.17,1.4.18)',\
- org.ops4j.pax.logging.pax-logging-api;version='[2.0.9,2.0.10)',\
+ xstream;version='[1.4.18,1.4.19)',\
org.openhab.binding.mielecloud;version='[3.2.0,3.2.1)',\
org.openhab.binding.mielecloud.tests;version='[3.2.0,3.2.1)',\
org.openhab.core;version='[3.2.0,3.2.1)',\
@@ -85,4 +67,22 @@ Fragment-Host: org.openhab.binding.mielecloud
org.openhab.core.io.net;version='[3.2.0,3.2.1)',\
org.openhab.core.test;version='[3.2.0,3.2.1)',\
org.openhab.core.thing;version='[3.2.0,3.2.1)',\
- org.openhab.core.thing.xml;version='[3.2.0,3.2.1)'
+ org.openhab.core.thing.xml;version='[3.2.0,3.2.1)',\
+ org.apache.felix.scr;version='[2.1.28,2.1.29)',\
+ org.eclipse.jetty.client;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.http;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.io;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.security;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.server;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.servlet;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.util;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.util.ajax;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.websocket.api;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.websocket.client;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.websocket.common;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.xml;version='[9.4.43,9.4.44)',\
+ org.ops4j.pax.logging.pax-logging-api;version='[2.0.10,2.0.11)',\
+ org.ops4j.pax.web.pax-web-api;version='[7.3.19,7.3.20)',\
+ org.ops4j.pax.web.pax-web-jetty;version='[7.3.19,7.3.20)',\
+ org.ops4j.pax.web.pax-web-runtime;version='[7.3.19,7.3.20)',\
+ org.ops4j.pax.web.pax-web-spi;version='[7.3.19,7.3.20)'
diff --git a/itests/org.openhab.binding.modbus.tests/itest.bndrun b/itests/org.openhab.binding.modbus.tests/itest.bndrun
index a726d84e0add..efe7dc00d596 100644
--- a/itests/org.openhab.binding.modbus.tests/itest.bndrun
+++ b/itests/org.openhab.binding.modbus.tests/itest.bndrun
@@ -40,7 +40,6 @@ Fragment-Host: org.openhab.binding.modbus
org.glassfish.hk2.osgi-resource-locator;version='[1.0.3,1.0.4)',\
biz.aQute.tester.junit-platform;version='[5.3.0,5.3.1)',\
com.google.gson;version='[2.8.6,2.8.7)',\
- org.apache.felix.scr;version='[2.1.26,2.1.27)',\
org.osgi.util.function;version='[1.1.0,1.1.1)',\
org.osgi.util.promise;version='[1.1.1,1.1.2)',\
jakarta.annotation-api;version='[2.0.0,2.0.1)',\
@@ -54,15 +53,7 @@ Fragment-Host: org.openhab.binding.modbus
tech.units.indriya;version='[2.1.2,2.1.3)',\
uom-lib-common;version='[2.1.0,2.1.1)',\
org.apache.felix.configadmin;version='[1.9.22,1.9.23)',\
- org.eclipse.jetty.http;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.io;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.security;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.server;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.servlet;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.util;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.util.ajax;version='[9.4.40,9.4.41)',\
- org.ops4j.pax.logging.pax-logging-api;version='[2.0.9,2.0.10)',\
- xstream;version='[1.4.17,1.4.18)',\
+ xstream;version='[1.4.18,1.4.19)',\
org.openhab.binding.modbus;version='[3.2.0,3.2.1)',\
org.openhab.binding.modbus.tests;version='[3.2.0,3.2.1)',\
org.openhab.core;version='[3.2.0,3.2.1)',\
@@ -75,4 +66,13 @@ Fragment-Host: org.openhab.binding.modbus
org.openhab.core.test;version='[3.2.0,3.2.1)',\
org.openhab.core.thing;version='[3.2.0,3.2.1)',\
org.openhab.core.thing.xml;version='[3.2.0,3.2.1)',\
- org.openhab.core.transform;version='[3.2.0,3.2.1)'
+ org.openhab.core.transform;version='[3.2.0,3.2.1)',\
+ org.apache.felix.scr;version='[2.1.28,2.1.29)',\
+ org.eclipse.jetty.http;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.io;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.security;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.server;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.servlet;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.util;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.util.ajax;version='[9.4.43,9.4.44)',\
+ org.ops4j.pax.logging.pax-logging-api;version='[2.0.10,2.0.11)'
diff --git a/itests/org.openhab.binding.nest.tests/itest.bndrun b/itests/org.openhab.binding.nest.tests/itest.bndrun
index 4abceebfdd0a..1432138eaf6e 100644
--- a/itests/org.openhab.binding.nest.tests/itest.bndrun
+++ b/itests/org.openhab.binding.nest.tests/itest.bndrun
@@ -40,7 +40,6 @@ Fragment-Host: org.openhab.binding.nest
biz.aQute.tester.junit-platform;version='[5.3.0,5.3.1)',\
com.google.gson;version='[2.8.6,2.8.7)',\
org.apache.aries.javax.jax.rs-api;version='[1.0.1,1.0.2)',\
- org.apache.felix.scr;version='[2.1.26,2.1.27)',\
org.osgi.util.promise;version='[1.1.1,1.1.2)',\
org.objectweb.asm;version='[9.1.0,9.1.1)',\
org.objectweb.asm.commons;version='[9.0.0,9.0.1)',\
@@ -75,23 +74,7 @@ Fragment-Host: org.openhab.binding.nest
org.apache.felix.configadmin;version='[1.9.22,1.9.23)',\
org.apache.xbean.bundleutils;version='[4.19.0,4.19.1)',\
org.apache.xbean.finder;version='[4.19.0,4.19.1)',\
- org.eclipse.jetty.client;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.http;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.io;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.security;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.server;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.servlet;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.util;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.util.ajax;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.websocket.api;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.websocket.client;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.websocket.common;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.xml;version='[9.4.40,9.4.41)',\
- org.ops4j.pax.logging.pax-logging-api;version='[2.0.9,2.0.10)',\
- org.ops4j.pax.web.pax-web-api;version='[7.3.16,7.3.17)',\
- org.ops4j.pax.web.pax-web-jetty;version='[7.3.16,7.3.17)',\
- org.ops4j.pax.web.pax-web-spi;version='[7.3.16,7.3.17)',\
- xstream;version='[1.4.17,1.4.18)',\
+ xstream;version='[1.4.18,1.4.19)',\
org.openhab.binding.nest;version='[3.2.0,3.2.1)',\
org.openhab.binding.nest.tests;version='[3.2.0,3.2.1)',\
org.openhab.core;version='[3.2.0,3.2.1)',\
@@ -104,4 +87,21 @@ Fragment-Host: org.openhab.binding.nest
org.openhab.core.io.net;version='[3.2.0,3.2.1)',\
org.openhab.core.test;version='[3.2.0,3.2.1)',\
org.openhab.core.thing;version='[3.2.0,3.2.1)',\
- org.openhab.core.thing.xml;version='[3.2.0,3.2.1)'
+ org.openhab.core.thing.xml;version='[3.2.0,3.2.1)',\
+ org.apache.felix.scr;version='[2.1.28,2.1.29)',\
+ org.eclipse.jetty.client;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.http;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.io;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.security;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.server;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.servlet;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.util;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.util.ajax;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.websocket.api;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.websocket.client;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.websocket.common;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.xml;version='[9.4.43,9.4.44)',\
+ org.ops4j.pax.logging.pax-logging-api;version='[2.0.10,2.0.11)',\
+ org.ops4j.pax.web.pax-web-api;version='[7.3.19,7.3.20)',\
+ org.ops4j.pax.web.pax-web-jetty;version='[7.3.19,7.3.20)',\
+ org.ops4j.pax.web.pax-web-spi;version='[7.3.19,7.3.20)'
diff --git a/itests/org.openhab.binding.ntp.tests/itest.bndrun b/itests/org.openhab.binding.ntp.tests/itest.bndrun
index 6062a151c352..75f5fee16074 100644
--- a/itests/org.openhab.binding.ntp.tests/itest.bndrun
+++ b/itests/org.openhab.binding.ntp.tests/itest.bndrun
@@ -37,7 +37,6 @@ Fragment-Host: org.openhab.binding.ntp
org.glassfish.hk2.osgi-resource-locator;version='[1.0.3,1.0.4)',\
biz.aQute.tester.junit-platform;version='[5.3.0,5.3.1)',\
com.google.gson;version='[2.8.6,2.8.7)',\
- org.apache.felix.scr;version='[2.1.26,2.1.27)',\
org.osgi.util.function;version='[1.1.0,1.1.1)',\
org.osgi.util.promise;version='[1.1.1,1.1.2)',\
jakarta.annotation-api;version='[2.0.0,2.0.1)',\
@@ -51,15 +50,7 @@ Fragment-Host: org.openhab.binding.ntp
tech.units.indriya;version='[2.1.2,2.1.3)',\
uom-lib-common;version='[2.1.0,2.1.1)',\
org.apache.felix.configadmin;version='[1.9.22,1.9.23)',\
- org.eclipse.jetty.http;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.io;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.security;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.server;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.servlet;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.util;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.util.ajax;version='[9.4.40,9.4.41)',\
- org.ops4j.pax.logging.pax-logging-api;version='[2.0.9,2.0.10)',\
- xstream;version='[1.4.17,1.4.18)',\
+ xstream;version='[1.4.18,1.4.19)',\
org.openhab.binding.ntp;version='[3.2.0,3.2.1)',\
org.openhab.binding.ntp.tests;version='[3.2.0,3.2.1)',\
org.openhab.core;version='[3.2.0,3.2.1)',\
@@ -70,4 +61,13 @@ Fragment-Host: org.openhab.binding.ntp
org.openhab.core.io.console;version='[3.2.0,3.2.1)',\
org.openhab.core.test;version='[3.2.0,3.2.1)',\
org.openhab.core.thing;version='[3.2.0,3.2.1)',\
- org.openhab.core.thing.xml;version='[3.2.0,3.2.1)'
+ org.openhab.core.thing.xml;version='[3.2.0,3.2.1)',\
+ org.apache.felix.scr;version='[2.1.28,2.1.29)',\
+ org.eclipse.jetty.http;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.io;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.security;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.server;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.servlet;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.util;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.util.ajax;version='[9.4.43,9.4.44)',\
+ org.ops4j.pax.logging.pax-logging-api;version='[2.0.10,2.0.11)'
diff --git a/itests/org.openhab.binding.systeminfo.tests/itest.bndrun b/itests/org.openhab.binding.systeminfo.tests/itest.bndrun
index 7504f61f32c7..f71325316b54 100644
--- a/itests/org.openhab.binding.systeminfo.tests/itest.bndrun
+++ b/itests/org.openhab.binding.systeminfo.tests/itest.bndrun
@@ -21,8 +21,6 @@ Fragment-Host: org.openhab.binding.systeminfo
org.apache.felix.http.servlet-api;version='[1.1.2,1.1.3)',\
org.osgi.service.event;version='[1.4.0,1.4.1)',\
org.eclipse.equinox.event;version='[1.4.300,1.4.301)',\
- com.sun.jna;version='[5.5.0,5.5.1)',\
- com.sun.jna.platform;version='[5.5.0,5.5.1)',\
org.hamcrest;version='[2.2.0,2.2.1)',\
org.opentest4j;version='[1.2.0,1.2.1)',\
com.sun.xml.bind.jaxb-osgi;version='[2.3.3,2.3.4)',\
@@ -41,7 +39,6 @@ Fragment-Host: org.openhab.binding.systeminfo
biz.aQute.tester.junit-platform;version='[5.3.0,5.3.1)',\
com.google.gson;version='[2.8.6,2.8.7)',\
org.apache.commons.lang3;version='[3.12.0,3.12.1)',\
- org.apache.felix.scr;version='[2.1.26,2.1.27)',\
org.osgi.util.function;version='[1.1.0,1.1.1)',\
org.osgi.util.promise;version='[1.1.1,1.1.2)',\
jakarta.annotation-api;version='[2.0.0,2.0.1)',\
@@ -55,15 +52,7 @@ Fragment-Host: org.openhab.binding.systeminfo
tech.units.indriya;version='[2.1.2,2.1.3)',\
uom-lib-common;version='[2.1.0,2.1.1)',\
org.apache.felix.configadmin;version='[1.9.22,1.9.23)',\
- org.eclipse.jetty.http;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.io;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.security;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.server;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.servlet;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.util;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.util.ajax;version='[9.4.40,9.4.41)',\
- org.ops4j.pax.logging.pax-logging-api;version='[2.0.9,2.0.10)',\
- xstream;version='[1.4.17,1.4.18)',\
+ xstream;version='[1.4.18,1.4.19)',\
org.openhab.binding.systeminfo;version='[3.2.0,3.2.1)',\
org.openhab.binding.systeminfo.tests;version='[3.2.0,3.2.1)',\
org.openhab.core;version='[3.2.0,3.2.1)',\
@@ -74,4 +63,15 @@ Fragment-Host: org.openhab.binding.systeminfo
org.openhab.core.io.console;version='[3.2.0,3.2.1)',\
org.openhab.core.test;version='[3.2.0,3.2.1)',\
org.openhab.core.thing;version='[3.2.0,3.2.1)',\
- org.openhab.core.thing.xml;version='[3.2.0,3.2.1)'
+ org.openhab.core.thing.xml;version='[3.2.0,3.2.1)',\
+ org.apache.felix.scr;version='[2.1.28,2.1.29)',\
+ org.eclipse.jetty.http;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.io;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.security;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.server;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.servlet;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.util;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.util.ajax;version='[9.4.43,9.4.44)',\
+ org.ops4j.pax.logging.pax-logging-api;version='[2.0.10,2.0.11)',\
+ com.sun.jna;version='[5.9.0,5.9.1)',\
+ com.sun.jna.platform;version='[5.9.0,5.9.1)'
diff --git a/itests/org.openhab.binding.systeminfo.tests/pom.xml b/itests/org.openhab.binding.systeminfo.tests/pom.xml
index 96c5c409fae4..d0a963d868bc 100644
--- a/itests/org.openhab.binding.systeminfo.tests/pom.xml
+++ b/itests/org.openhab.binding.systeminfo.tests/pom.xml
@@ -23,17 +23,17 @@
net.java.dev.jnajna-platform
- 5.5.0
+ 5.9.0net.java.dev.jnajna
- 5.5.0
+ 5.9.0com.github.oshioshi-core
- 4.5.2
+ 5.8.2org.slf4j
diff --git a/itests/org.openhab.binding.tradfri.tests/itest.bndrun b/itests/org.openhab.binding.tradfri.tests/itest.bndrun
index 8a27e97169b2..a58fc6119318 100644
--- a/itests/org.openhab.binding.tradfri.tests/itest.bndrun
+++ b/itests/org.openhab.binding.tradfri.tests/itest.bndrun
@@ -41,7 +41,6 @@ Fragment-Host: org.openhab.binding.tradfri
org.glassfish.hk2.osgi-resource-locator;version='[1.0.3,1.0.4)',\
biz.aQute.tester.junit-platform;version='[5.3.0,5.3.1)',\
com.google.gson;version='[2.8.6,2.8.7)',\
- org.apache.felix.scr;version='[2.1.26,2.1.27)',\
org.osgi.util.function;version='[1.1.0,1.1.1)',\
org.osgi.util.promise;version='[1.1.1,1.1.2)',\
jakarta.annotation-api;version='[2.0.0,2.0.1)',\
@@ -55,15 +54,7 @@ Fragment-Host: org.openhab.binding.tradfri
tech.units.indriya;version='[2.1.2,2.1.3)',\
uom-lib-common;version='[2.1.0,2.1.1)',\
org.apache.felix.configadmin;version='[1.9.22,1.9.23)',\
- org.eclipse.jetty.http;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.io;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.security;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.server;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.servlet;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.util;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.util.ajax;version='[9.4.40,9.4.41)',\
- org.ops4j.pax.logging.pax-logging-api;version='[2.0.9,2.0.10)',\
- xstream;version='[1.4.17,1.4.18)',\
+ xstream;version='[1.4.18,1.4.19)',\
org.openhab.binding.tradfri;version='[3.2.0,3.2.1)',\
org.openhab.binding.tradfri.tests;version='[3.2.0,3.2.1)',\
org.openhab.core;version='[3.2.0,3.2.1)',\
@@ -76,4 +67,13 @@ Fragment-Host: org.openhab.binding.tradfri
org.openhab.core.io.transport.mdns;version='[3.2.0,3.2.1)',\
org.openhab.core.test;version='[3.2.0,3.2.1)',\
org.openhab.core.thing;version='[3.2.0,3.2.1)',\
- org.openhab.core.thing.xml;version='[3.2.0,3.2.1)'
+ org.openhab.core.thing.xml;version='[3.2.0,3.2.1)',\
+ org.apache.felix.scr;version='[2.1.28,2.1.29)',\
+ org.eclipse.jetty.http;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.io;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.security;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.server;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.servlet;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.util;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.util.ajax;version='[9.4.43,9.4.44)',\
+ org.ops4j.pax.logging.pax-logging-api;version='[2.0.10,2.0.11)'
diff --git a/itests/org.openhab.binding.wemo.tests/itest.bndrun b/itests/org.openhab.binding.wemo.tests/itest.bndrun
index 19b62ccc13a9..0d2772fa73ce 100644
--- a/itests/org.openhab.binding.wemo.tests/itest.bndrun
+++ b/itests/org.openhab.binding.wemo.tests/itest.bndrun
@@ -37,7 +37,6 @@ Fragment-Host: org.openhab.binding.wemo
org.glassfish.hk2.osgi-resource-locator;version='[1.0.3,1.0.4)',\
biz.aQute.tester.junit-platform;version='[5.3.0,5.3.1)',\
com.google.gson;version='[2.8.6,2.8.7)',\
- org.apache.felix.scr;version='[2.1.26,2.1.27)',\
org.osgi.util.function;version='[1.1.0,1.1.1)',\
org.osgi.util.promise;version='[1.1.1,1.1.2)',\
org.objectweb.asm;version='[9.1.0,9.1.1)',\
@@ -56,20 +55,7 @@ Fragment-Host: org.openhab.binding.wemo
org.apache.felix.configadmin;version='[1.9.22,1.9.23)',\
org.apache.xbean.bundleutils;version='[4.19.0,4.19.1)',\
org.apache.xbean.finder;version='[4.19.0,4.19.1)',\
- org.eclipse.jetty.client;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.http;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.io;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.security;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.server;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.servlet;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.util;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.util.ajax;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.websocket.api;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.websocket.client;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.websocket.common;version='[9.4.40,9.4.41)',\
- org.ops4j.pax.logging.pax-logging-api;version='[2.0.9,2.0.10)',\
- org.ops4j.pax.web.pax-web-api;version='[7.3.16,7.3.17)',\
- xstream;version='[1.4.17,1.4.18)',\
+ xstream;version='[1.4.18,1.4.19)',\
org.openhab.binding.wemo;version='[3.2.0,3.2.1)',\
org.openhab.binding.wemo.tests;version='[3.2.0,3.2.1)',\
org.openhab.core;version='[3.2.0,3.2.1)',\
@@ -83,4 +69,18 @@ Fragment-Host: org.openhab.binding.wemo
org.openhab.core.io.transport.upnp;version='[3.2.0,3.2.1)',\
org.openhab.core.test;version='[3.2.0,3.2.1)',\
org.openhab.core.thing;version='[3.2.0,3.2.1)',\
- org.openhab.core.thing.xml;version='[3.2.0,3.2.1)'
+ org.openhab.core.thing.xml;version='[3.2.0,3.2.1)',\
+ org.apache.felix.scr;version='[2.1.28,2.1.29)',\
+ org.eclipse.jetty.client;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.http;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.io;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.security;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.server;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.servlet;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.util;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.util.ajax;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.websocket.api;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.websocket.client;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.websocket.common;version='[9.4.43,9.4.44)',\
+ org.ops4j.pax.logging.pax-logging-api;version='[2.0.10,2.0.11)',\
+ org.ops4j.pax.web.pax-web-api;version='[7.3.19,7.3.20)'
diff --git a/itests/org.openhab.binding.wemo.tests/src/main/java/org/openhab/binding/wemo/internal/handler/test/WemoHandlerTest.java b/itests/org.openhab.binding.wemo.tests/src/main/java/org/openhab/binding/wemo/internal/handler/test/WemoHandlerTest.java
index 144fa25e6232..c317b9dc5e4b 100644
--- a/itests/org.openhab.binding.wemo.tests/src/main/java/org/openhab/binding/wemo/internal/handler/test/WemoHandlerTest.java
+++ b/itests/org.openhab.binding.wemo.tests/src/main/java/org/openhab/binding/wemo/internal/handler/test/WemoHandlerTest.java
@@ -25,6 +25,8 @@
import org.openhab.binding.wemo.internal.http.WemoHttpCall;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.OnOffType;
+import org.openhab.core.library.types.QuantityType;
+import org.openhab.core.library.unit.Units;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingStatus;
import org.openhab.core.thing.ThingStatusDetail;
@@ -122,7 +124,7 @@ public void assertThatChannelTIMESPANIsUpdatedOnReceivedValue() {
@Test
public void assertThatChannelAVERAGEPOWERIsUpdatedOnReceivedValue() {
insightParams.avgPower = POWER_PARAM;
- State expectedStateType = new DecimalType(POWER_PARAM);
+ State expectedStateType = new QuantityType<>(POWER_PARAM, Units.WATT);
String expectedChannel = CHANNEL_AVERAGEPOWER;
testOnValueReceived(expectedChannel, expectedStateType, insightParams.toString());
diff --git a/itests/org.openhab.persistence.mapdb.tests/itest.bndrun b/itests/org.openhab.persistence.mapdb.tests/itest.bndrun
index 9e605e375fc2..548b19f04123 100644
--- a/itests/org.openhab.persistence.mapdb.tests/itest.bndrun
+++ b/itests/org.openhab.persistence.mapdb.tests/itest.bndrun
@@ -32,7 +32,6 @@ Fragment-Host: org.openhab.persistence.mapdb
org.glassfish.hk2.osgi-resource-locator;version='[1.0.3,1.0.4)',\
biz.aQute.tester.junit-platform;version='[5.3.0,5.3.1)',\
com.google.gson;version='[2.8.6,2.8.7)',\
- org.apache.felix.scr;version='[2.1.26,2.1.27)',\
org.osgi.util.function;version='[1.1.0,1.1.1)',\
org.osgi.util.promise;version='[1.1.1,1.1.2)',\
jakarta.annotation-api;version='[2.0.0,2.0.1)',\
@@ -44,17 +43,18 @@ Fragment-Host: org.openhab.persistence.mapdb
si.uom.si-quantity;version='[2.0.1,2.0.2)',\
tech.units.indriya;version='[2.1.2,2.1.3)',\
uom-lib-common;version='[2.1.0,2.1.1)',\
- org.eclipse.jetty.http;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.io;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.security;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.server;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.servlet;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.util;version='[9.4.40,9.4.41)',\
- org.eclipse.jetty.util.ajax;version='[9.4.40,9.4.41)',\
- org.ops4j.pax.logging.pax-logging-api;version='[2.0.9,2.0.10)',\
org.openhab.core;version='[3.2.0,3.2.1)',\
org.openhab.core.config.core;version='[3.2.0,3.2.1)',\
org.openhab.core.persistence;version='[3.2.0,3.2.1)',\
org.openhab.core.test;version='[3.2.0,3.2.1)',\
org.openhab.persistence.mapdb;version='[3.2.0,3.2.1)',\
- org.openhab.persistence.mapdb.tests;version='[3.2.0,3.2.1)'
+ org.openhab.persistence.mapdb.tests;version='[3.2.0,3.2.1)',\
+ org.apache.felix.scr;version='[2.1.28,2.1.29)',\
+ org.eclipse.jetty.http;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.io;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.security;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.server;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.servlet;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.util;version='[9.4.43,9.4.44)',\
+ org.eclipse.jetty.util.ajax;version='[9.4.43,9.4.44)',\
+ org.ops4j.pax.logging.pax-logging-api;version='[2.0.10,2.0.11)'
diff --git a/pom.xml b/pom.xml
index 8f0156153b9e..474015610c73 100644
--- a/pom.xml
+++ b/pom.xml
@@ -73,8 +73,9 @@
3.7.22.2.12.12.3
- 4.3.2
+ 4.3.34.1.63.Final
+ 3.14.90.11.12.0.3