Support refresh command for signalStrength items. (#11944)

Fixes #11942

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

View File

@ -166,6 +166,7 @@ For single shades the refresh takes the item's channel into consideration:
| lowBattery | Battery | | lowBattery | Battery |
| batteryLevel | Battery | | batteryLevel | Battery |
| batteryVoltage | Battery | | batteryVoltage | Battery |
| signalStrength | Survey |
## Full Example ## Full Example

View File

@ -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.ScheduledEvents;
import org.openhab.binding.hdpowerview.internal.api.responses.Shade; 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.Shades;
import org.openhab.binding.hdpowerview.internal.api.responses.Survey;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -46,7 +47,7 @@ import com.google.gson.JsonParser;
* *
* @author Andy Lintner - Initial contribution * @author Andy Lintner - Initial contribution
* @author Andrew Fiddian-Green - Added support for secondary rail positions * @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 @NonNullByDefault
public class HDPowerViewWebTargets { public class HDPowerViewWebTargets {
@ -325,6 +326,25 @@ public class HDPowerViewWebTargets {
return gson.fromJson(json, Shade.class); 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 * 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, * a specific shade's battery level; fetches a JSON package that describes that shade,

View File

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

View File

@ -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.ShadePosition;
import org.openhab.binding.hdpowerview.internal.api.responses.Shade; 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.Shades.ShadeData;
import org.openhab.binding.hdpowerview.internal.api.responses.Survey;
import org.openhab.binding.hdpowerview.internal.config.HDPowerViewShadeConfiguration; import org.openhab.binding.hdpowerview.internal.config.HDPowerViewShadeConfiguration;
import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.OnOffType;
@ -62,6 +63,7 @@ public class HDPowerViewShadeHandler extends AbstractHubbedThingHandler {
private enum RefreshKind { private enum RefreshKind {
POSITION, POSITION,
SURVEY,
BATTERY_LEVEL BATTERY_LEVEL
} }
@ -69,6 +71,7 @@ public class HDPowerViewShadeHandler extends AbstractHubbedThingHandler {
private static final int REFRESH_DELAY_SEC = 10; private static final int REFRESH_DELAY_SEC = 10;
private @Nullable ScheduledFuture<?> refreshPositionFuture = null; private @Nullable ScheduledFuture<?> refreshPositionFuture = null;
private @Nullable ScheduledFuture<?> refreshSignalFuture = null;
private @Nullable ScheduledFuture<?> refreshBatteryLevelFuture = null; private @Nullable ScheduledFuture<?> refreshBatteryLevelFuture = null;
public HDPowerViewShadeHandler(Thing thing) { public HDPowerViewShadeHandler(Thing thing) {
@ -118,6 +121,9 @@ public class HDPowerViewShadeHandler extends AbstractHubbedThingHandler {
case CHANNEL_SHADE_BATTERY_VOLTAGE: case CHANNEL_SHADE_BATTERY_VOLTAGE:
requestRefreshShadeBatteryLevel(); requestRefreshShadeBatteryLevel();
break; break;
case CHANNEL_SHADE_SIGNAL_STRENGTH:
requestRefreshShadeSurvey();
break;
} }
return; 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 * 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; refreshPositionFuture = null;
} }
private void doRefreshShadeSignal() {
this.doRefreshShade(RefreshKind.SURVEY);
refreshSignalFuture = null;
}
private void doRefreshShadeBatteryLevel() { private void doRefreshShadeBatteryLevel() {
this.doRefreshShade(RefreshKind.BATTERY_LEVEL); this.doRefreshShade(RefreshKind.BATTERY_LEVEL);
refreshBatteryLevelFuture = null; refreshBatteryLevelFuture = null;
@ -336,6 +356,14 @@ public class HDPowerViewShadeHandler extends AbstractHubbedThingHandler {
case POSITION: case POSITION:
shade = webTargets.refreshShadePosition(shadeId); shade = webTargets.refreshShadePosition(shadeId);
break; 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: case BATTERY_LEVEL:
shade = webTargets.refreshShadeBatteryLevel(shadeId); shade = webTargets.refreshShadeBatteryLevel(shadeId);
break; break;