Skip to content

Commit

Permalink
[hdpowerview] Add support for scene groups (openhab#11534)
Browse files Browse the repository at this point in the history
* Add support for scene collections.

Fixes openhab#11533

Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>

* Add unit test for parsing of scene collections response.

Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>

* Add default i18n properties file.

Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>

* Fix CAT: File does not end with a newline.

Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>

* Update documentation with scene collections.

Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>

* Fix CAT: File does not end with a newline.

Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>

* Fix formatting.

Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>

* Fix CAT: File does not end with a newline.

Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>

* Split offline tests into separate distinct tests.

Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>

* Increase test coverage for scene/scene collection parsing.

Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>

* Internationalization of dynamic scene/scene collection channels.

Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>

* Rename scene collections to scene groups.

Renamed for all user-oriented texts/references to be consistent with now abandoned feature of the PowerView app.

Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>

* Change custom text keys to not collide with framework.

Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>

* Avoid multiple thing updates.

Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>

* Add missing label/description texts for secondary channel.

Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>

* Remove unneeded @nullable annotations.

Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>
Signed-off-by: Nick Waterton <n.waterton@outlook.com>
  • Loading branch information
jlaur authored and NickWaterton committed Dec 30, 2021
1 parent b9849dd commit 8f9a5ed
Show file tree
Hide file tree
Showing 12 changed files with 420 additions and 96 deletions.
7 changes: 4 additions & 3 deletions bundles/org.openhab.binding.hdpowerview/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,13 @@ However, the configuration parameters are described below:

### Channels for PowerView Hub

Scene channels will be added dynamically to the binding as they are discovered in the hub.
Each scene channel will have an entry in the hub as shown below, whereby different scenes have different `id` values:
Scene and scene group channels will be added dynamically to the binding as they are discovered in the hub.
Each scene/scene group channel will have an entry in the hub as shown below, whereby different scenes/scene groups
have different `id` values:

| Channel | Item Type | Description |
|----------|-----------| ------------|
| id | Switch | Turning this to ON will activate the scene. Scenes are stateless in the PowerView hub; they have no on/off state. Note: include `{autoupdate="false"}` in the item configuration to avoid having to reset it to off after use. |
| id | Switch | Turning this to ON will activate the scene/scene group. Scenes/scene groups are stateless in the PowerView hub; they have no on/off state. Note: include `{autoupdate="false"}` in the item configuration to avoid having to reset it to off after use. |

### Channels for PowerView Shade

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
*
* @author Andy Lintner - Initial contribution
* @author Andrew Fiddian-Green - Added support for secondary rail positions
* @author Jacob Laursen - Add support for scene groups
*/
@NonNullByDefault
public class HDPowerViewBindingConstants {
Expand All @@ -46,6 +47,7 @@ public class HDPowerViewBindingConstants {
public static final String CHANNEL_SHADE_SIGNAL_STRENGTH = "signalStrength";

public static final String CHANNELTYPE_SCENE_ACTIVATE = "scene-activate";
public static final String CHANNELTYPE_SCENE_GROUP_ACTIVATE = "scene-group-activate";

public static final List<String> NETBIOS_NAMES = Arrays.asList("PDBU-Hub3.0", "PowerView-Hub");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,16 @@
import org.openhab.binding.hdpowerview.internal.handler.HDPowerViewHubHandler;
import org.openhab.binding.hdpowerview.internal.handler.HDPowerViewShadeHandler;
import org.openhab.core.config.discovery.DiscoveryService;
import org.openhab.core.i18n.LocaleProvider;
import org.openhab.core.i18n.TranslationProvider;
import org.openhab.core.io.net.http.HttpClientFactory;
import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingTypeUID;
import org.openhab.core.thing.binding.BaseThingHandlerFactory;
import org.openhab.core.thing.binding.ThingHandler;
import org.openhab.core.thing.binding.ThingHandlerFactory;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
Expand All @@ -43,10 +46,16 @@
public class HDPowerViewHandlerFactory extends BaseThingHandlerFactory {

private final HttpClient httpClient;
private final HDPowerViewTranslationProvider translationProvider;

@Activate
public HDPowerViewHandlerFactory(@Reference HttpClientFactory httpClientFactory) {
public HDPowerViewHandlerFactory(@Reference HttpClientFactory httpClientFactory,
final @Reference TranslationProvider i18nProvider, final @Reference LocaleProvider localeProvider,
ComponentContext componentContext) {
super.activate(componentContext);
this.httpClient = httpClientFactory.getCommonHttpClient();
this.translationProvider = new HDPowerViewTranslationProvider(getBundleContext().getBundle(), i18nProvider,
localeProvider);
}

@Override
Expand All @@ -59,7 +68,7 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) {
ThingTypeUID thingTypeUID = thing.getThingTypeUID();

if (thingTypeUID.equals(HDPowerViewBindingConstants.THING_TYPE_HUB)) {
HDPowerViewHubHandler handler = new HDPowerViewHubHandler((Bridge) thing, httpClient);
HDPowerViewHubHandler handler = new HDPowerViewHubHandler((Bridge) thing, httpClient, translationProvider);
registerService(new HDPowerViewShadeDiscoveryService(handler));
return handler;
} else if (thingTypeUID.equals(HDPowerViewBindingConstants.THING_TYPE_SHADE)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* 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;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.i18n.LocaleProvider;
import org.openhab.core.i18n.TranslationProvider;
import org.osgi.framework.Bundle;

/**
* {@link HDPowerViewTranslationProvider} provides i18n message lookup
*
* @author Jacob Laursen - Initial contribution
*/
@NonNullByDefault
public class HDPowerViewTranslationProvider {

private final Bundle bundle;
private final TranslationProvider i18nProvider;
private final LocaleProvider localeProvider;

public HDPowerViewTranslationProvider(Bundle bundle, TranslationProvider i18nProvider,
LocaleProvider localeProvider) {
this.bundle = bundle;
this.i18nProvider = i18nProvider;
this.localeProvider = localeProvider;
}

public String getText(String key, @Nullable Object... arguments) {
String text = i18nProvider.getText(bundle, key, key, localeProvider.getLocale(), arguments);
if (text != null) {
return text;
}
return key;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.openhab.binding.hdpowerview.internal.api.ShadePosition;
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.SceneCollections;
import org.openhab.binding.hdpowerview.internal.api.responses.Scenes;
import org.openhab.binding.hdpowerview.internal.api.responses.Shade;
import org.openhab.binding.hdpowerview.internal.api.responses.Shades;
Expand All @@ -42,6 +43,7 @@
*
* @author Andy Lintner - Initial contribution
* @author Andrew Fiddian-Green - Added support for secondary rail positions
* @author Jacob Laursen - Add support for scene groups
*/
@NonNullByDefault
public class HDPowerViewWebTargets {
Expand All @@ -61,6 +63,8 @@ public class HDPowerViewWebTargets {
private final String shades;
private final String sceneActivate;
private final String scenes;
private final String sceneCollectionActivate;
private final String sceneCollections;

private final Gson gson = new Gson();
private final HttpClient httpClient;
Expand Down Expand Up @@ -101,6 +105,8 @@ public HDPowerViewWebTargets(HttpClient httpClient, String ipAddress) {
shades = base + "shades/";
sceneActivate = base + "scenes";
scenes = base + "scenes/";
sceneCollectionActivate = base + "sceneCollections";
sceneCollections = base + "sceneCollections/";
this.httpClient = httpClient;
}

Expand Down Expand Up @@ -156,6 +162,33 @@ public void activateScene(int sceneId) throws HubProcessingException, HubMainten
invoke(HttpMethod.GET, sceneActivate, Query.of("sceneId", Integer.toString(sceneId)), null);
}

/**
* Fetches a JSON package that describes all scene collections in the hub, and wraps it in
* a SceneCollections class instance
*
* @return SceneCollections 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 SceneCollections getSceneCollections()
throws JsonParseException, HubProcessingException, HubMaintenanceException {
String json = invoke(HttpMethod.GET, sceneCollections, null, null);
return gson.fromJson(json, SceneCollections.class);
}

/**
* Instructs the hub to execute a specific scene collection
*
* @param sceneCollectionId id of the scene collection to be executed
* @throws HubProcessingException if there is any processing error
* @throws HubMaintenanceException if the hub is down for maintenance
*/
public void activateSceneCollection(int sceneCollectionId) throws HubProcessingException, HubMaintenanceException {
invoke(HttpMethod.GET, sceneCollectionActivate,
Query.of("sceneCollectionId", Integer.toString(sceneCollectionId)), null);
}

/**
* Invoke a call on the hub server to retrieve information or send a command
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* 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.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.List;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;

/**
* State of all Scenes in an HD PowerView hub
*
* @author Jacob Laursen - Initial contribution
*/
@NonNullByDefault
public class SceneCollections {

public @Nullable List<SceneCollection> sceneCollectionData;
public @Nullable List<Integer> sceneCollectionIds;

/*
* the following SuppressWarnings annotation is because the Eclipse compiler
* does NOT expect a NonNullByDefault annotation on the inner class, since it is
* implicitly inherited from the outer class, whereas the Maven compiler always
* requires an explicit NonNullByDefault annotation on all classes
*/
@SuppressWarnings("null")
@NonNullByDefault
public static class SceneCollection {
public int id;
public @Nullable String name;
public int order;
public int colorId;
public int iconId;

public String getName() {
return new String(Base64.getDecoder().decode(name), StandardCharsets.UTF_8);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*/
package org.openhab.binding.hdpowerview.internal.api.responses;

import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.List;

Expand Down Expand Up @@ -46,7 +47,7 @@ public static class Scene {
public int iconId;

public String getName() {
return new String(Base64.getDecoder().decode(name));
return new String(Base64.getDecoder().decode(name), StandardCharsets.UTF_8);
}
}
}
Loading

0 comments on commit 8f9a5ed

Please sign in to comment.