diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/HDPowerViewBindingConstants.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/HDPowerViewBindingConstants.java index 02c61d907..e680de5d7 100644 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/HDPowerViewBindingConstants.java +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/HDPowerViewBindingConstants.java @@ -65,6 +65,7 @@ public class HDPowerViewBindingConstants { // Hub properties public static final String PROPERTY_FIRMWARE_NAME = "firmwareName"; public static final String PROPERTY_RADIO_FIRMWARE_VERSION = "radioFirmwareVersion"; + public static final String PROPERTY_HUB_NAME = "hubName"; // Shade properties public static final String PROPERTY_SHADE_TYPE = "type"; diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/HDPowerViewWebTargets.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/HDPowerViewWebTargets.java index db2ea2433..f8ba04c15 100644 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/HDPowerViewWebTargets.java +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/HDPowerViewWebTargets.java @@ -28,8 +28,10 @@ import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpStatus; import org.openhab.binding.hdpowerview.internal.api.Color; +import org.openhab.binding.hdpowerview.internal.api.HubFirmware; import org.openhab.binding.hdpowerview.internal.api.ShadePosition; import org.openhab.binding.hdpowerview.internal.api.SurveyData; +import org.openhab.binding.hdpowerview.internal.api.UserData; import org.openhab.binding.hdpowerview.internal.api.requests.RepeaterBlinking; import org.openhab.binding.hdpowerview.internal.api.requests.RepeaterColor; import org.openhab.binding.hdpowerview.internal.api.requests.ShadeCalibrate; @@ -37,7 +39,6 @@ import org.openhab.binding.hdpowerview.internal.api.requests.ShadeJog; import org.openhab.binding.hdpowerview.internal.api.requests.ShadeMove; import org.openhab.binding.hdpowerview.internal.api.requests.ShadeStop; import org.openhab.binding.hdpowerview.internal.api.responses.FirmwareVersion; -import org.openhab.binding.hdpowerview.internal.api.responses.FirmwareVersions; import org.openhab.binding.hdpowerview.internal.api.responses.Repeater; import org.openhab.binding.hdpowerview.internal.api.responses.RepeaterData; import org.openhab.binding.hdpowerview.internal.api.responses.Repeaters; @@ -51,6 +52,7 @@ 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.ShadeData; import org.openhab.binding.hdpowerview.internal.api.responses.Survey; +import org.openhab.binding.hdpowerview.internal.api.responses.UserDataResponse; import org.openhab.binding.hdpowerview.internal.exceptions.HubInvalidResponseException; import org.openhab.binding.hdpowerview.internal.exceptions.HubMaintenanceException; import org.openhab.binding.hdpowerview.internal.exceptions.HubProcessingException; @@ -94,6 +96,7 @@ public class HDPowerViewWebTargets { private final String sceneCollections; private final String scheduledEvents; private final String repeaters; + private final String userData; private final Gson gson = new Gson(); private final HttpClient httpClient; @@ -137,7 +140,7 @@ public class HDPowerViewWebTargets { public HDPowerViewWebTargets(HttpClient httpClient, String ipAddress) { base = "http://" + ipAddress + "/api/"; shades = base + "shades/"; - firmwareVersion = base + "fwversion/"; + firmwareVersion = base + "fwversion"; sceneActivate = base + "scenes"; scenes = base + "scenes/"; @@ -146,8 +149,8 @@ public class HDPowerViewWebTargets { sceneCollections = base + "scenecollections/"; scheduledEvents = base + "scheduledevents"; - repeaters = base + "repeaters/"; + userData = base + "userdata"; this.httpClient = httpClient; } @@ -160,7 +163,7 @@ public class HDPowerViewWebTargets { * @throws HubProcessingException if there is any processing error * @throws HubMaintenanceException if the hub is down for maintenance */ - public FirmwareVersions getFirmwareVersions() + public HubFirmware getFirmwareVersions() throws HubInvalidResponseException, HubProcessingException, HubMaintenanceException { String json = invoke(HttpMethod.GET, firmwareVersion, null, null); try { @@ -168,7 +171,7 @@ public class HDPowerViewWebTargets { if (firmwareVersion == null) { throw new HubInvalidResponseException("Missing firmware response"); } - FirmwareVersions firmwareVersions = firmwareVersion.firmware; + HubFirmware firmwareVersions = firmwareVersion.firmware; if (firmwareVersions == null) { throw new HubInvalidResponseException("Missing 'firmware' element"); } @@ -178,6 +181,31 @@ public class HDPowerViewWebTargets { } } + /** + * Fetches a JSON package with user data information for the hub. + * + * @return {@link UserData} class instance + * @throws HubInvalidResponseException if response is invalid + * @throws HubProcessingException if there is any processing error + * @throws HubMaintenanceException if the hub is down for maintenance + */ + public UserData getUserData() throws HubInvalidResponseException, HubProcessingException, HubMaintenanceException { + String json = invoke(HttpMethod.GET, userData, null, null); + try { + UserDataResponse userDataResponse = gson.fromJson(json, UserDataResponse.class); + if (userDataResponse == null) { + throw new HubInvalidResponseException("Missing userData response"); + } + UserData userData = userDataResponse.userData; + if (userData == null) { + throw new HubInvalidResponseException("Missing 'userData' element"); + } + return userData; + } catch (JsonParseException e) { + throw new HubInvalidResponseException("Error parsing userData response", e); + } + } + /** * Fetches a JSON package that describes all shades in the hub, and wraps it in * a Shades class instance diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/FirmwareVersions.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/HubFirmware.java similarity index 81% rename from bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/FirmwareVersions.java rename to bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/HubFirmware.java index 0e50e3d8f..0a625b2f1 100644 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/FirmwareVersions.java +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/HubFirmware.java @@ -10,11 +10,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.hdpowerview.internal.api.responses; +package org.openhab.binding.hdpowerview.internal.api; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; -import org.openhab.binding.hdpowerview.internal.api.Firmware; /** * Firmware information for an HD PowerView hub @@ -22,7 +21,7 @@ import org.openhab.binding.hdpowerview.internal.api.Firmware; * @author Jacob Laursen - Initial contribution */ @NonNullByDefault -public class FirmwareVersions { +public class HubFirmware { @Nullable public Firmware mainProcessor; @Nullable diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/Times.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/Times.java new file mode 100644 index 000000000..0dbc911bf --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/Times.java @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2010-2022 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; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; + +/** + * Times as part of {@link UserData} for an HD PowerView hub + * + * @author Jacob Laursen - Initial contribution + */ +@NonNullByDefault +public class Times { + public @Nullable String timezone; + public int localSunriseTimeInMinutes; + public int localSunsetTimeInMinutes; + public int currentOffset; + public double longitude; + public double latitude; +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/UserData.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/UserData.java new file mode 100644 index 000000000..70c33a918 --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/UserData.java @@ -0,0 +1,58 @@ +/** + * Copyright (c) 2010-2022 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; + +import java.util.Base64; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; + +import com.google.gson.annotations.SerializedName; + +/** + * User data for an HD PowerView hub + * + * @author Jacob Laursen - Initial contribution + */ +@NonNullByDefault +public class UserData { + public @Nullable String hubName; + public boolean localTimeDataSet; + public boolean enableScheduledEvents; + public boolean editingEnabled; + public boolean setupCompleted; + public @Nullable String gateway; + public @Nullable String dns; + public boolean staticIp; + @SerializedName("_id") + public @Nullable String id; + public @Nullable Color color; + public boolean autoBackup; + public @Nullable String ip; + public @Nullable String macAddress; + public @Nullable String mask; + public boolean wireless; + public @Nullable HubFirmware firmware; + public @Nullable String serialNumber; + public @Nullable String rfIDInt; + public @Nullable String rfID; + public int rfStatus; + public @Nullable Times times; + public @Nullable String brand; + public boolean rcUp; + public boolean remoteConnectEnabled; + + public String getHubName() { + return hubName != null ? new String(Base64.getDecoder().decode(hubName)) : ""; + } +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/FirmwareVersion.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/FirmwareVersion.java index ecbb39ccd..d046f06a8 100644 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/FirmwareVersion.java +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/FirmwareVersion.java @@ -14,6 +14,7 @@ package org.openhab.binding.hdpowerview.internal.api.responses; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; +import org.openhab.binding.hdpowerview.internal.api.HubFirmware; /** * Firmware information for an HD PowerView hub @@ -23,5 +24,5 @@ import org.eclipse.jdt.annotation.Nullable; @NonNullByDefault public class FirmwareVersion { @Nullable - public FirmwareVersions firmware; + public HubFirmware firmware; } diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/UserDataResponse.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/UserDataResponse.java new file mode 100644 index 000000000..3509ffdb8 --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/UserDataResponse.java @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2010-2022 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 org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.openhab.binding.hdpowerview.internal.api.UserData; + +/** + * Response with {@link UserData} for an HD PowerView hub + * + * @author Jacob Laursen - Initial contribution + */ +@NonNullByDefault +public class UserDataResponse { + public @Nullable UserData userData; +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewHubHandler.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewHubHandler.java index df0f9e950..37020492e 100644 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewHubHandler.java +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewHubHandler.java @@ -31,7 +31,8 @@ import org.openhab.binding.hdpowerview.internal.HDPowerViewBindingConstants; import org.openhab.binding.hdpowerview.internal.HDPowerViewTranslationProvider; import org.openhab.binding.hdpowerview.internal.HDPowerViewWebTargets; import org.openhab.binding.hdpowerview.internal.api.Firmware; -import org.openhab.binding.hdpowerview.internal.api.responses.FirmwareVersions; +import org.openhab.binding.hdpowerview.internal.api.HubFirmware; +import org.openhab.binding.hdpowerview.internal.api.UserData; import org.openhab.binding.hdpowerview.internal.api.responses.SceneCollections; import org.openhab.binding.hdpowerview.internal.api.responses.SceneCollections.SceneCollection; import org.openhab.binding.hdpowerview.internal.api.responses.Scenes; @@ -98,7 +99,7 @@ public class HDPowerViewHubHandler extends BaseBridgeHandler { private List sceneCache = new CopyOnWriteArrayList<>(); private List sceneCollectionCache = new CopyOnWriteArrayList<>(); private List scheduledEventCache = new CopyOnWriteArrayList<>(); - private Instant firmwareVersionsUpdated = Instant.MIN; + private Instant UserDataUpdated = Instant.MIN; private Boolean deprecatedChannelsCreated = false; private final ChannelTypeUID sceneChannelTypeUID = new ChannelTypeUID(HDPowerViewBindingConstants.BINDING_ID, @@ -144,7 +145,7 @@ public class HDPowerViewHubHandler extends BaseBridgeHandler { } } catch (HubMaintenanceException e) { // exceptions are logged in HDPowerViewWebTargets - firmwareVersionsUpdated = Instant.MIN; + UserDataUpdated = Instant.MIN; } catch (NumberFormatException | HubException e) { logger.debug("Unexpected error {}", e.getMessage()); } @@ -168,7 +169,7 @@ public class HDPowerViewHubHandler extends BaseBridgeHandler { hardRefreshPositionInterval = config.hardRefresh; hardRefreshBatteryLevelInterval = config.hardRefreshBatteryLevel; initializeChannels(); - firmwareVersionsUpdated = Instant.MIN; + UserDataUpdated = Instant.MIN; updateStatus(ThingStatus.UNKNOWN); schedulePoll(); @@ -283,7 +284,7 @@ public class HDPowerViewHubHandler extends BaseBridgeHandler { private synchronized void poll() { try { - updateFirmwareProperties(); + updateUserDataProperties(); } catch (HubException e) { logger.warn("Failed to update firmware properties: {}", e.getMessage()); } @@ -308,27 +309,49 @@ public class HDPowerViewHubHandler extends BaseBridgeHandler { } } catch (HubMaintenanceException e) { // exceptions are logged in HDPowerViewWebTargets - firmwareVersionsUpdated = Instant.MIN; + UserDataUpdated = Instant.MIN; } catch (HubException e) { logger.warn("Error connecting to bridge: {}", e.getMessage()); updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage()); - firmwareVersionsUpdated = Instant.MIN; + UserDataUpdated = Instant.MIN; } } - private void updateFirmwareProperties() + private void updateUserDataProperties() throws HubInvalidResponseException, HubProcessingException, HubMaintenanceException { - if (firmwareVersionsUpdated.isAfter(Instant.now().minus(firmwareVersionValidityPeriod))) { + if (UserDataUpdated.isAfter(Instant.now().minus(firmwareVersionValidityPeriod))) { return; } - FirmwareVersions firmwareVersions = webTargets.getFirmwareVersions(); + + UserData userData = webTargets.getUserData(); + Map properties = editProperties(); + HubFirmware firmwareVersions = userData.firmware; + if (firmwareVersions != null) { + updateFirmwareProperties(properties, firmwareVersions); + } + String serialNumber = userData.serialNumber; + if (serialNumber != null) { + properties.put(Thing.PROPERTY_SERIAL_NUMBER, serialNumber); + } + String macAddress = userData.macAddress; + if (macAddress != null) { + properties.put(Thing.PROPERTY_MAC_ADDRESS, macAddress); + } + String hubName = userData.getHubName(); + if (!hubName.isEmpty()) { + properties.put(HDPowerViewBindingConstants.PROPERTY_HUB_NAME, hubName); + } + updateProperties(properties); + UserDataUpdated = Instant.now(); + } + + private void updateFirmwareProperties(Map properties, HubFirmware firmwareVersions) { Firmware mainProcessor = firmwareVersions.mainProcessor; if (mainProcessor == null) { logger.warn("Main processor firmware version missing in response."); return; } logger.debug("Main processor firmware version received: {}, {}", mainProcessor.name, mainProcessor.toString()); - Map properties = editProperties(); String mainProcessorName = mainProcessor.name; if (mainProcessorName != null) { properties.put(HDPowerViewBindingConstants.PROPERTY_FIRMWARE_NAME, mainProcessorName); @@ -339,8 +362,6 @@ public class HDPowerViewHubHandler extends BaseBridgeHandler { logger.debug("Radio firmware version received: {}", radio.toString()); properties.put(HDPowerViewBindingConstants.PROPERTY_RADIO_FIRMWARE_VERSION, radio.toString()); } - updateProperties(properties); - firmwareVersionsUpdated = Instant.now(); } private void pollShades() throws HubInvalidResponseException, HubProcessingException, HubMaintenanceException {