Skip to content

Commit

Permalink
Support refresh command for signalStrength items. (openhab#11944)
Browse files Browse the repository at this point in the history
Fixes openhab#11942

Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>
  • Loading branch information
jlaur authored and moesterheld committed Jan 18, 2022
1 parent c9b6541 commit 6aeea9f
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 1 deletion.
1 change: 1 addition & 0 deletions bundles/org.openhab.binding.hdpowerview/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ For single shades the refresh takes the item's channel into consideration:
| lowBattery | Battery |
| batteryLevel | Battery |
| batteryVoltage | Battery |
| signalStrength | Survey |

## Full Example

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.openhab.binding.hdpowerview.internal.api.responses.ScheduledEvents;
import org.openhab.binding.hdpowerview.internal.api.responses.Shade;
import org.openhab.binding.hdpowerview.internal.api.responses.Shades;
import org.openhab.binding.hdpowerview.internal.api.responses.Survey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -46,7 +47,7 @@
*
* @author Andy Lintner - Initial contribution
* @author Andrew Fiddian-Green - Added support for secondary rail positions
* @author Jacob Laursen - Add support for scene groups and automations
* @author Jacob Laursen - Added support for scene groups and automations
*/
@NonNullByDefault
public class HDPowerViewWebTargets {
Expand Down Expand Up @@ -325,6 +326,25 @@ private synchronized String invoke(HttpMethod method, String url, @Nullable Quer
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 survey data, which will also refresh signal strength;
* fetches a JSON package that describes that survey, and wraps it in a Survey
* class instance
*
* @param shadeId id of the shade to be surveyed
* @return Survey 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 Survey getShadeSurvey(int shadeId)
throws JsonParseException, HubProcessingException, HubMaintenanceException {
String json = invoke(HttpMethod.GET, shades + Integer.toString(shadeId),
Query.of("survey", Boolean.toString(true)), null);
return gson.fromJson(json, Survey.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,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/**
* 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.hdpowerview.internal.api.responses;

import java.util.List;
import java.util.StringJoiner;

import com.google.gson.annotations.SerializedName;

/**
* Survey data of a single Shade, as returned by an HD PowerView hub
*
* @author Jacob Laursen - Initial contribution
*/
public class Survey {
@SerializedName("shade_id")
public int shadeId;
@SerializedName("survey")
public List<SurveyData> surveyData;

public static class SurveyData {
@SerializedName("neighbor_id")
public int neighborId;
public int rssi;

@Override
public String toString() {
return String.format("{neighbor id:%d, rssi:%d}", neighborId, rssi);
}
}

@Override
public String toString() {
if (surveyData == null) {
return "{}";
}
StringJoiner joiner = new StringJoiner(", ");
surveyData.forEach(data -> joiner.add(data.toString()));
return joiner.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.openhab.binding.hdpowerview.internal.api.ShadePosition;
import org.openhab.binding.hdpowerview.internal.api.responses.Shade;
import org.openhab.binding.hdpowerview.internal.api.responses.Shades.ShadeData;
import org.openhab.binding.hdpowerview.internal.api.responses.Survey;
import org.openhab.binding.hdpowerview.internal.config.HDPowerViewShadeConfiguration;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.OnOffType;
Expand Down Expand Up @@ -62,13 +63,15 @@ public class HDPowerViewShadeHandler extends AbstractHubbedThingHandler {

private enum RefreshKind {
POSITION,
SURVEY,
BATTERY_LEVEL
}

private final Logger logger = LoggerFactory.getLogger(HDPowerViewShadeHandler.class);

private static final int REFRESH_DELAY_SEC = 10;
private @Nullable ScheduledFuture<?> refreshPositionFuture = null;
private @Nullable ScheduledFuture<?> refreshSignalFuture = null;
private @Nullable ScheduledFuture<?> refreshBatteryLevelFuture = null;

public HDPowerViewShadeHandler(Thing thing) {
Expand Down Expand Up @@ -118,6 +121,9 @@ public void handleCommand(ChannelUID channelUID, Command command) {
case CHANNEL_SHADE_BATTERY_VOLTAGE:
requestRefreshShadeBatteryLevel();
break;
case CHANNEL_SHADE_SIGNAL_STRENGTH:
requestRefreshShadeSurvey();
break;
}
return;
}
Expand Down Expand Up @@ -300,6 +306,15 @@ protected synchronized void requestRefreshShadePosition() {
}
}

/**
* Request that the shade shall undergo a 'hard' refresh for querying its survey data
*/
protected synchronized void requestRefreshShadeSurvey() {
if (refreshSignalFuture == null) {
refreshSignalFuture = scheduler.schedule(this::doRefreshShadeSignal, REFRESH_DELAY_SEC, TimeUnit.SECONDS);
}
}

/**
* Request that the shade shall undergo a 'hard' refresh for querying its battery level state
*/
Expand All @@ -315,6 +330,11 @@ private void doRefreshShadePosition() {
refreshPositionFuture = null;
}

private void doRefreshShadeSignal() {
this.doRefreshShade(RefreshKind.SURVEY);
refreshSignalFuture = null;
}

private void doRefreshShadeBatteryLevel() {
this.doRefreshShade(RefreshKind.BATTERY_LEVEL);
refreshBatteryLevelFuture = null;
Expand All @@ -336,6 +356,14 @@ private void doRefreshShade(RefreshKind kind) {
case POSITION:
shade = webTargets.refreshShadePosition(shadeId);
break;
case SURVEY:
Survey survey = webTargets.getShadeSurvey(shadeId);
if (survey != null && survey.surveyData != null) {
logger.debug("Survey response for shade {}: {}", survey.shadeId, survey.toString());
} else {
logger.warn("No response from shade {} survey", shadeId);
}
return;
case BATTERY_LEVEL:
shade = webTargets.refreshShadeBatteryLevel(shadeId);
break;
Expand Down

0 comments on commit 6aeea9f

Please sign in to comment.