Support refresh command for signalStrength items. ()

Fixes 

Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>
This commit is contained in:
Jacob Laursen 2022-01-03 13:36:36 +01:00 committed by GitHub
parent 4a8fd569f0
commit 5c9da5687c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 101 additions and 1 deletions
bundles/org.openhab.binding.hdpowerview
README.md
src/main/java/org/openhab/binding/hdpowerview/internal

@ -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

@ -33,6 +33,7 @@ import org.openhab.binding.hdpowerview.internal.api.responses.Scenes;
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;
@ -46,7 +47,7 @@ import com.google.gson.JsonParser;
*
* @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 {
@ -325,6 +326,25 @@ public class HDPowerViewWebTargets {
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,

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

@ -31,6 +31,7 @@ import org.openhab.binding.hdpowerview.internal.api.CoordinateSystem;
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;
@ -62,6 +63,7 @@ public class HDPowerViewShadeHandler extends AbstractHubbedThingHandler {
private enum RefreshKind {
POSITION,
SURVEY,
BATTERY_LEVEL
}
@ -69,6 +71,7 @@ public class HDPowerViewShadeHandler extends AbstractHubbedThingHandler {
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) {
@ -118,6 +121,9 @@ public class HDPowerViewShadeHandler extends AbstractHubbedThingHandler {
case CHANNEL_SHADE_BATTERY_VOLTAGE:
requestRefreshShadeBatteryLevel();
break;
case CHANNEL_SHADE_SIGNAL_STRENGTH:
requestRefreshShadeSurvey();
break;
}
return;
}
@ -300,6 +306,15 @@ public class HDPowerViewShadeHandler extends AbstractHubbedThingHandler {
}
}
/**
* 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
*/
@ -315,6 +330,11 @@ public class HDPowerViewShadeHandler extends AbstractHubbedThingHandler {
refreshPositionFuture = null;
}
private void doRefreshShadeSignal() {
this.doRefreshShade(RefreshKind.SURVEY);
refreshSignalFuture = null;
}
private void doRefreshShadeBatteryLevel() {
this.doRefreshShade(RefreshKind.BATTERY_LEVEL);
refreshBatteryLevelFuture = null;
@ -336,6 +356,14 @@ public class HDPowerViewShadeHandler extends AbstractHubbedThingHandler {
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;