Skip to content

Commit

Permalink
Merge branch 'main' into switchbot
Browse files Browse the repository at this point in the history
* main: (43 commits)
  [systeminfo] Upgrade OSHI dependency for latest fixes/improvements (openhab#11274)
  [openweathermap]:  Fix NPE on OneCall-API (#125740) and reduce min refreshInterval to support paid plans (openhab#11255)
  [LuxtronikHeatpump] Adds additional setting for heating limit temperature (openhab#11273)
  [telegram] [influxdb] Update okhttp3 lib (openhab#11130)
  [chamberlainmyq] Added new Close Error and Open Error Switch Items fo… (openhab#11115)
  [mqtt-homeassistant] Refactoring: fixed under_score/CamelCase usages and nullable annotations (openhab#11120)
  [miio] Automatic create experimental support for (unsupported) miot devices (openhab#11149)
  [kodi] Add channel for KODI JSON-RPC call Input.ButtonEvent (openhab#11181)
  Added possiblity to send WOL Requests to configured Hostname, also removed unnecessary unit from Timeout Annotation in WakeOnLanPacketSenderTest (openhab#11199)
  [melcloud] Fix thing type id in documentation
  [melcloud] Fix thing type id in documentation
  [lifx] Support HEV clean cycle (openhab#11262)
  Rename feature.xml in order to exclude it from feature aggregation (openhab#11266)
  [surepetcare] Check for null before updating pet location channels (openhab#11235)
  [miele] Fix multicast and multi-protocol support (ZigBee/Wi-Fi) (openhab#11244)
  Upgrade to Karaf 4.3.3 (openhab#11261)
  [telegram] Add event channels and Answer overload (openhab#9251)
  [homematic] Remove double press events and improve long press events for button trigger (openhab#11186)
  [somfytahoma] Fixed rssi channels creation & properties updating (openhab#11254)
  [hdpowerview] Add Hub configuration option hardRefreshBatteryLevel (openhab#11260)
  ...
  • Loading branch information
alamers committed Sep 20, 2021
2 parents 2e712c7 + 20f8a56 commit d7b1c59
Show file tree
Hide file tree
Showing 250 changed files with 6,961 additions and 2,338 deletions.
11 changes: 9 additions & 2 deletions bom/openhab-addons/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -741,11 +741,13 @@
<artifactId>org.openhab.binding.lifx</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<!-- linky binding suppressed from the distribution until it is fixed
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.linky</artifactId>
<version>${project.version}</version>
</dependency>
</dependency>
-->
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.linuxinput</artifactId>
Expand Down Expand Up @@ -1476,6 +1478,11 @@
<artifactId>org.openhab.binding.tradfri</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.twitter</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.unifi</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion bundles/org.openhab.automation.groovyscripting/README.md
Original file line number Diff line number Diff line change
@@ -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

Expand Down
2 changes: 1 addition & 1 deletion bundles/org.openhab.automation.groovyscripting/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

<properties>
<bnd.importpackage>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</bnd.importpackage>
<groovy.version>3.0.8</groovy.version>
<groovy.version>3.0.9</groovy.version>
</properties>

<dependencies>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@
<bridge-type id="bridge">
<label>BSB-LAN Bridge</label>
<description>A bridge to connect a BSB-LAN device</description>

<config-description>
<parameter-group name="network">
<label>Network Settings</label>
</parameter-group>

<parameter name="host" type="text" required="true" groupName="network">
<context>network-address</context>
<label>Host</label>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,20 @@
</channels>

<config-description>
<parameter-group name="change-requests">
<label>Change Requests</label>
</parameter-group>

<parameter name="id" type="integer" required="true">
<label>Parameter ID</label>
<description>Specific parameter identifier</description>
</parameter>
<parameter name="setId" type="integer" required="false" groupName="Change Requests">
<parameter name="setId" type="integer" required="false" groupName="change-requests">
<label>Parameter Set-ID</label>
<description>Parameter identifier used for change requests. Defaults to the value of Parameter ID</description>
<advanced>true</advanced>
</parameter>
<parameter name="setType" type="text" required="false" groupName="Change Requests">
<parameter name="setType" type="text" required="false" groupName="change-requests">
<label>Message Type</label>
<description>Message type used for change requests. Defaults to SET.</description>
<default>SET</default>
Expand Down
1 change: 1 addition & 0 deletions bundles/org.openhab.binding.doorbird/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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<String> relays = new ArrayList<>();

@SuppressWarnings("null")
Expand All @@ -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));
}
}
}
Expand Down Expand Up @@ -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<String> getRelays() {
return relays;
}

public void addRelay(String relay) {
relays.add(relay);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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"));
Expand All @@ -92,6 +92,6 @@ public void testGetControllerId() {
public void testControllerIdIsNull() {
DoorbirdInfo info = new DoorbirdInfo(infoWithoutControllerId);

assertNull(info.getControllerId());
assertNull(info.getControllerId(null));
}
}
8 changes: 7 additions & 1 deletion bundles/org.openhab.binding.hdpowerview/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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) |

Expand Down Expand Up @@ -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:

```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,22 +234,40 @@ 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
* @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 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
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,5 @@ public class HDPowerViewHubConfiguration {

public long refresh;
public long hardRefresh;
public long hardRefreshBatteryLevel;
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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;
}

Expand Down Expand Up @@ -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();
}

Expand Down Expand Up @@ -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);
}
}

Expand All @@ -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() {
Expand Down Expand Up @@ -304,13 +323,27 @@ private Map<String, Channel> getIdChannelMap() {
return ret;
}

private void requestRefreshShades() {
private void requestRefreshShadePositions() {
Map<Thing, String> thingIdMap = getThingIdMap();
for (Entry<Thing, String> 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<Thing, String> thingIdMap = getThingIdMap();
for (Entry<Thing, String> 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);
Expand Down
Loading

0 comments on commit d7b1c59

Please sign in to comment.