Skip to content

Commit

Permalink
[hue] Implement CLIP 2 / API v2 (openhab#13570)
Browse files Browse the repository at this point in the history
* [hue] Implement CLIP 2 / API v2

---------

Signed-off-by: Andrew Fiddian-Green <[email protected]>
Signed-off-by: Matt Myers <[email protected]>
  • Loading branch information
andrewfg authored and matchews committed Aug 9, 2023
1 parent 9b388e8 commit 844c173
Show file tree
Hide file tree
Showing 98 changed files with 23,869 additions and 421 deletions.
2 changes: 1 addition & 1 deletion CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@
/bundles/org.openhab.binding.homewizard/ @Daniel-42
/bundles/org.openhab.binding.hpprinter/ @cossey
/bundles/org.openhab.binding.http/ @openhab/add-ons-maintainers
/bundles/org.openhab.binding.hue/ @cweitkamp
/bundles/org.openhab.binding.hue/ @cweitkamp @andrewfg
/bundles/org.openhab.binding.hydrawise/ @digitaldan
/bundles/org.openhab.binding.hyperion/ @tavalin
/bundles/org.openhab.binding.iammeter/ @lewei50
Expand Down
382 changes: 54 additions & 328 deletions bundles/org.openhab.binding.hue/README.md

Large diffs are not rendered by default.

Binary file added bundles/org.openhab.binding.hue/doc/hue2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
358 changes: 358 additions & 0 deletions bundles/org.openhab.binding.hue/doc/readme_v1.md

Large diffs are not rendered by default.

237 changes: 237 additions & 0 deletions bundles/org.openhab.binding.hue/doc/readme_v2.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
*/
package org.openhab.binding.hue.internal;

import java.util.Map;
import java.util.Set;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.core.thing.ThingTypeUID;

Expand Down Expand Up @@ -53,9 +56,14 @@ public class HueBindingConstants {
public static final ThingTypeUID THING_TYPE_GEOFENCE_SENSOR = new ThingTypeUID(BINDING_ID, "geofencesensor");
public static final ThingTypeUID THING_TYPE_TEMPERATURE_SENSOR = new ThingTypeUID(BINDING_ID, "0302");
public static final ThingTypeUID THING_TYPE_LIGHT_LEVEL_SENSOR = new ThingTypeUID(BINDING_ID, "0106");

public static final ThingTypeUID THING_TYPE_GROUP = new ThingTypeUID(BINDING_ID, "group");

public static final Set<ThingTypeUID> V1_THING_TYPE_UIDS = Set.of(THING_TYPE_COLOR_LIGHT,
THING_TYPE_COLOR_TEMPERATURE_LIGHT, THING_TYPE_DIMMABLE_LIGHT, THING_TYPE_EXTENDED_COLOR_LIGHT,
THING_TYPE_ON_OFF_LIGHT, THING_TYPE_ON_OFF_PLUG, THING_TYPE_DIMMABLE_PLUG, THING_TYPE_DIMMER_SWITCH,
THING_TYPE_TAP_SWITCH, THING_TYPE_PRESENCE_SENSOR, THING_TYPE_TEMPERATURE_SENSOR,
THING_TYPE_LIGHT_LEVEL_SENSOR, THING_TYPE_GROUP);

// List all channels
public static final String CHANNEL_COLORTEMPERATURE = "color_temperature";
public static final String CHANNEL_COLORTEMPERATURE_ABS = "color_temperature_abs";
Expand Down Expand Up @@ -96,11 +104,25 @@ public class HueBindingConstants {
// Thing configuration properties
public static final String LIGHT_ID = "lightId";
public static final String SENSOR_ID = "sensorId";
public static final String PRODUCT_NAME = "productName";
public static final String PROPERTY_PRODUCT_NAME = "productName";
public static final String UNIQUE_ID = "uniqueId";
public static final String FADETIME = "fadetime";
public static final String GROUP_ID = "groupId";

// property names for API v2
public static final String PROPERTY_RESOURCE_ID = "resourceId";
public static final String PROPERTY_RESOURCE_TYPE = "resourceType";
public static final String PROPERTY_RESOURCE_NAME = "resourceName";
public static final String PROPERTY_RESOURCE_ARCHETYPE = "resourceArchetype";
public static final String PROPERTY_PRODUCT_ARCHETYPE = "productArchetype";
public static final String PROPERTY_PRODUCT_CERTIFIED = "productCertified";
public static final String PROPERTY_LEGACY_THING_UID = "legacyThingUID";
public static final String PROPERTY_OWNER = "owner";
public static final String PROPERTY_OWNER_TYPE = "ownerType";
public static final String PROPERTY_DIMMING_RANGE = "dimmingRange";
public static final String PROPERTY_COLOR_TEMP_RANGE = "colorTemperatureRange";
public static final String PROPERTY_COLOR_GAMUT = "colorGamut";

public static final String NORMALIZE_ID_REGEX = "[^a-zA-Z0-9_]";

public static final String DISCOVERY_LABEL_PATTERN = "Philips Hue (%s)";
Expand All @@ -111,4 +133,60 @@ public class HueBindingConstants {

// Config status messages
public static final String IP_ADDRESS_MISSING = "missing-ip-address-configuration";

// thing types for API v2
public static final ThingTypeUID THING_TYPE_BRIDGE_API2 = new ThingTypeUID(BINDING_ID, "bridge-api2");
public static final ThingTypeUID THING_TYPE_DEVICE = new ThingTypeUID(BINDING_ID, "device");
public static final ThingTypeUID THING_TYPE_ZONE = new ThingTypeUID(BINDING_ID, "zone");
public static final ThingTypeUID THING_TYPE_ROOM = new ThingTypeUID(BINDING_ID, "room");

// channels for API v2
public static final String CHANNEL_2_COLOR = CHANNEL_COLOR;
public static final String CHANNEL_2_COLOR_TEMP_PERCENT = "color-temperature";
public static final String CHANNEL_2_COLOR_TEMP_ABSOLUTE = "color-temperature-abs";
public static final String CHANNEL_2_BRIGHTNESS = CHANNEL_BRIGHTNESS;
public static final String CHANNEL_2_SWITCH = CHANNEL_SWITCH;
public static final String CHANNEL_2_SCENE = CHANNEL_SCENE;
public static final String CHANNEL_2_DYNAMICS = "dynamics";
public static final String CHANNEL_2_ALERT = CHANNEL_ALERT;
public static final String CHANNEL_2_EFFECT = CHANNEL_EFFECT;
public static final String CHANNEL_2_BUTTON_LAST_EVENT = "button-last-event";
public static final String CHANNEL_2_ROTARY_STEPS = "rotary-steps";
public static final String CHANNEL_2_MOTION = "motion";
public static final String CHANNEL_2_MOTION_ENABLED = "motion-enabled";
public static final String CHANNEL_2_LIGHT_LEVEL = "light-level";
public static final String CHANNEL_2_LIGHT_LEVEL_ENABLED = "light-level-enabled";
public static final String CHANNEL_2_TEMPERATURE = CHANNEL_TEMPERATURE;
public static final String CHANNEL_2_TEMPERATURE_ENABLED = "temperature-enabled";
public static final String CHANNEL_2_BATTERY_LEVEL = "battery-level";
public static final String CHANNEL_2_BATTERY_LOW = "battery-low";
public static final String CHANNEL_2_LAST_UPDATED = "last-updated";
public static final String CHANNEL_2_COLOR_XY_ONLY = "color-xy-only";
public static final String CHANNEL_2_DIMMING_ONLY = "dimming-only";
public static final String CHANNEL_2_ON_OFF_ONLY = "on-off-only";

// channel IDs that (optionally) support dynamics
public static final Set<String> DYNAMIC_CHANNELS = Set.of(CHANNEL_2_BRIGHTNESS, CHANNEL_2_COLOR,
CHANNEL_2_COLOR_TEMP_PERCENT, CHANNEL_2_COLOR_TEMP_ABSOLUTE, CHANNEL_2_SCENE);

/*
* Map of API v1 channel IDs against API v2 channel IDs where, if the v1 channel exists in the system, then we
* should try to replicate the channel/item links from the v1 channel into the respective v2 channel.
*/
public static final Map<String, String> REPLICATE_CHANNEL_ID_MAP = Map.ofEntries(
Map.entry(CHANNEL_BRIGHTNESS, CHANNEL_2_BRIGHTNESS), //
Map.entry(CHANNEL_COLOR, CHANNEL_2_COLOR), //
Map.entry(CHANNEL_SWITCH, CHANNEL_2_SWITCH), //
Map.entry(CHANNEL_SCENE, CHANNEL_2_SCENE), //
Map.entry(CHANNEL_COLORTEMPERATURE, CHANNEL_2_COLOR_TEMP_PERCENT), //
Map.entry(CHANNEL_COLORTEMPERATURE_ABS, CHANNEL_2_COLOR_TEMP_ABSOLUTE), //
Map.entry(CHANNEL_DIMMER_SWITCH, CHANNEL_2_BUTTON_LAST_EVENT), //
Map.entry(CHANNEL_LIGHT_LEVEL, CHANNEL_2_LIGHT_LEVEL), //
Map.entry(CHANNEL_PRESENCE, CHANNEL_2_MOTION), //
Map.entry(CHANNEL_TEMPERATURE, CHANNEL_2_TEMPERATURE), //
Map.entry(CHANNEL_BATTERY_LEVEL, CHANNEL_2_BATTERY_LEVEL), //
Map.entry(CHANNEL_BATTERY_LOW, CHANNEL_2_BATTERY_LOW), //
Map.entry(CHANNEL_LAST_UPDATED, CHANNEL_2_LAST_UPDATED));

public static final String ALL_LIGHTS_KEY = "discovery.group.all-lights.label";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/**
* Copyright (c) 2010-2023 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.hue.internal.action;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.hue.internal.handler.Clip2ThingHandler;
import org.openhab.core.automation.annotation.ActionInput;
import org.openhab.core.automation.annotation.RuleAction;
import org.openhab.core.library.types.QuantityType;
import org.openhab.core.library.unit.MetricPrefix;
import org.openhab.core.library.unit.Units;
import org.openhab.core.thing.binding.ThingActions;
import org.openhab.core.thing.binding.ThingActionsScope;
import org.openhab.core.thing.binding.ThingHandler;
import org.openhab.core.types.Command;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Implementation of the {@link ThingActions} interface used for sending 'dynamics' commands to Hue API v2 devices,
* rooms or zones.
*
* @author Andrew Fiddian-Green - Initial contribution
*/
@ThingActionsScope(name = "hue")
@NonNullByDefault
public class DynamicsActions implements ThingActions {

private final Logger logger = LoggerFactory.getLogger(DynamicsActions.class);

private @Nullable Clip2ThingHandler handler;

public static void dynamicCommand(ThingActions actions, @Nullable String channelId, @Nullable Command command,
@Nullable Long durationMs) {
((DynamicsActions) actions).dynamicCommand(channelId, command, durationMs);
}

@RuleAction(label = "@text/dynamics.action.label", description = "@text/dynamics.action.description")
public void dynamicCommand(
@ActionInput(name = "channelId", label = "@text/dynamics.channel.label", description = "@text/dynamics.channel.description") @Nullable String channelId,
@ActionInput(name = "command", label = "@text/dynamics.command.label", description = "@text/dynamics.command.description") @Nullable Command command,
@ActionInput(name = "durationMs", label = "@text/dynamics.duration.label", description = "@text/dynamics.duration.description") @Nullable Long durationMs) {
//
Clip2ThingHandler handler = this.handler;
if (handler == null) {
logger.warn("ThingHandler is null.");
return;
}
if (channelId == null) {
logger.debug("Channel ID is null.");
return;
}
if (command == null) {
logger.debug("Command is null.");
return;
}
if (durationMs == null || durationMs.longValue() <= 0) {
logger.debug("Duration is null, zero or negative.");
return;
}
handler.handleDynamicsCommand(channelId, command,
new QuantityType<>(durationMs.longValue(), MetricPrefix.MILLI(Units.SECOND)));
logger.debug("Dynamic command '{}' sent to channelId '{}' with duration {}ms.", command, channelId, durationMs);
}

@Override
public @Nullable ThingHandler getThingHandler() {
return handler;
}

@Override
public void setThingHandler(@Nullable ThingHandler handler) {
this.handler = (Clip2ThingHandler) handler;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* Copyright (c) 2010-2023 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.hue.internal.config;

import org.eclipse.jdt.annotation.NonNullByDefault;

/**
* Configuration for the Clip2BridgeHandler.
*
* @author Andrew Fiddian-Green - Initial contribution
*/
@NonNullByDefault
public class Clip2BridgeConfig {
public static final String APPLICATION_KEY = "applicationKey";

public String ipAddress = "";
public String applicationKey = "";
public int checkMinutes = 60;
public boolean useSelfSignedCertificate = true;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* Copyright (c) 2010-2023 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.hue.internal.config;

import org.eclipse.jdt.annotation.NonNullByDefault;

/**
* Configuration for CLIP V2 things.
*
* @author Andrew Fiddian-Green - Initial contribution
*/
@NonNullByDefault
public class Clip2ThingConfig {
public String resourceId = "";
}
Loading

0 comments on commit 844c173

Please sign in to comment.