| lowBattery | Battery |
| batteryLevel | Battery |
| batteryVoltage | Battery |
+| signalStrength | Survey |
## Full Example
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;
*
* @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 {
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,
--- /dev/null
+/**
+ * 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();
+ }
+}
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;
private enum RefreshKind {
POSITION,
+ SURVEY,
BATTERY_LEVEL
}
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) {
case CHANNEL_SHADE_BATTERY_VOLTAGE:
requestRefreshShadeBatteryLevel();
break;
+ case CHANNEL_SHADE_SIGNAL_STRENGTH:
+ requestRefreshShadeSurvey();
+ break;
}
return;
}
}
}
+ /**
+ * 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
*/
refreshPositionFuture = null;
}
+ private void doRefreshShadeSignal() {
+ this.doRefreshShade(RefreshKind.SURVEY);
+ refreshSignalFuture = null;
+ }
+
private void doRefreshShadeBatteryLevel() {
this.doRefreshShade(RefreshKind.BATTERY_LEVEL);
refreshBatteryLevelFuture = null;
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;