--- /dev/null
+/**
+ * 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.api.dto.clip1;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Represents the version of the API of the form 1.0 or 1.2.1
+ *
+ * @author Samuel Leisering - Initial contribution
+ */
+public class ApiVersion {
+ private final int major;
+ private final int minor;
+ private final int micro;
+
+ private static final Pattern VERSION_PATTERN = Pattern.compile("^([0-9]+)\\.([0-9]+)(\\.([0-9]+))?$");
+
+ public ApiVersion(int major, int minor, int micro) {
+ this.major = major;
+ this.minor = minor;
+ this.micro = micro;
+ }
+
+ public static ApiVersion of(String version) {
+ Matcher matcher = VERSION_PATTERN.matcher(version);
+ if (matcher.matches()) {
+ int major = Integer.parseInt(matcher.group(1));
+ int minor = Integer.parseInt(matcher.group(2));
+ String microString = matcher.group(4);
+ int micro = Integer.parseInt(microString == null ? "0" : microString);
+
+ return new ApiVersion(major, minor, micro);
+ }
+
+ throw new IllegalArgumentException("Version \"" + version + "\" is not valid");
+ }
+
+ /**
+ * returns the major version part of the version
+ *
+ * @return the major part of the version
+ */
+ public int getMajor() {
+ return major;
+ }
+
+ /**
+ * returns the minor version part of the version
+ *
+ * @return the minor part of the version
+ */
+ public int getMinor() {
+ return minor;
+ }
+
+ /**
+ * returns the micro version part of the version
+ *
+ * @return the micro part of the version
+ */
+ public int getMicro() {
+ return micro;
+ }
+
+ /**
+ * compare API versions according to {@link java.util.Comparator#compare(Object, Object)}
+ *
+ * @param other
+ * @return
+ */
+ public int compare(ApiVersion other) {
+ int c = Integer.compare(major, other.major);
+ if (c == 0) {
+ c = Integer.compare(minor, other.minor);
+ if (c == 0) {
+ c = Integer.compare(micro, other.micro);
+ }
+ }
+ return c;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + major;
+ result = prime * result + micro;
+ result = prime * result + minor;
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ ApiVersion other = (ApiVersion) obj;
+ if (major != other.major) {
+ return false;
+ }
+ if (micro != other.micro) {
+ return false;
+ }
+ return minor == other.minor;
+ }
+
+ @Override
+ public String toString() {
+ return major + "." + minor + "." + micro;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip1;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * @author Samuel Leisering - Initial contribution
+ */
+@NonNullByDefault
+public final class ApiVersionUtils {
+
+ private static final ApiVersion FULL_LIGHTS = new ApiVersion(1, 11, 0);
+
+ ApiVersionUtils() {
+ }
+
+ /**
+ * Starting from version 1.11, <code>GET</code>ing the Lights always returns {@link FullLight}s instead of
+ * {@link HueObject}s.
+ *
+ * @return
+ */
+ public static boolean supportsFullLights(ApiVersion version) {
+ return FULL_LIGHTS.compare(version) <= 0;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip1;
+
+/**
+ * Collection of updates to the bridge configuration.
+ *
+ * @author Q42 - Initial contribution
+ * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding, minor code cleanup
+ * @author Samuel Leisering - added Sensor support
+ */
+public class BridgeConfigUpdate extends ConfigUpdate {
+ /**
+ * Set the port of the proxy or null if there is no proxy.
+ *
+ * @param port port for proxy
+ * @return this object for chaining calls
+ */
+ public BridgeConfigUpdate setProxyPort(Integer port) {
+ if (port != null && port < 0) {
+ throw new IllegalArgumentException("Invalid value for port");
+ }
+
+ commands.add(new Command("proxyport", port == null ? 0 : port));
+ return this;
+ }
+
+ /**
+ * Set the name of the bridge, which also functions as the UPnP name.
+ *
+ * @param name new name [4..16]
+ * @return this object for chaining calls
+ */
+ public BridgeConfigUpdate setName(String name) {
+ if (Util.stringSize(name) < 4 || Util.stringSize(name) > 16) {
+ throw new IllegalArgumentException("Bridge name must be between 4 and 16 characters long");
+ }
+
+ commands.add(new Command("name", name));
+ return this;
+ }
+
+ /**
+ * Set the address of the proxy or null if there is no proxy.
+ *
+ * @param ip ip of proxy
+ * @return this object for chaining calls
+ */
+ public BridgeConfigUpdate setProxyAddress(String ip) {
+ if (ip != null && Util.stringSize(ip) > 40) {
+ throw new IllegalArgumentException("Bridge proxy address can be at most 40 characters long");
+ }
+
+ commands.add(new Command("proxyaddress", ip == null ? "none" : ip));
+ return this;
+ }
+
+ /**
+ * Set whether the link button has been pressed within the last 30 seconds or not.
+ *
+ * @param pressed true for pressed, false for not pressed
+ * @return this object for chaining calls
+ */
+ public BridgeConfigUpdate setLinkButton(boolean pressed) {
+ commands.add(new Command("linkbutton", pressed));
+ return this;
+ }
+
+ /**
+ * Set the IP address of the bridge.
+ *
+ * @param ip ip address of bridge
+ * @return this object for chaining calls
+ */
+ public BridgeConfigUpdate setIPAddress(String ip) {
+ commands.add(new Command("ipaddress", ip));
+ return this;
+ }
+
+ /**
+ * Set the network mask of the bridge.
+ *
+ * @param netmask network mask
+ * @return this object for chaining calls
+ */
+ public BridgeConfigUpdate setNetworkMask(String netmask) {
+ commands.add(new Command("netmask", netmask));
+ return this;
+ }
+
+ /**
+ * Set the gateway address of the bridge.
+ *
+ * @param ip gateway address
+ * @return this object for chaining calls
+ */
+ public BridgeConfigUpdate setGateway(String ip) {
+ commands.add(new Command("gateway", ip));
+ return this;
+ }
+
+ /**
+ * Set whether the bridge uses DHCP to get an ip address or not.
+ *
+ * @param enabled dhcp enabled
+ * @return this object for chaining calls
+ */
+ public BridgeConfigUpdate setDHCP(boolean enabled) {
+ commands.add(new Command("dhcp", enabled));
+ return this;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip1;
+
+/**
+ * Collection of capabilities for lights.
+ *
+ * @author Christoph Weitkamp - Initial contribution
+ */
+public class Capabilities {
+ public Control control;
+}
--- /dev/null
+/**
+ * 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.api.dto.clip1;
+
+/**
+ * Collection of color temperature capabilities to control lights.
+ *
+ * @author Christoph Weitkamp - Initial contribution
+ */
+public class ColorTemperature {
+ public int max = 500;
+ public int min = 153;
+}
--- /dev/null
+/**
+ * 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.api.dto.clip1;
+
+import com.google.gson.Gson;
+
+/**
+ *
+ * @author Q42 - Initial contribution
+ * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding
+ * @author Samuel Leisering - changed Command visibility to public
+ */
+public class Command {
+ public String key;
+ public Object value;
+
+ public Command(String key, Object value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ String toJson() {
+ return "\"" + key + "\":" + new Gson().toJson(value);
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip1;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * Detailed bridge info available if authenticated.
+ *
+ * @author Q42 - Initial contribution
+ * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding, minor code cleanup
+ * @author Samuel Leisering - added API-Version
+ */
+public class Config {
+ private String name;
+ private String swversion;
+ private String apiversion;
+ private String bridgeid;
+ private String mac;
+ private String modelid;
+ private boolean dhcp;
+ private String ipaddress;
+ private String netmask;
+ private String gateway;
+ private String proxyaddress;
+ private int proxyport;
+ @SerializedName("UTC")
+ private Date utc;
+ private boolean linkbutton;
+ private Map<String, User> whitelist;
+ private SoftwareUpdate swupdate;
+
+ Config() {
+ }
+
+ /**
+ * Returns the name.
+ *
+ * @return name of the bridge
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Returns the version of the software.
+ *
+ * @return version of software on the bridge
+ */
+ public String getSoftwareVersion() {
+ return swversion;
+ }
+
+ /**
+ * Returns the bridge id
+ *
+ * @return bridge id
+ */
+ public String getBridgeId() {
+ return bridgeid;
+ }
+
+ /**
+ * Returns the MAC address.
+ *
+ * @return mac address of bridge
+ */
+ public String getMACAddress() {
+ return mac;
+ }
+
+ /**
+ * Returns the model id
+ *
+ * @return model id
+ */
+ public String getModelId() {
+ return modelid;
+ }
+
+ /**
+ * Returns if the current IP address was obtained with DHCP.
+ *
+ * @return true if the current IP address was obtained with DHCP, false otherwise.
+ */
+ public boolean isDHCPEnabled() {
+ return dhcp;
+ }
+
+ /**
+ * Returns the IP address.
+ *
+ * @return ip address of bridge
+ */
+ public String getIPAddress() {
+ return ipaddress;
+ }
+
+ /**
+ * Returns the network mask.
+ *
+ * @return network mask
+ */
+ public String getNetworkMask() {
+ return netmask;
+ }
+
+ /**
+ * Returns the IP address of the gateway.
+ *
+ * @return ip address of gateway
+ */
+ public String getGateway() {
+ return gateway;
+ }
+
+ /**
+ * Returns the IP address of the proxy or null if there is none.
+ *
+ * @return ip address of proxy or null
+ */
+ public String getProxyAddress() {
+ return "none".equals(proxyaddress) ? null : proxyaddress;
+ }
+
+ /**
+ * Returns the port of the proxy or null if there is none.
+ *
+ * @return port of proxy or null
+ */
+ public Integer getProxyPort() {
+ return "none".equals(proxyaddress) ? null : proxyport;
+ }
+
+ /**
+ * Returns the time on the bridge.
+ *
+ * @return time on the bridge
+ */
+ public Date getUTCTime() {
+ return utc;
+ }
+
+ /**
+ * Returns if the link button has been pressed within the last 30 seconds.
+ *
+ * @return true if the link button has been pressed within the last 30 seconds, false otherwise
+ */
+ public boolean isLinkButtonPressed() {
+ return linkbutton;
+ }
+
+ /**
+ * Returns the list of whitelisted users.
+ *
+ * @return list of whitelisted users
+ */
+ public List<User> getWhitelist() {
+ ArrayList<User> usersList = new ArrayList<>();
+
+ usersList.addAll(whitelist.values());
+
+ return usersList;
+ }
+
+ /**
+ * Returns information about a bridge firmware update.
+ *
+ * @return bridge firmware update info
+ */
+ public SoftwareUpdate getSoftwareUpdate() {
+ return swupdate;
+ }
+
+ /**
+ * Returns the current API-Version of the Bridge. This always returns <code>1.0</code>
+ * for bridges with version less than <code>1.2.1</code>, which introduces this call.
+ *
+ * @return
+ */
+ public String getApiVersion() {
+ if (apiversion == null) {
+ return "1.0";
+ }
+ return apiversion;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip1;
+
+import static java.util.stream.Collectors.joining;
+
+import java.util.ArrayList;
+
+/**
+ * Collection of updates
+ *
+ * @author Q42 - Initial contribution
+ * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding, minor code cleanup
+ * @author Samuel Leisering - Added support for sensor API
+ * @author Christoph Weitkamp - Added support for sensor API
+ */
+public class ConfigUpdate {
+
+ public final ArrayList<Command> commands = new ArrayList<>();
+
+ public ConfigUpdate() {
+ super();
+ }
+
+ public boolean isEmpty() {
+ return commands.isEmpty();
+ }
+
+ public String toJson() {
+ return commands.stream().map(c -> c.toJson()).collect(joining(",", "{", "}"));
+ }
+
+ /**
+ * Returns the message delay recommended by Philips
+ * Regarding to this article: https://developers.meethue.com/documentation/hue-system-performance
+ */
+ public long getMessageDelay() {
+ return commands.size() * 40L;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip1;
+
+import org.eclipse.jdt.annotation.Nullable;
+
+/**
+ * Collection of capabilities to control lights.
+ *
+ * @author Christoph Weitkamp - Initial contribution
+ */
+public class Control {
+ public @Nullable ColorTemperature ct;
+}
--- /dev/null
+/**
+ * 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.api.dto.clip1;
+
+/**
+ *
+ * @author Q42 - Initial contribution
+ * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding
+ */
+@SuppressWarnings("unused")
+public class CreateUserRequest {
+ private String username;
+ private String devicetype;
+
+ public CreateUserRequest(String username, String devicetype) {
+ if (Util.stringSize(devicetype) > 40) {
+ throw new IllegalArgumentException("Device type can be at most 40 characters long");
+ }
+
+ if (Util.stringSize(username) < 10 || Util.stringSize(username) > 40) {
+ throw new IllegalArgumentException("Username must be between 10 and 40 characters long");
+ }
+
+ this.username = username;
+ this.devicetype = devicetype;
+ }
+
+ public CreateUserRequest(String devicetype) {
+ if (Util.stringSize(devicetype) > 40) {
+ throw new IllegalArgumentException("Device type can be at most 40 characters long");
+ }
+
+ this.devicetype = devicetype;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip1;
+
+import java.lang.reflect.Type;
+import java.util.List;
+
+import com.google.gson.reflect.TypeToken;
+
+/**
+ * @author Q42 - Initial contribution
+ * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding
+ */
+public class ErrorResponse {
+ public static final Type GSON_TYPE = new TypeToken<List<ErrorResponse>>() {
+ }.getType();
+
+ public class Error {
+ private Integer type;
+ private String address;
+ private String description;
+ }
+
+ private Error error;
+
+ public Integer getType() {
+ if (error == null) {
+ return null;
+ }
+ return error.type;
+ }
+
+ public String getAddress() {
+ if (error == null) {
+ return null;
+ }
+ return error.address;
+ }
+
+ public String getDescription() {
+ if (error == null) {
+ return null;
+ }
+ return error.description;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip1;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Container for all data on a bridge.
+ *
+ * @author Q42 - Initial contribution
+ * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding
+ */
+public class FullConfig {
+ private Map<String, FullLight> lights;
+ private Map<String, FullGroup> groups;
+ private Config config;
+
+ /**
+ * Returns detailed information about all lights known to the bridge.
+ *
+ * @return detailed lights list
+ */
+ public List<FullLight> getLights() {
+ ArrayList<FullLight> lightsList = new ArrayList<>();
+
+ for (Map.Entry<String, FullLight> entry : lights.entrySet()) {
+ String id = entry.getKey();
+ FullLight light = entry.getValue();
+ light.setId(id);
+ lightsList.add(light);
+ }
+
+ return lightsList;
+ }
+
+ /**
+ * Returns detailed information about all groups on the bridge.
+ *
+ * @return detailed groups list
+ */
+ public List<FullGroup> getGroups() {
+ ArrayList<FullGroup> groupsList = new ArrayList<>();
+
+ for (Map.Entry<String, FullGroup> entry : groups.entrySet()) {
+ String id = entry.getKey();
+ FullGroup group = entry.getValue();
+ group.setId(id);
+ groupsList.add(group);
+ }
+
+ return groupsList;
+ }
+
+ /**
+ * Returns bridge configuration.
+ * Use HueBridge.getConfig() if you only need this.
+ *
+ * @return bridge configuration
+ */
+ public Config getConfig() {
+ return config;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip1;
+
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
+import com.google.gson.reflect.TypeToken;
+
+/**
+ * Detailed group information.
+ *
+ * @author Q42 - Initial contribution
+ * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding
+ * @author Laurent Garnier - field state added
+ */
+@NonNullByDefault
+public class FullGroup extends Group {
+ public static final Type GSON_TYPE = new TypeToken<Map<String, FullGroup>>() {
+ }.getType();
+
+ private @Nullable State action;
+ private @Nullable List<String> lights;
+ private @Nullable State groupState; // Will not be set by hue API
+
+ FullGroup() {
+ super();
+ }
+
+ /**
+ * Test constructor
+ */
+ public FullGroup(String id, String name, String type, State action, List<String> lights, State state) {
+ super(id, name, type);
+ this.action = action;
+ this.lights = lights;
+ this.groupState = state;
+ }
+
+ /**
+ * Returns the last sent state update to the group.
+ * This does not have to reflect the current state of the group.
+ *
+ * @return last state update
+ */
+ public @Nullable State getAction() {
+ return action;
+ }
+
+ /**
+ * Returns a list of the lights in the group.
+ *
+ * @return lights in the group
+ */
+ public List<String> getLightIds() {
+ List<String> lights = this.lights;
+ return lights != null ? lights : new ArrayList<>();
+ }
+
+ /**
+ * Returns the current state of the group.
+ *
+ * @return current state
+ */
+ public State getState() {
+ State groupState = this.groupState;
+ if (groupState == null) {
+ throw new IllegalStateException("Group state not initialized when requested");
+ }
+ return groupState;
+ }
+
+ public void setState(State state) {
+ this.groupState = state;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip1;
+
+import static org.openhab.binding.hue.internal.HueBindingConstants.NORMALIZE_ID_REGEX;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * Detailed information about an object on the Hue Bridge
+ *
+ * @author Samuel Leisering - Initial contribution
+ * @author Christoph Weitkamp - Initial contribution
+ */
+@NonNullByDefault
+public class FullHueObject extends HueObject {
+
+ private @NonNullByDefault({}) String type;
+ private @Nullable String modelid;
+ @SerializedName("manufacturername")
+ private @NonNullByDefault({}) String manufacturerName;
+ @SerializedName("productname")
+ private @NonNullByDefault({}) String productName;
+ private @Nullable String swversion;
+ private @Nullable String uniqueid;
+
+ public FullHueObject() {
+ super();
+ }
+
+ /**
+ * Returns the type of the object.
+ *
+ * @return type
+ */
+ public String getType() {
+ return type;
+ }
+
+ /**
+ * Set the type of the object.
+ */
+ public void setType(final String type) {
+ this.type = type;
+ }
+
+ /**
+ * Returns the model ID of the object.
+ *
+ * @return model id
+ */
+ public @Nullable String getModelID() {
+ return modelid;
+ }
+
+ public @Nullable String getNormalizedModelID() {
+ String modelid = this.modelid;
+ return modelid != null ? modelid.replaceAll(NORMALIZE_ID_REGEX, "_") : modelid;
+ }
+
+ /**
+ * Set the model ID of the object.
+ */
+ public void setModelID(final String modelId) {
+ this.modelid = modelId;
+ }
+
+ public String getManufacturerName() {
+ return manufacturerName;
+ }
+
+ public void setManufacturerName(String manufacturerName) {
+ this.manufacturerName = manufacturerName;
+ }
+
+ public String getProductName() {
+ return productName;
+ }
+
+ public void setProductName(String productName) {
+ this.productName = productName;
+ }
+
+ /**
+ * Returns the software version of the object.
+ *
+ * @return software version
+ */
+ public @Nullable String getSoftwareVersion() {
+ return swversion;
+ }
+
+ /**
+ * Returns the unique id of the object. The unique is the MAC address of the device with a unique endpoint id in the
+ * form: AA:BB:CC:DD:EE:FF:00:11-XX
+ *
+ * @return the unique id, can be null for some virtual types like the daylight sensor
+ */
+ public @Nullable String getUniqueID() {
+ return uniqueid;
+ }
+
+ /**
+ * Sets the unique id of the object.
+ */
+ public void setUniqueID(final String uniqueid) {
+ this.uniqueid = uniqueid;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip1;
+
+import java.lang.reflect.Type;
+import java.time.Duration;
+import java.util.Map;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
+import com.google.gson.reflect.TypeToken;
+
+/**
+ * Detailed light information.
+ *
+ * @author Q42 - Initial contribution
+ * @author Thomas Höfer - added unique id and changed range check for brightness and saturation
+ * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding
+ * @author Samuel Leisering - added GSon Type to FullLight, refactored content to {@link FullHueObject}
+ */
+@NonNullByDefault
+public class FullLight extends FullHueObject {
+ public static final Type GSON_TYPE = new TypeToken<Map<String, FullLight>>() {
+ }.getType();
+
+ public @Nullable Capabilities capabilities;
+ private @NonNullByDefault({}) State state;
+ private final long fadetime = 400; // milliseconds
+
+ /**
+ * Returns the current state of the light.
+ *
+ * @return current state
+ */
+ public State getState() {
+ return state;
+ }
+
+ public Duration getFadeTime() {
+ return Duration.ofMillis(fadetime);
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip1;
+
+import java.lang.reflect.Type;
+import java.util.Map;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+import com.google.gson.reflect.TypeToken;
+
+/**
+ * Detailed sensor information
+ *
+ * @author Samuel Leisering - Initial contribution
+ * @author Christoph Weitkamp - Initial contribution
+ */
+@NonNullByDefault
+public class FullSensor extends FullHueObject {
+ public static final Type GSON_TYPE = new TypeToken<Map<String, FullSensor>>() {
+ }.getType();
+
+ public static final String STATE_LAST_UPDATED = "lastupdated";
+ public static final String STATE_BUTTON_EVENT = "buttonevent";
+ public static final String STATE_PRESENCE = "presence";
+ public static final String STATE_TEMPERATURE = "temperature";
+ public static final String STATE_LIGHT_LEVEL = "lightlevel";
+ public static final String STATE_DARK = "dark";
+ public static final String STATE_DAYLIGHT = "daylight";
+ public static final String STATE_STATUS = "status";
+ public static final String STATE_FLAG = "flag";
+
+ public static final String CONFIG_REACHABLE = "reachable";
+ public static final String CONFIG_BATTERY = "battery";
+ public static final String CONFIG_ON = "on";
+ public static final String CONFIG_LED_INDICATION = "ledindication";
+
+ public static final String CONFIG_PRESENCE_SENSITIVITY = "sensitivity";
+ public static final String CONFIG_PRESENCE_SENSITIVITY_MAX = "sensitivitymax";
+
+ public static final String CONFIG_LIGHT_LEVEL_THRESHOLD_DARK = "tholddark";
+ public static final String CONFIG_LIGHT_LEVEL_THRESHOLD_OFFSET = "tholdoffset";
+
+ private @NonNullByDefault({}) Map<String, Object> state;
+ private @NonNullByDefault({}) Map<String, Object> config;
+
+ public Map<String, Object> getState() {
+ return state;
+ }
+
+ public Map<String, Object> getConfig() {
+ return config;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip1;
+
+/**
+ * Basic group information.
+ *
+ * @author Q42 - Initial contribution
+ * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding
+ * @author Laurent Garnier - field type added
+ */
+public class Group {
+ private String id;
+ private String name;
+ private String type;
+
+ public Group() {
+ this.id = "0";
+ this.name = "Lightset 0";
+ this.type = "LightGroup";
+ }
+
+ /**
+ * Test constructor
+ */
+ Group(String id, String name, String type) {
+ this.id = id;
+ this.name = name;
+ this.type = type;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ void setType(String type) {
+ this.type = type;
+ }
+
+ /**
+ * Returns if the group can be modified.
+ * Currently only returns false for the all lights pseudo group.
+ *
+ * @return modifiability of group
+ */
+ public boolean isModifiable() {
+ return !"0".equals(id);
+ }
+
+ /**
+ * Returns the id of the group.
+ *
+ * @return id
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * Returns the name of the group.
+ *
+ * @return name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Returns the tyoe of the group.
+ *
+ * @return type
+ */
+ public String getType() {
+ return type;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip1;
+
+import java.lang.reflect.Type;
+import java.util.Map;
+
+import com.google.gson.reflect.TypeToken;
+
+/**
+ * Basic hue object information.
+ *
+ * @author Q42 - Initial contribution
+ * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding
+ * @author Samuel Leisering - introduced Sensor support, renamed supertype to HueObject
+ */
+public class HueObject {
+ public static final Type GSON_TYPE = new TypeToken<Map<String, HueObject>>() {
+ }.getType();
+
+ private String id;
+ private String name;
+
+ HueObject() {
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * Returns the id of the light.
+ *
+ * @return id
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * Returns the name of the light.
+ *
+ * @return name
+ */
+ public String getName() {
+ return name;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip1;
+
+import static org.openhab.binding.hue.internal.api.dto.clip1.FullSensor.*;
+
+/**
+ * Updates the configuration of a light level sensor
+ *
+ * @author Samuel Leisering - Initial contribution
+ * @author Christoph Weitkamp - Initial contribution
+ */
+public class LightLevelConfigUpdate extends SensorConfigUpdate {
+ /**
+ *
+ * @param onOff
+ */
+ public void setLedIndication(boolean onOff) {
+ commands.add(new Command(CONFIG_LED_INDICATION, onOff));
+ }
+
+ /**
+ *
+ * @param threshold
+ */
+ public void setThresholdDark(int threshold) {
+ commands.add(new Command(CONFIG_LIGHT_LEVEL_THRESHOLD_DARK, threshold));
+ }
+
+ /**
+ *
+ * @param offset
+ */
+ public void setThresholdOffset(int offset) {
+ commands.add(new Command(CONFIG_LIGHT_LEVEL_THRESHOLD_OFFSET, offset));
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip1;
+
+/**
+ * @author Q42 - Initial contribution
+ * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding
+ */
+public class NewLightsResponse {
+ public String lastscan;
+}
--- /dev/null
+/**
+ * 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.api.dto.clip1;
+
+import static org.openhab.binding.hue.internal.api.dto.clip1.FullSensor.*;
+
+/**
+ * Updates the configuration of a presence sensor
+ *
+ * @author Samuel Leisering - Initial contribution
+ * @author Christoph Weitkamp - Initial contribution
+ */
+public class PresenceConfigUpdate extends SensorConfigUpdate {
+ /**
+ *
+ * @param onOff
+ */
+ public void setLedIndication(boolean onOff) {
+ commands.add(new Command(CONFIG_LED_INDICATION, onOff));
+ }
+
+ /**
+ *
+ * @param sensitivity
+ */
+ public void setSensitivity(int sensitivity) {
+ commands.add(new Command(CONFIG_PRESENCE_SENSITIVITY, sensitivity));
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip1;
+
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.core.types.StateOption;
+
+import com.google.gson.annotations.SerializedName;
+import com.google.gson.reflect.TypeToken;
+
+/**
+ * Basic scene information.
+ *
+ * @author Hengrui Jiang - Initial contribution
+ */
+@NonNullByDefault
+public class Scene {
+ public static final Type GSON_TYPE = new TypeToken<Map<String, Scene>>() {
+ }.getType();
+
+ private @NonNullByDefault({}) String id;
+ private @NonNullByDefault({}) String name;
+ @SerializedName("lights")
+ private @Nullable List<String> lightIds;
+ @SerializedName("group")
+ private @Nullable String groupId;
+ private boolean recycle;
+
+ /**
+ * Default constructor for GSon.
+ */
+ public Scene() {
+ super();
+ }
+
+ /**
+ * Test constructor
+ */
+ public Scene(String id, String name, @Nullable String groupId, List<String> lightIds, boolean recycle) {
+ this.id = id;
+ this.name = name;
+ this.groupId = groupId;
+ this.lightIds = lightIds;
+ this.recycle = recycle;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * Returns the human readable name of the scene. If the name is omitted upon creation, this
+ * defaults to the ID.
+ *
+ * @return human readable name of the scene
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Returns the list of lights that the scene applies to. For group scenes, this list should be identical to the list
+ * of all lights that are in the group.
+ *
+ * @return list of lights that the scene applies to
+ */
+ public List<String> getLightIds() {
+ List<String> lightIds = this.lightIds;
+ return lightIds != null ? lightIds : new ArrayList<String>();
+ }
+
+ /**
+ * Returns the group that the scene belongs to. This field is optional for scenes that applies to a specific list of
+ * lights instead of a group.
+ *
+ * @return the group that the scene belongs to
+ */
+ public @Nullable String getGroupId() {
+ return groupId;
+ }
+
+ /**
+ * Indicates if the scene can be recycled by the bridge. A recyclable scene is not able to be activated.
+ *
+ * @return whether the scene can be recycled
+ */
+ public boolean isRecycle() {
+ return recycle;
+ }
+
+ /**
+ * Creates a {@link StateOption} to display this scene, including the group that it belongs to.
+ * <p>
+ * The display name is built with the following pattern:
+ * <ol>
+ * <li>Human readable name of the scene if set. Otherwise, the ID is displayed</li>
+ * <li>Group for which the scene is defined</li>
+ * </ol>
+ */
+ public StateOption toStateOption(Map<String, String> groupNames) {
+ StringBuilder stateOptionLabel = new StringBuilder(name);
+ if (groupId != null && groupNames.containsKey(groupId)) {
+ stateOptionLabel.append(" (").append(groupNames.get(groupId)).append(")");
+ }
+
+ return new StateOption(id, stateOptionLabel.toString());
+ }
+
+ /**
+ * Creates a {@link StateOption} to display this scene.
+ */
+ public StateOption toStateOption() {
+ return new StateOption(id, name);
+ }
+
+ /**
+ * Returns whether the scene is applicable to the given group.
+ * <p>
+ * According to the hue API, a scene is applicable to a group if either
+ * <ol>
+ * <li>The scene is defined for the group</li>
+ * <li>All lights of the scene also belong to the group</li>
+ * </ol>
+ */
+ public boolean isApplicableTo(FullGroup group) {
+ String groupId = this.groupId;
+ if (groupId == null) {
+ return getLightIds().stream().allMatch(id -> group.getLightIds().contains(id));
+ } else {
+ return group.getId().contentEquals(groupId);
+ }
+ }
+
+ public String extractKeyForComparator() {
+ return (groupId != null ? groupId : "") + "#" + name;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("{Scene name: %s; id: %s; lightIds: %s; groupId: %s; recycle: %s}", name, id, lightIds,
+ groupId, recycle);
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip1;
+
+import java.lang.reflect.Type;
+import java.util.Map;
+
+import com.google.gson.reflect.TypeToken;
+
+/**
+ * Basic schedule information.
+ *
+ * @author Q42 - Initial contribution
+ * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding
+ */
+public class Schedule {
+ public static final Type GSON_TYPE = new TypeToken<Map<String, Schedule>>() {
+ }.getType();
+
+ private String id;
+ private String name;
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip1;
+
+import java.util.Date;
+
+/**
+ * Collection of updates to a schedule.
+ *
+ * @author Q42 - Initial contribution
+ * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding, minor code cleanup
+ * @author Samuel Leisering - refactor configuration updates
+ */
+public class ScheduleUpdate extends ConfigUpdate {
+
+ /**
+ * Set the name of the schedule.
+ *
+ * @param name new name
+ * @return this object for chaining calls
+ */
+ public ScheduleUpdate setName(String name) {
+ if (Util.stringSize(name) > 32) {
+ throw new IllegalArgumentException("Schedule name can be at most 32 characters long");
+ }
+
+ commands.add(new Command("name", name));
+ return this;
+ }
+
+ /**
+ * Set the description of the schedule.
+ *
+ * @param description new description
+ * @return this object for chaining calls
+ */
+ public ScheduleUpdate setDescription(String description) {
+ if (Util.stringSize(description) > 64) {
+ throw new IllegalArgumentException("Schedule description can be at most 64 characters long");
+ }
+
+ commands.add(new Command("description", description));
+ return this;
+ }
+
+ /**
+ * Set the time of the schedule.
+ *
+ * @param time new time
+ * @return this object for chaining calls
+ */
+ public ScheduleUpdate setTime(Date time) {
+ commands.add(new Command("time", time));
+ return this;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip1;
+
+import java.util.List;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ *
+ * @author Q42 - Initial contribution
+ * @author Andre Fuechsel - search for lights with given serial number added
+ * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding
+ */
+@NonNullByDefault
+public class SearchForLightsRequest {
+ @SuppressWarnings("unused")
+ private List<String> deviceid;
+
+ public SearchForLightsRequest(List<String> deviceid) {
+ if (deviceid.isEmpty() || deviceid.size() > 16) {
+ throw new IllegalArgumentException("Group cannot be empty and cannot have more than 16 lights");
+ }
+ this.deviceid = deviceid;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip1;
+
+import static org.openhab.binding.hue.internal.api.dto.clip1.FullSensor.CONFIG_ON;
+
+/**
+ * Collection of updates to the sensor configuration.
+ *
+ * @author Christoph Weitkamp - Initial contribution
+ */
+public class SensorConfigUpdate extends ConfigUpdate {
+ /**
+ *
+ * @param onOff
+ */
+ public void setOn(boolean onOff) {
+ commands.add(new Command(CONFIG_ON, onOff));
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip1;
+
+import java.util.List;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
+/**
+ *
+ * @author Q42 - Initial contribution
+ * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding
+ */
+@SuppressWarnings("unused")
+@NonNullByDefault
+public class SetAttributesRequest {
+ private final @Nullable String name;
+ private final @Nullable List<String> lights;
+
+ public SetAttributesRequest(String name) {
+ this(name, null);
+ }
+
+ public SetAttributesRequest(List<HueObject> lights) {
+ this(null, lights);
+ }
+
+ public SetAttributesRequest(@Nullable String name, @Nullable List<HueObject> lights) {
+ if (name != null && Util.stringSize(name) > 32) {
+ throw new IllegalArgumentException("Name can be at most 32 characters long");
+ } else if (lights != null && (lights.isEmpty() || lights.size() > 16)) {
+ throw new IllegalArgumentException("Group cannot be empty and cannot have more than 16 lights");
+ }
+
+ this.name = name;
+ this.lights = lights == null ? null : lights.stream().map(l -> l.getId()).toList();
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip1;
+
+/**
+ * Details of a bridge firmware update.
+ *
+ * @author Q42 - Initial contribution
+ * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding
+ */
+public class SoftwareUpdate {
+ private int updatestate;
+ private String url;
+ private String text;
+ private boolean notify;
+
+ /**
+ * Returns the state of the update.
+ *
+ * <p>
+ * Actual meaning currently undocumented
+ *
+ * @return state of update
+ */
+ public int getUpdateState() {
+ return updatestate;
+ }
+
+ /**
+ * Returns the url of the changelog.
+ *
+ * @return changelog url
+ */
+ public String getUrl() {
+ return url;
+ }
+
+ /**
+ * Returns a description of the update.
+ *
+ * @return update description
+ */
+ public String getText() {
+ return text;
+ }
+
+ /**
+ * Returns if there will be a notification about this update.
+ *
+ * @return true for notification, false otherwise
+ */
+ public boolean isNotified() {
+ return notify;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip1;
+
+import java.util.Arrays;
+
+/**
+ * Current state of light.
+ *
+ * @author Q42 - Initial contribution
+ * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding
+ * @author Laurent Garnier - add few methods to update the object
+ */
+public class State {
+ private boolean on;
+ public int bri;
+ public int hue;
+ public int sat;
+ private float[] xy;
+ public int ct;
+ private String alert;
+ private String effect;
+ public String colormode;
+ private boolean reachable;
+
+ public State() {
+ }
+
+ /**
+ * Color modes of a light.
+ */
+ public enum ColorMode {
+ /**
+ * CIE color space coordinates
+ */
+ XY,
+
+ /**
+ * Hue and saturation
+ */
+ HS,
+
+ /**
+ * Color temperature in mired
+ */
+ CT
+ }
+
+ /**
+ * Alert modes of a light.
+ */
+ public enum AlertMode {
+ /**
+ * Light is not performing alert effect
+ */
+ NONE,
+
+ /**
+ * Light is performing one breathe cycle
+ */
+ SELECT,
+
+ /**
+ * Light is performing breathe cycles for 30 seconds (unless cancelled)
+ */
+ LSELECT
+ }
+
+ /**
+ * Effects possible for a light.
+ */
+ public enum Effect {
+ /**
+ * No effect
+ */
+ NONE,
+
+ /**
+ * Cycle through all hues with current saturation and brightness
+ */
+ COLORLOOP
+ }
+
+ /**
+ * Returns the on state.
+ *
+ * @return true if the light is on, false if it isn't
+ */
+ public boolean isOn() {
+ return on;
+ }
+
+ public void setOn(boolean on) {
+ this.on = on;
+ }
+
+ /**
+ * Returns the brightness.
+ *
+ * @return brightness
+ */
+ public int getBrightness() {
+ return bri;
+ }
+
+ public void setBri(int bri) {
+ this.bri = bri;
+ }
+
+ /**
+ * Returns the hue.
+ *
+ * @return hue
+ */
+ public int getHue() {
+ return hue;
+ }
+
+ public void setHue(int hue) {
+ this.hue = hue;
+ }
+
+ /**
+ * Returns the saturation.
+ *
+ * @return saturation
+ */
+ public int getSaturation() {
+ return sat;
+ }
+
+ public void setSaturation(int sat) {
+ this.sat = sat;
+ }
+
+ /**
+ * Returns the coordinates in CIE color space.
+ *
+ * @return cie color spaces coordinates
+ */
+ public float[] getXY() {
+ return xy;
+ }
+
+ public void setXY(float[] xy) {
+ this.xy = xy;
+ }
+
+ /**
+ * Returns the color temperature.
+ *
+ * @return color temperature
+ */
+ public int getColorTemperature() {
+ return ct;
+ }
+
+ public void setColorTemperature(int ct) {
+ this.ct = ct;
+ }
+
+ /**
+ * Returns the last alert mode set.
+ * Future firmware updates may change this to actually report the current alert mode.
+ *
+ * @return last alert mode
+ */
+ public AlertMode getAlertMode() {
+ if (alert == null) {
+ return null;
+ }
+ return AlertMode.valueOf(alert.toUpperCase());
+ }
+
+ /**
+ * Returns the current color mode.
+ *
+ * @return current color mode
+ */
+ public ColorMode getColorMode() {
+ if (colormode == null) {
+ return null;
+ }
+ return ColorMode.valueOf(colormode.toUpperCase());
+ }
+
+ public void setColormode(ColorMode colormode) {
+ this.colormode = colormode.name();
+ }
+
+ /**
+ * Returns the current active effect.
+ *
+ * @return current active effect
+ */
+ public Effect getEffect() {
+ if (effect == null) {
+ return null;
+ }
+ return Effect.valueOf(effect.toUpperCase());
+ }
+
+ /**
+ * Returns reachability.
+ *
+ * @return true if reachable, false if it isn't
+ */
+ public boolean isReachable() {
+ return reachable;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((alert == null) ? 0 : alert.hashCode());
+ result = prime * result + bri;
+ result = prime * result + ((colormode == null) ? 0 : colormode.hashCode());
+ result = prime * result + ct;
+ result = prime * result + ((effect == null) ? 0 : effect.hashCode());
+ result = prime * result + hue;
+ result = prime * result + (on ? 1231 : 1237);
+ result = prime * result + (reachable ? 1231 : 1237);
+ result = prime * result + sat;
+ result = prime * result + Arrays.hashCode(xy);
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ State other = (State) obj;
+ if (alert == null) {
+ if (other.alert != null) {
+ return false;
+ }
+ } else if (!alert.equals(other.alert)) {
+ return false;
+ }
+ if (bri != other.bri) {
+ return false;
+ }
+ if (colormode == null) {
+ if (other.colormode != null) {
+ return false;
+ }
+ } else if (!colormode.equals(other.colormode)) {
+ return false;
+ }
+ if (ct != other.ct) {
+ return false;
+ }
+ if (effect == null) {
+ if (other.effect != null) {
+ return false;
+ }
+ } else if (!effect.equals(other.effect)) {
+ return false;
+ }
+ if (hue != other.hue) {
+ return false;
+ }
+ if (on != other.on) {
+ return false;
+ }
+ if (reachable != other.reachable) {
+ return false;
+ }
+ if (sat != other.sat) {
+ return false;
+ }
+ return Arrays.equals(xy, other.xy);
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip1;
+
+import org.openhab.binding.hue.internal.api.dto.clip1.State.AlertMode;
+import org.openhab.binding.hue.internal.api.dto.clip1.State.Effect;
+
+/**
+ * Collection of updates to the state of a light.
+ *
+ * @author Q42 - Initial contribution
+ * @author Thomas Höfer - added unique id and changed range check for brightness and saturation
+ * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding, minor code cleanup
+ * @author Samuel Leisering - refactor configuration updates
+ */
+public class StateUpdate extends ConfigUpdate {
+
+ private Integer colorTemperature;
+ private Integer brightness;
+
+ /**
+ * Turn light on.
+ *
+ * @return this object for chaining calls
+ */
+ public StateUpdate turnOn() {
+ return setOn(true);
+ }
+
+ /**
+ * Turn light off.
+ *
+ * @return this object for chaining calls
+ */
+ public StateUpdate turnOff() {
+ return setOn(false);
+ }
+
+ /**
+ * Turn light on or off.
+ *
+ * @param on on if true, off otherwise
+ * @return this object for chaining calls
+ */
+ public StateUpdate setOn(boolean on) {
+ commands.add(new Command("on", on));
+ return this;
+ }
+
+ /**
+ * Set brightness of light.
+ * Brightness 0 is not the same as off.
+ *
+ * @param brightness brightness [1..254]
+ * @return this object for chaining calls
+ */
+ public StateUpdate setBrightness(int brightness) {
+ if (brightness < 1 || brightness > 254) {
+ throw new IllegalArgumentException("Brightness out of range");
+ }
+
+ commands.add(new Command("bri", brightness));
+ this.brightness = brightness;
+ return this;
+ }
+
+ public Integer getBrightness() {
+ return this.brightness;
+ }
+
+ /**
+ * Switch to HS color mode and set hue.
+ *
+ * @param hue hue [0..65535]
+ * @return this object for chaining calls
+ */
+ public StateUpdate setHue(int hue) {
+ if (hue < 0 || hue > 65535) {
+ throw new IllegalArgumentException("Hue out of range");
+ }
+
+ commands.add(new Command("hue", hue));
+ return this;
+ }
+
+ /**
+ * Switch to HS color mode and set saturation.
+ *
+ * @param saturation saturation [0..254]
+ * @return this object for chaining calls
+ */
+ public StateUpdate setSat(int saturation) {
+ if (saturation < 0 || saturation > 254) {
+ throw new IllegalArgumentException("Saturation out of range");
+ }
+
+ commands.add(new Command("sat", saturation));
+ return this;
+ }
+
+ /**
+ * Switch to XY color mode and set CIE color space coordinates.
+ *
+ * @param x x coordinate [0..1]
+ * @param y y coordinate [0..1]
+ * @return this object for chaining calls
+ */
+ public StateUpdate setXY(float x, float y) {
+ return setXY(new float[] { x, y });
+ }
+
+ /**
+ * Switch to XY color mode and set CIE color space coordinates.
+ *
+ * @param xy x and y coordinates [0..1, 0..1]
+ * @return this object for chaining calls
+ */
+ public StateUpdate setXY(float[] xy) {
+ if (xy.length != 2) {
+ throw new IllegalArgumentException("Invalid coordinate array given");
+ } else if (xy[0] < 0.0f || xy[0] > 1.0f || xy[1] < 0.0f || xy[1] > 1.0f) {
+ throw new IllegalArgumentException("X and/or Y coordinate(s) out of bounds");
+ }
+
+ commands.add(new Command("xy", xy));
+ return this;
+ }
+
+ /**
+ * Switch to CT color mode and set color temperature in mired.
+ *
+ * @param colorTemperature color temperature
+ * @return this object for chaining calls
+ */
+ public StateUpdate setColorTemperature(int colorTemperature, ColorTemperature capabilities) {
+ if (colorTemperature < capabilities.min || colorTemperature > capabilities.max) {
+ throw new IllegalArgumentException(String.format("Color temperature %d is out of range [%d..%d]",
+ colorTemperature, capabilities.min, capabilities.max));
+ }
+
+ commands.add(new Command("ct", colorTemperature));
+ this.colorTemperature = colorTemperature;
+ return this;
+ }
+
+ public Integer getColorTemperature() {
+ return this.colorTemperature;
+ }
+
+ /**
+ * Set the alert mode.
+ *
+ * @see AlertMode
+ * @param mode alert mode
+ * @return this object for chaining calls
+ */
+ public StateUpdate setAlert(AlertMode mode) {
+ commands.add(new Command("alert", mode.toString().toLowerCase()));
+ return this;
+ }
+
+ /**
+ * Set the current effect.
+ *
+ * @see Effect
+ * @param effect effect
+ * @return this object for chaining calls
+ */
+ public StateUpdate setEffect(Effect effect) {
+ commands.add(new Command("effect", effect.toString().toLowerCase()));
+ return this;
+ }
+
+ /**
+ * Set the transition time from the current state to the new state.
+ * Time is accurate to 100 milliseconds.
+ *
+ * @param timeMillis time in milliseconds [0..6553600]
+ * @return this object for chaining calls
+ */
+ public StateUpdate setTransitionTime(long timeMillis) {
+ if (timeMillis < 0 || timeMillis > 6553600) {
+ throw new IllegalArgumentException("Transition time out of range");
+ }
+
+ commands.add(new Command("transitiontime", timeMillis / 100));
+ return this;
+ }
+
+ /**
+ * Turn sensor flag on or off.
+ *
+ * @param flag on if true, off otherwise
+ * @return this object for chaining calls
+ */
+
+ public StateUpdate setFlag(boolean flag) {
+ commands.add(new Command("flag", flag));
+ return this;
+ }
+
+ /**
+ * Set status of sensor.
+ *
+ * @param status status
+ * @return this object for chaining calls
+ */
+ public StateUpdate setStatus(int status) {
+ commands.add(new Command("status", status));
+ return this;
+ }
+
+ /**
+ * Recall the given scene.
+ *
+ * @param sceneId Identifier of the scene
+ * @return this object for chaining calls
+ */
+ public StateUpdate setScene(String sceneId) {
+ commands.add(new Command("scene", sceneId));
+ return this;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip1;
+
+import java.lang.reflect.Type;
+import java.util.List;
+import java.util.Map;
+
+import com.google.gson.reflect.TypeToken;
+
+/**
+ * @author Q42 - Initial contribution
+ * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding
+ */
+public class SuccessResponse {
+ public static final Type GSON_TYPE = new TypeToken<List<SuccessResponse>>() {
+ }.getType();
+
+ public Map<String, Object> success;
+}
--- /dev/null
+/**
+ * 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.api.dto.clip1;
+
+import static org.openhab.binding.hue.internal.api.dto.clip1.FullSensor.CONFIG_LED_INDICATION;
+
+/**
+ * Updates the configuration of a temperature sensor
+ *
+ * @author Christoph Weitkamp - Initial contribution
+ */
+public class TemperatureConfigUpdate extends SensorConfigUpdate {
+ /**
+ *
+ * @param onOff
+ */
+ public void setLedIndication(boolean onOff) {
+ commands.add(new Command(CONFIG_LED_INDICATION, onOff));
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip1;
+
+import java.util.Date;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * A whitelisted user.
+ *
+ * @author Q42 - Initial contribution
+ * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding
+ */
+public class User {
+ @SerializedName("last use date")
+ private Date lastUseDate;
+
+ @SerializedName("create date")
+ private Date createDate;
+
+ private String name;
+
+ /**
+ * Returns the last time a command was issued as this user.
+ *
+ * @return time of last command by this user
+ */
+ public Date getLastUseDate() {
+ return lastUseDate;
+ }
+
+ /**
+ * Returns the date this user was created.
+ *
+ * @return creation date of user
+ */
+ public Date getCreationDate() {
+ return createDate;
+ }
+
+ /**
+ * Returns the username of this user.
+ *
+ * @return username
+ */
+ public String getUsername() {
+ return name;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip1;
+
+import java.nio.charset.StandardCharsets;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
+/**
+ * @author Q42 - Initial contribution
+ * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding
+ */
+@NonNullByDefault
+public final class Util {
+
+ private Util() {
+ }
+
+ // This is used to check what byte size strings have, because the bridge doesn't natively support UTF-8
+ public static int stringSize(String str) {
+ return str.getBytes(StandardCharsets.UTF_8).length;
+ }
+
+ public static @Nullable String quickMatch(String needle, String haystack) {
+ Matcher m = Pattern.compile(needle).matcher(haystack);
+ m.find();
+ return m.group(1);
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * DTO that contains an API Action entry.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public class ActionEntry {
+ private @NonNullByDefault({}) ResourceReference target;
+ private @NonNullByDefault({}) Resource action;
+
+ public ResourceReference getTarget() {
+ return target;
+ }
+
+ public Resource getAction() {
+ return action;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.ActionType;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * DTO for 'alert' of a light.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public class Alerts {
+ private @Nullable @SerializedName("action_values") List<String> actionValues;
+ private @Nullable String action;
+
+ public @Nullable ActionType getAction() {
+ String action = this.action;
+ return Objects.nonNull(action) ? ActionType.of(action) : null;
+ }
+
+ public List<ActionType> getActionValues() {
+ List<String> actionValues = this.actionValues;
+ if (Objects.nonNull(actionValues)) {
+ return actionValues.stream().map(ActionType::of).collect(Collectors.toList());
+ }
+ return List.of();
+ }
+
+ public Alerts setAction(ActionType actionType) {
+ this.action = actionType.name().toLowerCase();
+ return this;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
+/**
+ * A 'special' DTO for bridge discovery to read the software version from a bridge.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public class BridgeConfig {
+ public @Nullable String swversion;
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.ButtonEventType;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * DTO for CLIP 2 button state.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public class Button {
+ private @Nullable @SerializedName("last_event") String lastEvent;
+ private @Nullable @SerializedName("button_report") ButtonReport buttonReport;
+ private @SerializedName("repeat_interval") int repeatInterval;
+
+ /**
+ * The underlying field is deprecated in the CLIP 2 API.
+ * Moved to button_report/event
+ *
+ * @return the last button event as an enum (null if none or invalid).
+ */
+ public @Nullable ButtonEventType getLastEvent() {
+ String lastEvent = this.lastEvent;
+ if (lastEvent == null) {
+ return null;
+ }
+
+ try {
+ return ButtonEventType.valueOf(lastEvent.toUpperCase());
+ } catch (IllegalArgumentException e) {
+ return null;
+ }
+ }
+
+ public @Nullable ButtonReport getButtonReport() {
+ return buttonReport;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2;
+
+import java.time.Instant;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.ButtonEventType;
+
+/**
+ * DTO for CLIP 2 button report.
+ *
+ * @author Jacob Laursen - Initial contribution
+ */
+@NonNullByDefault
+public class ButtonReport {
+ private @NonNullByDefault({}) Instant updated;
+ private @Nullable String event;
+
+ /**
+ * @return last time the value of this property is updated.
+ */
+ public Instant getLastChanged() {
+ return updated;
+ }
+
+ /**
+ * @return event which can be sent by a button control (null if none or invalid).
+ */
+ public @Nullable ButtonEventType getLastEvent() {
+ String event = this.event;
+ if (event == null) {
+ return null;
+ }
+
+ try {
+ return ButtonEventType.valueOf(event.toUpperCase());
+ } catch (IllegalArgumentException e) {
+ return null;
+ }
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2;
+
+import java.util.Objects;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.hue.internal.exceptions.DTOPresentButEmptyException;
+import org.openhab.core.library.types.QuantityType;
+import org.openhab.core.library.unit.Units;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * DTO for colour temperature of a light in CLIP 2.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public class ColorTemperature {
+ private @Nullable Long mirek;
+ private @Nullable @SerializedName("mirek_schema") MirekSchema mirekSchema;
+
+ /**
+ * Get the color temperature as a QuantityType value.
+ *
+ * @return a QuantityType value
+ * @throws DTOPresentButEmptyException to indicate that the DTO is present but empty.
+ */
+ public @Nullable QuantityType<?> getAbsolute() throws DTOPresentButEmptyException {
+ Long mirek = this.mirek;
+ if (Objects.nonNull(mirek)) {
+ return QuantityType.valueOf(mirek, Units.MIRED).toInvertibleUnit(Units.KELVIN);
+ }
+ throw new DTOPresentButEmptyException("'color_temperature' DTO is present but empty");
+ }
+
+ public @Nullable Long getMirek() {
+ return mirek;
+ }
+
+ public @Nullable MirekSchema getMirekSchema() {
+ return mirekSchema;
+ }
+
+ /**
+ * Get the color temperature as a percentage based on the MirekSchema. Note: this method is only to be used on
+ * cached state DTOs which already have a defined mirek schema.
+ *
+ * @return the percentage of the mirekSchema range.
+ * @throws DTOPresentButEmptyException to indicate that the DTO is present but empty.
+ */
+ public @Nullable Double getPercent() throws DTOPresentButEmptyException {
+ Long mirek = this.mirek;
+ if (Objects.nonNull(mirek)) {
+ MirekSchema mirekSchema = this.mirekSchema;
+ mirekSchema = Objects.nonNull(mirekSchema) ? mirekSchema : MirekSchema.DEFAULT_SCHEMA;
+ double min = mirekSchema.getMirekMinimum();
+ double max = mirekSchema.getMirekMaximum();
+ double percent = 100f * (mirek.doubleValue() - min) / (max - min);
+ return Math.max(0, Math.min(100, percent));
+ }
+ throw new DTOPresentButEmptyException("'mirek_schema' DTO is present but empty");
+ }
+
+ public ColorTemperature setMirek(double mirek) {
+ this.mirek = Math.round(mirek);
+ return this;
+ }
+
+ public ColorTemperature setMirekSchema(@Nullable MirekSchema mirekSchema) {
+ this.mirekSchema = mirekSchema;
+ return this;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2;
+
+import java.util.Objects;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.hue.internal.exceptions.DTOPresentButEmptyException;
+import org.openhab.core.util.ColorUtil.Gamut;
+
+/**
+ * DTO for colour X/Y of a light.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public class ColorXy {
+ private @Nullable PairXy xy;
+ private @Nullable Gamut2 gamut;
+
+ public @Nullable Gamut getGamut() {
+ Gamut2 gamut = this.gamut;
+ return Objects.nonNull(gamut) ? gamut.getGamut() : null;
+ }
+
+ public @Nullable Gamut2 getGamut2() {
+ return this.gamut;
+ }
+
+ /**
+ * @throws DTOPresentButEmptyException to indicate that the DTO is present but empty.
+ */
+ public double[] getXY() throws DTOPresentButEmptyException {
+ PairXy pairXy = this.xy;
+ if (Objects.nonNull(pairXy)) {
+ return pairXy.getXY();
+ }
+ throw new DTOPresentButEmptyException("'color' DTO is present but empty");
+ }
+
+ public ColorXy setGamut(@Nullable Gamut gamut) {
+ this.gamut = Objects.nonNull(gamut) ? new Gamut2().setGamut(gamut) : null;
+ return this;
+ }
+
+ public ColorXy setXY(double[] xyValues) {
+ PairXy pairXy = this.xy;
+ pairXy = Objects.nonNull(pairXy) ? pairXy : new PairXy();
+ pairXy.setXY(xyValues);
+ this.xy = pairXy;
+ return this;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2;
+
+import java.time.Instant;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.ContactStateType;
+
+/**
+ * DTO for CLIP 2 home security alarm contact.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public class ContactReport {
+
+ private @NonNullByDefault({}) Instant changed;
+ private @NonNullByDefault({}) String state;
+
+ public ContactStateType getContactState() throws IllegalArgumentException {
+ return ContactStateType.valueOf(state.toUpperCase());
+ }
+
+ public Instant getLastChanged() {
+ return changed;
+ }
+
+ public ContactReport setLastChanged(Instant changed) {
+ this.changed = changed;
+ return this;
+ }
+
+ public ContactReport setContactState(String state) {
+ this.state = state;
+ return this;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2;
+
+import java.util.Objects;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.hue.internal.exceptions.DTOPresentButEmptyException;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * DTO for dimming brightness of a light.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public class Dimming {
+ private @Nullable Double brightness;
+ private @Nullable @SerializedName("min_dim_level") Double minimumDimmingLevel;
+
+ public static final double DEFAULT_MINIMUM_DIMMIMG_LEVEL = 0.5f;
+
+ /**
+ * @throws DTOPresentButEmptyException to indicate that the DTO is present but empty.
+ */
+ public double getBrightness() throws DTOPresentButEmptyException {
+ Double brightness = this.brightness;
+ if (Objects.nonNull(brightness)) {
+ return brightness;
+ }
+ throw new DTOPresentButEmptyException("'dimming' DTO is present but empty");
+ }
+
+ public @Nullable Double getMinimumDimmingLevel() {
+ return minimumDimmingLevel;
+ }
+
+ public Dimming setBrightness(double brightness) {
+ this.brightness = brightness;
+ return this;
+ }
+
+ public Dimming setMinimumDimmingLevel(Double minimumDimmingLevel) {
+ this.minimumDimmingLevel = minimumDimmingLevel;
+ return this;
+ }
+
+ public @Nullable String toPropertyValue() {
+ Double minimumDimmingLevel = this.minimumDimmingLevel;
+ if (Objects.nonNull(minimumDimmingLevel)) {
+ return String.format("%.1f %% .. 100 %%", minimumDimmingLevel.doubleValue());
+ }
+ return null;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2;
+
+import java.time.Duration;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
+/**
+ * DTO for dynamics of transitions between light states.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public class Dynamics {
+ private @Nullable @SuppressWarnings("unused") Long duration;
+ private @Nullable @SuppressWarnings("unused") Double speed;
+
+ public Dynamics setDuration(Duration duration) {
+ this.duration = duration.toMillis();
+ return this;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2;
+
+import java.util.List;
+import java.util.Objects;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.EffectType;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * DTO for 'effects' of a light.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public class Effects {
+ private @Nullable @SerializedName("effect_values") List<String> effectValues;
+ private @Nullable String effect;
+ private @Nullable @SerializedName("status_values") List<String> statusValues;
+ private @Nullable String status;
+
+ public boolean allows(EffectType effect) {
+ List<String> statusValues = this.statusValues;
+ return Objects.nonNull(statusValues) ? statusValues.contains(effect.name().toLowerCase()) : false;
+ }
+
+ public EffectType getEffect() {
+ String effect = this.effect;
+ return Objects.nonNull(effect) ? EffectType.of(effect) : EffectType.NO_EFFECT;
+ }
+
+ public EffectType getStatus() {
+ return Objects.nonNull(status) ? EffectType.of(status) : EffectType.NO_EFFECT;
+ }
+
+ public List<String> getStatusValues() {
+ List<String> statusValues = this.statusValues;
+ return Objects.nonNull(statusValues) ? statusValues : List.of();
+ }
+
+ public Effects setEffect(EffectType effectType) {
+ effect = effectType.name().toLowerCase();
+ return this;
+ }
+
+ public Effects setStatusValues(List<String> statusValues) {
+ this.statusValues = statusValues;
+ return this;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * DTO for CLIP 2 communication errors.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public class Error {
+ private @NonNullByDefault({}) String description;
+
+ public String getDescription() {
+ return description;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2;
+
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
+import com.google.gson.reflect.TypeToken;
+
+/**
+ * DTO for CLIP 2 event stream objects.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public class Event {
+ public static final Type EVENT_LIST_TYPE = new TypeToken<List<Event>>() {
+ }.getType();
+
+ private @Nullable List<Resource> data = new ArrayList<>();
+
+ public List<Resource> getData() {
+ List<Resource> data = this.data;
+ return Objects.nonNull(data) ? data : List.of();
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2;
+
+import java.util.Objects;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.core.util.ColorUtil.Gamut;
+
+/**
+ * DTO for colour gamut of a light.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public class Gamut2 {
+ private @Nullable PairXy red;
+ private @Nullable PairXy green;
+ private @Nullable PairXy blue;
+
+ public @Nullable Gamut getGamut() {
+ PairXy red = this.red;
+ PairXy green = this.green;
+ PairXy blue = this.blue;
+ if (Objects.nonNull(red) && Objects.nonNull(green) && Objects.nonNull(blue)) {
+ return new Gamut(red.getXY(), green.getXY(), blue.getXY());
+ }
+ return null;
+ }
+
+ public Gamut2 setGamut(Gamut gamut) {
+ red = new PairXy().setXY(gamut.r());
+ green = new PairXy().setXY(gamut.g());
+ blue = new PairXy().setXY(gamut.b());
+ return this;
+ }
+
+ public @Nullable String toPropertyValue() {
+ PairXy red = this.red;
+ PairXy green = this.green;
+ PairXy blue = this.blue;
+ if (Objects.nonNull(red) && Objects.nonNull(green) && Objects.nonNull(blue)) {
+ double[] r = red.getXY();
+ double[] g = green.getXY();
+ double[] b = blue.getXY();
+ return String.format("(%.3f,%.3f) (%.3f,%.3f) (%.3f,%.3f)", r[0], r[1], g[0], g[1], b[0], b[1]);
+ }
+ return null;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.core.library.types.OnOffType;
+import org.openhab.core.library.types.QuantityType;
+import org.openhab.core.library.unit.Units;
+import org.openhab.core.types.State;
+import org.openhab.core.types.UnDefType;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * DTO for CLIP 2 light level sensor.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public class LightLevel {
+ private @SerializedName("light_level") int lightLevel;
+ private @SerializedName("light_level_valid") boolean lightLevelValid;
+ private @Nullable @SerializedName("light_level_report") LightLevelReport lightLevelReport;
+
+ /**
+ * The underlying field is deprecated in the CLIP 2 API.
+ * Moved to light_level_report/light_level
+ * Should be used only as fallback for older firmwares.
+ */
+ public int getLightLevel() {
+ return lightLevel;
+ }
+
+ /**
+ * The underlying field is deprecated in the CLIP 2 API.
+ * Indication whether the value presented in light_level is valid
+ * Should be used only as fallback for older firmwares.
+ */
+ public boolean isLightLevelValid() {
+ return lightLevelValid;
+ }
+
+ /**
+ * Raw sensor light level formula is '10000 * log10(lux + 1)' so apply the inverse formula to convert back to Lux.
+ * NOTE: the Philips/Signify API documentation quotes the formula as '10000 * log10(lux) + 1', however this code
+ * author thinks that that formula is wrong since zero Lux would cause a log10(0) negative infinity overflow!
+ *
+ * @return a QuantityType with light level in Lux, or UNDEF.
+ */
+ public State getLightLevelState() {
+ if (lightLevelValid) {
+ return new QuantityType<>(Math.pow(10f, (double) lightLevel / 10000f) - 1f, Units.LUX);
+ }
+ return UnDefType.UNDEF;
+ }
+
+ public State isLightLevelValidState() {
+ return OnOffType.from(lightLevelValid);
+ }
+
+ public @Nullable LightLevelReport getLightLevelReport() {
+ return lightLevelReport;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2;
+
+import java.time.Instant;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * DTO for CLIP 2 light level sensor report.
+ *
+ * @author Jacob Laursen - Initial contribution
+ */
+@NonNullByDefault
+public class LightLevelReport {
+ private @NonNullByDefault({}) Instant changed;
+ private @SerializedName("light_level") int lightLevel;
+
+ /**
+ * @return last time the value of this property is changed.
+ */
+ public Instant getLastChanged() {
+ return changed;
+ }
+
+ /**
+ * Light level in 10000*log10(lux) +1 measured by sensor.
+ * Logarithmic scale used because the human eye adjusts to light levels and small changes at low lux levels
+ * are more noticeable than at high lux levels. This allows use of linear scale configuration sliders.
+ *
+ * @return light level in 10000*log10(lux) +1 measured by sensor
+ */
+ public int getLightLevel() {
+ return lightLevel;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.Archetype;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * DTO for CLIP 2 product metadata.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public class MetaData {
+ private @Nullable String archetype;
+ private @Nullable String name;
+ private @Nullable @SerializedName("control_id") Integer controlId;
+
+ public Archetype getArchetype() {
+ return Archetype.of(archetype);
+ }
+
+ public @Nullable String getName() {
+ return name;
+ }
+
+ public int getControlId() {
+ Integer controlId = this.controlId;
+ return controlId != null ? controlId.intValue() : 0;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2;
+
+import java.util.Objects;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.core.library.types.QuantityType;
+import org.openhab.core.library.unit.Units;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * DTO for CLIP 2 mirek schema.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public class MirekSchema {
+ private static final int MIN = 153;
+ private static final int MAX = 500;
+
+ public static final MirekSchema DEFAULT_SCHEMA = new MirekSchema();
+
+ private @SerializedName("mirek_minimum") int mirekMinimum = MIN;
+ private @SerializedName("mirek_maximum") int mirekMaximum = MAX;
+
+ public int getMirekMaximum() {
+ return mirekMaximum;
+ }
+
+ public int getMirekMinimum() {
+ return mirekMinimum;
+ }
+
+ private String toKelvin(int mirek) {
+ QuantityType<?> kelvin = QuantityType.valueOf(mirek, Units.MIRED).toInvertibleUnit(Units.KELVIN);
+ return Objects.nonNull(kelvin) ? String.format("%.0f K", kelvin.doubleValue()) : "";
+ }
+
+ public String toPropertyValue() {
+ return String.format("%s .. %s", toKelvin(mirekMinimum), toKelvin(mirekMaximum));
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.core.library.types.OnOffType;
+import org.openhab.core.types.State;
+import org.openhab.core.types.UnDefType;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * DTO for CLIP 2 motion sensor.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public class Motion {
+ private boolean motion;
+ private @SerializedName("motion_valid") boolean motionValid;
+ private @Nullable @SerializedName("motion_report") MotionReport motionReport;
+
+ /**
+ * The underlying field is deprecated in the CLIP 2 API.
+ * Moved to motion_report/motion.
+ * Should be used only as fallback for older firmwares.
+ *
+ * @return true if motion is detected
+ */
+ public boolean isMotion() {
+ return motion;
+ }
+
+ /**
+ * The underlying field is deprecated in the CLIP 2 API.
+ * Motion is valid when motion_report property is present, invalid when absent.
+ * Should be used only as fallback for older firmwares.
+ */
+ public boolean isMotionValid() {
+ return motionValid;
+ }
+
+ public State getMotionState() {
+ return motionValid ? OnOffType.from(motion) : UnDefType.UNDEF;
+ }
+
+ public State getMotionValidState() {
+ return OnOffType.from(motionValid);
+ }
+
+ public @Nullable MotionReport getMotionReport() {
+ return motionReport;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2;
+
+import java.time.Instant;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * DTO for CLIP 2 motion sensor report.
+ *
+ * @author Jacob Laursen - Initial contribution
+ */
+@NonNullByDefault
+public class MotionReport {
+ private @NonNullByDefault({}) Instant changed;
+ private boolean motion;
+
+ /**
+ * @return last time the value of this property is changed.
+ */
+ public Instant getLastChanged() {
+ return changed;
+ }
+
+ /**
+ * @return true if motion is detected
+ */
+ public boolean isMotion() {
+ return motion;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2;
+
+import java.util.Objects;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.hue.internal.exceptions.DTOPresentButEmptyException;
+
+/**
+ * DTO for 'on' state of a light.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public class OnState {
+ private @Nullable Boolean on;
+
+ /**
+ * @throws DTOPresentButEmptyException to indicate that the DTO is present but empty.
+ */
+ public boolean isOn() throws DTOPresentButEmptyException {
+ Boolean on = this.on;
+ if (Objects.nonNull(on)) {
+ return on;
+ }
+ throw new DTOPresentButEmptyException("'on' DTO is present but empty");
+ }
+
+ public void setOn(boolean on) {
+ this.on = on;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2;
+
+/**
+ * DTO that contains an x and y pair of doubles.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+public class PairXy {
+ private double x;
+ private double y;
+
+ public double[] getXY() {
+ return new double[] { x, y };
+ }
+
+ public PairXy setXY(double[] xy) {
+ x = xy.length > 0 ? xy[0] : 0f;
+ y = xy.length > 1 ? xy[1] : 0f;
+ return this;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.BatteryStateType;
+import org.openhab.core.library.types.DecimalType;
+import org.openhab.core.library.types.OnOffType;
+import org.openhab.core.types.State;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * DTO for CLIP 2 power state.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public class Power {
+ private @NonNullByDefault({}) @SerializedName("battery_state") String batteryState;
+ private @SerializedName("battery_level") int batteryLevel;
+
+ public BatteryStateType getBatteryState() {
+ try {
+ return BatteryStateType.valueOf(batteryState.toUpperCase());
+ } catch (IllegalArgumentException e) {
+ return BatteryStateType.CRITICAL;
+ }
+ }
+
+ public int getBatteryLevel() {
+ return batteryLevel;
+ }
+
+ public State getBatteryLowState() {
+ return OnOffType.from(getBatteryState() != BatteryStateType.NORMAL);
+ }
+
+ public State getBatteryLevelState() {
+ return new DecimalType(getBatteryLevel());
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.Archetype;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * DTO for CLIP 2 product data.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public class ProductData {
+ private @NonNullByDefault({}) @SerializedName("model_id") String modelId;
+ private @NonNullByDefault({}) @SerializedName("manufacturer_name") String manufacturerName;
+ private @NonNullByDefault({}) @SerializedName("product_name") String productName;
+ private @NonNullByDefault({}) @SerializedName("product_archetype") String productArchetype;
+ private @NonNullByDefault({}) Boolean certified;
+ private @NonNullByDefault({}) @SerializedName("software_version") String softwareVersion;
+ private @Nullable @SerializedName("hardware_platform_type") String hardwarePlatformType;
+
+ public String getModelId() {
+ return modelId;
+ }
+
+ public String getManufacturerName() {
+ return manufacturerName;
+ }
+
+ public String getProductName() {
+ return productName;
+ }
+
+ public Archetype getProductArchetype() {
+ return Archetype.of(productArchetype);
+ }
+
+ public Boolean getCertified() {
+ return certified != null ? certified : false;
+ }
+
+ public String getSoftwareVersion() {
+ return softwareVersion != null ? softwareVersion : "";
+ }
+
+ public @Nullable String getHardwarePlatformType() {
+ return hardwarePlatformType;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2;
+
+import java.time.Duration;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.SceneRecallAction;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.SmartSceneRecallAction;
+
+/**
+ * DTO for scene and smart scene recall.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public class Recall {
+ private @Nullable @SuppressWarnings("unused") String action;
+ private @Nullable @SuppressWarnings("unused") String status;
+ private @Nullable @SuppressWarnings("unused") Long duration;
+
+ public Recall setAction(SceneRecallAction action) {
+ this.action = action.name().toLowerCase();
+ return this;
+ }
+
+ public Recall setAction(SmartSceneRecallAction action) {
+ this.action = action.name().toLowerCase();
+ return this;
+ }
+
+ public Recall setDuration(Duration duration) {
+ this.duration = duration.toMillis();
+ return this;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2;
+
+import java.util.Objects;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.core.types.State;
+import org.openhab.core.types.UnDefType;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * DTO for CLIP 2 tap switch rotary dial state.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public class RelativeRotary {
+ private @Nullable @SerializedName("last_event") RotationEvent lastEvent;
+ private @Nullable @SerializedName("rotary_report") RotaryReport rotaryReport;
+
+ public State getActionState() {
+ RotationEvent lastEvent = getLastEvent();
+ return Objects.nonNull(lastEvent) ? lastEvent.getActionState() : UnDefType.NULL;
+ }
+
+ /**
+ * The underlying field is deprecated in the CLIP 2 API.
+ * Renamed to RelativeRotaryReport. Indicate which type of rotary event is received.
+ * Should be used only as fallback for older firmwares.
+ */
+ public @Nullable RotationEvent getLastEvent() {
+ return lastEvent;
+ }
+
+ /**
+ * The underlying field is deprecated in the CLIP 2 API.
+ * Renamed to RelativeRotaryReport.
+ * Should be used only as fallback for older firmwares.
+ */
+ public State getStepsState() {
+ RotationEvent lastEvent = getLastEvent();
+ return Objects.nonNull(lastEvent) ? lastEvent.getStepsState() : UnDefType.NULL;
+ }
+
+ public @Nullable RotaryReport getRotaryReport() {
+ return rotaryReport;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2;
+
+import java.math.BigDecimal;
+import java.math.MathContext;
+import java.math.RoundingMode;
+import java.time.Duration;
+import java.time.Instant;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.ActionType;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.ButtonEventType;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.ContactStateType;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.EffectType;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.ResourceType;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.SceneRecallAction;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.SmartSceneRecallAction;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.SmartSceneState;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.TamperStateType;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.ZigbeeStatus;
+import org.openhab.binding.hue.internal.exceptions.DTOPresentButEmptyException;
+import org.openhab.core.library.types.DateTimeType;
+import org.openhab.core.library.types.DecimalType;
+import org.openhab.core.library.types.HSBType;
+import org.openhab.core.library.types.OnOffType;
+import org.openhab.core.library.types.OpenClosedType;
+import org.openhab.core.library.types.PercentType;
+import org.openhab.core.library.types.QuantityType;
+import org.openhab.core.library.types.StringType;
+import org.openhab.core.library.unit.SIUnits;
+import org.openhab.core.library.unit.Units;
+import org.openhab.core.types.Command;
+import org.openhab.core.types.State;
+import org.openhab.core.types.UnDefType;
+import org.openhab.core.util.ColorUtil;
+import org.openhab.core.util.ColorUtil.Gamut;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * Complete Resource information DTO for CLIP 2.
+ *
+ * Note: all fields are @Nullable because some cases do not (must not) use them.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public class Resource {
+
+ public static final double PERCENT_DELTA = 30f;
+ public static final MathContext PERCENT_MATH_CONTEXT = new MathContext(4, RoundingMode.HALF_UP);
+
+ /**
+ * The SSE event mechanism sends resources in a sparse (skeleton) format that only includes state fields whose
+ * values have changed. A sparse resource does not contain the full state of the resource. And the absence of any
+ * field from such a resource does not indicate that the field value is UNDEF, but rather that the value is the same
+ * as what it was previously set to by the last non-sparse resource.
+ */
+ private transient boolean hasSparseData;
+
+ private @Nullable String type;
+ private @Nullable String id;
+ private @Nullable @SerializedName("bridge_id") String bridgeId;
+ private @Nullable @SerializedName("id_v1") String idV1;
+ private @Nullable ResourceReference owner;
+ private @Nullable MetaData metadata;
+ private @Nullable @SerializedName("product_data") ProductData productData;
+ private @Nullable List<ResourceReference> services;
+ private @Nullable OnState on;
+ private @Nullable Dimming dimming;
+ private @Nullable @SerializedName("color_temperature") ColorTemperature colorTemperature;
+ private @Nullable ColorXy color;
+ private @Nullable Alerts alert;
+ private @Nullable Effects effects;
+ private @Nullable @SerializedName("timed_effects") TimedEffects timedEffects;
+ private @Nullable ResourceReference group;
+ private @Nullable List<ActionEntry> actions;
+ private @Nullable Recall recall;
+ private @Nullable Boolean enabled;
+ private @Nullable LightLevel light;
+ private @Nullable Button button;
+ private @Nullable Temperature temperature;
+ private @Nullable Motion motion;
+ private @Nullable @SerializedName("power_state") Power powerState;
+ private @Nullable @SerializedName("relative_rotary") RelativeRotary relativeRotary;
+ private @Nullable List<ResourceReference> children;
+ private @Nullable JsonElement status;
+ private @Nullable @SuppressWarnings("unused") Dynamics dynamics;
+ private @Nullable @SerializedName("contact_report") ContactReport contactReport;
+ private @Nullable @SerializedName("tamper_reports") List<TamperReport> tamperReports;
+ private @Nullable String state;
+
+ /**
+ * Constructor
+ *
+ * @param resourceType
+ */
+ public Resource(@Nullable ResourceType resourceType) {
+ if (Objects.nonNull(resourceType)) {
+ setType(resourceType);
+ }
+ }
+
+ public @Nullable List<ActionEntry> getActions() {
+ return actions;
+ }
+
+ public @Nullable Alerts getAlerts() {
+ return alert;
+ }
+
+ public State getAlertState() {
+ Alerts alerts = this.alert;
+ if (Objects.nonNull(alerts)) {
+ if (!alerts.getActionValues().isEmpty()) {
+ ActionType alertType = alerts.getAction();
+ if (Objects.nonNull(alertType)) {
+ return new StringType(alertType.name());
+ }
+ return new StringType(ActionType.NO_ACTION.name());
+ }
+ }
+ return UnDefType.NULL;
+ }
+
+ public String getArchetype() {
+ MetaData metaData = getMetaData();
+ if (Objects.nonNull(metaData)) {
+ return metaData.getArchetype().toString();
+ }
+ return getType().toString();
+ }
+
+ public State getBatteryLevelState() {
+ Power powerState = this.powerState;
+ return Objects.nonNull(powerState) ? powerState.getBatteryLevelState() : UnDefType.NULL;
+ }
+
+ public State getBatteryLowState() {
+ Power powerState = this.powerState;
+ return Objects.nonNull(powerState) ? powerState.getBatteryLowState() : UnDefType.NULL;
+ }
+
+ public @Nullable String getBridgeId() {
+ String bridgeId = this.bridgeId;
+ return Objects.isNull(bridgeId) || bridgeId.isBlank() ? null : bridgeId;
+ }
+
+ /**
+ * Get the brightness as a PercentType. If off the brightness is 0, otherwise use dimming value.
+ *
+ * @return a PercentType with the dimming state, or UNDEF, or NULL
+ */
+ public State getBrightnessState() {
+ Dimming dimming = this.dimming;
+ if (Objects.nonNull(dimming)) {
+ try {
+ // if off the brightness is 0, otherwise it is dimming value
+ OnState on = this.on;
+ double brightness = Objects.nonNull(on) && !on.isOn() ? 0f
+ : Math.max(0f, Math.min(100f, dimming.getBrightness()));
+ return new PercentType(new BigDecimal(brightness, PERCENT_MATH_CONTEXT));
+ } catch (DTOPresentButEmptyException e) {
+ return UnDefType.UNDEF; // indicates the DTO is present but its inner fields are missing
+ }
+ }
+ return UnDefType.NULL;
+ }
+
+ public @Nullable Button getButton() {
+ return button;
+ }
+
+ /**
+ * Get the state corresponding to a button's last event value multiplied by the controlId found for it in the given
+ * controlIds map. States are decimal values formatted like '1002' where the first digit is the button's controlId
+ * and the last digit is the ordinal value of the button's last event.
+ *
+ * @param controlIds the map of control ids to be referenced.
+ * @return the state.
+ */
+ public State getButtonEventState(Map<String, Integer> controlIds) {
+ Button button = this.button;
+ if (button == null) {
+ return UnDefType.NULL;
+ }
+ ButtonEventType event;
+ ButtonReport buttonReport = button.getButtonReport();
+ if (buttonReport == null) {
+ event = button.getLastEvent();
+ } else {
+ event = buttonReport.getLastEvent();
+ }
+ if (event == null) {
+ return UnDefType.NULL;
+ }
+ return new DecimalType((controlIds.getOrDefault(getId(), 0).intValue() * 1000) + event.ordinal());
+ }
+
+ public State getButtonLastUpdatedState(ZoneId zoneId) {
+ Button button = this.button;
+ if (button == null) {
+ return UnDefType.NULL;
+ }
+ ButtonReport buttonReport = button.getButtonReport();
+ if (buttonReport == null) {
+ return UnDefType.UNDEF;
+ }
+ Instant lastChanged = buttonReport.getLastChanged();
+ if (Instant.EPOCH.equals(lastChanged)) {
+ return UnDefType.UNDEF;
+ }
+ return new DateTimeType(ZonedDateTime.ofInstant(lastChanged, zoneId));
+ }
+
+ public List<ResourceReference> getChildren() {
+ List<ResourceReference> children = this.children;
+ return Objects.nonNull(children) ? children : List.of();
+ }
+
+ /**
+ * Get the color as an HSBType. This returns an HSB that is based on an amalgamation of the color xy, dimming, and
+ * on/off JSON elements. It takes its 'H' and 'S' parts from the 'ColorXy' JSON element, and its 'B' part from the
+ * on/off resp. dimming JSON elements. If off the B part is 0, otherwise it is the dimming element value. Note: this
+ * method is only to be used on cached state DTOs which already have a defined color gamut.
+ *
+ * @return an HSBType containing the current color and brightness level, or UNDEF or NULL.
+ */
+ public State getColorState() {
+ ColorXy color = this.color;
+ if (Objects.nonNull(color)) {
+ try {
+ Gamut gamut = color.getGamut();
+ gamut = Objects.nonNull(gamut) ? gamut : ColorUtil.DEFAULT_GAMUT;
+ HSBType hsb = ColorUtil.xyToHsb(color.getXY(), gamut);
+ OnState on = this.on;
+ Dimming dimming = this.dimming;
+ double brightness = Objects.nonNull(on) && !on.isOn() ? 0
+ : Objects.nonNull(dimming) ? Math.max(0, Math.min(100, dimming.getBrightness())) : 50;
+ return new HSBType(hsb.getHue(), hsb.getSaturation(),
+ new PercentType(new BigDecimal(brightness, PERCENT_MATH_CONTEXT)));
+ } catch (DTOPresentButEmptyException e) {
+ return UnDefType.UNDEF; // indicates the DTO is present but its inner fields are missing
+ }
+ }
+ return UnDefType.NULL;
+ }
+
+ public @Nullable ColorTemperature getColorTemperature() {
+ return colorTemperature;
+ }
+
+ public State getColorTemperatureAbsoluteState() {
+ ColorTemperature colorTemp = colorTemperature;
+ if (Objects.nonNull(colorTemp)) {
+ try {
+ QuantityType<?> colorTemperature = colorTemp.getAbsolute();
+ if (Objects.nonNull(colorTemperature)) {
+ return colorTemperature;
+ }
+ } catch (DTOPresentButEmptyException e) {
+ return UnDefType.UNDEF; // indicates the DTO is present but its inner fields are missing
+ }
+ }
+ return UnDefType.NULL;
+ }
+
+ /**
+ * Get the colour temperature in percent. Note: this method is only to be used on cached state DTOs which already
+ * have a defined mirek schema.
+ *
+ * @return a PercentType with the colour temperature percentage.
+ */
+ public State getColorTemperaturePercentState() {
+ ColorTemperature colorTemperature = this.colorTemperature;
+ if (Objects.nonNull(colorTemperature)) {
+ try {
+ Double percent = colorTemperature.getPercent();
+ if (Objects.nonNull(percent)) {
+ return new PercentType(new BigDecimal(percent, PERCENT_MATH_CONTEXT));
+ }
+ } catch (DTOPresentButEmptyException e) {
+ return UnDefType.UNDEF; // indicates the DTO is present but its inner fields are missing
+ }
+ }
+ return UnDefType.NULL;
+ }
+
+ public @Nullable ColorXy getColorXy() {
+ return color;
+ }
+
+ /**
+ * Return an HSB where the HS part is derived from the color xy JSON element (only), so the B part is 100%
+ *
+ * @return an HSBType.
+ */
+ public State getColorXyState() {
+ ColorXy color = this.color;
+ if (Objects.nonNull(color)) {
+ try {
+ Gamut gamut = color.getGamut();
+ gamut = Objects.nonNull(gamut) ? gamut : ColorUtil.DEFAULT_GAMUT;
+ HSBType hsb = ColorUtil.xyToHsb(color.getXY(), gamut);
+ return new HSBType(hsb.getHue(), hsb.getSaturation(), PercentType.HUNDRED);
+ } catch (DTOPresentButEmptyException e) {
+ return UnDefType.UNDEF; // indicates the DTO is present but its inner fields are missing
+ }
+ }
+ return UnDefType.NULL;
+ }
+
+ public State getContactLastUpdatedState(ZoneId zoneId) {
+ ContactReport contactReport = this.contactReport;
+ return Objects.nonNull(contactReport)
+ ? new DateTimeType(ZonedDateTime.ofInstant(contactReport.getLastChanged(), zoneId))
+ : UnDefType.NULL;
+ }
+
+ public State getContactState() {
+ ContactReport contactReport = this.contactReport;
+ return Objects.isNull(contactReport) ? UnDefType.NULL
+ : ContactStateType.CONTACT == contactReport.getContactState() ? OpenClosedType.CLOSED
+ : OpenClosedType.OPEN;
+ }
+
+ public int getControlId() {
+ MetaData metadata = this.metadata;
+ return Objects.nonNull(metadata) ? metadata.getControlId() : 0;
+ }
+
+ public @Nullable Dimming getDimming() {
+ return dimming;
+ }
+
+ /**
+ * Return a PercentType which is derived from the dimming JSON element (only).
+ *
+ * @return a PercentType.
+ */
+ public State getDimmingState() {
+ Dimming dimming = this.dimming;
+ if (Objects.nonNull(dimming)) {
+ try {
+ double dimmingValue = Math.max(0f, Math.min(100f, dimming.getBrightness()));
+ return new PercentType(new BigDecimal(dimmingValue, PERCENT_MATH_CONTEXT));
+ } catch (DTOPresentButEmptyException e) {
+ return UnDefType.UNDEF; // indicates the DTO is present but its inner fields are missing
+ }
+ }
+ return UnDefType.NULL;
+ }
+
+ public @Nullable Effects getFixedEffects() {
+ return effects;
+ }
+
+ /**
+ * Get the amalgamated effect state. The result may be either from an 'effects' field or from a 'timedEffects'
+ * field. If both fields are missing it returns UnDefType.NULL, otherwise if either field is present and has an
+ * active value (other than EffectType.NO_EFFECT) it returns a StringType of the name of the respective active
+ * effect; and if none of the above apply, it returns a StringType of 'NO_EFFECT'.
+ *
+ * @return either a StringType value or UnDefType.NULL
+ */
+ public State getEffectState() {
+ Effects effects = this.effects;
+ TimedEffects timedEffects = this.timedEffects;
+ if (Objects.isNull(effects) && Objects.isNull(timedEffects)) {
+ return UnDefType.NULL;
+ }
+ EffectType effect = Objects.nonNull(effects) ? effects.getStatus() : null;
+ if (Objects.nonNull(effect) && effect != EffectType.NO_EFFECT) {
+ return new StringType(effect.name());
+ }
+ EffectType timedEffect = Objects.nonNull(timedEffects) ? timedEffects.getStatus() : null;
+ if (Objects.nonNull(timedEffect) && timedEffect != EffectType.NO_EFFECT) {
+ return new StringType(timedEffect.name());
+ }
+ return new StringType(EffectType.NO_EFFECT.name());
+ }
+
+ public @Nullable Boolean getEnabled() {
+ return enabled;
+ }
+
+ public State getEnabledState() {
+ Boolean enabled = this.enabled;
+ return Objects.nonNull(enabled) ? OnOffType.from(enabled.booleanValue()) : UnDefType.NULL;
+ }
+
+ public @Nullable Gamut getGamut() {
+ ColorXy color = this.color;
+ return Objects.nonNull(color) ? color.getGamut() : null;
+ }
+
+ public @Nullable ResourceReference getGroup() {
+ return group;
+ }
+
+ public String getId() {
+ String id = this.id;
+ return Objects.nonNull(id) ? id : "";
+ }
+
+ public String getIdV1() {
+ String idV1 = this.idV1;
+ return Objects.nonNull(idV1) ? idV1 : "";
+ }
+
+ public @Nullable LightLevel getLightLevel() {
+ return light;
+ }
+
+ public State getLightLevelState() {
+ LightLevel lightLevel = this.light;
+ if (lightLevel == null) {
+ return UnDefType.NULL;
+ }
+ LightLevelReport lightLevelReport = lightLevel.getLightLevelReport();
+ if (lightLevelReport == null) {
+ return lightLevel.getLightLevelState();
+ }
+ return new QuantityType<>(Math.pow(10f, (double) lightLevelReport.getLightLevel() / 10000f) - 1f, Units.LUX);
+ }
+
+ public State getLightLevelLastUpdatedState(ZoneId zoneId) {
+ LightLevel lightLevel = this.light;
+ if (lightLevel == null) {
+ return UnDefType.NULL;
+ }
+ LightLevelReport lightLevelReport = lightLevel.getLightLevelReport();
+ if (lightLevelReport == null) {
+ return UnDefType.UNDEF;
+ }
+ Instant lastChanged = lightLevelReport.getLastChanged();
+ if (Instant.EPOCH.equals(lastChanged)) {
+ return UnDefType.UNDEF;
+ }
+ return new DateTimeType(ZonedDateTime.ofInstant(lastChanged, zoneId));
+ }
+
+ public @Nullable MetaData getMetaData() {
+ return metadata;
+ }
+
+ public @Nullable Double getMinimumDimmingLevel() {
+ Dimming dimming = this.dimming;
+ return Objects.nonNull(dimming) ? dimming.getMinimumDimmingLevel() : null;
+ }
+
+ public @Nullable MirekSchema getMirekSchema() {
+ ColorTemperature colorTemp = this.colorTemperature;
+ return Objects.nonNull(colorTemp) ? colorTemp.getMirekSchema() : null;
+ }
+
+ public @Nullable Motion getMotion() {
+ return motion;
+ }
+
+ public State getMotionState() {
+ Motion motion = this.motion;
+ if (motion == null) {
+ return UnDefType.NULL;
+ }
+ MotionReport motionReport = motion.getMotionReport();
+ if (motionReport == null) {
+ return motion.getMotionState();
+ }
+ return OnOffType.from(motionReport.isMotion());
+ }
+
+ public State getMotionLastUpdatedState(ZoneId zoneId) {
+ Motion motion = this.motion;
+ if (motion == null) {
+ return UnDefType.NULL;
+ }
+ MotionReport motionReport = motion.getMotionReport();
+ if (motionReport == null) {
+ return UnDefType.UNDEF;
+ }
+ Instant lastChanged = motionReport.getLastChanged();
+ if (Instant.EPOCH.equals(lastChanged)) {
+ return UnDefType.UNDEF;
+ }
+ return new DateTimeType(ZonedDateTime.ofInstant(lastChanged, zoneId));
+ }
+
+ public State getMotionValidState() {
+ Motion motion = this.motion;
+ return Objects.nonNull(motion) ? motion.getMotionValidState() : UnDefType.NULL;
+ }
+
+ public String getName() {
+ MetaData metaData = getMetaData();
+ if (Objects.nonNull(metaData)) {
+ String name = metaData.getName();
+ if (Objects.nonNull(name)) {
+ return name;
+ }
+ }
+ return getType().toString();
+ }
+
+ /**
+ * Return the state of the On/Off element (only).
+ */
+ public State getOnOffState() {
+ try {
+ OnState on = this.on;
+ return Objects.nonNull(on) ? OnOffType.from(on.isOn()) : UnDefType.NULL;
+ } catch (DTOPresentButEmptyException e) {
+ return UnDefType.UNDEF; // indicates the DTO is present but its inner fields are missing
+ }
+ }
+
+ public @Nullable OnState getOnState() {
+ return on;
+ }
+
+ public @Nullable ResourceReference getOwner() {
+ return owner;
+ }
+
+ public @Nullable Power getPowerState() {
+ return powerState;
+ }
+
+ public @Nullable ProductData getProductData() {
+ return productData;
+ }
+
+ public String getProductName() {
+ ProductData productData = getProductData();
+ if (Objects.nonNull(productData)) {
+ return productData.getProductName();
+ }
+ return getType().toString();
+ }
+
+ public @Nullable Recall getRecall() {
+ return recall;
+ }
+
+ public @Nullable RelativeRotary getRelativeRotary() {
+ return relativeRotary;
+ }
+
+ public State getRotaryStepsState() {
+ RelativeRotary relativeRotary = this.relativeRotary;
+ if (relativeRotary == null) {
+ return UnDefType.NULL;
+ }
+ RotaryReport rotaryReport = relativeRotary.getRotaryReport();
+ if (rotaryReport == null) {
+ return relativeRotary.getStepsState();
+ }
+ Rotation rotation = rotaryReport.getRotation();
+ if (rotation == null) {
+ return UnDefType.NULL;
+ }
+ return rotation.getStepsState();
+ }
+
+ public State getRotaryStepsLastUpdatedState(ZoneId zoneId) {
+ RelativeRotary relativeRotary = this.relativeRotary;
+ if (relativeRotary == null) {
+ return UnDefType.NULL;
+ }
+ RotaryReport rotaryReport = relativeRotary.getRotaryReport();
+ if (rotaryReport == null) {
+ return UnDefType.UNDEF;
+ }
+ Instant lastChanged = rotaryReport.getLastChanged();
+ if (Instant.EPOCH.equals(lastChanged)) {
+ return UnDefType.UNDEF;
+ }
+ return new DateTimeType(ZonedDateTime.ofInstant(lastChanged, zoneId));
+ }
+
+ /**
+ * Check if the scene resource contains a 'status.active' element. If such an element is present, returns a Boolean
+ * Optional whose value depends on the value of that element, or an empty Optional if it is not.
+ *
+ * @return true, false, or empty.
+ */
+ public Optional<Boolean> getSceneActive() {
+ if (ResourceType.SCENE == getType()) {
+ JsonElement status = this.status;
+ if (Objects.nonNull(status) && status.isJsonObject()) {
+ JsonElement active = ((JsonObject) status).get("active");
+ if (Objects.nonNull(active) && active.isJsonPrimitive()) {
+ return Optional.of(!"inactive".equalsIgnoreCase(active.getAsString()));
+ }
+ }
+ }
+ return Optional.empty();
+ }
+
+ /**
+ * If the getSceneActive() optional result is empty return 'UnDefType.NULL'. Otherwise if the optional result is
+ * present and 'true' (i.e. the scene is active) return the scene name. Or finally (the optional result is present
+ * and 'false') return 'UnDefType.UNDEF'.
+ *
+ * @return either 'UnDefType.NULL', a StringType containing the (active) scene name, or 'UnDefType.UNDEF'.
+ */
+ public State getSceneState() {
+ return getSceneActive().map(a -> a ? new StringType(getName()) : UnDefType.UNDEF).orElse(UnDefType.NULL);
+ }
+
+ /**
+ * Check if the smart scene resource contains a 'state' element. If such an element is present, returns a Boolean
+ * Optional whose value depends on the value of that element, or an empty Optional if it is not.
+ *
+ * @return true, false, or empty.
+ */
+ public Optional<Boolean> getSmartSceneActive() {
+ if (ResourceType.SMART_SCENE == getType()) {
+ String state = this.state;
+ if (Objects.nonNull(state)) {
+ return Optional.of(SmartSceneState.ACTIVE == SmartSceneState.of(state));
+ }
+ }
+ return Optional.empty();
+ }
+
+ /**
+ * If the getSmartSceneActive() optional result is empty return 'UnDefType.NULL'. Otherwise if the optional result
+ * is present and 'true' (i.e. the scene is active) return the smart scene name. Or finally (the optional result is
+ * present and 'false') return 'UnDefType.UNDEF'.
+ *
+ * @return either 'UnDefType.NULL', a StringType containing the (active) scene name, or 'UnDefType.UNDEF'.
+ */
+ public State getSmartSceneState() {
+ return getSmartSceneActive().map(a -> a ? new StringType(getName()) : UnDefType.UNDEF).orElse(UnDefType.NULL);
+ }
+
+ public List<ResourceReference> getServiceReferences() {
+ List<ResourceReference> services = this.services;
+ return Objects.nonNull(services) ? services : List.of();
+ }
+
+ public JsonObject getStatus() {
+ JsonElement status = this.status;
+ if (Objects.nonNull(status) && status.isJsonObject()) {
+ return status.getAsJsonObject();
+ }
+ return new JsonObject();
+ }
+
+ public State getTamperLastUpdatedState(ZoneId zoneId) {
+ TamperReport report = getTamperReportsLatest();
+ return Objects.nonNull(report) ? new DateTimeType(ZonedDateTime.ofInstant(report.getLastChanged(), zoneId))
+ : UnDefType.NULL;
+ }
+
+ /**
+ * The the Hue bridge could return its raw list of tamper reports in any order, so sort the list (latest entry
+ * first) according to the respective 'changed' instant and return the first entry i.e. the latest changed entry.
+ *
+ * @return the latest changed tamper report
+ */
+ private @Nullable TamperReport getTamperReportsLatest() {
+ List<TamperReport> reports = this.tamperReports;
+ return Objects.nonNull(reports)
+ ? reports.stream().sorted((e1, e2) -> e2.getLastChanged().compareTo(e1.getLastChanged())).findFirst()
+ .orElse(null)
+ : null;
+ }
+
+ public State getTamperState() {
+ TamperReport report = getTamperReportsLatest();
+ return Objects.nonNull(report)
+ ? TamperStateType.TAMPERED == report.getTamperState() ? OpenClosedType.OPEN : OpenClosedType.CLOSED
+ : UnDefType.NULL;
+ }
+
+ public @Nullable Temperature getTemperature() {
+ return temperature;
+ }
+
+ public State getTemperatureState() {
+ Temperature temperature = this.temperature;
+ if (temperature == null) {
+ return UnDefType.NULL;
+ }
+ TemperatureReport temperatureReport = temperature.getTemperatureReport();
+ if (temperatureReport == null) {
+ return temperature.getTemperatureState();
+ }
+ return new QuantityType<>(temperatureReport.getTemperature(), SIUnits.CELSIUS);
+ }
+
+ public State getTemperatureLastUpdatedState(ZoneId zoneId) {
+ Temperature temperature = this.temperature;
+ if (temperature == null) {
+ return UnDefType.NULL;
+ }
+ TemperatureReport temperatureReport = temperature.getTemperatureReport();
+ if (temperatureReport == null) {
+ return UnDefType.UNDEF;
+ }
+ Instant lastChanged = temperatureReport.getLastChanged();
+ if (Instant.EPOCH.equals(lastChanged)) {
+ return UnDefType.UNDEF;
+ }
+ return new DateTimeType(ZonedDateTime.ofInstant(lastChanged, zoneId));
+ }
+
+ public State getTemperatureValidState() {
+ Temperature temperature = this.temperature;
+ return Objects.nonNull(temperature) ? temperature.getTemperatureValidState() : UnDefType.NULL;
+ }
+
+ public @Nullable TimedEffects getTimedEffects() {
+ return timedEffects;
+ }
+
+ public ResourceType getType() {
+ return ResourceType.of(type);
+ }
+
+ public State getZigbeeState() {
+ ZigbeeStatus zigbeeStatus = getZigbeeStatus();
+ return Objects.nonNull(zigbeeStatus) ? new StringType(zigbeeStatus.toString()) : UnDefType.NULL;
+ }
+
+ public @Nullable ZigbeeStatus getZigbeeStatus() {
+ JsonElement status = this.status;
+ if (Objects.nonNull(status) && status.isJsonPrimitive()) {
+ return ZigbeeStatus.of(status.getAsString());
+ }
+ return null;
+ }
+
+ public boolean hasFullState() {
+ return !hasSparseData;
+ }
+
+ /**
+ * Mark that the resource has sparse data.
+ *
+ * @return this instance.
+ */
+ public Resource markAsSparse() {
+ hasSparseData = true;
+ return this;
+ }
+
+ public Resource setAlerts(Alerts alert) {
+ this.alert = alert;
+ return this;
+ }
+
+ public Resource setColorTemperature(ColorTemperature colorTemperature) {
+ this.colorTemperature = colorTemperature;
+ return this;
+ }
+
+ public Resource setColorXy(ColorXy color) {
+ this.color = color;
+ return this;
+ }
+
+ public Resource setContactReport(ContactReport contactReport) {
+ this.contactReport = contactReport;
+ return this;
+ }
+
+ public Resource setDimming(Dimming dimming) {
+ this.dimming = dimming;
+ return this;
+ }
+
+ public Resource setDynamicsDuration(Duration duration) {
+ dynamics = new Dynamics().setDuration(duration);
+ return this;
+ }
+
+ public Resource setFixedEffects(Effects effect) {
+ this.effects = effect;
+ return this;
+ }
+
+ public Resource setEnabled(Command command) {
+ if (command instanceof OnOffType) {
+ this.enabled = ((OnOffType) command) == OnOffType.ON;
+ }
+ return this;
+ }
+
+ public Resource setId(String id) {
+ this.id = id;
+ return this;
+ }
+
+ public Resource setMetadata(MetaData metadata) {
+ this.metadata = metadata;
+ return this;
+ }
+
+ public Resource setMirekSchema(@Nullable MirekSchema schema) {
+ ColorTemperature colorTemperature = this.colorTemperature;
+ if (Objects.nonNull(colorTemperature)) {
+ colorTemperature.setMirekSchema(schema);
+ }
+ return this;
+ }
+
+ /**
+ * Set the on/off JSON element (only).
+ *
+ * @param command an OnOffTypee command value.
+ * @return this resource instance.
+ */
+ public Resource setOnOff(Command command) {
+ if (command instanceof OnOffType) {
+ OnOffType onOff = (OnOffType) command;
+ OnState on = this.on;
+ on = Objects.nonNull(on) ? on : new OnState();
+ on.setOn(OnOffType.ON.equals(onOff));
+ this.on = on;
+ }
+ return this;
+ }
+
+ public void setOnState(OnState on) {
+ this.on = on;
+ }
+
+ public Resource setRecallAction(SceneRecallAction recallAction) {
+ Recall recall = this.recall;
+ this.recall = ((Objects.nonNull(recall) ? recall : new Recall())).setAction(recallAction);
+ return this;
+ }
+
+ public Resource setRecallAction(SmartSceneRecallAction recallAction) {
+ Recall recall = this.recall;
+ this.recall = ((Objects.nonNull(recall) ? recall : new Recall())).setAction(recallAction);
+ return this;
+ }
+
+ public Resource setRecallDuration(Duration recallDuration) {
+ Recall recall = this.recall;
+ this.recall = ((Objects.nonNull(recall) ? recall : new Recall())).setDuration(recallDuration);
+ return this;
+ }
+
+ public Resource setTamperReports(List<TamperReport> tamperReports) {
+ this.tamperReports = tamperReports;
+ return this;
+ }
+
+ public Resource setTimedEffects(TimedEffects timedEffects) {
+ this.timedEffects = timedEffects;
+ return this;
+ }
+
+ public Resource setTimedEffectsDuration(Duration dynamicsDuration) {
+ TimedEffects timedEffects = this.timedEffects;
+ if (Objects.nonNull(timedEffects)) {
+ timedEffects.setDuration(dynamicsDuration);
+ }
+ return this;
+ }
+
+ public Resource setType(ResourceType resourceType) {
+ this.type = resourceType.name().toLowerCase();
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ String id = this.id;
+ return String.format("id:%s, type:%s", Objects.nonNull(id) ? id : "?" + " ".repeat(35),
+ getType().name().toLowerCase());
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.ResourceType;
+
+/**
+ * DTO that contains an API reference element.
+ *
+ * The V2 API is set up in such a way that all resources of the same type are grouped together under the
+ * {@code /resource/<resourcetype>} endpoint, but all those resources commonly reference each other, which is done in a
+ * standardized way by indicating the resource type (rtype) and resource id (rid).
+ *
+ * A typical usage is in a single physical device that hosts multiple services. An existing example is the Philips Hue
+ * Motion sensor which has a motion, light_level, and temperature service, but theoretically any combination can be
+ * supported such as an integrated device with two independently controllable light points and a motion sensor.
+ *
+ * This means that the information of the device itself can be found under the /device resource endpoint, but it then
+ * contains a services array which references for example the light and motion resources, for which the details can be
+ * found under the /light and /motion resource endpoints respectively. Other services the device might have, such as a
+ * Zigbee radio (zigbee_connectivy) or battery (device_power) are modeled in the same way.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public class ResourceReference {
+ private @Nullable String rid;
+ private @NonNullByDefault({}) String rtype;
+
+ @Override
+ public boolean equals(@Nullable Object obj) {
+ String rid = this.rid;
+ return (obj instanceof ResourceReference) && (rid != null) && rid.equals(((ResourceReference) obj).rid);
+ }
+
+ public @Nullable String getId() {
+ return rid;
+ }
+
+ public ResourceType getType() {
+ return ResourceType.of(rtype);
+ }
+
+ public ResourceReference setId(String id) {
+ rid = id;
+ return this;
+ }
+
+ public ResourceReference setType(ResourceType resourceType) {
+ rtype = resourceType.name().toLowerCase();
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ String id = rid;
+ return String.format("id:%s, type:%s", id != null ? id : "*" + " ".repeat(35), getType().name().toLowerCase());
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * DTO for CLIP 2 to retrieve a list of generic resources from the bridge.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public class Resources {
+ private List<Error> errors = new ArrayList<>();
+ private List<Resource> data = new ArrayList<>();
+
+ public List<String> getErrors() {
+ return errors.stream().map(Error::getDescription).collect(Collectors.toList());
+ }
+
+ public boolean hasErrors() {
+ return !errors.isEmpty();
+ }
+
+ public List<Resource> getResources() {
+ return data;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2;
+
+import java.time.Instant;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.RotationEventType;
+
+/**
+ * DTO for CLIP 2 relative rotary report.
+ *
+ * @author Jacob Laursen - Initial contribution
+ */
+@NonNullByDefault
+public class RotaryReport {
+ private @NonNullByDefault({}) Instant updated;
+ private @Nullable String action;
+ private @Nullable Rotation rotation;
+
+ /**
+ * @return last time the value of this property is changed.
+ */
+ public Instant getLastChanged() {
+ return updated;
+ }
+
+ /**
+ * @return which type of rotary event is received
+ */
+ public @Nullable RotationEventType getAction() {
+ String action = this.action;
+ return action == null ? null : RotationEventType.valueOf(action.toUpperCase());
+ }
+
+ public @Nullable Rotation getRotation() {
+ return rotation;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2;
+
+import java.util.Objects;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.DirectionType;
+import org.openhab.core.library.types.DecimalType;
+import org.openhab.core.types.State;
+import org.openhab.core.types.UnDefType;
+
+/**
+ * DTO for rotation element of a tap dial switch.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public class Rotation {
+ private @Nullable String direction;
+ private @Nullable Integer duration;
+ private @Nullable Integer steps;
+
+ public @Nullable DirectionType getDirection() {
+ String direction = this.direction;
+ return Objects.nonNull(direction) ? DirectionType.valueOf(direction.toUpperCase()) : null;
+ }
+
+ public int getDuration() {
+ Integer duration = this.duration;
+ return Objects.nonNull(duration) ? duration.intValue() : 0;
+ }
+
+ public int getSteps() {
+ Integer steps = this.steps;
+ return Objects.nonNull(steps) ? steps.intValue() : 0;
+ }
+
+ /**
+ * Get the state corresponding to a relative rotary dial's last steps value. Clockwise rotations are positive, and
+ * counter clockwise rotations negative.
+ *
+ * @return the state or UNDEF.
+ */
+ public State getStepsState() {
+ DirectionType direction = getDirection();
+ Integer steps = this.steps;
+ if (Objects.nonNull(direction) && Objects.nonNull(steps)) {
+ return new DecimalType(DirectionType.CLOCK_WISE.equals(direction) ? steps.intValue() : -steps.intValue());
+ }
+ return UnDefType.NULL;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2;
+
+import java.util.Objects;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.RotationEventType;
+import org.openhab.core.library.types.StringType;
+import org.openhab.core.types.State;
+import org.openhab.core.types.UnDefType;
+
+/**
+ * DTO for rotation event of a dial switch.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public class RotationEvent {
+ private @Nullable String action;
+ private @Nullable Rotation rotation;
+
+ public @Nullable RotationEventType getAction() {
+ String action = this.action;
+ return Objects.nonNull(action) ? RotationEventType.valueOf(action.toUpperCase()) : null;
+ }
+
+ public State getActionState() {
+ RotationEventType action = getAction();
+ return Objects.nonNull(action) ? new StringType(action.name()) : UnDefType.NULL;
+ }
+
+ public @Nullable Rotation getRotation() {
+ return rotation;
+ }
+
+ public State getStepsState() {
+ Rotation rotation = this.rotation;
+ return Objects.nonNull(rotation) ? rotation.getStepsState() : UnDefType.NULL;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2;
+
+import java.time.Instant;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.TamperStateType;
+
+/**
+ * DTO for CLIP 2 home security tamper switch.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public class TamperReport {
+
+ private @NonNullByDefault({}) Instant changed;
+ private @NonNullByDefault({}) String state;
+
+ public Instant getLastChanged() {
+ return changed;
+ }
+
+ public TamperStateType getTamperState() throws IllegalArgumentException {
+ return TamperStateType.valueOf(state.toUpperCase());
+ }
+
+ public TamperReport setLastChanged(Instant changed) {
+ this.changed = changed;
+ return this;
+ }
+
+ public TamperReport setTamperState(String state) {
+ this.state = state;
+ return this;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.core.library.types.OnOffType;
+import org.openhab.core.library.types.QuantityType;
+import org.openhab.core.library.unit.SIUnits;
+import org.openhab.core.types.State;
+import org.openhab.core.types.UnDefType;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * DTO for CLIP 2 temperature sensor.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public class Temperature {
+ private float temperature;
+ private @SerializedName("temperature_valid") boolean temperatureValid;
+ private @Nullable @SerializedName("temperature_report") TemperatureReport temperatureReport;
+
+ /**
+ * The underlying field is deprecated in the CLIP 2 API.
+ * Moved to temperature_report/temperature.
+ * Should be used only as fallback for older firmwares.
+ *
+ * @return temperature in 1.00 degrees Celsius
+ */
+ public float getTemperature() {
+ return temperature;
+ }
+
+ /**
+ * The underlying field is deprecated in the CLIP 2 API.
+ * Indication whether the value presented in temperature is valid
+ * Should be used only as fallback for older firmwares.
+ */
+ public boolean isTemperatureValid() {
+ return temperatureValid;
+ }
+
+ public State getTemperatureState() {
+ return temperatureValid ? new QuantityType<>(temperature, SIUnits.CELSIUS) : UnDefType.UNDEF;
+ }
+
+ public State getTemperatureValidState() {
+ return OnOffType.from(temperatureValid);
+ }
+
+ public @Nullable TemperatureReport getTemperatureReport() {
+ return temperatureReport;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2;
+
+import java.time.Instant;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * DTO for CLIP 2 temperature sensor report.
+ *
+ * @author Jacob Laursen - Initial contribution
+ */
+@NonNullByDefault
+public class TemperatureReport {
+ private @NonNullByDefault({}) Instant changed;
+ private float temperature;
+
+ /**
+ * @return last time the value of this property is changed.
+ */
+ public Instant getLastChanged() {
+ return changed;
+ }
+
+ /**
+ * @return temperature in 1.00 degrees Celsius
+ */
+ public float getTemperature() {
+ return temperature;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2;
+
+import java.time.Duration;
+import java.util.Objects;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
+/**
+ * DTO for 'timed_effects' of a light.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public class TimedEffects extends Effects {
+ public static final Duration DEFAULT_DURATION = Duration.ofMinutes(15);
+
+ private @Nullable Long duration;
+
+ public @Nullable Duration getDuration() {
+ Long duration = this.duration;
+ return Objects.nonNull(duration) ? Duration.ofMillis(duration) : null;
+ }
+
+ public TimedEffects setDuration(Duration duration) {
+ this.duration = duration.toMillis();
+ return this;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2.enums;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
+/**
+ * Enum for 'alert' actions.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public enum ActionType {
+ BREATHE,
+ NO_ACTION;
+
+ public static ActionType of(@Nullable String value) {
+ if (value != null) {
+ try {
+ return valueOf(value.toUpperCase());
+ } catch (IllegalArgumentException e) {
+ // fall through
+ }
+ }
+ return NO_ACTION;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2.enums;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
+/**
+ * Enum for product archetypes.
+ *
+ * @see <a href="https://developers.meethue.com/develop/hue-api-v2/api-reference/#resource_light_get">API v2
+ * documentation</a>
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public enum Archetype {
+ // device archetypes
+ BRIDGE_V2,
+ UNKNOWN_ARCHETYPE,
+ CLASSIC_BULB,
+ SULTAN_BULB,
+ FLOOD_BULB,
+ SPOT_BULB,
+ CANDLE_BULB,
+ LUSTER_BULB,
+ PENDANT_ROUND,
+ PENDANT_LONG,
+ CEILING_ROUND,
+ CEILING_SQUARE,
+ FLOOR_SHADE,
+ FLOOR_LANTERN,
+ TABLE_SHADE,
+ RECESSED_CEILING,
+ RECESSED_FLOOR,
+ SINGLE_SPOT,
+ DOUBLE_SPOT,
+ TABLE_WASH,
+ WALL_LANTERN,
+ WALL_SHADE,
+ FLEXIBLE_LAMP,
+ GROUND_SPOT,
+ WALL_SPOT,
+ PLUG,
+ HUE_GO,
+ HUE_LIGHTSTRIP,
+ HUE_IRIS,
+ HUE_BLOOM,
+ BOLLARD,
+ WALL_WASHER,
+ HUE_PLAY,
+ VINTAGE_BULB,
+ CHRISTMAS_TREE,
+ HUE_CENTRIS,
+ HUE_LIGHTSTRIP_TV,
+ HUE_TUBE,
+ HUE_SIGNE,
+ STRING_LIGHT,
+ // room archetypes
+ LIVING_ROOM,
+ KITCHEN,
+ DINING,
+ BEDROOM,
+ KIDS_BEDROOM,
+ BATHROOM,
+ NURSERY,
+ RECREATION,
+ OFFICE,
+ GYM,
+ HALLWAY,
+ TOILET,
+ FRONT_DOOR,
+ GARAGE,
+ TERRACE,
+ GARDEN,
+ DRIVEWAY,
+ CARPORT,
+ HOME,
+ DOWNSTAIRS,
+ UPSTAIRS,
+ TOP_FLOOR,
+ ATTIC,
+ GUEST_ROOM,
+ STAIRCASE,
+ LOUNGE,
+ MAN_CAVE,
+ COMPUTER,
+ STUDIO,
+ MUSIC,
+ TV,
+ READING,
+ CLOSET,
+ STORAGE,
+ LAUNDRY_ROOM,
+ BALCONY,
+ PORCH,
+ BARBECUE,
+ POOL,
+ OTHER;
+
+ public static Archetype of(@Nullable String value) {
+ if (value != null) {
+ try {
+ return valueOf(value.toUpperCase());
+ } catch (IllegalArgumentException e) {
+ // fall through
+ }
+ }
+ return UNKNOWN_ARCHETYPE;
+ }
+
+ @Override
+ public String toString() {
+ String s = this.name().replace("_", " ");
+ return s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase();
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2.enums;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * Enum for types battery state.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public enum BatteryStateType {
+ NORMAL,
+ LOW,
+ CRITICAL
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2.enums;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * Enum for types button press.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public enum ButtonEventType {
+ INITIAL_PRESS,
+ REPEAT,
+ SHORT_RELEASE,
+ LONG_RELEASE,
+ DOUBLE_SHORT_RELEASE
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2.enums;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * Enum for security contact states.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public enum ContactStateType {
+ NO_CONTACT,
+ CONTACT
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2.enums;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * Enum for tap dial rotation directions.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public enum DirectionType {
+ CLOCK_WISE,
+ COUNTER_CLOCK_WISE
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2.enums;
+
+import java.util.Set;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
+/**
+ * Enum for 'effect' types.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public enum EffectType {
+ // fixed Effects
+ PRISM,
+ OPAL,
+ GLISTEN,
+ SPARKLE,
+ FIRE,
+ CANDLE,
+ // timed Effects
+ SUNRISE,
+ // applies to both
+ NO_EFFECT;
+
+ private static final Set<EffectType> FIXED = Set.of(PRISM, OPAL, GLISTEN, SPARKLE, FIRE, CANDLE);
+ private static final Set<EffectType> TIMED = Set.of(SUNRISE);
+
+ public static EffectType of(@Nullable String value) {
+ if (value != null) {
+ try {
+ return valueOf(value.toUpperCase());
+ } catch (IllegalArgumentException e) {
+ // fall through
+ }
+ }
+ return NO_EFFECT;
+ }
+
+ public boolean isFixed() {
+ return FIXED.contains(this);
+ }
+
+ public boolean isTimed() {
+ return TIMED.contains(this);
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2.enums;
+
+import java.util.EnumSet;
+import java.util.Set;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
+/**
+ * Enum for resource types.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public enum ResourceType {
+ AUTH_V1,
+ BEHAVIOR_INSTANCE,
+ BEHAVIOR_SCRIPT,
+ BRIDGE,
+ BRIDGE_HOME,
+ BUTTON,
+ CAMERA_MOTION,
+ CONTACT,
+ DEVICE,
+ DEVICE_POWER,
+ ENTERTAINMENT,
+ ENTERTAINMENT_CONFIGURATION,
+ GEOFENCE,
+ GEOFENCE_CLIENT,
+ GEOLOCATION,
+ GROUPED_LIGHT,
+ HOMEKIT,
+ LIGHT,
+ LIGHT_LEVEL,
+ MOTION,
+ PUBLIC_IMAGE,
+ ROOM,
+ RELATIVE_ROTARY,
+ SCENE,
+ TAMPER,
+ SMART_SCENE,
+ TEMPERATURE,
+ ZGP_CONNECTIVITY,
+ ZIGBEE_CONNECTIVITY,
+ ZONE,
+ UPDATE,
+ ADD,
+ DELETE,
+ ERROR;
+
+ public static final Set<ResourceType> SSE_TYPES = EnumSet.of(UPDATE, ADD, DELETE, ERROR);
+
+ public static ResourceType of(@Nullable String value) {
+ if (value != null) {
+ try {
+ return valueOf(value.toUpperCase());
+ } catch (IllegalArgumentException e) {
+ // fall through
+ }
+ }
+ return ERROR.setUnknownTypeId(value);
+ }
+
+ private @Nullable String unknownTypeId;
+
+ private ResourceType setUnknownTypeId(@Nullable String value) {
+ unknownTypeId = value;
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ String s = this.name().replace("_", " ");
+ s = s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase();
+ return unknownTypeId == null ? s : s + String.format(" (%s)", unknownTypeId);
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2.enums;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * Enum for types of rotary dial events.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public enum RotationEventType {
+ START,
+ REPEAT
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2.enums;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
+/**
+ * Enum for scene recall actions.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public enum SceneRecallAction {
+ ACTIVE,
+ DYNAMIC_PALETTE,
+ STATIC,
+ UNKNOWN;
+
+ public static SceneRecallAction of(@Nullable String value) {
+ if (value != null) {
+ try {
+ return valueOf(value.toUpperCase());
+ } catch (IllegalArgumentException e) {
+ // fall through
+ }
+ }
+ return UNKNOWN;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2.enums;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
+/**
+ * Enum for smart scene recall actions.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public enum SmartSceneRecallAction {
+ ACTIVATE,
+ DEACTIVATE,
+ UNKNOWN;
+
+ public static SmartSceneRecallAction of(@Nullable String value) {
+ if (value != null) {
+ try {
+ return valueOf(value.toUpperCase());
+ } catch (IllegalArgumentException e) {
+ // fall through
+ }
+ }
+ return UNKNOWN;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2.enums;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
+/**
+ * Enum for 'smart_scene' states.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public enum SmartSceneState {
+ INACTIVE,
+ ACTIVE,
+ UNKNOWN;
+
+ public static SmartSceneState of(@Nullable String value) {
+ if (value != null) {
+ try {
+ return valueOf(value.toUpperCase());
+ } catch (IllegalArgumentException e) {
+ // fall through
+ }
+ }
+ return UNKNOWN;
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2.enums;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * Enum for tamper switch states.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public enum TamperStateType {
+ NOT_TAMPERED,
+ TAMPERED
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2.enums;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
+/**
+ * Enum for possible Zigbee states.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public enum ZigbeeStatus {
+ CONNECTED,
+ DISCONNECTED,
+ CONNECTIVITY_ISSUE,
+ UNIDIRECTIONAL_INCOMING;
+
+ public static ZigbeeStatus of(@Nullable String value) {
+ if (value != null) {
+ try {
+ return valueOf(value.toUpperCase());
+ } catch (IllegalArgumentException e) {
+ // fall through
+ }
+ }
+ return DISCONNECTED;
+ }
+
+ @Override
+ public String toString() {
+ String s = this.name().replace("_", " ");
+ return s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase();
+ }
+}
--- /dev/null
+/**
+ * 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.api.dto.clip2.helper;
+
+import java.math.BigDecimal;
+import java.time.Duration;
+import java.util.List;
+import java.util.Objects;
+
+import javax.measure.Unit;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.hue.internal.api.dto.clip2.Alerts;
+import org.openhab.binding.hue.internal.api.dto.clip2.ColorTemperature;
+import org.openhab.binding.hue.internal.api.dto.clip2.ColorXy;
+import org.openhab.binding.hue.internal.api.dto.clip2.Dimming;
+import org.openhab.binding.hue.internal.api.dto.clip2.Effects;
+import org.openhab.binding.hue.internal.api.dto.clip2.MetaData;
+import org.openhab.binding.hue.internal.api.dto.clip2.MirekSchema;
+import org.openhab.binding.hue.internal.api.dto.clip2.OnState;
+import org.openhab.binding.hue.internal.api.dto.clip2.Resource;
+import org.openhab.binding.hue.internal.api.dto.clip2.TimedEffects;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.ActionType;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.EffectType;
+import org.openhab.core.library.types.DecimalType;
+import org.openhab.core.library.types.HSBType;
+import org.openhab.core.library.types.PercentType;
+import org.openhab.core.library.types.QuantityType;
+import org.openhab.core.library.types.StringType;
+import org.openhab.core.library.unit.Units;
+import org.openhab.core.types.Command;
+import org.openhab.core.util.ColorUtil;
+import org.openhab.core.util.ColorUtil.Gamut;
+
+/**
+ * Advanced setter methods for fields in the Resource class for special cases where setting the new value in the target
+ * resource depends on logic using the values of other fields in a another source Resource.
+ *
+ * @author Andrew Fiddian-Green - Initial contribution
+ */
+@NonNullByDefault
+public class Setters {
+
+ /**
+ * Setter for Alert field:
+ * Use the given command value to set the target resource DTO value based on the attributes of the source resource
+ * (if any).
+ *
+ * @param target the target resource.
+ * @param command the new state command should be a StringType.
+ * @param source another resource containing the allowed alert action values.
+ *
+ * @return the target resource.
+ */
+ public static Resource setAlert(Resource target, Command command, @Nullable Resource source) {
+ if ((command instanceof StringType) && Objects.nonNull(source)) {
+ Alerts otherAlert = source.getAlerts();
+ if (Objects.nonNull(otherAlert)) {
+ ActionType actionType = ActionType.of(((StringType) command).toString());
+ if (otherAlert.getActionValues().contains(actionType)) {
+ target.setAlerts(new Alerts().setAction(actionType));
+ }
+ }
+ }
+ return target;
+ }
+
+ /**
+ * Setter for Color Temperature field:
+ * Use the given command value to set the target resource DTO value based on the attributes of the source resource
+ * (if any).
+ *
+ * @param target the target resource.
+ * @param command the new state command should be a {@code QuantityType<Temperature>} (but it can also handle
+ * {@code DecimalType}).
+ * @param source another resource containing the MirekSchema.
+ *
+ * @return the target resource.
+ */
+ public static Resource setColorTemperatureAbsolute(Resource target, Command command, @Nullable Resource source) {
+ QuantityType<?> mirek;
+ if (command instanceof QuantityType<?>) {
+ QuantityType<?> quantity = (QuantityType<?>) command;
+ Unit<?> unit = quantity.getUnit();
+ if (Units.KELVIN.equals(unit)) {
+ mirek = quantity.toInvertibleUnit(Units.MIRED);
+ } else if (Units.MIRED.equals(unit)) {
+ mirek = quantity;
+ } else {
+ QuantityType<?> kelvin = quantity.toInvertibleUnit(Units.KELVIN);
+ mirek = Objects.nonNull(kelvin) ? kelvin.toInvertibleUnit(Units.MIRED) : null;
+ }
+ } else if (command instanceof DecimalType) {
+ mirek = QuantityType.valueOf(((DecimalType) command).doubleValue(), Units.KELVIN)
+ .toInvertibleUnit(Units.MIRED);
+ } else {
+ mirek = null;
+ }
+ if (Objects.nonNull(mirek)) {
+ MirekSchema schema = target.getMirekSchema();
+ schema = Objects.nonNull(schema) ? schema : Objects.nonNull(source) ? source.getMirekSchema() : null;
+ schema = Objects.nonNull(schema) ? schema : MirekSchema.DEFAULT_SCHEMA;
+ ColorTemperature colorTemperature = target.getColorTemperature();
+ colorTemperature = Objects.nonNull(colorTemperature) ? colorTemperature : new ColorTemperature();
+ double min = schema.getMirekMinimum();
+ double max = schema.getMirekMaximum();
+ double val = Math.max(min, Math.min(max, mirek.doubleValue()));
+ target.setColorTemperature(colorTemperature.setMirek(val));
+ }
+ return target;
+ }
+
+ /**
+ * Setter for Color Temperature field:
+ * Use the given command value to set the target resource DTO value based on the attributes of the source resource
+ * (if any).
+ *
+ * @param target the target resource.
+ * @param command the new state command should be a PercentType.
+ * @param source another resource containing the MirekSchema.
+ *
+ * @return the target resource.
+ */
+ public static Resource setColorTemperaturePercent(Resource target, Command command, @Nullable Resource source) {
+ if (command instanceof PercentType) {
+ MirekSchema schema = target.getMirekSchema();
+ schema = Objects.nonNull(schema) ? schema : Objects.nonNull(source) ? source.getMirekSchema() : null;
+ schema = Objects.nonNull(schema) ? schema : MirekSchema.DEFAULT_SCHEMA;
+ ColorTemperature colorTemperature = target.getColorTemperature();
+ colorTemperature = Objects.nonNull(colorTemperature) ? colorTemperature : new ColorTemperature();
+ double min = schema.getMirekMinimum();
+ double max = schema.getMirekMaximum();
+ double val = min + ((max - min) * ((PercentType) command).doubleValue() / 100f);
+ target.setColorTemperature(colorTemperature.setMirek(val));
+ }
+ return target;
+ }
+
+ /**
+ * Setter for Color Xy field:
+ * Use the given command value to set the target resource DTO value based on the attributes of the source resource
+ * (if any). Use the HS parts of the HSB value to set the value of the 'ColorXy' JSON element, and ignore the 'B'
+ * part.
+ *
+ * @param target the target resource.
+ * @param command the new state command should be an HSBType with the new color XY value.
+ * @param source another resource containing the color Gamut.
+ *
+ * @return the target resource.
+ */
+ public static Resource setColorXy(Resource target, Command command, @Nullable Resource source) {
+ if (command instanceof HSBType) {
+ Gamut gamut = target.getGamut();
+ gamut = Objects.nonNull(gamut) ? gamut : Objects.nonNull(source) ? source.getGamut() : null;
+ gamut = Objects.nonNull(gamut) ? gamut : ColorUtil.DEFAULT_GAMUT;
+ HSBType hsb = (HSBType) command;
+ ColorXy color = target.getColorXy();
+ target.setColorXy((Objects.nonNull(color) ? color : new ColorXy()).setXY(ColorUtil.hsbToXY(hsb, gamut)));
+ }
+ return target;
+ }
+
+ /**
+ * Setter for Dimming field:
+ * Use the given command value to set the target resource DTO value based on the attributes of the source resource
+ * (if any).
+ *
+ * @param target the target resource.
+ * @param command the new state command should be a PercentType with the new dimming parameter.
+ * @param source another resource containing the minimum dimming level.
+ *
+ * @return the target resource.
+ */
+ public static Resource setDimming(Resource target, Command command, @Nullable Resource source) {
+ if (command instanceof PercentType) {
+ Double min = target.getMinimumDimmingLevel();
+ min = Objects.nonNull(min) ? min : Objects.nonNull(source) ? source.getMinimumDimmingLevel() : null;
+ min = Objects.nonNull(min) ? min : Dimming.DEFAULT_MINIMUM_DIMMIMG_LEVEL;
+ PercentType brightness = (PercentType) command;
+ if (brightness.doubleValue() < min.doubleValue()) {
+ brightness = new PercentType(new BigDecimal(min, Resource.PERCENT_MATH_CONTEXT));
+ }
+ Dimming dimming = target.getDimming();
+ dimming = Objects.nonNull(dimming) ? dimming : new Dimming();
+ dimming.setBrightness(brightness.doubleValue());
+ target.setDimming(dimming);
+ }
+ return target;
+ }
+
+ /**
+ * Setter for fixed or timed effect field:
+ * Use the given command value to set the target fixed or timed effects resource DTO value based on the attributes
+ * of the source resource (if any).
+ *
+ * @param target the target resource.
+ * @param command the new state command should be a StringType.
+ * @param source another resource containing the allowed effect action values.
+ *
+ * @return the target resource.
+ */
+ public static Resource setEffect(Resource target, Command command, @Nullable Resource source) {
+ if ((command instanceof StringType) && Objects.nonNull(source)) {
+ EffectType commandEffectType = EffectType.of(((StringType) command).toString());
+ Effects sourceFixedEffects = source.getFixedEffects();
+ if (Objects.nonNull(sourceFixedEffects) && sourceFixedEffects.allows(commandEffectType)) {
+ target.setFixedEffects(new Effects().setEffect(commandEffectType));
+ }
+ TimedEffects sourceTimedEffects = source.getTimedEffects();
+ if (Objects.nonNull(sourceTimedEffects) && sourceTimedEffects.allows(commandEffectType)) {
+ Duration duration = sourceTimedEffects.getDuration();
+ target.setTimedEffects(((TimedEffects) new TimedEffects().setEffect(commandEffectType))
+ .setDuration(Objects.nonNull(duration) ? duration : TimedEffects.DEFAULT_DURATION));
+ }
+ }
+ return target;
+ }
+
+ /**
+ * Setter to copy persisted fields from the source Resource into the target Resource. If the field in the target is
+ * null and the same field in the source is not null, then the value from the source is copied to the target. This
+ * method allows 'hasSparseData' resources to expand themselves to include necessary fields taken over from a
+ * previously cached full data resource.
+ *
+ * @param target the target resource.
+ * @param source another resource containing the values to be taken over.
+ *
+ * @return the target resource.
+ */
+ public static Resource setResource(Resource target, Resource source) {
+ // on
+ OnState targetOnOff = target.getOnState();
+ OnState sourceOnOff = source.getOnState();
+ if (Objects.isNull(targetOnOff) && Objects.nonNull(sourceOnOff)) {
+ target.setOnState(sourceOnOff);
+ }
+
+ // dimming
+ Dimming targetDimming = target.getDimming();
+ Dimming sourceDimming = source.getDimming();
+ if (Objects.isNull(targetDimming) && Objects.nonNull(sourceDimming)) {
+ target.setDimming(sourceDimming);
+ targetDimming = target.getDimming();
+ }
+
+ // minimum dimming level
+ if (Objects.nonNull(targetDimming)) {
+ Double sourceMinDimLevel = Objects.isNull(sourceDimming) ? null : sourceDimming.getMinimumDimmingLevel();
+ if (Objects.nonNull(sourceMinDimLevel)) {
+ targetDimming.setMinimumDimmingLevel(sourceMinDimLevel);
+ }
+ }
+
+ // color
+ ColorXy targetColor = target.getColorXy();
+ ColorXy sourceColor = source.getColorXy();
+ if (Objects.isNull(targetColor) && Objects.nonNull(sourceColor)) {
+ target.setColorXy(sourceColor);
+ targetColor = target.getColorXy();
+ }
+
+ // color gamut
+ Gamut sourceGamut = Objects.isNull(sourceColor) ? null : sourceColor.getGamut();
+ if (Objects.nonNull(targetColor) && Objects.nonNull(sourceGamut)) {
+ targetColor.setGamut(sourceGamut);
+ }
+
+ // color temperature
+ ColorTemperature targetColorTemp = target.getColorTemperature();
+ ColorTemperature sourceColorTemp = source.getColorTemperature();
+ if (Objects.isNull(targetColorTemp) && Objects.nonNull(sourceColorTemp)) {
+ target.setColorTemperature(sourceColorTemp);
+ targetColorTemp = target.getColorTemperature();
+ }
+
+ // mirek schema
+ if (Objects.nonNull(targetColorTemp)) {
+ MirekSchema sourceMirekSchema = Objects.isNull(sourceColorTemp) ? null : sourceColorTemp.getMirekSchema();
+ if (Objects.nonNull(sourceMirekSchema)) {
+ targetColorTemp.setMirekSchema(sourceMirekSchema);
+ }
+ }
+
+ // metadata
+ MetaData targetMetaData = target.getMetaData();
+ MetaData sourceMetaData = source.getMetaData();
+ if (Objects.isNull(targetMetaData) && Objects.nonNull(sourceMetaData)) {
+ target.setMetadata(sourceMetaData);
+ }
+
+ // alerts
+ Alerts targetAlerts = target.getAlerts();
+ Alerts sourceAlerts = source.getAlerts();
+ if (Objects.isNull(targetAlerts) && Objects.nonNull(sourceAlerts)) {
+ target.setAlerts(sourceAlerts);
+ }
+
+ // fixed effects
+ Effects targetFixedEffects = target.getFixedEffects();
+ Effects sourceFixedEffects = source.getFixedEffects();
+ if (Objects.isNull(targetFixedEffects) && Objects.nonNull(sourceFixedEffects)) {
+ target.setFixedEffects(sourceFixedEffects);
+ targetFixedEffects = target.getFixedEffects();
+ }
+
+ // fixed effects allowed values
+ if (Objects.nonNull(targetFixedEffects)) {
+ List<String> values = Objects.isNull(sourceFixedEffects) ? List.of() : sourceFixedEffects.getStatusValues();
+ if (!values.isEmpty()) {
+ targetFixedEffects.setStatusValues(values);
+ }
+ }
+
+ // timed effects
+ TimedEffects targetTimedEffects = target.getTimedEffects();
+ TimedEffects sourceTimedEffects = source.getTimedEffects();
+ if (Objects.isNull(targetTimedEffects) && Objects.nonNull(sourceTimedEffects)) {
+ target.setTimedEffects(sourceTimedEffects);
+ targetTimedEffects = target.getTimedEffects();
+ }
+
+ // timed effects allowed values and duration
+ if (Objects.nonNull(targetTimedEffects)) {
+ List<String> values = Objects.isNull(sourceTimedEffects) ? List.of() : sourceTimedEffects.getStatusValues();
+ if (!values.isEmpty()) {
+ targetTimedEffects.setStatusValues(values);
+ }
+ Duration duration = Objects.isNull(sourceTimedEffects) ? null : sourceTimedEffects.getDuration();
+ if (Objects.nonNull(duration)) {
+ targetTimedEffects.setDuration(duration);
+ }
+ }
+
+ return target;
+ }
+}
--- /dev/null
+/**
+ * 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.api.serialization;
+
+import java.lang.reflect.Type;
+import java.time.Instant;
+import java.time.format.DateTimeParseException;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
+import com.google.gson.JsonDeserializationContext;
+import com.google.gson.JsonDeserializer;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParseException;
+
+/**
+ * The {@link InstantDeserializer} converts a formatted UTC string to {@link Instant}.
+ *
+ * @author Jacob Laursen - Initial contribution
+ */
+@NonNullByDefault
+public class InstantDeserializer implements JsonDeserializer<Instant> {
+
+ @Override
+ public @Nullable Instant deserialize(JsonElement element, Type arg1, JsonDeserializationContext arg2)
+ throws JsonParseException {
+ String content = element.getAsString();
+ try {
+ return Instant.parse(content);
+ } catch (DateTimeParseException e) {
+ throw new JsonParseException("Could not parse as Instant: " + content, e);
+ }
+ }
+}
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.Promise.Completable;
import org.eclipse.jetty.util.ssl.SslContextFactory;
-import org.openhab.binding.hue.internal.dto.CreateUserRequest;
-import org.openhab.binding.hue.internal.dto.SuccessResponse;
-import org.openhab.binding.hue.internal.dto.clip2.BridgeConfig;
-import org.openhab.binding.hue.internal.dto.clip2.Event;
-import org.openhab.binding.hue.internal.dto.clip2.Resource;
-import org.openhab.binding.hue.internal.dto.clip2.ResourceReference;
-import org.openhab.binding.hue.internal.dto.clip2.Resources;
-import org.openhab.binding.hue.internal.dto.clip2.enums.ResourceType;
+import org.openhab.binding.hue.internal.api.dto.clip1.CreateUserRequest;
+import org.openhab.binding.hue.internal.api.dto.clip1.SuccessResponse;
+import org.openhab.binding.hue.internal.api.dto.clip2.BridgeConfig;
+import org.openhab.binding.hue.internal.api.dto.clip2.Event;
+import org.openhab.binding.hue.internal.api.dto.clip2.Resource;
+import org.openhab.binding.hue.internal.api.dto.clip2.ResourceReference;
+import org.openhab.binding.hue.internal.api.dto.clip2.Resources;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.ResourceType;
+import org.openhab.binding.hue.internal.api.serialization.InstantDeserializer;
import org.openhab.binding.hue.internal.exceptions.ApiException;
import org.openhab.binding.hue.internal.exceptions.HttpUnauthorizedException;
import org.openhab.binding.hue.internal.handler.Clip2BridgeHandler;
-import org.openhab.binding.hue.internal.serialization.InstantDeserializer;
import org.openhab.core.io.net.http.HttpClientFactory;
import org.openhab.core.io.net.http.HttpUtil;
import org.slf4j.Logger;
import org.eclipse.jetty.client.util.StringContentProvider;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpStatus;
-import org.openhab.binding.hue.internal.dto.ApiVersion;
-import org.openhab.binding.hue.internal.dto.ApiVersionUtils;
-import org.openhab.binding.hue.internal.dto.Config;
-import org.openhab.binding.hue.internal.dto.ConfigUpdate;
-import org.openhab.binding.hue.internal.dto.CreateUserRequest;
-import org.openhab.binding.hue.internal.dto.ErrorResponse;
-import org.openhab.binding.hue.internal.dto.FullConfig;
-import org.openhab.binding.hue.internal.dto.FullGroup;
-import org.openhab.binding.hue.internal.dto.FullHueObject;
-import org.openhab.binding.hue.internal.dto.FullLight;
-import org.openhab.binding.hue.internal.dto.FullSensor;
-import org.openhab.binding.hue.internal.dto.Group;
-import org.openhab.binding.hue.internal.dto.HueObject;
-import org.openhab.binding.hue.internal.dto.NewLightsResponse;
-import org.openhab.binding.hue.internal.dto.Scene;
-import org.openhab.binding.hue.internal.dto.Schedule;
-import org.openhab.binding.hue.internal.dto.ScheduleUpdate;
-import org.openhab.binding.hue.internal.dto.SearchForLightsRequest;
-import org.openhab.binding.hue.internal.dto.SetAttributesRequest;
-import org.openhab.binding.hue.internal.dto.StateUpdate;
-import org.openhab.binding.hue.internal.dto.SuccessResponse;
-import org.openhab.binding.hue.internal.dto.Util;
+import org.openhab.binding.hue.internal.api.dto.clip1.ApiVersion;
+import org.openhab.binding.hue.internal.api.dto.clip1.ApiVersionUtils;
+import org.openhab.binding.hue.internal.api.dto.clip1.Config;
+import org.openhab.binding.hue.internal.api.dto.clip1.ConfigUpdate;
+import org.openhab.binding.hue.internal.api.dto.clip1.CreateUserRequest;
+import org.openhab.binding.hue.internal.api.dto.clip1.ErrorResponse;
+import org.openhab.binding.hue.internal.api.dto.clip1.FullConfig;
+import org.openhab.binding.hue.internal.api.dto.clip1.FullGroup;
+import org.openhab.binding.hue.internal.api.dto.clip1.FullHueObject;
+import org.openhab.binding.hue.internal.api.dto.clip1.FullLight;
+import org.openhab.binding.hue.internal.api.dto.clip1.FullSensor;
+import org.openhab.binding.hue.internal.api.dto.clip1.Group;
+import org.openhab.binding.hue.internal.api.dto.clip1.HueObject;
+import org.openhab.binding.hue.internal.api.dto.clip1.NewLightsResponse;
+import org.openhab.binding.hue.internal.api.dto.clip1.Scene;
+import org.openhab.binding.hue.internal.api.dto.clip1.Schedule;
+import org.openhab.binding.hue.internal.api.dto.clip1.ScheduleUpdate;
+import org.openhab.binding.hue.internal.api.dto.clip1.SearchForLightsRequest;
+import org.openhab.binding.hue.internal.api.dto.clip1.SetAttributesRequest;
+import org.openhab.binding.hue.internal.api.dto.clip1.StateUpdate;
+import org.openhab.binding.hue.internal.api.dto.clip1.SuccessResponse;
+import org.openhab.binding.hue.internal.api.dto.clip1.Util;
import org.openhab.binding.hue.internal.exceptions.ApiException;
import org.openhab.binding.hue.internal.exceptions.DeviceOffException;
import org.openhab.binding.hue.internal.exceptions.EmptyResponseException;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.hue.internal.dto.clip2.MetaData;
-import org.openhab.binding.hue.internal.dto.clip2.Resource;
-import org.openhab.binding.hue.internal.dto.clip2.ResourceReference;
-import org.openhab.binding.hue.internal.dto.clip2.enums.Archetype;
-import org.openhab.binding.hue.internal.dto.clip2.enums.ResourceType;
+import org.openhab.binding.hue.internal.api.dto.clip2.MetaData;
+import org.openhab.binding.hue.internal.api.dto.clip2.Resource;
+import org.openhab.binding.hue.internal.api.dto.clip2.ResourceReference;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.Archetype;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.ResourceType;
import org.openhab.binding.hue.internal.exceptions.ApiException;
import org.openhab.binding.hue.internal.exceptions.AssetNotLoadedException;
import org.openhab.binding.hue.internal.handler.Clip2BridgeHandler;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.hue.internal.dto.clip2.MetaData;
-import org.openhab.binding.hue.internal.dto.clip2.Resource;
-import org.openhab.binding.hue.internal.dto.clip2.ResourceReference;
-import org.openhab.binding.hue.internal.dto.clip2.enums.Archetype;
-import org.openhab.binding.hue.internal.dto.clip2.enums.ResourceType;
+import org.openhab.binding.hue.internal.api.dto.clip2.MetaData;
+import org.openhab.binding.hue.internal.api.dto.clip2.Resource;
+import org.openhab.binding.hue.internal.api.dto.clip2.ResourceReference;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.Archetype;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.ResourceType;
import org.openhab.binding.hue.internal.exceptions.ApiException;
import org.openhab.binding.hue.internal.exceptions.AssetNotLoadedException;
import org.openhab.binding.hue.internal.handler.Clip2BridgeHandler;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.hue.internal.dto.FullGroup;
-import org.openhab.binding.hue.internal.dto.FullHueObject;
-import org.openhab.binding.hue.internal.dto.FullLight;
-import org.openhab.binding.hue.internal.dto.FullSensor;
+import org.openhab.binding.hue.internal.api.dto.clip1.FullGroup;
+import org.openhab.binding.hue.internal.api.dto.clip1.FullHueObject;
+import org.openhab.binding.hue.internal.api.dto.clip1.FullLight;
+import org.openhab.binding.hue.internal.api.dto.clip1.FullSensor;
import org.openhab.binding.hue.internal.handler.HueBridgeHandler;
import org.openhab.binding.hue.internal.handler.HueGroupHandler;
import org.openhab.binding.hue.internal.handler.HueLightHandler;
+++ /dev/null
-/**
- * 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.dto;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Represents the version of the API of the form 1.0 or 1.2.1
- *
- * @author Samuel Leisering - Initial contribution
- */
-public class ApiVersion {
- private final int major;
- private final int minor;
- private final int micro;
-
- private static final Pattern VERSION_PATTERN = Pattern.compile("^([0-9]+)\\.([0-9]+)(\\.([0-9]+))?$");
-
- public ApiVersion(int major, int minor, int micro) {
- this.major = major;
- this.minor = minor;
- this.micro = micro;
- }
-
- public static ApiVersion of(String version) {
- Matcher matcher = VERSION_PATTERN.matcher(version);
- if (matcher.matches()) {
- int major = Integer.parseInt(matcher.group(1));
- int minor = Integer.parseInt(matcher.group(2));
- String microString = matcher.group(4);
- int micro = Integer.parseInt(microString == null ? "0" : microString);
-
- return new ApiVersion(major, minor, micro);
- }
-
- throw new IllegalArgumentException("Version \"" + version + "\" is not valid");
- }
-
- /**
- * returns the major version part of the version
- *
- * @return the major part of the version
- */
- public int getMajor() {
- return major;
- }
-
- /**
- * returns the minor version part of the version
- *
- * @return the minor part of the version
- */
- public int getMinor() {
- return minor;
- }
-
- /**
- * returns the micro version part of the version
- *
- * @return the micro part of the version
- */
- public int getMicro() {
- return micro;
- }
-
- /**
- * compare API versions according to {@link java.util.Comparator#compare(Object, Object)}
- *
- * @param other
- * @return
- */
- public int compare(ApiVersion other) {
- int c = Integer.compare(major, other.major);
- if (c == 0) {
- c = Integer.compare(minor, other.minor);
- if (c == 0) {
- c = Integer.compare(micro, other.micro);
- }
- }
- return c;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + major;
- result = prime * result + micro;
- result = prime * result + minor;
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- ApiVersion other = (ApiVersion) obj;
- if (major != other.major) {
- return false;
- }
- if (micro != other.micro) {
- return false;
- }
- return minor == other.minor;
- }
-
- @Override
- public String toString() {
- return major + "." + minor + "." + micro;
- }
-}
+++ /dev/null
-/**
- * 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.dto;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-
-/**
- * @author Samuel Leisering - Initial contribution
- */
-@NonNullByDefault
-public final class ApiVersionUtils {
-
- private static final ApiVersion FULL_LIGHTS = new ApiVersion(1, 11, 0);
-
- ApiVersionUtils() {
- }
-
- /**
- * Starting from version 1.11, <code>GET</code>ing the Lights always returns {@link FullLight}s instead of
- * {@link HueObject}s.
- *
- * @return
- */
- public static boolean supportsFullLights(ApiVersion version) {
- return FULL_LIGHTS.compare(version) <= 0;
- }
-}
+++ /dev/null
-/**
- * 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.dto;
-
-/**
- * Collection of updates to the bridge configuration.
- *
- * @author Q42 - Initial contribution
- * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding, minor code cleanup
- * @author Samuel Leisering - added Sensor support
- */
-public class BridgeConfigUpdate extends ConfigUpdate {
- /**
- * Set the port of the proxy or null if there is no proxy.
- *
- * @param port port for proxy
- * @return this object for chaining calls
- */
- public BridgeConfigUpdate setProxyPort(Integer port) {
- if (port != null && port < 0) {
- throw new IllegalArgumentException("Invalid value for port");
- }
-
- commands.add(new Command("proxyport", port == null ? 0 : port));
- return this;
- }
-
- /**
- * Set the name of the bridge, which also functions as the UPnP name.
- *
- * @param name new name [4..16]
- * @return this object for chaining calls
- */
- public BridgeConfigUpdate setName(String name) {
- if (Util.stringSize(name) < 4 || Util.stringSize(name) > 16) {
- throw new IllegalArgumentException("Bridge name must be between 4 and 16 characters long");
- }
-
- commands.add(new Command("name", name));
- return this;
- }
-
- /**
- * Set the address of the proxy or null if there is no proxy.
- *
- * @param ip ip of proxy
- * @return this object for chaining calls
- */
- public BridgeConfigUpdate setProxyAddress(String ip) {
- if (ip != null && Util.stringSize(ip) > 40) {
- throw new IllegalArgumentException("Bridge proxy address can be at most 40 characters long");
- }
-
- commands.add(new Command("proxyaddress", ip == null ? "none" : ip));
- return this;
- }
-
- /**
- * Set whether the link button has been pressed within the last 30 seconds or not.
- *
- * @param pressed true for pressed, false for not pressed
- * @return this object for chaining calls
- */
- public BridgeConfigUpdate setLinkButton(boolean pressed) {
- commands.add(new Command("linkbutton", pressed));
- return this;
- }
-
- /**
- * Set the IP address of the bridge.
- *
- * @param ip ip address of bridge
- * @return this object for chaining calls
- */
- public BridgeConfigUpdate setIPAddress(String ip) {
- commands.add(new Command("ipaddress", ip));
- return this;
- }
-
- /**
- * Set the network mask of the bridge.
- *
- * @param netmask network mask
- * @return this object for chaining calls
- */
- public BridgeConfigUpdate setNetworkMask(String netmask) {
- commands.add(new Command("netmask", netmask));
- return this;
- }
-
- /**
- * Set the gateway address of the bridge.
- *
- * @param ip gateway address
- * @return this object for chaining calls
- */
- public BridgeConfigUpdate setGateway(String ip) {
- commands.add(new Command("gateway", ip));
- return this;
- }
-
- /**
- * Set whether the bridge uses DHCP to get an ip address or not.
- *
- * @param enabled dhcp enabled
- * @return this object for chaining calls
- */
- public BridgeConfigUpdate setDHCP(boolean enabled) {
- commands.add(new Command("dhcp", enabled));
- return this;
- }
-}
+++ /dev/null
-/**
- * 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.dto;
-
-/**
- * Collection of capabilities for lights.
- *
- * @author Christoph Weitkamp - Initial contribution
- */
-public class Capabilities {
- public Control control;
-}
+++ /dev/null
-/**
- * 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.dto;
-
-/**
- * Collection of color temperature capabilities to control lights.
- *
- * @author Christoph Weitkamp - Initial contribution
- */
-public class ColorTemperature {
- public int max = 500;
- public int min = 153;
-}
+++ /dev/null
-/**
- * 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.dto;
-
-import com.google.gson.Gson;
-
-/**
- *
- * @author Q42 - Initial contribution
- * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding
- * @author Samuel Leisering - changed Command visibility to public
- */
-public class Command {
- public String key;
- public Object value;
-
- public Command(String key, Object value) {
- this.key = key;
- this.value = value;
- }
-
- String toJson() {
- return "\"" + key + "\":" + new Gson().toJson(value);
- }
-}
+++ /dev/null
-/**
- * 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.dto;
-
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-
-import com.google.gson.annotations.SerializedName;
-
-/**
- * Detailed bridge info available if authenticated.
- *
- * @author Q42 - Initial contribution
- * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding, minor code cleanup
- * @author Samuel Leisering - added API-Version
- */
-public class Config {
- private String name;
- private String swversion;
- private String apiversion;
- private String bridgeid;
- private String mac;
- private String modelid;
- private boolean dhcp;
- private String ipaddress;
- private String netmask;
- private String gateway;
- private String proxyaddress;
- private int proxyport;
- @SerializedName("UTC")
- private Date utc;
- private boolean linkbutton;
- private Map<String, User> whitelist;
- private SoftwareUpdate swupdate;
-
- Config() {
- }
-
- /**
- * Returns the name.
- *
- * @return name of the bridge
- */
- public String getName() {
- return name;
- }
-
- /**
- * Returns the version of the software.
- *
- * @return version of software on the bridge
- */
- public String getSoftwareVersion() {
- return swversion;
- }
-
- /**
- * Returns the bridge id
- *
- * @return bridge id
- */
- public String getBridgeId() {
- return bridgeid;
- }
-
- /**
- * Returns the MAC address.
- *
- * @return mac address of bridge
- */
- public String getMACAddress() {
- return mac;
- }
-
- /**
- * Returns the model id
- *
- * @return model id
- */
- public String getModelId() {
- return modelid;
- }
-
- /**
- * Returns if the current IP address was obtained with DHCP.
- *
- * @return true if the current IP address was obtained with DHCP, false otherwise.
- */
- public boolean isDHCPEnabled() {
- return dhcp;
- }
-
- /**
- * Returns the IP address.
- *
- * @return ip address of bridge
- */
- public String getIPAddress() {
- return ipaddress;
- }
-
- /**
- * Returns the network mask.
- *
- * @return network mask
- */
- public String getNetworkMask() {
- return netmask;
- }
-
- /**
- * Returns the IP address of the gateway.
- *
- * @return ip address of gateway
- */
- public String getGateway() {
- return gateway;
- }
-
- /**
- * Returns the IP address of the proxy or null if there is none.
- *
- * @return ip address of proxy or null
- */
- public String getProxyAddress() {
- return "none".equals(proxyaddress) ? null : proxyaddress;
- }
-
- /**
- * Returns the port of the proxy or null if there is none.
- *
- * @return port of proxy or null
- */
- public Integer getProxyPort() {
- return "none".equals(proxyaddress) ? null : proxyport;
- }
-
- /**
- * Returns the time on the bridge.
- *
- * @return time on the bridge
- */
- public Date getUTCTime() {
- return utc;
- }
-
- /**
- * Returns if the link button has been pressed within the last 30 seconds.
- *
- * @return true if the link button has been pressed within the last 30 seconds, false otherwise
- */
- public boolean isLinkButtonPressed() {
- return linkbutton;
- }
-
- /**
- * Returns the list of whitelisted users.
- *
- * @return list of whitelisted users
- */
- public List<User> getWhitelist() {
- ArrayList<User> usersList = new ArrayList<>();
-
- usersList.addAll(whitelist.values());
-
- return usersList;
- }
-
- /**
- * Returns information about a bridge firmware update.
- *
- * @return bridge firmware update info
- */
- public SoftwareUpdate getSoftwareUpdate() {
- return swupdate;
- }
-
- /**
- * Returns the current API-Version of the Bridge. This always returns <code>1.0</code>
- * for bridges with version less than <code>1.2.1</code>, which introduces this call.
- *
- * @return
- */
- public String getApiVersion() {
- if (apiversion == null) {
- return "1.0";
- }
- return apiversion;
- }
-}
+++ /dev/null
-/**
- * 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.dto;
-
-import static java.util.stream.Collectors.joining;
-
-import java.util.ArrayList;
-
-/**
- * Collection of updates
- *
- * @author Q42 - Initial contribution
- * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding, minor code cleanup
- * @author Samuel Leisering - Added support for sensor API
- * @author Christoph Weitkamp - Added support for sensor API
- */
-public class ConfigUpdate {
-
- public final ArrayList<Command> commands = new ArrayList<>();
-
- public ConfigUpdate() {
- super();
- }
-
- public boolean isEmpty() {
- return commands.isEmpty();
- }
-
- public String toJson() {
- return commands.stream().map(c -> c.toJson()).collect(joining(",", "{", "}"));
- }
-
- /**
- * Returns the message delay recommended by Philips
- * Regarding to this article: https://developers.meethue.com/documentation/hue-system-performance
- */
- public long getMessageDelay() {
- return commands.size() * 40L;
- }
-}
+++ /dev/null
-/**
- * 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.dto;
-
-import org.eclipse.jdt.annotation.Nullable;
-
-/**
- * Collection of capabilities to control lights.
- *
- * @author Christoph Weitkamp - Initial contribution
- */
-public class Control {
- public @Nullable ColorTemperature ct;
-}
+++ /dev/null
-/**
- * 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.dto;
-
-/**
- *
- * @author Q42 - Initial contribution
- * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding
- */
-@SuppressWarnings("unused")
-public class CreateUserRequest {
- private String username;
- private String devicetype;
-
- public CreateUserRequest(String username, String devicetype) {
- if (Util.stringSize(devicetype) > 40) {
- throw new IllegalArgumentException("Device type can be at most 40 characters long");
- }
-
- if (Util.stringSize(username) < 10 || Util.stringSize(username) > 40) {
- throw new IllegalArgumentException("Username must be between 10 and 40 characters long");
- }
-
- this.username = username;
- this.devicetype = devicetype;
- }
-
- public CreateUserRequest(String devicetype) {
- if (Util.stringSize(devicetype) > 40) {
- throw new IllegalArgumentException("Device type can be at most 40 characters long");
- }
-
- this.devicetype = devicetype;
- }
-}
+++ /dev/null
-/**
- * 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.dto;
-
-import java.lang.reflect.Type;
-import java.util.List;
-
-import com.google.gson.reflect.TypeToken;
-
-/**
- * @author Q42 - Initial contribution
- * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding
- */
-public class ErrorResponse {
- public static final Type GSON_TYPE = new TypeToken<List<ErrorResponse>>() {
- }.getType();
-
- public class Error {
- private Integer type;
- private String address;
- private String description;
- }
-
- private Error error;
-
- public Integer getType() {
- if (error == null) {
- return null;
- }
- return error.type;
- }
-
- public String getAddress() {
- if (error == null) {
- return null;
- }
- return error.address;
- }
-
- public String getDescription() {
- if (error == null) {
- return null;
- }
- return error.description;
- }
-}
+++ /dev/null
-/**
- * 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.dto;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Container for all data on a bridge.
- *
- * @author Q42 - Initial contribution
- * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding
- */
-public class FullConfig {
- private Map<String, FullLight> lights;
- private Map<String, FullGroup> groups;
- private Config config;
-
- /**
- * Returns detailed information about all lights known to the bridge.
- *
- * @return detailed lights list
- */
- public List<FullLight> getLights() {
- ArrayList<FullLight> lightsList = new ArrayList<>();
-
- for (Map.Entry<String, FullLight> entry : lights.entrySet()) {
- String id = entry.getKey();
- FullLight light = entry.getValue();
- light.setId(id);
- lightsList.add(light);
- }
-
- return lightsList;
- }
-
- /**
- * Returns detailed information about all groups on the bridge.
- *
- * @return detailed groups list
- */
- public List<FullGroup> getGroups() {
- ArrayList<FullGroup> groupsList = new ArrayList<>();
-
- for (Map.Entry<String, FullGroup> entry : groups.entrySet()) {
- String id = entry.getKey();
- FullGroup group = entry.getValue();
- group.setId(id);
- groupsList.add(group);
- }
-
- return groupsList;
- }
-
- /**
- * Returns bridge configuration.
- * Use HueBridge.getConfig() if you only need this.
- *
- * @return bridge configuration
- */
- public Config getConfig() {
- return config;
- }
-}
+++ /dev/null
-/**
- * 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.dto;
-
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-import com.google.gson.reflect.TypeToken;
-
-/**
- * Detailed group information.
- *
- * @author Q42 - Initial contribution
- * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding
- * @author Laurent Garnier - field state added
- */
-@NonNullByDefault
-public class FullGroup extends Group {
- public static final Type GSON_TYPE = new TypeToken<Map<String, FullGroup>>() {
- }.getType();
-
- private @Nullable State action;
- private @Nullable List<String> lights;
- private @Nullable State groupState; // Will not be set by hue API
-
- FullGroup() {
- super();
- }
-
- /**
- * Test constructor
- */
- public FullGroup(String id, String name, String type, State action, List<String> lights, State state) {
- super(id, name, type);
- this.action = action;
- this.lights = lights;
- this.groupState = state;
- }
-
- /**
- * Returns the last sent state update to the group.
- * This does not have to reflect the current state of the group.
- *
- * @return last state update
- */
- public @Nullable State getAction() {
- return action;
- }
-
- /**
- * Returns a list of the lights in the group.
- *
- * @return lights in the group
- */
- public List<String> getLightIds() {
- List<String> lights = this.lights;
- return lights != null ? lights : new ArrayList<>();
- }
-
- /**
- * Returns the current state of the group.
- *
- * @return current state
- */
- public State getState() {
- State groupState = this.groupState;
- if (groupState == null) {
- throw new IllegalStateException("Group state not initialized when requested");
- }
- return groupState;
- }
-
- public void setState(State state) {
- this.groupState = state;
- }
-}
+++ /dev/null
-/**
- * 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.dto;
-
-import static org.openhab.binding.hue.internal.HueBindingConstants.NORMALIZE_ID_REGEX;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-import com.google.gson.annotations.SerializedName;
-
-/**
- * Detailed information about an object on the Hue Bridge
- *
- * @author Samuel Leisering - Initial contribution
- * @author Christoph Weitkamp - Initial contribution
- */
-@NonNullByDefault
-public class FullHueObject extends HueObject {
-
- private @NonNullByDefault({}) String type;
- private @Nullable String modelid;
- @SerializedName("manufacturername")
- private @NonNullByDefault({}) String manufacturerName;
- @SerializedName("productname")
- private @NonNullByDefault({}) String productName;
- private @Nullable String swversion;
- private @Nullable String uniqueid;
-
- public FullHueObject() {
- super();
- }
-
- /**
- * Returns the type of the object.
- *
- * @return type
- */
- public String getType() {
- return type;
- }
-
- /**
- * Set the type of the object.
- */
- public void setType(final String type) {
- this.type = type;
- }
-
- /**
- * Returns the model ID of the object.
- *
- * @return model id
- */
- public @Nullable String getModelID() {
- return modelid;
- }
-
- public @Nullable String getNormalizedModelID() {
- String modelid = this.modelid;
- return modelid != null ? modelid.replaceAll(NORMALIZE_ID_REGEX, "_") : modelid;
- }
-
- /**
- * Set the model ID of the object.
- */
- public void setModelID(final String modelId) {
- this.modelid = modelId;
- }
-
- public String getManufacturerName() {
- return manufacturerName;
- }
-
- public void setManufacturerName(String manufacturerName) {
- this.manufacturerName = manufacturerName;
- }
-
- public String getProductName() {
- return productName;
- }
-
- public void setProductName(String productName) {
- this.productName = productName;
- }
-
- /**
- * Returns the software version of the object.
- *
- * @return software version
- */
- public @Nullable String getSoftwareVersion() {
- return swversion;
- }
-
- /**
- * Returns the unique id of the object. The unique is the MAC address of the device with a unique endpoint id in the
- * form: AA:BB:CC:DD:EE:FF:00:11-XX
- *
- * @return the unique id, can be null for some virtual types like the daylight sensor
- */
- public @Nullable String getUniqueID() {
- return uniqueid;
- }
-
- /**
- * Sets the unique id of the object.
- */
- public void setUniqueID(final String uniqueid) {
- this.uniqueid = uniqueid;
- }
-}
+++ /dev/null
-/**
- * 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.dto;
-
-import java.lang.reflect.Type;
-import java.time.Duration;
-import java.util.Map;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-import com.google.gson.reflect.TypeToken;
-
-/**
- * Detailed light information.
- *
- * @author Q42 - Initial contribution
- * @author Thomas Höfer - added unique id and changed range check for brightness and saturation
- * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding
- * @author Samuel Leisering - added GSon Type to FullLight, refactored content to {@link FullHueObject}
- */
-@NonNullByDefault
-public class FullLight extends FullHueObject {
- public static final Type GSON_TYPE = new TypeToken<Map<String, FullLight>>() {
- }.getType();
-
- public @Nullable Capabilities capabilities;
- private @NonNullByDefault({}) State state;
- private final long fadetime = 400; // milliseconds
-
- /**
- * Returns the current state of the light.
- *
- * @return current state
- */
- public State getState() {
- return state;
- }
-
- public Duration getFadeTime() {
- return Duration.ofMillis(fadetime);
- }
-}
+++ /dev/null
-/**
- * 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.dto;
-
-import java.lang.reflect.Type;
-import java.util.Map;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-
-import com.google.gson.reflect.TypeToken;
-
-/**
- * Detailed sensor information
- *
- * @author Samuel Leisering - Initial contribution
- * @author Christoph Weitkamp - Initial contribution
- */
-@NonNullByDefault
-public class FullSensor extends FullHueObject {
- public static final Type GSON_TYPE = new TypeToken<Map<String, FullSensor>>() {
- }.getType();
-
- public static final String STATE_LAST_UPDATED = "lastupdated";
- public static final String STATE_BUTTON_EVENT = "buttonevent";
- public static final String STATE_PRESENCE = "presence";
- public static final String STATE_TEMPERATURE = "temperature";
- public static final String STATE_LIGHT_LEVEL = "lightlevel";
- public static final String STATE_DARK = "dark";
- public static final String STATE_DAYLIGHT = "daylight";
- public static final String STATE_STATUS = "status";
- public static final String STATE_FLAG = "flag";
-
- public static final String CONFIG_REACHABLE = "reachable";
- public static final String CONFIG_BATTERY = "battery";
- public static final String CONFIG_ON = "on";
- public static final String CONFIG_LED_INDICATION = "ledindication";
-
- public static final String CONFIG_PRESENCE_SENSITIVITY = "sensitivity";
- public static final String CONFIG_PRESENCE_SENSITIVITY_MAX = "sensitivitymax";
-
- public static final String CONFIG_LIGHT_LEVEL_THRESHOLD_DARK = "tholddark";
- public static final String CONFIG_LIGHT_LEVEL_THRESHOLD_OFFSET = "tholdoffset";
-
- private @NonNullByDefault({}) Map<String, Object> state;
- private @NonNullByDefault({}) Map<String, Object> config;
-
- public Map<String, Object> getState() {
- return state;
- }
-
- public Map<String, Object> getConfig() {
- return config;
- }
-}
+++ /dev/null
-/**
- * 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.dto;
-
-/**
- * Basic group information.
- *
- * @author Q42 - Initial contribution
- * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding
- * @author Laurent Garnier - field type added
- */
-public class Group {
- private String id;
- private String name;
- private String type;
-
- public Group() {
- this.id = "0";
- this.name = "Lightset 0";
- this.type = "LightGroup";
- }
-
- /**
- * Test constructor
- */
- Group(String id, String name, String type) {
- this.id = id;
- this.name = name;
- this.type = type;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public void setId(String id) {
- this.id = id;
- }
-
- void setType(String type) {
- this.type = type;
- }
-
- /**
- * Returns if the group can be modified.
- * Currently only returns false for the all lights pseudo group.
- *
- * @return modifiability of group
- */
- public boolean isModifiable() {
- return !"0".equals(id);
- }
-
- /**
- * Returns the id of the group.
- *
- * @return id
- */
- public String getId() {
- return id;
- }
-
- /**
- * Returns the name of the group.
- *
- * @return name
- */
- public String getName() {
- return name;
- }
-
- /**
- * Returns the tyoe of the group.
- *
- * @return type
- */
- public String getType() {
- return type;
- }
-}
+++ /dev/null
-/**
- * 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.dto;
-
-import java.lang.reflect.Type;
-import java.util.Map;
-
-import com.google.gson.reflect.TypeToken;
-
-/**
- * Basic hue object information.
- *
- * @author Q42 - Initial contribution
- * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding
- * @author Samuel Leisering - introduced Sensor support, renamed supertype to HueObject
- */
-public class HueObject {
- public static final Type GSON_TYPE = new TypeToken<Map<String, HueObject>>() {
- }.getType();
-
- private String id;
- private String name;
-
- HueObject() {
- }
-
- public void setId(String id) {
- this.id = id;
- }
-
- /**
- * Returns the id of the light.
- *
- * @return id
- */
- public String getId() {
- return id;
- }
-
- /**
- * Returns the name of the light.
- *
- * @return name
- */
- public String getName() {
- return name;
- }
-}
+++ /dev/null
-/**
- * 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.dto;
-
-import static org.openhab.binding.hue.internal.dto.FullSensor.*;
-
-/**
- * Updates the configuration of a light level sensor
- *
- * @author Samuel Leisering - Initial contribution
- * @author Christoph Weitkamp - Initial contribution
- */
-public class LightLevelConfigUpdate extends SensorConfigUpdate {
- /**
- *
- * @param onOff
- */
- public void setLedIndication(boolean onOff) {
- commands.add(new Command(CONFIG_LED_INDICATION, onOff));
- }
-
- /**
- *
- * @param threshold
- */
- public void setThresholdDark(int threshold) {
- commands.add(new Command(CONFIG_LIGHT_LEVEL_THRESHOLD_DARK, threshold));
- }
-
- /**
- *
- * @param offset
- */
- public void setThresholdOffset(int offset) {
- commands.add(new Command(CONFIG_LIGHT_LEVEL_THRESHOLD_OFFSET, offset));
- }
-}
+++ /dev/null
-/**
- * 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.dto;
-
-/**
- * @author Q42 - Initial contribution
- * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding
- */
-public class NewLightsResponse {
- public String lastscan;
-}
+++ /dev/null
-/**
- * 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.dto;
-
-import static org.openhab.binding.hue.internal.dto.FullSensor.*;
-
-/**
- * Updates the configuration of a presence sensor
- *
- * @author Samuel Leisering - Initial contribution
- * @author Christoph Weitkamp - Initial contribution
- */
-public class PresenceConfigUpdate extends SensorConfigUpdate {
- /**
- *
- * @param onOff
- */
- public void setLedIndication(boolean onOff) {
- commands.add(new Command(CONFIG_LED_INDICATION, onOff));
- }
-
- /**
- *
- * @param sensitivity
- */
- public void setSensitivity(int sensitivity) {
- commands.add(new Command(CONFIG_PRESENCE_SENSITIVITY, sensitivity));
- }
-}
+++ /dev/null
-/**
- * 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.dto;
-
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.core.types.StateOption;
-
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.reflect.TypeToken;
-
-/**
- * Basic scene information.
- *
- * @author Hengrui Jiang - Initial contribution
- */
-@NonNullByDefault
-public class Scene {
- public static final Type GSON_TYPE = new TypeToken<Map<String, Scene>>() {
- }.getType();
-
- private @NonNullByDefault({}) String id;
- private @NonNullByDefault({}) String name;
- @SerializedName("lights")
- private @Nullable List<String> lightIds;
- @SerializedName("group")
- private @Nullable String groupId;
- private boolean recycle;
-
- /**
- * Default constructor for GSon.
- */
- public Scene() {
- super();
- }
-
- /**
- * Test constructor
- */
- public Scene(String id, String name, @Nullable String groupId, List<String> lightIds, boolean recycle) {
- this.id = id;
- this.name = name;
- this.groupId = groupId;
- this.lightIds = lightIds;
- this.recycle = recycle;
- }
-
- public String getId() {
- return id;
- }
-
- public void setId(String id) {
- this.id = id;
- }
-
- /**
- * Returns the human readable name of the scene. If the name is omitted upon creation, this
- * defaults to the ID.
- *
- * @return human readable name of the scene
- */
- public String getName() {
- return name;
- }
-
- /**
- * Returns the list of lights that the scene applies to. For group scenes, this list should be identical to the list
- * of all lights that are in the group.
- *
- * @return list of lights that the scene applies to
- */
- public List<String> getLightIds() {
- List<String> lightIds = this.lightIds;
- return lightIds != null ? lightIds : new ArrayList<String>();
- }
-
- /**
- * Returns the group that the scene belongs to. This field is optional for scenes that applies to a specific list of
- * lights instead of a group.
- *
- * @return the group that the scene belongs to
- */
- public @Nullable String getGroupId() {
- return groupId;
- }
-
- /**
- * Indicates if the scene can be recycled by the bridge. A recyclable scene is not able to be activated.
- *
- * @return whether the scene can be recycled
- */
- public boolean isRecycle() {
- return recycle;
- }
-
- /**
- * Creates a {@link StateOption} to display this scene, including the group that it belongs to.
- * <p>
- * The display name is built with the following pattern:
- * <ol>
- * <li>Human readable name of the scene if set. Otherwise, the ID is displayed</li>
- * <li>Group for which the scene is defined</li>
- * </ol>
- */
- public StateOption toStateOption(Map<String, String> groupNames) {
- StringBuilder stateOptionLabel = new StringBuilder(name);
- if (groupId != null && groupNames.containsKey(groupId)) {
- stateOptionLabel.append(" (").append(groupNames.get(groupId)).append(")");
- }
-
- return new StateOption(id, stateOptionLabel.toString());
- }
-
- /**
- * Creates a {@link StateOption} to display this scene.
- */
- public StateOption toStateOption() {
- return new StateOption(id, name);
- }
-
- /**
- * Returns whether the scene is applicable to the given group.
- * <p>
- * According to the hue API, a scene is applicable to a group if either
- * <ol>
- * <li>The scene is defined for the group</li>
- * <li>All lights of the scene also belong to the group</li>
- * </ol>
- */
- public boolean isApplicableTo(FullGroup group) {
- String groupId = this.groupId;
- if (groupId == null) {
- return getLightIds().stream().allMatch(id -> group.getLightIds().contains(id));
- } else {
- return group.getId().contentEquals(groupId);
- }
- }
-
- public String extractKeyForComparator() {
- return (groupId != null ? groupId : "") + "#" + name;
- }
-
- @Override
- public String toString() {
- return String.format("{Scene name: %s; id: %s; lightIds: %s; groupId: %s; recycle: %s}", name, id, lightIds,
- groupId, recycle);
- }
-}
+++ /dev/null
-/**
- * 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.dto;
-
-import java.lang.reflect.Type;
-import java.util.Map;
-
-import com.google.gson.reflect.TypeToken;
-
-/**
- * Basic schedule information.
- *
- * @author Q42 - Initial contribution
- * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding
- */
-public class Schedule {
- public static final Type GSON_TYPE = new TypeToken<Map<String, Schedule>>() {
- }.getType();
-
- private String id;
- private String name;
-
- public void setId(String id) {
- this.id = id;
- }
-
- public String getId() {
- return id;
- }
-
- public String getName() {
- return name;
- }
-}
+++ /dev/null
-/**
- * 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.dto;
-
-import java.util.Date;
-
-/**
- * Collection of updates to a schedule.
- *
- * @author Q42 - Initial contribution
- * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding, minor code cleanup
- * @author Samuel Leisering - refactor configuration updates
- */
-public class ScheduleUpdate extends ConfigUpdate {
-
- /**
- * Set the name of the schedule.
- *
- * @param name new name
- * @return this object for chaining calls
- */
- public ScheduleUpdate setName(String name) {
- if (Util.stringSize(name) > 32) {
- throw new IllegalArgumentException("Schedule name can be at most 32 characters long");
- }
-
- commands.add(new Command("name", name));
- return this;
- }
-
- /**
- * Set the description of the schedule.
- *
- * @param description new description
- * @return this object for chaining calls
- */
- public ScheduleUpdate setDescription(String description) {
- if (Util.stringSize(description) > 64) {
- throw new IllegalArgumentException("Schedule description can be at most 64 characters long");
- }
-
- commands.add(new Command("description", description));
- return this;
- }
-
- /**
- * Set the time of the schedule.
- *
- * @param time new time
- * @return this object for chaining calls
- */
- public ScheduleUpdate setTime(Date time) {
- commands.add(new Command("time", time));
- return this;
- }
-}
+++ /dev/null
-/**
- * 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.dto;
-
-import java.util.List;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-
-/**
- *
- * @author Q42 - Initial contribution
- * @author Andre Fuechsel - search for lights with given serial number added
- * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding
- */
-@NonNullByDefault
-public class SearchForLightsRequest {
- @SuppressWarnings("unused")
- private List<String> deviceid;
-
- public SearchForLightsRequest(List<String> deviceid) {
- if (deviceid.isEmpty() || deviceid.size() > 16) {
- throw new IllegalArgumentException("Group cannot be empty and cannot have more than 16 lights");
- }
- this.deviceid = deviceid;
- }
-}
+++ /dev/null
-/**
- * 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.dto;
-
-import static org.openhab.binding.hue.internal.dto.FullSensor.CONFIG_ON;
-
-/**
- * Collection of updates to the sensor configuration.
- *
- * @author Christoph Weitkamp - Initial contribution
- */
-public class SensorConfigUpdate extends ConfigUpdate {
- /**
- *
- * @param onOff
- */
- public void setOn(boolean onOff) {
- commands.add(new Command(CONFIG_ON, onOff));
- }
-}
+++ /dev/null
-/**
- * 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.dto;
-
-import java.util.List;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-/**
- *
- * @author Q42 - Initial contribution
- * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding
- */
-@SuppressWarnings("unused")
-@NonNullByDefault
-public class SetAttributesRequest {
- private final @Nullable String name;
- private final @Nullable List<String> lights;
-
- public SetAttributesRequest(String name) {
- this(name, null);
- }
-
- public SetAttributesRequest(List<HueObject> lights) {
- this(null, lights);
- }
-
- public SetAttributesRequest(@Nullable String name, @Nullable List<HueObject> lights) {
- if (name != null && Util.stringSize(name) > 32) {
- throw new IllegalArgumentException("Name can be at most 32 characters long");
- } else if (lights != null && (lights.isEmpty() || lights.size() > 16)) {
- throw new IllegalArgumentException("Group cannot be empty and cannot have more than 16 lights");
- }
-
- this.name = name;
- this.lights = lights == null ? null : lights.stream().map(l -> l.getId()).toList();
- }
-}
+++ /dev/null
-/**
- * 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.dto;
-
-/**
- * Details of a bridge firmware update.
- *
- * @author Q42 - Initial contribution
- * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding
- */
-public class SoftwareUpdate {
- private int updatestate;
- private String url;
- private String text;
- private boolean notify;
-
- /**
- * Returns the state of the update.
- *
- * <p>
- * Actual meaning currently undocumented
- *
- * @return state of update
- */
- public int getUpdateState() {
- return updatestate;
- }
-
- /**
- * Returns the url of the changelog.
- *
- * @return changelog url
- */
- public String getUrl() {
- return url;
- }
-
- /**
- * Returns a description of the update.
- *
- * @return update description
- */
- public String getText() {
- return text;
- }
-
- /**
- * Returns if there will be a notification about this update.
- *
- * @return true for notification, false otherwise
- */
- public boolean isNotified() {
- return notify;
- }
-}
+++ /dev/null
-/**
- * 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.dto;
-
-import java.util.Arrays;
-
-/**
- * Current state of light.
- *
- * @author Q42 - Initial contribution
- * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding
- * @author Laurent Garnier - add few methods to update the object
- */
-public class State {
- private boolean on;
- public int bri;
- public int hue;
- public int sat;
- private float[] xy;
- public int ct;
- private String alert;
- private String effect;
- public String colormode;
- private boolean reachable;
-
- public State() {
- }
-
- /**
- * Color modes of a light.
- */
- public enum ColorMode {
- /**
- * CIE color space coordinates
- */
- XY,
-
- /**
- * Hue and saturation
- */
- HS,
-
- /**
- * Color temperature in mired
- */
- CT
- }
-
- /**
- * Alert modes of a light.
- */
- public enum AlertMode {
- /**
- * Light is not performing alert effect
- */
- NONE,
-
- /**
- * Light is performing one breathe cycle
- */
- SELECT,
-
- /**
- * Light is performing breathe cycles for 30 seconds (unless cancelled)
- */
- LSELECT
- }
-
- /**
- * Effects possible for a light.
- */
- public enum Effect {
- /**
- * No effect
- */
- NONE,
-
- /**
- * Cycle through all hues with current saturation and brightness
- */
- COLORLOOP
- }
-
- /**
- * Returns the on state.
- *
- * @return true if the light is on, false if it isn't
- */
- public boolean isOn() {
- return on;
- }
-
- public void setOn(boolean on) {
- this.on = on;
- }
-
- /**
- * Returns the brightness.
- *
- * @return brightness
- */
- public int getBrightness() {
- return bri;
- }
-
- public void setBri(int bri) {
- this.bri = bri;
- }
-
- /**
- * Returns the hue.
- *
- * @return hue
- */
- public int getHue() {
- return hue;
- }
-
- public void setHue(int hue) {
- this.hue = hue;
- }
-
- /**
- * Returns the saturation.
- *
- * @return saturation
- */
- public int getSaturation() {
- return sat;
- }
-
- public void setSaturation(int sat) {
- this.sat = sat;
- }
-
- /**
- * Returns the coordinates in CIE color space.
- *
- * @return cie color spaces coordinates
- */
- public float[] getXY() {
- return xy;
- }
-
- public void setXY(float[] xy) {
- this.xy = xy;
- }
-
- /**
- * Returns the color temperature.
- *
- * @return color temperature
- */
- public int getColorTemperature() {
- return ct;
- }
-
- public void setColorTemperature(int ct) {
- this.ct = ct;
- }
-
- /**
- * Returns the last alert mode set.
- * Future firmware updates may change this to actually report the current alert mode.
- *
- * @return last alert mode
- */
- public AlertMode getAlertMode() {
- if (alert == null) {
- return null;
- }
- return AlertMode.valueOf(alert.toUpperCase());
- }
-
- /**
- * Returns the current color mode.
- *
- * @return current color mode
- */
- public ColorMode getColorMode() {
- if (colormode == null) {
- return null;
- }
- return ColorMode.valueOf(colormode.toUpperCase());
- }
-
- public void setColormode(ColorMode colormode) {
- this.colormode = colormode.name();
- }
-
- /**
- * Returns the current active effect.
- *
- * @return current active effect
- */
- public Effect getEffect() {
- if (effect == null) {
- return null;
- }
- return Effect.valueOf(effect.toUpperCase());
- }
-
- /**
- * Returns reachability.
- *
- * @return true if reachable, false if it isn't
- */
- public boolean isReachable() {
- return reachable;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((alert == null) ? 0 : alert.hashCode());
- result = prime * result + bri;
- result = prime * result + ((colormode == null) ? 0 : colormode.hashCode());
- result = prime * result + ct;
- result = prime * result + ((effect == null) ? 0 : effect.hashCode());
- result = prime * result + hue;
- result = prime * result + (on ? 1231 : 1237);
- result = prime * result + (reachable ? 1231 : 1237);
- result = prime * result + sat;
- result = prime * result + Arrays.hashCode(xy);
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- State other = (State) obj;
- if (alert == null) {
- if (other.alert != null) {
- return false;
- }
- } else if (!alert.equals(other.alert)) {
- return false;
- }
- if (bri != other.bri) {
- return false;
- }
- if (colormode == null) {
- if (other.colormode != null) {
- return false;
- }
- } else if (!colormode.equals(other.colormode)) {
- return false;
- }
- if (ct != other.ct) {
- return false;
- }
- if (effect == null) {
- if (other.effect != null) {
- return false;
- }
- } else if (!effect.equals(other.effect)) {
- return false;
- }
- if (hue != other.hue) {
- return false;
- }
- if (on != other.on) {
- return false;
- }
- if (reachable != other.reachable) {
- return false;
- }
- if (sat != other.sat) {
- return false;
- }
- return Arrays.equals(xy, other.xy);
- }
-}
+++ /dev/null
-/**
- * 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.dto;
-
-import org.openhab.binding.hue.internal.dto.State.AlertMode;
-import org.openhab.binding.hue.internal.dto.State.Effect;
-
-/**
- * Collection of updates to the state of a light.
- *
- * @author Q42 - Initial contribution
- * @author Thomas Höfer - added unique id and changed range check for brightness and saturation
- * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding, minor code cleanup
- * @author Samuel Leisering - refactor configuration updates
- */
-public class StateUpdate extends ConfigUpdate {
-
- private Integer colorTemperature;
- private Integer brightness;
-
- /**
- * Turn light on.
- *
- * @return this object for chaining calls
- */
- public StateUpdate turnOn() {
- return setOn(true);
- }
-
- /**
- * Turn light off.
- *
- * @return this object for chaining calls
- */
- public StateUpdate turnOff() {
- return setOn(false);
- }
-
- /**
- * Turn light on or off.
- *
- * @param on on if true, off otherwise
- * @return this object for chaining calls
- */
- public StateUpdate setOn(boolean on) {
- commands.add(new Command("on", on));
- return this;
- }
-
- /**
- * Set brightness of light.
- * Brightness 0 is not the same as off.
- *
- * @param brightness brightness [1..254]
- * @return this object for chaining calls
- */
- public StateUpdate setBrightness(int brightness) {
- if (brightness < 1 || brightness > 254) {
- throw new IllegalArgumentException("Brightness out of range");
- }
-
- commands.add(new Command("bri", brightness));
- this.brightness = brightness;
- return this;
- }
-
- public Integer getBrightness() {
- return this.brightness;
- }
-
- /**
- * Switch to HS color mode and set hue.
- *
- * @param hue hue [0..65535]
- * @return this object for chaining calls
- */
- public StateUpdate setHue(int hue) {
- if (hue < 0 || hue > 65535) {
- throw new IllegalArgumentException("Hue out of range");
- }
-
- commands.add(new Command("hue", hue));
- return this;
- }
-
- /**
- * Switch to HS color mode and set saturation.
- *
- * @param saturation saturation [0..254]
- * @return this object for chaining calls
- */
- public StateUpdate setSat(int saturation) {
- if (saturation < 0 || saturation > 254) {
- throw new IllegalArgumentException("Saturation out of range");
- }
-
- commands.add(new Command("sat", saturation));
- return this;
- }
-
- /**
- * Switch to XY color mode and set CIE color space coordinates.
- *
- * @param x x coordinate [0..1]
- * @param y y coordinate [0..1]
- * @return this object for chaining calls
- */
- public StateUpdate setXY(float x, float y) {
- return setXY(new float[] { x, y });
- }
-
- /**
- * Switch to XY color mode and set CIE color space coordinates.
- *
- * @param xy x and y coordinates [0..1, 0..1]
- * @return this object for chaining calls
- */
- public StateUpdate setXY(float[] xy) {
- if (xy.length != 2) {
- throw new IllegalArgumentException("Invalid coordinate array given");
- } else if (xy[0] < 0.0f || xy[0] > 1.0f || xy[1] < 0.0f || xy[1] > 1.0f) {
- throw new IllegalArgumentException("X and/or Y coordinate(s) out of bounds");
- }
-
- commands.add(new Command("xy", xy));
- return this;
- }
-
- /**
- * Switch to CT color mode and set color temperature in mired.
- *
- * @param colorTemperature color temperature
- * @return this object for chaining calls
- */
- public StateUpdate setColorTemperature(int colorTemperature, ColorTemperature capabilities) {
- if (colorTemperature < capabilities.min || colorTemperature > capabilities.max) {
- throw new IllegalArgumentException(String.format("Color temperature %d is out of range [%d..%d]",
- colorTemperature, capabilities.min, capabilities.max));
- }
-
- commands.add(new Command("ct", colorTemperature));
- this.colorTemperature = colorTemperature;
- return this;
- }
-
- public Integer getColorTemperature() {
- return this.colorTemperature;
- }
-
- /**
- * Set the alert mode.
- *
- * @see AlertMode
- * @param mode alert mode
- * @return this object for chaining calls
- */
- public StateUpdate setAlert(AlertMode mode) {
- commands.add(new Command("alert", mode.toString().toLowerCase()));
- return this;
- }
-
- /**
- * Set the current effect.
- *
- * @see Effect
- * @param effect effect
- * @return this object for chaining calls
- */
- public StateUpdate setEffect(Effect effect) {
- commands.add(new Command("effect", effect.toString().toLowerCase()));
- return this;
- }
-
- /**
- * Set the transition time from the current state to the new state.
- * Time is accurate to 100 milliseconds.
- *
- * @param timeMillis time in milliseconds [0..6553600]
- * @return this object for chaining calls
- */
- public StateUpdate setTransitionTime(long timeMillis) {
- if (timeMillis < 0 || timeMillis > 6553600) {
- throw new IllegalArgumentException("Transition time out of range");
- }
-
- commands.add(new Command("transitiontime", timeMillis / 100));
- return this;
- }
-
- /**
- * Turn sensor flag on or off.
- *
- * @param flag on if true, off otherwise
- * @return this object for chaining calls
- */
-
- public StateUpdate setFlag(boolean flag) {
- commands.add(new Command("flag", flag));
- return this;
- }
-
- /**
- * Set status of sensor.
- *
- * @param status status
- * @return this object for chaining calls
- */
- public StateUpdate setStatus(int status) {
- commands.add(new Command("status", status));
- return this;
- }
-
- /**
- * Recall the given scene.
- *
- * @param sceneId Identifier of the scene
- * @return this object for chaining calls
- */
- public StateUpdate setScene(String sceneId) {
- commands.add(new Command("scene", sceneId));
- return this;
- }
-}
+++ /dev/null
-/**
- * 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.dto;
-
-import java.lang.reflect.Type;
-import java.util.List;
-import java.util.Map;
-
-import com.google.gson.reflect.TypeToken;
-
-/**
- * @author Q42 - Initial contribution
- * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding
- */
-public class SuccessResponse {
- public static final Type GSON_TYPE = new TypeToken<List<SuccessResponse>>() {
- }.getType();
-
- public Map<String, Object> success;
-}
+++ /dev/null
-/**
- * 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.dto;
-
-import static org.openhab.binding.hue.internal.dto.FullSensor.CONFIG_LED_INDICATION;
-
-/**
- * Updates the configuration of a temperature sensor
- *
- * @author Christoph Weitkamp - Initial contribution
- */
-public class TemperatureConfigUpdate extends SensorConfigUpdate {
- /**
- *
- * @param onOff
- */
- public void setLedIndication(boolean onOff) {
- commands.add(new Command(CONFIG_LED_INDICATION, onOff));
- }
-}
+++ /dev/null
-/**
- * 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.dto;
-
-import java.util.Date;
-
-import com.google.gson.annotations.SerializedName;
-
-/**
- * A whitelisted user.
- *
- * @author Q42 - Initial contribution
- * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding
- */
-public class User {
- @SerializedName("last use date")
- private Date lastUseDate;
-
- @SerializedName("create date")
- private Date createDate;
-
- private String name;
-
- /**
- * Returns the last time a command was issued as this user.
- *
- * @return time of last command by this user
- */
- public Date getLastUseDate() {
- return lastUseDate;
- }
-
- /**
- * Returns the date this user was created.
- *
- * @return creation date of user
- */
- public Date getCreationDate() {
- return createDate;
- }
-
- /**
- * Returns the username of this user.
- *
- * @return username
- */
- public String getUsername() {
- return name;
- }
-}
+++ /dev/null
-/**
- * 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.dto;
-
-import java.nio.charset.StandardCharsets;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-/**
- * @author Q42 - Initial contribution
- * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding
- */
-@NonNullByDefault
-public final class Util {
-
- private Util() {
- }
-
- // This is used to check what byte size strings have, because the bridge doesn't natively support UTF-8
- public static int stringSize(String str) {
- return str.getBytes(StandardCharsets.UTF_8).length;
- }
-
- public static @Nullable String quickMatch(String needle, String haystack) {
- Matcher m = Pattern.compile(needle).matcher(haystack);
- m.find();
- return m.group(1);
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-
-/**
- * DTO that contains an API Action entry.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public class ActionEntry {
- private @NonNullByDefault({}) ResourceReference target;
- private @NonNullByDefault({}) Resource action;
-
- public ResourceReference getTarget() {
- return target;
- }
-
- public Resource getAction() {
- return action;
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2;
-
-import java.util.List;
-import java.util.Objects;
-import java.util.stream.Collectors;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.hue.internal.dto.clip2.enums.ActionType;
-
-import com.google.gson.annotations.SerializedName;
-
-/**
- * DTO for 'alert' of a light.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public class Alerts {
- private @Nullable @SerializedName("action_values") List<String> actionValues;
- private @Nullable String action;
-
- public @Nullable ActionType getAction() {
- String action = this.action;
- return Objects.nonNull(action) ? ActionType.of(action) : null;
- }
-
- public List<ActionType> getActionValues() {
- List<String> actionValues = this.actionValues;
- if (Objects.nonNull(actionValues)) {
- return actionValues.stream().map(ActionType::of).collect(Collectors.toList());
- }
- return List.of();
- }
-
- public Alerts setAction(ActionType actionType) {
- this.action = actionType.name().toLowerCase();
- return this;
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-/**
- * A 'special' DTO for bridge discovery to read the software version from a bridge.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public class BridgeConfig {
- public @Nullable String swversion;
-}
+++ /dev/null
-/**
- * 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.dto.clip2;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.hue.internal.dto.clip2.enums.ButtonEventType;
-
-import com.google.gson.annotations.SerializedName;
-
-/**
- * DTO for CLIP 2 button state.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public class Button {
- private @Nullable @SerializedName("last_event") String lastEvent;
- private @Nullable @SerializedName("button_report") ButtonReport buttonReport;
- private @SerializedName("repeat_interval") int repeatInterval;
-
- /**
- * The underlying field is deprecated in the CLIP 2 API.
- * Moved to button_report/event
- *
- * @return the last button event as an enum (null if none or invalid).
- */
- public @Nullable ButtonEventType getLastEvent() {
- String lastEvent = this.lastEvent;
- if (lastEvent == null) {
- return null;
- }
-
- try {
- return ButtonEventType.valueOf(lastEvent.toUpperCase());
- } catch (IllegalArgumentException e) {
- return null;
- }
- }
-
- public @Nullable ButtonReport getButtonReport() {
- return buttonReport;
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2;
-
-import java.time.Instant;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.hue.internal.dto.clip2.enums.ButtonEventType;
-
-/**
- * DTO for CLIP 2 button report.
- *
- * @author Jacob Laursen - Initial contribution
- */
-@NonNullByDefault
-public class ButtonReport {
- private @NonNullByDefault({}) Instant updated;
- private @Nullable String event;
-
- /**
- * @return last time the value of this property is updated.
- */
- public Instant getLastChanged() {
- return updated;
- }
-
- /**
- * @return event which can be sent by a button control (null if none or invalid).
- */
- public @Nullable ButtonEventType getLastEvent() {
- String event = this.event;
- if (event == null) {
- return null;
- }
-
- try {
- return ButtonEventType.valueOf(event.toUpperCase());
- } catch (IllegalArgumentException e) {
- return null;
- }
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2;
-
-import java.util.Objects;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.hue.internal.exceptions.DTOPresentButEmptyException;
-import org.openhab.core.library.types.QuantityType;
-import org.openhab.core.library.unit.Units;
-
-import com.google.gson.annotations.SerializedName;
-
-/**
- * DTO for colour temperature of a light in CLIP 2.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public class ColorTemperature {
- private @Nullable Long mirek;
- private @Nullable @SerializedName("mirek_schema") MirekSchema mirekSchema;
-
- /**
- * Get the color temperature as a QuantityType value.
- *
- * @return a QuantityType value
- * @throws DTOPresentButEmptyException to indicate that the DTO is present but empty.
- */
- public @Nullable QuantityType<?> getAbsolute() throws DTOPresentButEmptyException {
- Long mirek = this.mirek;
- if (Objects.nonNull(mirek)) {
- return QuantityType.valueOf(mirek, Units.MIRED).toInvertibleUnit(Units.KELVIN);
- }
- throw new DTOPresentButEmptyException("'color_temperature' DTO is present but empty");
- }
-
- public @Nullable Long getMirek() {
- return mirek;
- }
-
- public @Nullable MirekSchema getMirekSchema() {
- return mirekSchema;
- }
-
- /**
- * Get the color temperature as a percentage based on the MirekSchema. Note: this method is only to be used on
- * cached state DTOs which already have a defined mirek schema.
- *
- * @return the percentage of the mirekSchema range.
- * @throws DTOPresentButEmptyException to indicate that the DTO is present but empty.
- */
- public @Nullable Double getPercent() throws DTOPresentButEmptyException {
- Long mirek = this.mirek;
- if (Objects.nonNull(mirek)) {
- MirekSchema mirekSchema = this.mirekSchema;
- mirekSchema = Objects.nonNull(mirekSchema) ? mirekSchema : MirekSchema.DEFAULT_SCHEMA;
- double min = mirekSchema.getMirekMinimum();
- double max = mirekSchema.getMirekMaximum();
- double percent = 100f * (mirek.doubleValue() - min) / (max - min);
- return Math.max(0, Math.min(100, percent));
- }
- throw new DTOPresentButEmptyException("'mirek_schema' DTO is present but empty");
- }
-
- public ColorTemperature setMirek(double mirek) {
- this.mirek = Math.round(mirek);
- return this;
- }
-
- public ColorTemperature setMirekSchema(@Nullable MirekSchema mirekSchema) {
- this.mirekSchema = mirekSchema;
- return this;
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2;
-
-import java.util.Objects;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.hue.internal.exceptions.DTOPresentButEmptyException;
-import org.openhab.core.util.ColorUtil.Gamut;
-
-/**
- * DTO for colour X/Y of a light.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public class ColorXy {
- private @Nullable PairXy xy;
- private @Nullable Gamut2 gamut;
-
- public @Nullable Gamut getGamut() {
- Gamut2 gamut = this.gamut;
- return Objects.nonNull(gamut) ? gamut.getGamut() : null;
- }
-
- public @Nullable Gamut2 getGamut2() {
- return this.gamut;
- }
-
- /**
- * @throws DTOPresentButEmptyException to indicate that the DTO is present but empty.
- */
- public double[] getXY() throws DTOPresentButEmptyException {
- PairXy pairXy = this.xy;
- if (Objects.nonNull(pairXy)) {
- return pairXy.getXY();
- }
- throw new DTOPresentButEmptyException("'color' DTO is present but empty");
- }
-
- public ColorXy setGamut(@Nullable Gamut gamut) {
- this.gamut = Objects.nonNull(gamut) ? new Gamut2().setGamut(gamut) : null;
- return this;
- }
-
- public ColorXy setXY(double[] xyValues) {
- PairXy pairXy = this.xy;
- pairXy = Objects.nonNull(pairXy) ? pairXy : new PairXy();
- pairXy.setXY(xyValues);
- this.xy = pairXy;
- return this;
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2;
-
-import java.time.Instant;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.openhab.binding.hue.internal.dto.clip2.enums.ContactStateType;
-
-/**
- * DTO for CLIP 2 home security alarm contact.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public class ContactReport {
-
- private @NonNullByDefault({}) Instant changed;
- private @NonNullByDefault({}) String state;
-
- public ContactStateType getContactState() throws IllegalArgumentException {
- return ContactStateType.valueOf(state.toUpperCase());
- }
-
- public Instant getLastChanged() {
- return changed;
- }
-
- public ContactReport setLastChanged(Instant changed) {
- this.changed = changed;
- return this;
- }
-
- public ContactReport setContactState(String state) {
- this.state = state;
- return this;
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2;
-
-import java.util.Objects;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.hue.internal.exceptions.DTOPresentButEmptyException;
-
-import com.google.gson.annotations.SerializedName;
-
-/**
- * DTO for dimming brightness of a light.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public class Dimming {
- private @Nullable Double brightness;
- private @Nullable @SerializedName("min_dim_level") Double minimumDimmingLevel;
-
- public static final double DEFAULT_MINIMUM_DIMMIMG_LEVEL = 0.5f;
-
- /**
- * @throws DTOPresentButEmptyException to indicate that the DTO is present but empty.
- */
- public double getBrightness() throws DTOPresentButEmptyException {
- Double brightness = this.brightness;
- if (Objects.nonNull(brightness)) {
- return brightness;
- }
- throw new DTOPresentButEmptyException("'dimming' DTO is present but empty");
- }
-
- public @Nullable Double getMinimumDimmingLevel() {
- return minimumDimmingLevel;
- }
-
- public Dimming setBrightness(double brightness) {
- this.brightness = brightness;
- return this;
- }
-
- public Dimming setMinimumDimmingLevel(Double minimumDimmingLevel) {
- this.minimumDimmingLevel = minimumDimmingLevel;
- return this;
- }
-
- public @Nullable String toPropertyValue() {
- Double minimumDimmingLevel = this.minimumDimmingLevel;
- if (Objects.nonNull(minimumDimmingLevel)) {
- return String.format("%.1f %% .. 100 %%", minimumDimmingLevel.doubleValue());
- }
- return null;
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2;
-
-import java.time.Duration;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-/**
- * DTO for dynamics of transitions between light states.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public class Dynamics {
- private @Nullable @SuppressWarnings("unused") Long duration;
- private @Nullable @SuppressWarnings("unused") Double speed;
-
- public Dynamics setDuration(Duration duration) {
- this.duration = duration.toMillis();
- return this;
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2;
-
-import java.util.List;
-import java.util.Objects;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.hue.internal.dto.clip2.enums.EffectType;
-
-import com.google.gson.annotations.SerializedName;
-
-/**
- * DTO for 'effects' of a light.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public class Effects {
- private @Nullable @SerializedName("effect_values") List<String> effectValues;
- private @Nullable String effect;
- private @Nullable @SerializedName("status_values") List<String> statusValues;
- private @Nullable String status;
-
- public boolean allows(EffectType effect) {
- List<String> statusValues = this.statusValues;
- return Objects.nonNull(statusValues) ? statusValues.contains(effect.name().toLowerCase()) : false;
- }
-
- public EffectType getEffect() {
- String effect = this.effect;
- return Objects.nonNull(effect) ? EffectType.of(effect) : EffectType.NO_EFFECT;
- }
-
- public EffectType getStatus() {
- return Objects.nonNull(status) ? EffectType.of(status) : EffectType.NO_EFFECT;
- }
-
- public List<String> getStatusValues() {
- List<String> statusValues = this.statusValues;
- return Objects.nonNull(statusValues) ? statusValues : List.of();
- }
-
- public Effects setEffect(EffectType effectType) {
- effect = effectType.name().toLowerCase();
- return this;
- }
-
- public Effects setStatusValues(List<String> statusValues) {
- this.statusValues = statusValues;
- return this;
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-
-/**
- * DTO for CLIP 2 communication errors.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public class Error {
- private @NonNullByDefault({}) String description;
-
- public String getDescription() {
- return description;
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2;
-
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-import com.google.gson.reflect.TypeToken;
-
-/**
- * DTO for CLIP 2 event stream objects.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public class Event {
- public static final Type EVENT_LIST_TYPE = new TypeToken<List<Event>>() {
- }.getType();
-
- private @Nullable List<Resource> data = new ArrayList<>();
-
- public List<Resource> getData() {
- List<Resource> data = this.data;
- return Objects.nonNull(data) ? data : List.of();
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2;
-
-import java.util.Objects;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.core.util.ColorUtil.Gamut;
-
-/**
- * DTO for colour gamut of a light.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public class Gamut2 {
- private @Nullable PairXy red;
- private @Nullable PairXy green;
- private @Nullable PairXy blue;
-
- public @Nullable Gamut getGamut() {
- PairXy red = this.red;
- PairXy green = this.green;
- PairXy blue = this.blue;
- if (Objects.nonNull(red) && Objects.nonNull(green) && Objects.nonNull(blue)) {
- return new Gamut(red.getXY(), green.getXY(), blue.getXY());
- }
- return null;
- }
-
- public Gamut2 setGamut(Gamut gamut) {
- red = new PairXy().setXY(gamut.r());
- green = new PairXy().setXY(gamut.g());
- blue = new PairXy().setXY(gamut.b());
- return this;
- }
-
- public @Nullable String toPropertyValue() {
- PairXy red = this.red;
- PairXy green = this.green;
- PairXy blue = this.blue;
- if (Objects.nonNull(red) && Objects.nonNull(green) && Objects.nonNull(blue)) {
- double[] r = red.getXY();
- double[] g = green.getXY();
- double[] b = blue.getXY();
- return String.format("(%.3f,%.3f) (%.3f,%.3f) (%.3f,%.3f)", r[0], r[1], g[0], g[1], b[0], b[1]);
- }
- return null;
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.core.library.types.OnOffType;
-import org.openhab.core.library.types.QuantityType;
-import org.openhab.core.library.unit.Units;
-import org.openhab.core.types.State;
-import org.openhab.core.types.UnDefType;
-
-import com.google.gson.annotations.SerializedName;
-
-/**
- * DTO for CLIP 2 light level sensor.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public class LightLevel {
- private @SerializedName("light_level") int lightLevel;
- private @SerializedName("light_level_valid") boolean lightLevelValid;
- private @Nullable @SerializedName("light_level_report") LightLevelReport lightLevelReport;
-
- /**
- * The underlying field is deprecated in the CLIP 2 API.
- * Moved to light_level_report/light_level
- * Should be used only as fallback for older firmwares.
- */
- public int getLightLevel() {
- return lightLevel;
- }
-
- /**
- * The underlying field is deprecated in the CLIP 2 API.
- * Indication whether the value presented in light_level is valid
- * Should be used only as fallback for older firmwares.
- */
- public boolean isLightLevelValid() {
- return lightLevelValid;
- }
-
- /**
- * Raw sensor light level formula is '10000 * log10(lux + 1)' so apply the inverse formula to convert back to Lux.
- * NOTE: the Philips/Signify API documentation quotes the formula as '10000 * log10(lux) + 1', however this code
- * author thinks that that formula is wrong since zero Lux would cause a log10(0) negative infinity overflow!
- *
- * @return a QuantityType with light level in Lux, or UNDEF.
- */
- public State getLightLevelState() {
- if (lightLevelValid) {
- return new QuantityType<>(Math.pow(10f, (double) lightLevel / 10000f) - 1f, Units.LUX);
- }
- return UnDefType.UNDEF;
- }
-
- public State isLightLevelValidState() {
- return OnOffType.from(lightLevelValid);
- }
-
- public @Nullable LightLevelReport getLightLevelReport() {
- return lightLevelReport;
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2;
-
-import java.time.Instant;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-
-import com.google.gson.annotations.SerializedName;
-
-/**
- * DTO for CLIP 2 light level sensor report.
- *
- * @author Jacob Laursen - Initial contribution
- */
-@NonNullByDefault
-public class LightLevelReport {
- private @NonNullByDefault({}) Instant changed;
- private @SerializedName("light_level") int lightLevel;
-
- /**
- * @return last time the value of this property is changed.
- */
- public Instant getLastChanged() {
- return changed;
- }
-
- /**
- * Light level in 10000*log10(lux) +1 measured by sensor.
- * Logarithmic scale used because the human eye adjusts to light levels and small changes at low lux levels
- * are more noticeable than at high lux levels. This allows use of linear scale configuration sliders.
- *
- * @return light level in 10000*log10(lux) +1 measured by sensor
- */
- public int getLightLevel() {
- return lightLevel;
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.hue.internal.dto.clip2.enums.Archetype;
-
-import com.google.gson.annotations.SerializedName;
-
-/**
- * DTO for CLIP 2 product metadata.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public class MetaData {
- private @Nullable String archetype;
- private @Nullable String name;
- private @Nullable @SerializedName("control_id") Integer controlId;
-
- public Archetype getArchetype() {
- return Archetype.of(archetype);
- }
-
- public @Nullable String getName() {
- return name;
- }
-
- public int getControlId() {
- Integer controlId = this.controlId;
- return controlId != null ? controlId.intValue() : 0;
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2;
-
-import java.util.Objects;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.openhab.core.library.types.QuantityType;
-import org.openhab.core.library.unit.Units;
-
-import com.google.gson.annotations.SerializedName;
-
-/**
- * DTO for CLIP 2 mirek schema.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public class MirekSchema {
- private static final int MIN = 153;
- private static final int MAX = 500;
-
- public static final MirekSchema DEFAULT_SCHEMA = new MirekSchema();
-
- private @SerializedName("mirek_minimum") int mirekMinimum = MIN;
- private @SerializedName("mirek_maximum") int mirekMaximum = MAX;
-
- public int getMirekMaximum() {
- return mirekMaximum;
- }
-
- public int getMirekMinimum() {
- return mirekMinimum;
- }
-
- private String toKelvin(int mirek) {
- QuantityType<?> kelvin = QuantityType.valueOf(mirek, Units.MIRED).toInvertibleUnit(Units.KELVIN);
- return Objects.nonNull(kelvin) ? String.format("%.0f K", kelvin.doubleValue()) : "";
- }
-
- public String toPropertyValue() {
- return String.format("%s .. %s", toKelvin(mirekMinimum), toKelvin(mirekMaximum));
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.core.library.types.OnOffType;
-import org.openhab.core.types.State;
-import org.openhab.core.types.UnDefType;
-
-import com.google.gson.annotations.SerializedName;
-
-/**
- * DTO for CLIP 2 motion sensor.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public class Motion {
- private boolean motion;
- private @SerializedName("motion_valid") boolean motionValid;
- private @Nullable @SerializedName("motion_report") MotionReport motionReport;
-
- /**
- * The underlying field is deprecated in the CLIP 2 API.
- * Moved to motion_report/motion.
- * Should be used only as fallback for older firmwares.
- *
- * @return true if motion is detected
- */
- public boolean isMotion() {
- return motion;
- }
-
- /**
- * The underlying field is deprecated in the CLIP 2 API.
- * Motion is valid when motion_report property is present, invalid when absent.
- * Should be used only as fallback for older firmwares.
- */
- public boolean isMotionValid() {
- return motionValid;
- }
-
- public State getMotionState() {
- return motionValid ? OnOffType.from(motion) : UnDefType.UNDEF;
- }
-
- public State getMotionValidState() {
- return OnOffType.from(motionValid);
- }
-
- public @Nullable MotionReport getMotionReport() {
- return motionReport;
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2;
-
-import java.time.Instant;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-
-/**
- * DTO for CLIP 2 motion sensor report.
- *
- * @author Jacob Laursen - Initial contribution
- */
-@NonNullByDefault
-public class MotionReport {
- private @NonNullByDefault({}) Instant changed;
- private boolean motion;
-
- /**
- * @return last time the value of this property is changed.
- */
- public Instant getLastChanged() {
- return changed;
- }
-
- /**
- * @return true if motion is detected
- */
- public boolean isMotion() {
- return motion;
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2;
-
-import java.util.Objects;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.hue.internal.exceptions.DTOPresentButEmptyException;
-
-/**
- * DTO for 'on' state of a light.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public class OnState {
- private @Nullable Boolean on;
-
- /**
- * @throws DTOPresentButEmptyException to indicate that the DTO is present but empty.
- */
- public boolean isOn() throws DTOPresentButEmptyException {
- Boolean on = this.on;
- if (Objects.nonNull(on)) {
- return on;
- }
- throw new DTOPresentButEmptyException("'on' DTO is present but empty");
- }
-
- public void setOn(boolean on) {
- this.on = on;
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2;
-
-/**
- * DTO that contains an x and y pair of doubles.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-public class PairXy {
- private double x;
- private double y;
-
- public double[] getXY() {
- return new double[] { x, y };
- }
-
- public PairXy setXY(double[] xy) {
- x = xy.length > 0 ? xy[0] : 0f;
- y = xy.length > 1 ? xy[1] : 0f;
- return this;
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.openhab.binding.hue.internal.dto.clip2.enums.BatteryStateType;
-import org.openhab.core.library.types.DecimalType;
-import org.openhab.core.library.types.OnOffType;
-import org.openhab.core.types.State;
-
-import com.google.gson.annotations.SerializedName;
-
-/**
- * DTO for CLIP 2 power state.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public class Power {
- private @NonNullByDefault({}) @SerializedName("battery_state") String batteryState;
- private @SerializedName("battery_level") int batteryLevel;
-
- public BatteryStateType getBatteryState() {
- try {
- return BatteryStateType.valueOf(batteryState.toUpperCase());
- } catch (IllegalArgumentException e) {
- return BatteryStateType.CRITICAL;
- }
- }
-
- public int getBatteryLevel() {
- return batteryLevel;
- }
-
- public State getBatteryLowState() {
- return OnOffType.from(getBatteryState() != BatteryStateType.NORMAL);
- }
-
- public State getBatteryLevelState() {
- return new DecimalType(getBatteryLevel());
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.hue.internal.dto.clip2.enums.Archetype;
-
-import com.google.gson.annotations.SerializedName;
-
-/**
- * DTO for CLIP 2 product data.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public class ProductData {
- private @NonNullByDefault({}) @SerializedName("model_id") String modelId;
- private @NonNullByDefault({}) @SerializedName("manufacturer_name") String manufacturerName;
- private @NonNullByDefault({}) @SerializedName("product_name") String productName;
- private @NonNullByDefault({}) @SerializedName("product_archetype") String productArchetype;
- private @NonNullByDefault({}) Boolean certified;
- private @NonNullByDefault({}) @SerializedName("software_version") String softwareVersion;
- private @Nullable @SerializedName("hardware_platform_type") String hardwarePlatformType;
-
- public String getModelId() {
- return modelId;
- }
-
- public String getManufacturerName() {
- return manufacturerName;
- }
-
- public String getProductName() {
- return productName;
- }
-
- public Archetype getProductArchetype() {
- return Archetype.of(productArchetype);
- }
-
- public Boolean getCertified() {
- return certified != null ? certified : false;
- }
-
- public String getSoftwareVersion() {
- return softwareVersion != null ? softwareVersion : "";
- }
-
- public @Nullable String getHardwarePlatformType() {
- return hardwarePlatformType;
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2;
-
-import java.time.Duration;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.hue.internal.dto.clip2.enums.SceneRecallAction;
-import org.openhab.binding.hue.internal.dto.clip2.enums.SmartSceneRecallAction;
-
-/**
- * DTO for scene and smart scene recall.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public class Recall {
- private @Nullable @SuppressWarnings("unused") String action;
- private @Nullable @SuppressWarnings("unused") String status;
- private @Nullable @SuppressWarnings("unused") Long duration;
-
- public Recall setAction(SceneRecallAction action) {
- this.action = action.name().toLowerCase();
- return this;
- }
-
- public Recall setAction(SmartSceneRecallAction action) {
- this.action = action.name().toLowerCase();
- return this;
- }
-
- public Recall setDuration(Duration duration) {
- this.duration = duration.toMillis();
- return this;
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2;
-
-import java.util.Objects;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.core.types.State;
-import org.openhab.core.types.UnDefType;
-
-import com.google.gson.annotations.SerializedName;
-
-/**
- * DTO for CLIP 2 tap switch rotary dial state.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public class RelativeRotary {
- private @Nullable @SerializedName("last_event") RotationEvent lastEvent;
- private @Nullable @SerializedName("rotary_report") RotaryReport rotaryReport;
-
- public State getActionState() {
- RotationEvent lastEvent = getLastEvent();
- return Objects.nonNull(lastEvent) ? lastEvent.getActionState() : UnDefType.NULL;
- }
-
- /**
- * The underlying field is deprecated in the CLIP 2 API.
- * Renamed to RelativeRotaryReport. Indicate which type of rotary event is received.
- * Should be used only as fallback for older firmwares.
- */
- public @Nullable RotationEvent getLastEvent() {
- return lastEvent;
- }
-
- /**
- * The underlying field is deprecated in the CLIP 2 API.
- * Renamed to RelativeRotaryReport.
- * Should be used only as fallback for older firmwares.
- */
- public State getStepsState() {
- RotationEvent lastEvent = getLastEvent();
- return Objects.nonNull(lastEvent) ? lastEvent.getStepsState() : UnDefType.NULL;
- }
-
- public @Nullable RotaryReport getRotaryReport() {
- return rotaryReport;
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2;
-
-import java.math.BigDecimal;
-import java.math.MathContext;
-import java.math.RoundingMode;
-import java.time.Duration;
-import java.time.Instant;
-import java.time.ZoneId;
-import java.time.ZonedDateTime;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.hue.internal.dto.clip2.enums.ActionType;
-import org.openhab.binding.hue.internal.dto.clip2.enums.ButtonEventType;
-import org.openhab.binding.hue.internal.dto.clip2.enums.ContactStateType;
-import org.openhab.binding.hue.internal.dto.clip2.enums.EffectType;
-import org.openhab.binding.hue.internal.dto.clip2.enums.ResourceType;
-import org.openhab.binding.hue.internal.dto.clip2.enums.SceneRecallAction;
-import org.openhab.binding.hue.internal.dto.clip2.enums.SmartSceneRecallAction;
-import org.openhab.binding.hue.internal.dto.clip2.enums.SmartSceneState;
-import org.openhab.binding.hue.internal.dto.clip2.enums.TamperStateType;
-import org.openhab.binding.hue.internal.dto.clip2.enums.ZigbeeStatus;
-import org.openhab.binding.hue.internal.exceptions.DTOPresentButEmptyException;
-import org.openhab.core.library.types.DateTimeType;
-import org.openhab.core.library.types.DecimalType;
-import org.openhab.core.library.types.HSBType;
-import org.openhab.core.library.types.OnOffType;
-import org.openhab.core.library.types.OpenClosedType;
-import org.openhab.core.library.types.PercentType;
-import org.openhab.core.library.types.QuantityType;
-import org.openhab.core.library.types.StringType;
-import org.openhab.core.library.unit.SIUnits;
-import org.openhab.core.library.unit.Units;
-import org.openhab.core.types.Command;
-import org.openhab.core.types.State;
-import org.openhab.core.types.UnDefType;
-import org.openhab.core.util.ColorUtil;
-import org.openhab.core.util.ColorUtil.Gamut;
-
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.annotations.SerializedName;
-
-/**
- * Complete Resource information DTO for CLIP 2.
- *
- * Note: all fields are @Nullable because some cases do not (must not) use them.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public class Resource {
-
- public static final double PERCENT_DELTA = 30f;
- public static final MathContext PERCENT_MATH_CONTEXT = new MathContext(4, RoundingMode.HALF_UP);
-
- /**
- * The SSE event mechanism sends resources in a sparse (skeleton) format that only includes state fields whose
- * values have changed. A sparse resource does not contain the full state of the resource. And the absence of any
- * field from such a resource does not indicate that the field value is UNDEF, but rather that the value is the same
- * as what it was previously set to by the last non-sparse resource.
- */
- private transient boolean hasSparseData;
-
- private @Nullable String type;
- private @Nullable String id;
- private @Nullable @SerializedName("bridge_id") String bridgeId;
- private @Nullable @SerializedName("id_v1") String idV1;
- private @Nullable ResourceReference owner;
- private @Nullable MetaData metadata;
- private @Nullable @SerializedName("product_data") ProductData productData;
- private @Nullable List<ResourceReference> services;
- private @Nullable OnState on;
- private @Nullable Dimming dimming;
- private @Nullable @SerializedName("color_temperature") ColorTemperature colorTemperature;
- private @Nullable ColorXy color;
- private @Nullable Alerts alert;
- private @Nullable Effects effects;
- private @Nullable @SerializedName("timed_effects") TimedEffects timedEffects;
- private @Nullable ResourceReference group;
- private @Nullable List<ActionEntry> actions;
- private @Nullable Recall recall;
- private @Nullable Boolean enabled;
- private @Nullable LightLevel light;
- private @Nullable Button button;
- private @Nullable Temperature temperature;
- private @Nullable Motion motion;
- private @Nullable @SerializedName("power_state") Power powerState;
- private @Nullable @SerializedName("relative_rotary") RelativeRotary relativeRotary;
- private @Nullable List<ResourceReference> children;
- private @Nullable JsonElement status;
- private @Nullable @SuppressWarnings("unused") Dynamics dynamics;
- private @Nullable @SerializedName("contact_report") ContactReport contactReport;
- private @Nullable @SerializedName("tamper_reports") List<TamperReport> tamperReports;
- private @Nullable String state;
-
- /**
- * Constructor
- *
- * @param resourceType
- */
- public Resource(@Nullable ResourceType resourceType) {
- if (Objects.nonNull(resourceType)) {
- setType(resourceType);
- }
- }
-
- public @Nullable List<ActionEntry> getActions() {
- return actions;
- }
-
- public @Nullable Alerts getAlerts() {
- return alert;
- }
-
- public State getAlertState() {
- Alerts alerts = this.alert;
- if (Objects.nonNull(alerts)) {
- if (!alerts.getActionValues().isEmpty()) {
- ActionType alertType = alerts.getAction();
- if (Objects.nonNull(alertType)) {
- return new StringType(alertType.name());
- }
- return new StringType(ActionType.NO_ACTION.name());
- }
- }
- return UnDefType.NULL;
- }
-
- public String getArchetype() {
- MetaData metaData = getMetaData();
- if (Objects.nonNull(metaData)) {
- return metaData.getArchetype().toString();
- }
- return getType().toString();
- }
-
- public State getBatteryLevelState() {
- Power powerState = this.powerState;
- return Objects.nonNull(powerState) ? powerState.getBatteryLevelState() : UnDefType.NULL;
- }
-
- public State getBatteryLowState() {
- Power powerState = this.powerState;
- return Objects.nonNull(powerState) ? powerState.getBatteryLowState() : UnDefType.NULL;
- }
-
- public @Nullable String getBridgeId() {
- String bridgeId = this.bridgeId;
- return Objects.isNull(bridgeId) || bridgeId.isBlank() ? null : bridgeId;
- }
-
- /**
- * Get the brightness as a PercentType. If off the brightness is 0, otherwise use dimming value.
- *
- * @return a PercentType with the dimming state, or UNDEF, or NULL
- */
- public State getBrightnessState() {
- Dimming dimming = this.dimming;
- if (Objects.nonNull(dimming)) {
- try {
- // if off the brightness is 0, otherwise it is dimming value
- OnState on = this.on;
- double brightness = Objects.nonNull(on) && !on.isOn() ? 0f
- : Math.max(0f, Math.min(100f, dimming.getBrightness()));
- return new PercentType(new BigDecimal(brightness, PERCENT_MATH_CONTEXT));
- } catch (DTOPresentButEmptyException e) {
- return UnDefType.UNDEF; // indicates the DTO is present but its inner fields are missing
- }
- }
- return UnDefType.NULL;
- }
-
- public @Nullable Button getButton() {
- return button;
- }
-
- /**
- * Get the state corresponding to a button's last event value multiplied by the controlId found for it in the given
- * controlIds map. States are decimal values formatted like '1002' where the first digit is the button's controlId
- * and the last digit is the ordinal value of the button's last event.
- *
- * @param controlIds the map of control ids to be referenced.
- * @return the state.
- */
- public State getButtonEventState(Map<String, Integer> controlIds) {
- Button button = this.button;
- if (button == null) {
- return UnDefType.NULL;
- }
- ButtonEventType event;
- ButtonReport buttonReport = button.getButtonReport();
- if (buttonReport == null) {
- event = button.getLastEvent();
- } else {
- event = buttonReport.getLastEvent();
- }
- if (event == null) {
- return UnDefType.NULL;
- }
- return new DecimalType((controlIds.getOrDefault(getId(), 0).intValue() * 1000) + event.ordinal());
- }
-
- public State getButtonLastUpdatedState(ZoneId zoneId) {
- Button button = this.button;
- if (button == null) {
- return UnDefType.NULL;
- }
- ButtonReport buttonReport = button.getButtonReport();
- if (buttonReport == null) {
- return UnDefType.UNDEF;
- }
- Instant lastChanged = buttonReport.getLastChanged();
- if (Instant.EPOCH.equals(lastChanged)) {
- return UnDefType.UNDEF;
- }
- return new DateTimeType(ZonedDateTime.ofInstant(lastChanged, zoneId));
- }
-
- public List<ResourceReference> getChildren() {
- List<ResourceReference> children = this.children;
- return Objects.nonNull(children) ? children : List.of();
- }
-
- /**
- * Get the color as an HSBType. This returns an HSB that is based on an amalgamation of the color xy, dimming, and
- * on/off JSON elements. It takes its 'H' and 'S' parts from the 'ColorXy' JSON element, and its 'B' part from the
- * on/off resp. dimming JSON elements. If off the B part is 0, otherwise it is the dimming element value. Note: this
- * method is only to be used on cached state DTOs which already have a defined color gamut.
- *
- * @return an HSBType containing the current color and brightness level, or UNDEF or NULL.
- */
- public State getColorState() {
- ColorXy color = this.color;
- if (Objects.nonNull(color)) {
- try {
- Gamut gamut = color.getGamut();
- gamut = Objects.nonNull(gamut) ? gamut : ColorUtil.DEFAULT_GAMUT;
- HSBType hsb = ColorUtil.xyToHsb(color.getXY(), gamut);
- OnState on = this.on;
- Dimming dimming = this.dimming;
- double brightness = Objects.nonNull(on) && !on.isOn() ? 0
- : Objects.nonNull(dimming) ? Math.max(0, Math.min(100, dimming.getBrightness())) : 50;
- return new HSBType(hsb.getHue(), hsb.getSaturation(),
- new PercentType(new BigDecimal(brightness, PERCENT_MATH_CONTEXT)));
- } catch (DTOPresentButEmptyException e) {
- return UnDefType.UNDEF; // indicates the DTO is present but its inner fields are missing
- }
- }
- return UnDefType.NULL;
- }
-
- public @Nullable ColorTemperature getColorTemperature() {
- return colorTemperature;
- }
-
- public State getColorTemperatureAbsoluteState() {
- ColorTemperature colorTemp = colorTemperature;
- if (Objects.nonNull(colorTemp)) {
- try {
- QuantityType<?> colorTemperature = colorTemp.getAbsolute();
- if (Objects.nonNull(colorTemperature)) {
- return colorTemperature;
- }
- } catch (DTOPresentButEmptyException e) {
- return UnDefType.UNDEF; // indicates the DTO is present but its inner fields are missing
- }
- }
- return UnDefType.NULL;
- }
-
- /**
- * Get the colour temperature in percent. Note: this method is only to be used on cached state DTOs which already
- * have a defined mirek schema.
- *
- * @return a PercentType with the colour temperature percentage.
- */
- public State getColorTemperaturePercentState() {
- ColorTemperature colorTemperature = this.colorTemperature;
- if (Objects.nonNull(colorTemperature)) {
- try {
- Double percent = colorTemperature.getPercent();
- if (Objects.nonNull(percent)) {
- return new PercentType(new BigDecimal(percent, PERCENT_MATH_CONTEXT));
- }
- } catch (DTOPresentButEmptyException e) {
- return UnDefType.UNDEF; // indicates the DTO is present but its inner fields are missing
- }
- }
- return UnDefType.NULL;
- }
-
- public @Nullable ColorXy getColorXy() {
- return color;
- }
-
- /**
- * Return an HSB where the HS part is derived from the color xy JSON element (only), so the B part is 100%
- *
- * @return an HSBType.
- */
- public State getColorXyState() {
- ColorXy color = this.color;
- if (Objects.nonNull(color)) {
- try {
- Gamut gamut = color.getGamut();
- gamut = Objects.nonNull(gamut) ? gamut : ColorUtil.DEFAULT_GAMUT;
- HSBType hsb = ColorUtil.xyToHsb(color.getXY(), gamut);
- return new HSBType(hsb.getHue(), hsb.getSaturation(), PercentType.HUNDRED);
- } catch (DTOPresentButEmptyException e) {
- return UnDefType.UNDEF; // indicates the DTO is present but its inner fields are missing
- }
- }
- return UnDefType.NULL;
- }
-
- public State getContactLastUpdatedState(ZoneId zoneId) {
- ContactReport contactReport = this.contactReport;
- return Objects.nonNull(contactReport)
- ? new DateTimeType(ZonedDateTime.ofInstant(contactReport.getLastChanged(), zoneId))
- : UnDefType.NULL;
- }
-
- public State getContactState() {
- ContactReport contactReport = this.contactReport;
- return Objects.isNull(contactReport) ? UnDefType.NULL
- : ContactStateType.CONTACT == contactReport.getContactState() ? OpenClosedType.CLOSED
- : OpenClosedType.OPEN;
- }
-
- public int getControlId() {
- MetaData metadata = this.metadata;
- return Objects.nonNull(metadata) ? metadata.getControlId() : 0;
- }
-
- public @Nullable Dimming getDimming() {
- return dimming;
- }
-
- /**
- * Return a PercentType which is derived from the dimming JSON element (only).
- *
- * @return a PercentType.
- */
- public State getDimmingState() {
- Dimming dimming = this.dimming;
- if (Objects.nonNull(dimming)) {
- try {
- double dimmingValue = Math.max(0f, Math.min(100f, dimming.getBrightness()));
- return new PercentType(new BigDecimal(dimmingValue, PERCENT_MATH_CONTEXT));
- } catch (DTOPresentButEmptyException e) {
- return UnDefType.UNDEF; // indicates the DTO is present but its inner fields are missing
- }
- }
- return UnDefType.NULL;
- }
-
- public @Nullable Effects getFixedEffects() {
- return effects;
- }
-
- /**
- * Get the amalgamated effect state. The result may be either from an 'effects' field or from a 'timedEffects'
- * field. If both fields are missing it returns UnDefType.NULL, otherwise if either field is present and has an
- * active value (other than EffectType.NO_EFFECT) it returns a StringType of the name of the respective active
- * effect; and if none of the above apply, it returns a StringType of 'NO_EFFECT'.
- *
- * @return either a StringType value or UnDefType.NULL
- */
- public State getEffectState() {
- Effects effects = this.effects;
- TimedEffects timedEffects = this.timedEffects;
- if (Objects.isNull(effects) && Objects.isNull(timedEffects)) {
- return UnDefType.NULL;
- }
- EffectType effect = Objects.nonNull(effects) ? effects.getStatus() : null;
- if (Objects.nonNull(effect) && effect != EffectType.NO_EFFECT) {
- return new StringType(effect.name());
- }
- EffectType timedEffect = Objects.nonNull(timedEffects) ? timedEffects.getStatus() : null;
- if (Objects.nonNull(timedEffect) && timedEffect != EffectType.NO_EFFECT) {
- return new StringType(timedEffect.name());
- }
- return new StringType(EffectType.NO_EFFECT.name());
- }
-
- public @Nullable Boolean getEnabled() {
- return enabled;
- }
-
- public State getEnabledState() {
- Boolean enabled = this.enabled;
- return Objects.nonNull(enabled) ? OnOffType.from(enabled.booleanValue()) : UnDefType.NULL;
- }
-
- public @Nullable Gamut getGamut() {
- ColorXy color = this.color;
- return Objects.nonNull(color) ? color.getGamut() : null;
- }
-
- public @Nullable ResourceReference getGroup() {
- return group;
- }
-
- public String getId() {
- String id = this.id;
- return Objects.nonNull(id) ? id : "";
- }
-
- public String getIdV1() {
- String idV1 = this.idV1;
- return Objects.nonNull(idV1) ? idV1 : "";
- }
-
- public @Nullable LightLevel getLightLevel() {
- return light;
- }
-
- public State getLightLevelState() {
- LightLevel lightLevel = this.light;
- if (lightLevel == null) {
- return UnDefType.NULL;
- }
- LightLevelReport lightLevelReport = lightLevel.getLightLevelReport();
- if (lightLevelReport == null) {
- return lightLevel.getLightLevelState();
- }
- return new QuantityType<>(Math.pow(10f, (double) lightLevelReport.getLightLevel() / 10000f) - 1f, Units.LUX);
- }
-
- public State getLightLevelLastUpdatedState(ZoneId zoneId) {
- LightLevel lightLevel = this.light;
- if (lightLevel == null) {
- return UnDefType.NULL;
- }
- LightLevelReport lightLevelReport = lightLevel.getLightLevelReport();
- if (lightLevelReport == null) {
- return UnDefType.UNDEF;
- }
- Instant lastChanged = lightLevelReport.getLastChanged();
- if (Instant.EPOCH.equals(lastChanged)) {
- return UnDefType.UNDEF;
- }
- return new DateTimeType(ZonedDateTime.ofInstant(lastChanged, zoneId));
- }
-
- public @Nullable MetaData getMetaData() {
- return metadata;
- }
-
- public @Nullable Double getMinimumDimmingLevel() {
- Dimming dimming = this.dimming;
- return Objects.nonNull(dimming) ? dimming.getMinimumDimmingLevel() : null;
- }
-
- public @Nullable MirekSchema getMirekSchema() {
- ColorTemperature colorTemp = this.colorTemperature;
- return Objects.nonNull(colorTemp) ? colorTemp.getMirekSchema() : null;
- }
-
- public @Nullable Motion getMotion() {
- return motion;
- }
-
- public State getMotionState() {
- Motion motion = this.motion;
- if (motion == null) {
- return UnDefType.NULL;
- }
- MotionReport motionReport = motion.getMotionReport();
- if (motionReport == null) {
- return motion.getMotionState();
- }
- return OnOffType.from(motionReport.isMotion());
- }
-
- public State getMotionLastUpdatedState(ZoneId zoneId) {
- Motion motion = this.motion;
- if (motion == null) {
- return UnDefType.NULL;
- }
- MotionReport motionReport = motion.getMotionReport();
- if (motionReport == null) {
- return UnDefType.UNDEF;
- }
- Instant lastChanged = motionReport.getLastChanged();
- if (Instant.EPOCH.equals(lastChanged)) {
- return UnDefType.UNDEF;
- }
- return new DateTimeType(ZonedDateTime.ofInstant(lastChanged, zoneId));
- }
-
- public State getMotionValidState() {
- Motion motion = this.motion;
- return Objects.nonNull(motion) ? motion.getMotionValidState() : UnDefType.NULL;
- }
-
- public String getName() {
- MetaData metaData = getMetaData();
- if (Objects.nonNull(metaData)) {
- String name = metaData.getName();
- if (Objects.nonNull(name)) {
- return name;
- }
- }
- return getType().toString();
- }
-
- /**
- * Return the state of the On/Off element (only).
- */
- public State getOnOffState() {
- try {
- OnState on = this.on;
- return Objects.nonNull(on) ? OnOffType.from(on.isOn()) : UnDefType.NULL;
- } catch (DTOPresentButEmptyException e) {
- return UnDefType.UNDEF; // indicates the DTO is present but its inner fields are missing
- }
- }
-
- public @Nullable OnState getOnState() {
- return on;
- }
-
- public @Nullable ResourceReference getOwner() {
- return owner;
- }
-
- public @Nullable Power getPowerState() {
- return powerState;
- }
-
- public @Nullable ProductData getProductData() {
- return productData;
- }
-
- public String getProductName() {
- ProductData productData = getProductData();
- if (Objects.nonNull(productData)) {
- return productData.getProductName();
- }
- return getType().toString();
- }
-
- public @Nullable Recall getRecall() {
- return recall;
- }
-
- public @Nullable RelativeRotary getRelativeRotary() {
- return relativeRotary;
- }
-
- public State getRotaryStepsState() {
- RelativeRotary relativeRotary = this.relativeRotary;
- if (relativeRotary == null) {
- return UnDefType.NULL;
- }
- RotaryReport rotaryReport = relativeRotary.getRotaryReport();
- if (rotaryReport == null) {
- return relativeRotary.getStepsState();
- }
- Rotation rotation = rotaryReport.getRotation();
- if (rotation == null) {
- return UnDefType.NULL;
- }
- return rotation.getStepsState();
- }
-
- public State getRotaryStepsLastUpdatedState(ZoneId zoneId) {
- RelativeRotary relativeRotary = this.relativeRotary;
- if (relativeRotary == null) {
- return UnDefType.NULL;
- }
- RotaryReport rotaryReport = relativeRotary.getRotaryReport();
- if (rotaryReport == null) {
- return UnDefType.UNDEF;
- }
- Instant lastChanged = rotaryReport.getLastChanged();
- if (Instant.EPOCH.equals(lastChanged)) {
- return UnDefType.UNDEF;
- }
- return new DateTimeType(ZonedDateTime.ofInstant(lastChanged, zoneId));
- }
-
- /**
- * Check if the scene resource contains a 'status.active' element. If such an element is present, returns a Boolean
- * Optional whose value depends on the value of that element, or an empty Optional if it is not.
- *
- * @return true, false, or empty.
- */
- public Optional<Boolean> getSceneActive() {
- if (ResourceType.SCENE == getType()) {
- JsonElement status = this.status;
- if (Objects.nonNull(status) && status.isJsonObject()) {
- JsonElement active = ((JsonObject) status).get("active");
- if (Objects.nonNull(active) && active.isJsonPrimitive()) {
- return Optional.of(!"inactive".equalsIgnoreCase(active.getAsString()));
- }
- }
- }
- return Optional.empty();
- }
-
- /**
- * If the getSceneActive() optional result is empty return 'UnDefType.NULL'. Otherwise if the optional result is
- * present and 'true' (i.e. the scene is active) return the scene name. Or finally (the optional result is present
- * and 'false') return 'UnDefType.UNDEF'.
- *
- * @return either 'UnDefType.NULL', a StringType containing the (active) scene name, or 'UnDefType.UNDEF'.
- */
- public State getSceneState() {
- return getSceneActive().map(a -> a ? new StringType(getName()) : UnDefType.UNDEF).orElse(UnDefType.NULL);
- }
-
- /**
- * Check if the smart scene resource contains a 'state' element. If such an element is present, returns a Boolean
- * Optional whose value depends on the value of that element, or an empty Optional if it is not.
- *
- * @return true, false, or empty.
- */
- public Optional<Boolean> getSmartSceneActive() {
- if (ResourceType.SMART_SCENE == getType()) {
- String state = this.state;
- if (Objects.nonNull(state)) {
- return Optional.of(SmartSceneState.ACTIVE == SmartSceneState.of(state));
- }
- }
- return Optional.empty();
- }
-
- /**
- * If the getSmartSceneActive() optional result is empty return 'UnDefType.NULL'. Otherwise if the optional result
- * is present and 'true' (i.e. the scene is active) return the smart scene name. Or finally (the optional result is
- * present and 'false') return 'UnDefType.UNDEF'.
- *
- * @return either 'UnDefType.NULL', a StringType containing the (active) scene name, or 'UnDefType.UNDEF'.
- */
- public State getSmartSceneState() {
- return getSmartSceneActive().map(a -> a ? new StringType(getName()) : UnDefType.UNDEF).orElse(UnDefType.NULL);
- }
-
- public List<ResourceReference> getServiceReferences() {
- List<ResourceReference> services = this.services;
- return Objects.nonNull(services) ? services : List.of();
- }
-
- public JsonObject getStatus() {
- JsonElement status = this.status;
- if (Objects.nonNull(status) && status.isJsonObject()) {
- return status.getAsJsonObject();
- }
- return new JsonObject();
- }
-
- public State getTamperLastUpdatedState(ZoneId zoneId) {
- TamperReport report = getTamperReportsLatest();
- return Objects.nonNull(report) ? new DateTimeType(ZonedDateTime.ofInstant(report.getLastChanged(), zoneId))
- : UnDefType.NULL;
- }
-
- /**
- * The the Hue bridge could return its raw list of tamper reports in any order, so sort the list (latest entry
- * first) according to the respective 'changed' instant and return the first entry i.e. the latest changed entry.
- *
- * @return the latest changed tamper report
- */
- private @Nullable TamperReport getTamperReportsLatest() {
- List<TamperReport> reports = this.tamperReports;
- return Objects.nonNull(reports)
- ? reports.stream().sorted((e1, e2) -> e2.getLastChanged().compareTo(e1.getLastChanged())).findFirst()
- .orElse(null)
- : null;
- }
-
- public State getTamperState() {
- TamperReport report = getTamperReportsLatest();
- return Objects.nonNull(report)
- ? TamperStateType.TAMPERED == report.getTamperState() ? OpenClosedType.OPEN : OpenClosedType.CLOSED
- : UnDefType.NULL;
- }
-
- public @Nullable Temperature getTemperature() {
- return temperature;
- }
-
- public State getTemperatureState() {
- Temperature temperature = this.temperature;
- if (temperature == null) {
- return UnDefType.NULL;
- }
- TemperatureReport temperatureReport = temperature.getTemperatureReport();
- if (temperatureReport == null) {
- return temperature.getTemperatureState();
- }
- return new QuantityType<>(temperatureReport.getTemperature(), SIUnits.CELSIUS);
- }
-
- public State getTemperatureLastUpdatedState(ZoneId zoneId) {
- Temperature temperature = this.temperature;
- if (temperature == null) {
- return UnDefType.NULL;
- }
- TemperatureReport temperatureReport = temperature.getTemperatureReport();
- if (temperatureReport == null) {
- return UnDefType.UNDEF;
- }
- Instant lastChanged = temperatureReport.getLastChanged();
- if (Instant.EPOCH.equals(lastChanged)) {
- return UnDefType.UNDEF;
- }
- return new DateTimeType(ZonedDateTime.ofInstant(lastChanged, zoneId));
- }
-
- public State getTemperatureValidState() {
- Temperature temperature = this.temperature;
- return Objects.nonNull(temperature) ? temperature.getTemperatureValidState() : UnDefType.NULL;
- }
-
- public @Nullable TimedEffects getTimedEffects() {
- return timedEffects;
- }
-
- public ResourceType getType() {
- return ResourceType.of(type);
- }
-
- public State getZigbeeState() {
- ZigbeeStatus zigbeeStatus = getZigbeeStatus();
- return Objects.nonNull(zigbeeStatus) ? new StringType(zigbeeStatus.toString()) : UnDefType.NULL;
- }
-
- public @Nullable ZigbeeStatus getZigbeeStatus() {
- JsonElement status = this.status;
- if (Objects.nonNull(status) && status.isJsonPrimitive()) {
- return ZigbeeStatus.of(status.getAsString());
- }
- return null;
- }
-
- public boolean hasFullState() {
- return !hasSparseData;
- }
-
- /**
- * Mark that the resource has sparse data.
- *
- * @return this instance.
- */
- public Resource markAsSparse() {
- hasSparseData = true;
- return this;
- }
-
- public Resource setAlerts(Alerts alert) {
- this.alert = alert;
- return this;
- }
-
- public Resource setColorTemperature(ColorTemperature colorTemperature) {
- this.colorTemperature = colorTemperature;
- return this;
- }
-
- public Resource setColorXy(ColorXy color) {
- this.color = color;
- return this;
- }
-
- public Resource setContactReport(ContactReport contactReport) {
- this.contactReport = contactReport;
- return this;
- }
-
- public Resource setDimming(Dimming dimming) {
- this.dimming = dimming;
- return this;
- }
-
- public Resource setDynamicsDuration(Duration duration) {
- dynamics = new Dynamics().setDuration(duration);
- return this;
- }
-
- public Resource setFixedEffects(Effects effect) {
- this.effects = effect;
- return this;
- }
-
- public Resource setEnabled(Command command) {
- if (command instanceof OnOffType) {
- this.enabled = ((OnOffType) command) == OnOffType.ON;
- }
- return this;
- }
-
- public Resource setId(String id) {
- this.id = id;
- return this;
- }
-
- public Resource setMetadata(MetaData metadata) {
- this.metadata = metadata;
- return this;
- }
-
- public Resource setMirekSchema(@Nullable MirekSchema schema) {
- ColorTemperature colorTemperature = this.colorTemperature;
- if (Objects.nonNull(colorTemperature)) {
- colorTemperature.setMirekSchema(schema);
- }
- return this;
- }
-
- /**
- * Set the on/off JSON element (only).
- *
- * @param command an OnOffTypee command value.
- * @return this resource instance.
- */
- public Resource setOnOff(Command command) {
- if (command instanceof OnOffType) {
- OnOffType onOff = (OnOffType) command;
- OnState on = this.on;
- on = Objects.nonNull(on) ? on : new OnState();
- on.setOn(OnOffType.ON.equals(onOff));
- this.on = on;
- }
- return this;
- }
-
- public void setOnState(OnState on) {
- this.on = on;
- }
-
- public Resource setRecallAction(SceneRecallAction recallAction) {
- Recall recall = this.recall;
- this.recall = ((Objects.nonNull(recall) ? recall : new Recall())).setAction(recallAction);
- return this;
- }
-
- public Resource setRecallAction(SmartSceneRecallAction recallAction) {
- Recall recall = this.recall;
- this.recall = ((Objects.nonNull(recall) ? recall : new Recall())).setAction(recallAction);
- return this;
- }
-
- public Resource setRecallDuration(Duration recallDuration) {
- Recall recall = this.recall;
- this.recall = ((Objects.nonNull(recall) ? recall : new Recall())).setDuration(recallDuration);
- return this;
- }
-
- public Resource setTamperReports(List<TamperReport> tamperReports) {
- this.tamperReports = tamperReports;
- return this;
- }
-
- public Resource setTimedEffects(TimedEffects timedEffects) {
- this.timedEffects = timedEffects;
- return this;
- }
-
- public Resource setTimedEffectsDuration(Duration dynamicsDuration) {
- TimedEffects timedEffects = this.timedEffects;
- if (Objects.nonNull(timedEffects)) {
- timedEffects.setDuration(dynamicsDuration);
- }
- return this;
- }
-
- public Resource setType(ResourceType resourceType) {
- this.type = resourceType.name().toLowerCase();
- return this;
- }
-
- @Override
- public String toString() {
- String id = this.id;
- return String.format("id:%s, type:%s", Objects.nonNull(id) ? id : "?" + " ".repeat(35),
- getType().name().toLowerCase());
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.hue.internal.dto.clip2.enums.ResourceType;
-
-/**
- * DTO that contains an API reference element.
- *
- * The V2 API is set up in such a way that all resources of the same type are grouped together under the
- * {@code /resource/<resourcetype>} endpoint, but all those resources commonly reference each other, which is done in a
- * standardized way by indicating the resource type (rtype) and resource id (rid).
- *
- * A typical usage is in a single physical device that hosts multiple services. An existing example is the Philips Hue
- * Motion sensor which has a motion, light_level, and temperature service, but theoretically any combination can be
- * supported such as an integrated device with two independently controllable light points and a motion sensor.
- *
- * This means that the information of the device itself can be found under the /device resource endpoint, but it then
- * contains a services array which references for example the light and motion resources, for which the details can be
- * found under the /light and /motion resource endpoints respectively. Other services the device might have, such as a
- * Zigbee radio (zigbee_connectivy) or battery (device_power) are modeled in the same way.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public class ResourceReference {
- private @Nullable String rid;
- private @NonNullByDefault({}) String rtype;
-
- @Override
- public boolean equals(@Nullable Object obj) {
- String rid = this.rid;
- return (obj instanceof ResourceReference) && (rid != null) && rid.equals(((ResourceReference) obj).rid);
- }
-
- public @Nullable String getId() {
- return rid;
- }
-
- public ResourceType getType() {
- return ResourceType.of(rtype);
- }
-
- public ResourceReference setId(String id) {
- rid = id;
- return this;
- }
-
- public ResourceReference setType(ResourceType resourceType) {
- rtype = resourceType.name().toLowerCase();
- return this;
- }
-
- @Override
- public String toString() {
- String id = rid;
- return String.format("id:%s, type:%s", id != null ? id : "*" + " ".repeat(35), getType().name().toLowerCase());
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-
-/**
- * DTO for CLIP 2 to retrieve a list of generic resources from the bridge.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public class Resources {
- private List<Error> errors = new ArrayList<>();
- private List<Resource> data = new ArrayList<>();
-
- public List<String> getErrors() {
- return errors.stream().map(Error::getDescription).collect(Collectors.toList());
- }
-
- public boolean hasErrors() {
- return !errors.isEmpty();
- }
-
- public List<Resource> getResources() {
- return data;
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2;
-
-import java.time.Instant;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.hue.internal.dto.clip2.enums.RotationEventType;
-
-/**
- * DTO for CLIP 2 relative rotary report.
- *
- * @author Jacob Laursen - Initial contribution
- */
-@NonNullByDefault
-public class RotaryReport {
- private @NonNullByDefault({}) Instant updated;
- private @Nullable String action;
- private @Nullable Rotation rotation;
-
- /**
- * @return last time the value of this property is changed.
- */
- public Instant getLastChanged() {
- return updated;
- }
-
- /**
- * @return which type of rotary event is received
- */
- public @Nullable RotationEventType getAction() {
- String action = this.action;
- return action == null ? null : RotationEventType.valueOf(action.toUpperCase());
- }
-
- public @Nullable Rotation getRotation() {
- return rotation;
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2;
-
-import java.util.Objects;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.hue.internal.dto.clip2.enums.DirectionType;
-import org.openhab.core.library.types.DecimalType;
-import org.openhab.core.types.State;
-import org.openhab.core.types.UnDefType;
-
-/**
- * DTO for rotation element of a tap dial switch.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public class Rotation {
- private @Nullable String direction;
- private @Nullable Integer duration;
- private @Nullable Integer steps;
-
- public @Nullable DirectionType getDirection() {
- String direction = this.direction;
- return Objects.nonNull(direction) ? DirectionType.valueOf(direction.toUpperCase()) : null;
- }
-
- public int getDuration() {
- Integer duration = this.duration;
- return Objects.nonNull(duration) ? duration.intValue() : 0;
- }
-
- public int getSteps() {
- Integer steps = this.steps;
- return Objects.nonNull(steps) ? steps.intValue() : 0;
- }
-
- /**
- * Get the state corresponding to a relative rotary dial's last steps value. Clockwise rotations are positive, and
- * counter clockwise rotations negative.
- *
- * @return the state or UNDEF.
- */
- public State getStepsState() {
- DirectionType direction = getDirection();
- Integer steps = this.steps;
- if (Objects.nonNull(direction) && Objects.nonNull(steps)) {
- return new DecimalType(DirectionType.CLOCK_WISE.equals(direction) ? steps.intValue() : -steps.intValue());
- }
- return UnDefType.NULL;
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2;
-
-import java.util.Objects;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.hue.internal.dto.clip2.enums.RotationEventType;
-import org.openhab.core.library.types.StringType;
-import org.openhab.core.types.State;
-import org.openhab.core.types.UnDefType;
-
-/**
- * DTO for rotation event of a dial switch.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public class RotationEvent {
- private @Nullable String action;
- private @Nullable Rotation rotation;
-
- public @Nullable RotationEventType getAction() {
- String action = this.action;
- return Objects.nonNull(action) ? RotationEventType.valueOf(action.toUpperCase()) : null;
- }
-
- public State getActionState() {
- RotationEventType action = getAction();
- return Objects.nonNull(action) ? new StringType(action.name()) : UnDefType.NULL;
- }
-
- public @Nullable Rotation getRotation() {
- return rotation;
- }
-
- public State getStepsState() {
- Rotation rotation = this.rotation;
- return Objects.nonNull(rotation) ? rotation.getStepsState() : UnDefType.NULL;
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2;
-
-import java.time.Instant;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.openhab.binding.hue.internal.dto.clip2.enums.TamperStateType;
-
-/**
- * DTO for CLIP 2 home security tamper switch.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public class TamperReport {
-
- private @NonNullByDefault({}) Instant changed;
- private @NonNullByDefault({}) String state;
-
- public Instant getLastChanged() {
- return changed;
- }
-
- public TamperStateType getTamperState() throws IllegalArgumentException {
- return TamperStateType.valueOf(state.toUpperCase());
- }
-
- public TamperReport setLastChanged(Instant changed) {
- this.changed = changed;
- return this;
- }
-
- public TamperReport setTamperState(String state) {
- this.state = state;
- return this;
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.core.library.types.OnOffType;
-import org.openhab.core.library.types.QuantityType;
-import org.openhab.core.library.unit.SIUnits;
-import org.openhab.core.types.State;
-import org.openhab.core.types.UnDefType;
-
-import com.google.gson.annotations.SerializedName;
-
-/**
- * DTO for CLIP 2 temperature sensor.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public class Temperature {
- private float temperature;
- private @SerializedName("temperature_valid") boolean temperatureValid;
- private @Nullable @SerializedName("temperature_report") TemperatureReport temperatureReport;
-
- /**
- * The underlying field is deprecated in the CLIP 2 API.
- * Moved to temperature_report/temperature.
- * Should be used only as fallback for older firmwares.
- *
- * @return temperature in 1.00 degrees Celsius
- */
- public float getTemperature() {
- return temperature;
- }
-
- /**
- * The underlying field is deprecated in the CLIP 2 API.
- * Indication whether the value presented in temperature is valid
- * Should be used only as fallback for older firmwares.
- */
- public boolean isTemperatureValid() {
- return temperatureValid;
- }
-
- public State getTemperatureState() {
- return temperatureValid ? new QuantityType<>(temperature, SIUnits.CELSIUS) : UnDefType.UNDEF;
- }
-
- public State getTemperatureValidState() {
- return OnOffType.from(temperatureValid);
- }
-
- public @Nullable TemperatureReport getTemperatureReport() {
- return temperatureReport;
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2;
-
-import java.time.Instant;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-
-/**
- * DTO for CLIP 2 temperature sensor report.
- *
- * @author Jacob Laursen - Initial contribution
- */
-@NonNullByDefault
-public class TemperatureReport {
- private @NonNullByDefault({}) Instant changed;
- private float temperature;
-
- /**
- * @return last time the value of this property is changed.
- */
- public Instant getLastChanged() {
- return changed;
- }
-
- /**
- * @return temperature in 1.00 degrees Celsius
- */
- public float getTemperature() {
- return temperature;
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2;
-
-import java.time.Duration;
-import java.util.Objects;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-/**
- * DTO for 'timed_effects' of a light.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public class TimedEffects extends Effects {
- public static final Duration DEFAULT_DURATION = Duration.ofMinutes(15);
-
- private @Nullable Long duration;
-
- public @Nullable Duration getDuration() {
- Long duration = this.duration;
- return Objects.nonNull(duration) ? Duration.ofMillis(duration) : null;
- }
-
- public TimedEffects setDuration(Duration duration) {
- this.duration = duration.toMillis();
- return this;
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2.enums;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-/**
- * Enum for 'alert' actions.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public enum ActionType {
- BREATHE,
- NO_ACTION;
-
- public static ActionType of(@Nullable String value) {
- if (value != null) {
- try {
- return valueOf(value.toUpperCase());
- } catch (IllegalArgumentException e) {
- // fall through
- }
- }
- return NO_ACTION;
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2.enums;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-/**
- * Enum for product archetypes.
- *
- * @see <a href="https://developers.meethue.com/develop/hue-api-v2/api-reference/#resource_light_get">API v2
- * documentation</a>
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public enum Archetype {
- // device archetypes
- BRIDGE_V2,
- UNKNOWN_ARCHETYPE,
- CLASSIC_BULB,
- SULTAN_BULB,
- FLOOD_BULB,
- SPOT_BULB,
- CANDLE_BULB,
- LUSTER_BULB,
- PENDANT_ROUND,
- PENDANT_LONG,
- CEILING_ROUND,
- CEILING_SQUARE,
- FLOOR_SHADE,
- FLOOR_LANTERN,
- TABLE_SHADE,
- RECESSED_CEILING,
- RECESSED_FLOOR,
- SINGLE_SPOT,
- DOUBLE_SPOT,
- TABLE_WASH,
- WALL_LANTERN,
- WALL_SHADE,
- FLEXIBLE_LAMP,
- GROUND_SPOT,
- WALL_SPOT,
- PLUG,
- HUE_GO,
- HUE_LIGHTSTRIP,
- HUE_IRIS,
- HUE_BLOOM,
- BOLLARD,
- WALL_WASHER,
- HUE_PLAY,
- VINTAGE_BULB,
- CHRISTMAS_TREE,
- HUE_CENTRIS,
- HUE_LIGHTSTRIP_TV,
- HUE_TUBE,
- HUE_SIGNE,
- STRING_LIGHT,
- // room archetypes
- LIVING_ROOM,
- KITCHEN,
- DINING,
- BEDROOM,
- KIDS_BEDROOM,
- BATHROOM,
- NURSERY,
- RECREATION,
- OFFICE,
- GYM,
- HALLWAY,
- TOILET,
- FRONT_DOOR,
- GARAGE,
- TERRACE,
- GARDEN,
- DRIVEWAY,
- CARPORT,
- HOME,
- DOWNSTAIRS,
- UPSTAIRS,
- TOP_FLOOR,
- ATTIC,
- GUEST_ROOM,
- STAIRCASE,
- LOUNGE,
- MAN_CAVE,
- COMPUTER,
- STUDIO,
- MUSIC,
- TV,
- READING,
- CLOSET,
- STORAGE,
- LAUNDRY_ROOM,
- BALCONY,
- PORCH,
- BARBECUE,
- POOL,
- OTHER;
-
- public static Archetype of(@Nullable String value) {
- if (value != null) {
- try {
- return valueOf(value.toUpperCase());
- } catch (IllegalArgumentException e) {
- // fall through
- }
- }
- return UNKNOWN_ARCHETYPE;
- }
-
- @Override
- public String toString() {
- String s = this.name().replace("_", " ");
- return s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase();
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2.enums;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-
-/**
- * Enum for types battery state.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public enum BatteryStateType {
- NORMAL,
- LOW,
- CRITICAL
-}
+++ /dev/null
-/**
- * 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.dto.clip2.enums;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-
-/**
- * Enum for types button press.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public enum ButtonEventType {
- INITIAL_PRESS,
- REPEAT,
- SHORT_RELEASE,
- LONG_RELEASE,
- DOUBLE_SHORT_RELEASE
-}
+++ /dev/null
-/**
- * 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.dto.clip2.enums;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-
-/**
- * Enum for security contact states.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public enum ContactStateType {
- NO_CONTACT,
- CONTACT
-}
+++ /dev/null
-/**
- * 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.dto.clip2.enums;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-
-/**
- * Enum for tap dial rotation directions.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public enum DirectionType {
- CLOCK_WISE,
- COUNTER_CLOCK_WISE
-}
+++ /dev/null
-/**
- * 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.dto.clip2.enums;
-
-import java.util.Set;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-/**
- * Enum for 'effect' types.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public enum EffectType {
- // fixed Effects
- PRISM,
- OPAL,
- GLISTEN,
- SPARKLE,
- FIRE,
- CANDLE,
- // timed Effects
- SUNRISE,
- // applies to both
- NO_EFFECT;
-
- private static final Set<EffectType> FIXED = Set.of(PRISM, OPAL, GLISTEN, SPARKLE, FIRE, CANDLE);
- private static final Set<EffectType> TIMED = Set.of(SUNRISE);
-
- public static EffectType of(@Nullable String value) {
- if (value != null) {
- try {
- return valueOf(value.toUpperCase());
- } catch (IllegalArgumentException e) {
- // fall through
- }
- }
- return NO_EFFECT;
- }
-
- public boolean isFixed() {
- return FIXED.contains(this);
- }
-
- public boolean isTimed() {
- return TIMED.contains(this);
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2.enums;
-
-import java.util.EnumSet;
-import java.util.Set;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-/**
- * Enum for resource types.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public enum ResourceType {
- AUTH_V1,
- BEHAVIOR_INSTANCE,
- BEHAVIOR_SCRIPT,
- BRIDGE,
- BRIDGE_HOME,
- BUTTON,
- CAMERA_MOTION,
- CONTACT,
- DEVICE,
- DEVICE_POWER,
- ENTERTAINMENT,
- ENTERTAINMENT_CONFIGURATION,
- GEOFENCE,
- GEOFENCE_CLIENT,
- GEOLOCATION,
- GROUPED_LIGHT,
- HOMEKIT,
- LIGHT,
- LIGHT_LEVEL,
- MOTION,
- PUBLIC_IMAGE,
- ROOM,
- RELATIVE_ROTARY,
- SCENE,
- TAMPER,
- SMART_SCENE,
- TEMPERATURE,
- ZGP_CONNECTIVITY,
- ZIGBEE_CONNECTIVITY,
- ZONE,
- UPDATE,
- ADD,
- DELETE,
- ERROR;
-
- public static final Set<ResourceType> SSE_TYPES = EnumSet.of(UPDATE, ADD, DELETE, ERROR);
-
- public static ResourceType of(@Nullable String value) {
- if (value != null) {
- try {
- return valueOf(value.toUpperCase());
- } catch (IllegalArgumentException e) {
- // fall through
- }
- }
- return ERROR.setUnknownTypeId(value);
- }
-
- private @Nullable String unknownTypeId;
-
- private ResourceType setUnknownTypeId(@Nullable String value) {
- unknownTypeId = value;
- return this;
- }
-
- @Override
- public String toString() {
- String s = this.name().replace("_", " ");
- s = s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase();
- return unknownTypeId == null ? s : s + String.format(" (%s)", unknownTypeId);
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2.enums;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-
-/**
- * Enum for types of rotary dial events.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public enum RotationEventType {
- START,
- REPEAT
-}
+++ /dev/null
-/**
- * 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.dto.clip2.enums;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-/**
- * Enum for scene recall actions.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public enum SceneRecallAction {
- ACTIVE,
- DYNAMIC_PALETTE,
- STATIC,
- UNKNOWN;
-
- public static SceneRecallAction of(@Nullable String value) {
- if (value != null) {
- try {
- return valueOf(value.toUpperCase());
- } catch (IllegalArgumentException e) {
- // fall through
- }
- }
- return UNKNOWN;
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2.enums;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-/**
- * Enum for smart scene recall actions.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public enum SmartSceneRecallAction {
- ACTIVATE,
- DEACTIVATE,
- UNKNOWN;
-
- public static SmartSceneRecallAction of(@Nullable String value) {
- if (value != null) {
- try {
- return valueOf(value.toUpperCase());
- } catch (IllegalArgumentException e) {
- // fall through
- }
- }
- return UNKNOWN;
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2.enums;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-/**
- * Enum for 'smart_scene' states.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public enum SmartSceneState {
- INACTIVE,
- ACTIVE,
- UNKNOWN;
-
- public static SmartSceneState of(@Nullable String value) {
- if (value != null) {
- try {
- return valueOf(value.toUpperCase());
- } catch (IllegalArgumentException e) {
- // fall through
- }
- }
- return UNKNOWN;
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2.enums;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-
-/**
- * Enum for tamper switch states.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public enum TamperStateType {
- NOT_TAMPERED,
- TAMPERED
-}
+++ /dev/null
-/**
- * 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.dto.clip2.enums;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-/**
- * Enum for possible Zigbee states.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public enum ZigbeeStatus {
- CONNECTED,
- DISCONNECTED,
- CONNECTIVITY_ISSUE,
- UNIDIRECTIONAL_INCOMING;
-
- public static ZigbeeStatus of(@Nullable String value) {
- if (value != null) {
- try {
- return valueOf(value.toUpperCase());
- } catch (IllegalArgumentException e) {
- // fall through
- }
- }
- return DISCONNECTED;
- }
-
- @Override
- public String toString() {
- String s = this.name().replace("_", " ");
- return s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase();
- }
-}
+++ /dev/null
-/**
- * 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.dto.clip2.helper;
-
-import java.math.BigDecimal;
-import java.time.Duration;
-import java.util.List;
-import java.util.Objects;
-
-import javax.measure.Unit;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.hue.internal.dto.clip2.Alerts;
-import org.openhab.binding.hue.internal.dto.clip2.ColorTemperature;
-import org.openhab.binding.hue.internal.dto.clip2.ColorXy;
-import org.openhab.binding.hue.internal.dto.clip2.Dimming;
-import org.openhab.binding.hue.internal.dto.clip2.Effects;
-import org.openhab.binding.hue.internal.dto.clip2.MetaData;
-import org.openhab.binding.hue.internal.dto.clip2.MirekSchema;
-import org.openhab.binding.hue.internal.dto.clip2.OnState;
-import org.openhab.binding.hue.internal.dto.clip2.Resource;
-import org.openhab.binding.hue.internal.dto.clip2.TimedEffects;
-import org.openhab.binding.hue.internal.dto.clip2.enums.ActionType;
-import org.openhab.binding.hue.internal.dto.clip2.enums.EffectType;
-import org.openhab.core.library.types.DecimalType;
-import org.openhab.core.library.types.HSBType;
-import org.openhab.core.library.types.PercentType;
-import org.openhab.core.library.types.QuantityType;
-import org.openhab.core.library.types.StringType;
-import org.openhab.core.library.unit.Units;
-import org.openhab.core.types.Command;
-import org.openhab.core.util.ColorUtil;
-import org.openhab.core.util.ColorUtil.Gamut;
-
-/**
- * Advanced setter methods for fields in the Resource class for special cases where setting the new value in the target
- * resource depends on logic using the values of other fields in a another source Resource.
- *
- * @author Andrew Fiddian-Green - Initial contribution
- */
-@NonNullByDefault
-public class Setters {
-
- /**
- * Setter for Alert field:
- * Use the given command value to set the target resource DTO value based on the attributes of the source resource
- * (if any).
- *
- * @param target the target resource.
- * @param command the new state command should be a StringType.
- * @param source another resource containing the allowed alert action values.
- *
- * @return the target resource.
- */
- public static Resource setAlert(Resource target, Command command, @Nullable Resource source) {
- if ((command instanceof StringType) && Objects.nonNull(source)) {
- Alerts otherAlert = source.getAlerts();
- if (Objects.nonNull(otherAlert)) {
- ActionType actionType = ActionType.of(((StringType) command).toString());
- if (otherAlert.getActionValues().contains(actionType)) {
- target.setAlerts(new Alerts().setAction(actionType));
- }
- }
- }
- return target;
- }
-
- /**
- * Setter for Color Temperature field:
- * Use the given command value to set the target resource DTO value based on the attributes of the source resource
- * (if any).
- *
- * @param target the target resource.
- * @param command the new state command should be a {@code QuantityType<Temperature>} (but it can also handle
- * {@code DecimalType}).
- * @param source another resource containing the MirekSchema.
- *
- * @return the target resource.
- */
- public static Resource setColorTemperatureAbsolute(Resource target, Command command, @Nullable Resource source) {
- QuantityType<?> mirek;
- if (command instanceof QuantityType<?>) {
- QuantityType<?> quantity = (QuantityType<?>) command;
- Unit<?> unit = quantity.getUnit();
- if (Units.KELVIN.equals(unit)) {
- mirek = quantity.toInvertibleUnit(Units.MIRED);
- } else if (Units.MIRED.equals(unit)) {
- mirek = quantity;
- } else {
- QuantityType<?> kelvin = quantity.toInvertibleUnit(Units.KELVIN);
- mirek = Objects.nonNull(kelvin) ? kelvin.toInvertibleUnit(Units.MIRED) : null;
- }
- } else if (command instanceof DecimalType) {
- mirek = QuantityType.valueOf(((DecimalType) command).doubleValue(), Units.KELVIN)
- .toInvertibleUnit(Units.MIRED);
- } else {
- mirek = null;
- }
- if (Objects.nonNull(mirek)) {
- MirekSchema schema = target.getMirekSchema();
- schema = Objects.nonNull(schema) ? schema : Objects.nonNull(source) ? source.getMirekSchema() : null;
- schema = Objects.nonNull(schema) ? schema : MirekSchema.DEFAULT_SCHEMA;
- ColorTemperature colorTemperature = target.getColorTemperature();
- colorTemperature = Objects.nonNull(colorTemperature) ? colorTemperature : new ColorTemperature();
- double min = schema.getMirekMinimum();
- double max = schema.getMirekMaximum();
- double val = Math.max(min, Math.min(max, mirek.doubleValue()));
- target.setColorTemperature(colorTemperature.setMirek(val));
- }
- return target;
- }
-
- /**
- * Setter for Color Temperature field:
- * Use the given command value to set the target resource DTO value based on the attributes of the source resource
- * (if any).
- *
- * @param target the target resource.
- * @param command the new state command should be a PercentType.
- * @param source another resource containing the MirekSchema.
- *
- * @return the target resource.
- */
- public static Resource setColorTemperaturePercent(Resource target, Command command, @Nullable Resource source) {
- if (command instanceof PercentType) {
- MirekSchema schema = target.getMirekSchema();
- schema = Objects.nonNull(schema) ? schema : Objects.nonNull(source) ? source.getMirekSchema() : null;
- schema = Objects.nonNull(schema) ? schema : MirekSchema.DEFAULT_SCHEMA;
- ColorTemperature colorTemperature = target.getColorTemperature();
- colorTemperature = Objects.nonNull(colorTemperature) ? colorTemperature : new ColorTemperature();
- double min = schema.getMirekMinimum();
- double max = schema.getMirekMaximum();
- double val = min + ((max - min) * ((PercentType) command).doubleValue() / 100f);
- target.setColorTemperature(colorTemperature.setMirek(val));
- }
- return target;
- }
-
- /**
- * Setter for Color Xy field:
- * Use the given command value to set the target resource DTO value based on the attributes of the source resource
- * (if any). Use the HS parts of the HSB value to set the value of the 'ColorXy' JSON element, and ignore the 'B'
- * part.
- *
- * @param target the target resource.
- * @param command the new state command should be an HSBType with the new color XY value.
- * @param source another resource containing the color Gamut.
- *
- * @return the target resource.
- */
- public static Resource setColorXy(Resource target, Command command, @Nullable Resource source) {
- if (command instanceof HSBType) {
- Gamut gamut = target.getGamut();
- gamut = Objects.nonNull(gamut) ? gamut : Objects.nonNull(source) ? source.getGamut() : null;
- gamut = Objects.nonNull(gamut) ? gamut : ColorUtil.DEFAULT_GAMUT;
- HSBType hsb = (HSBType) command;
- ColorXy color = target.getColorXy();
- target.setColorXy((Objects.nonNull(color) ? color : new ColorXy()).setXY(ColorUtil.hsbToXY(hsb, gamut)));
- }
- return target;
- }
-
- /**
- * Setter for Dimming field:
- * Use the given command value to set the target resource DTO value based on the attributes of the source resource
- * (if any).
- *
- * @param target the target resource.
- * @param command the new state command should be a PercentType with the new dimming parameter.
- * @param source another resource containing the minimum dimming level.
- *
- * @return the target resource.
- */
- public static Resource setDimming(Resource target, Command command, @Nullable Resource source) {
- if (command instanceof PercentType) {
- Double min = target.getMinimumDimmingLevel();
- min = Objects.nonNull(min) ? min : Objects.nonNull(source) ? source.getMinimumDimmingLevel() : null;
- min = Objects.nonNull(min) ? min : Dimming.DEFAULT_MINIMUM_DIMMIMG_LEVEL;
- PercentType brightness = (PercentType) command;
- if (brightness.doubleValue() < min.doubleValue()) {
- brightness = new PercentType(new BigDecimal(min, Resource.PERCENT_MATH_CONTEXT));
- }
- Dimming dimming = target.getDimming();
- dimming = Objects.nonNull(dimming) ? dimming : new Dimming();
- dimming.setBrightness(brightness.doubleValue());
- target.setDimming(dimming);
- }
- return target;
- }
-
- /**
- * Setter for fixed or timed effect field:
- * Use the given command value to set the target fixed or timed effects resource DTO value based on the attributes
- * of the source resource (if any).
- *
- * @param target the target resource.
- * @param command the new state command should be a StringType.
- * @param source another resource containing the allowed effect action values.
- *
- * @return the target resource.
- */
- public static Resource setEffect(Resource target, Command command, @Nullable Resource source) {
- if ((command instanceof StringType) && Objects.nonNull(source)) {
- EffectType commandEffectType = EffectType.of(((StringType) command).toString());
- Effects sourceFixedEffects = source.getFixedEffects();
- if (Objects.nonNull(sourceFixedEffects) && sourceFixedEffects.allows(commandEffectType)) {
- target.setFixedEffects(new Effects().setEffect(commandEffectType));
- }
- TimedEffects sourceTimedEffects = source.getTimedEffects();
- if (Objects.nonNull(sourceTimedEffects) && sourceTimedEffects.allows(commandEffectType)) {
- Duration duration = sourceTimedEffects.getDuration();
- target.setTimedEffects(((TimedEffects) new TimedEffects().setEffect(commandEffectType))
- .setDuration(Objects.nonNull(duration) ? duration : TimedEffects.DEFAULT_DURATION));
- }
- }
- return target;
- }
-
- /**
- * Setter to copy persisted fields from the source Resource into the target Resource. If the field in the target is
- * null and the same field in the source is not null, then the value from the source is copied to the target. This
- * method allows 'hasSparseData' resources to expand themselves to include necessary fields taken over from a
- * previously cached full data resource.
- *
- * @param target the target resource.
- * @param source another resource containing the values to be taken over.
- *
- * @return the target resource.
- */
- public static Resource setResource(Resource target, Resource source) {
- // on
- OnState targetOnOff = target.getOnState();
- OnState sourceOnOff = source.getOnState();
- if (Objects.isNull(targetOnOff) && Objects.nonNull(sourceOnOff)) {
- target.setOnState(sourceOnOff);
- }
-
- // dimming
- Dimming targetDimming = target.getDimming();
- Dimming sourceDimming = source.getDimming();
- if (Objects.isNull(targetDimming) && Objects.nonNull(sourceDimming)) {
- target.setDimming(sourceDimming);
- targetDimming = target.getDimming();
- }
-
- // minimum dimming level
- if (Objects.nonNull(targetDimming)) {
- Double sourceMinDimLevel = Objects.isNull(sourceDimming) ? null : sourceDimming.getMinimumDimmingLevel();
- if (Objects.nonNull(sourceMinDimLevel)) {
- targetDimming.setMinimumDimmingLevel(sourceMinDimLevel);
- }
- }
-
- // color
- ColorXy targetColor = target.getColorXy();
- ColorXy sourceColor = source.getColorXy();
- if (Objects.isNull(targetColor) && Objects.nonNull(sourceColor)) {
- target.setColorXy(sourceColor);
- targetColor = target.getColorXy();
- }
-
- // color gamut
- Gamut sourceGamut = Objects.isNull(sourceColor) ? null : sourceColor.getGamut();
- if (Objects.nonNull(targetColor) && Objects.nonNull(sourceGamut)) {
- targetColor.setGamut(sourceGamut);
- }
-
- // color temperature
- ColorTemperature targetColorTemp = target.getColorTemperature();
- ColorTemperature sourceColorTemp = source.getColorTemperature();
- if (Objects.isNull(targetColorTemp) && Objects.nonNull(sourceColorTemp)) {
- target.setColorTemperature(sourceColorTemp);
- targetColorTemp = target.getColorTemperature();
- }
-
- // mirek schema
- if (Objects.nonNull(targetColorTemp)) {
- MirekSchema sourceMirekSchema = Objects.isNull(sourceColorTemp) ? null : sourceColorTemp.getMirekSchema();
- if (Objects.nonNull(sourceMirekSchema)) {
- targetColorTemp.setMirekSchema(sourceMirekSchema);
- }
- }
-
- // metadata
- MetaData targetMetaData = target.getMetaData();
- MetaData sourceMetaData = source.getMetaData();
- if (Objects.isNull(targetMetaData) && Objects.nonNull(sourceMetaData)) {
- target.setMetadata(sourceMetaData);
- }
-
- // alerts
- Alerts targetAlerts = target.getAlerts();
- Alerts sourceAlerts = source.getAlerts();
- if (Objects.isNull(targetAlerts) && Objects.nonNull(sourceAlerts)) {
- target.setAlerts(sourceAlerts);
- }
-
- // fixed effects
- Effects targetFixedEffects = target.getFixedEffects();
- Effects sourceFixedEffects = source.getFixedEffects();
- if (Objects.isNull(targetFixedEffects) && Objects.nonNull(sourceFixedEffects)) {
- target.setFixedEffects(sourceFixedEffects);
- targetFixedEffects = target.getFixedEffects();
- }
-
- // fixed effects allowed values
- if (Objects.nonNull(targetFixedEffects)) {
- List<String> values = Objects.isNull(sourceFixedEffects) ? List.of() : sourceFixedEffects.getStatusValues();
- if (!values.isEmpty()) {
- targetFixedEffects.setStatusValues(values);
- }
- }
-
- // timed effects
- TimedEffects targetTimedEffects = target.getTimedEffects();
- TimedEffects sourceTimedEffects = source.getTimedEffects();
- if (Objects.isNull(targetTimedEffects) && Objects.nonNull(sourceTimedEffects)) {
- target.setTimedEffects(sourceTimedEffects);
- targetTimedEffects = target.getTimedEffects();
- }
-
- // timed effects allowed values and duration
- if (Objects.nonNull(targetTimedEffects)) {
- List<String> values = Objects.isNull(sourceTimedEffects) ? List.of() : sourceTimedEffects.getStatusValues();
- if (!values.isEmpty()) {
- targetTimedEffects.setStatusValues(values);
- }
- Duration duration = Objects.isNull(sourceTimedEffects) ? null : sourceTimedEffects.getDuration();
- if (Objects.nonNull(duration)) {
- targetTimedEffects.setDuration(duration);
- }
- }
-
- return target;
- }
-}
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.hue.internal.api.dto.clip2.MetaData;
+import org.openhab.binding.hue.internal.api.dto.clip2.ProductData;
+import org.openhab.binding.hue.internal.api.dto.clip2.Resource;
+import org.openhab.binding.hue.internal.api.dto.clip2.ResourceReference;
+import org.openhab.binding.hue.internal.api.dto.clip2.Resources;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.Archetype;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.ResourceType;
import org.openhab.binding.hue.internal.config.Clip2BridgeConfig;
import org.openhab.binding.hue.internal.connection.Clip2Bridge;
import org.openhab.binding.hue.internal.connection.HueTlsTrustManagerProvider;
import org.openhab.binding.hue.internal.discovery.Clip2ThingDiscoveryService;
-import org.openhab.binding.hue.internal.dto.clip2.MetaData;
-import org.openhab.binding.hue.internal.dto.clip2.ProductData;
-import org.openhab.binding.hue.internal.dto.clip2.Resource;
-import org.openhab.binding.hue.internal.dto.clip2.ResourceReference;
-import org.openhab.binding.hue.internal.dto.clip2.Resources;
-import org.openhab.binding.hue.internal.dto.clip2.enums.Archetype;
-import org.openhab.binding.hue.internal.dto.clip2.enums.ResourceType;
import org.openhab.binding.hue.internal.exceptions.ApiException;
import org.openhab.binding.hue.internal.exceptions.AssetNotLoadedException;
import org.openhab.binding.hue.internal.exceptions.HttpUnauthorizedException;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.hue.internal.action.DynamicsActions;
+import org.openhab.binding.hue.internal.api.dto.clip2.Alerts;
+import org.openhab.binding.hue.internal.api.dto.clip2.ColorXy;
+import org.openhab.binding.hue.internal.api.dto.clip2.Dimming;
+import org.openhab.binding.hue.internal.api.dto.clip2.Effects;
+import org.openhab.binding.hue.internal.api.dto.clip2.Gamut2;
+import org.openhab.binding.hue.internal.api.dto.clip2.MetaData;
+import org.openhab.binding.hue.internal.api.dto.clip2.MirekSchema;
+import org.openhab.binding.hue.internal.api.dto.clip2.ProductData;
+import org.openhab.binding.hue.internal.api.dto.clip2.Resource;
+import org.openhab.binding.hue.internal.api.dto.clip2.ResourceReference;
+import org.openhab.binding.hue.internal.api.dto.clip2.Resources;
+import org.openhab.binding.hue.internal.api.dto.clip2.TimedEffects;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.ActionType;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.EffectType;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.ResourceType;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.SceneRecallAction;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.SmartSceneRecallAction;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.ZigbeeStatus;
+import org.openhab.binding.hue.internal.api.dto.clip2.helper.Setters;
import org.openhab.binding.hue.internal.config.Clip2ThingConfig;
-import org.openhab.binding.hue.internal.dto.clip2.Alerts;
-import org.openhab.binding.hue.internal.dto.clip2.ColorXy;
-import org.openhab.binding.hue.internal.dto.clip2.Dimming;
-import org.openhab.binding.hue.internal.dto.clip2.Effects;
-import org.openhab.binding.hue.internal.dto.clip2.Gamut2;
-import org.openhab.binding.hue.internal.dto.clip2.MetaData;
-import org.openhab.binding.hue.internal.dto.clip2.MirekSchema;
-import org.openhab.binding.hue.internal.dto.clip2.ProductData;
-import org.openhab.binding.hue.internal.dto.clip2.Resource;
-import org.openhab.binding.hue.internal.dto.clip2.ResourceReference;
-import org.openhab.binding.hue.internal.dto.clip2.Resources;
-import org.openhab.binding.hue.internal.dto.clip2.TimedEffects;
-import org.openhab.binding.hue.internal.dto.clip2.enums.ActionType;
-import org.openhab.binding.hue.internal.dto.clip2.enums.EffectType;
-import org.openhab.binding.hue.internal.dto.clip2.enums.ResourceType;
-import org.openhab.binding.hue.internal.dto.clip2.enums.SceneRecallAction;
-import org.openhab.binding.hue.internal.dto.clip2.enums.SmartSceneRecallAction;
-import org.openhab.binding.hue.internal.dto.clip2.enums.ZigbeeStatus;
-import org.openhab.binding.hue.internal.dto.clip2.helper.Setters;
import org.openhab.binding.hue.internal.exceptions.ApiException;
import org.openhab.binding.hue.internal.exceptions.AssetNotLoadedException;
import org.openhab.core.i18n.TimeZoneProvider;
import java.util.List;
import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.openhab.binding.hue.internal.dto.FullGroup;
-import org.openhab.binding.hue.internal.dto.Scene;
+import org.openhab.binding.hue.internal.api.dto.clip1.FullGroup;
+import org.openhab.binding.hue.internal.api.dto.clip1.Scene;
/**
* The {@link GroupStatusListener} is notified when a group status has changed or a group has been removed or added.
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jetty.client.HttpClient;
+import org.openhab.binding.hue.internal.api.dto.clip1.ApiVersionUtils;
+import org.openhab.binding.hue.internal.api.dto.clip1.Config;
+import org.openhab.binding.hue.internal.api.dto.clip1.ConfigUpdate;
+import org.openhab.binding.hue.internal.api.dto.clip1.FullConfig;
+import org.openhab.binding.hue.internal.api.dto.clip1.FullGroup;
+import org.openhab.binding.hue.internal.api.dto.clip1.FullLight;
+import org.openhab.binding.hue.internal.api.dto.clip1.FullSensor;
+import org.openhab.binding.hue.internal.api.dto.clip1.Scene;
+import org.openhab.binding.hue.internal.api.dto.clip1.State;
+import org.openhab.binding.hue.internal.api.dto.clip1.StateUpdate;
import org.openhab.binding.hue.internal.config.HueBridgeConfig;
import org.openhab.binding.hue.internal.connection.HueBridge;
import org.openhab.binding.hue.internal.connection.HueTlsTrustManagerProvider;
import org.openhab.binding.hue.internal.discovery.HueDeviceDiscoveryService;
-import org.openhab.binding.hue.internal.dto.ApiVersionUtils;
-import org.openhab.binding.hue.internal.dto.Config;
-import org.openhab.binding.hue.internal.dto.ConfigUpdate;
-import org.openhab.binding.hue.internal.dto.FullConfig;
-import org.openhab.binding.hue.internal.dto.FullGroup;
-import org.openhab.binding.hue.internal.dto.FullLight;
-import org.openhab.binding.hue.internal.dto.FullSensor;
-import org.openhab.binding.hue.internal.dto.Scene;
-import org.openhab.binding.hue.internal.dto.State;
-import org.openhab.binding.hue.internal.dto.StateUpdate;
import org.openhab.binding.hue.internal.exceptions.ApiException;
import org.openhab.binding.hue.internal.exceptions.DeviceOffException;
import org.openhab.binding.hue.internal.exceptions.EmptyResponseException;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.hue.internal.api.dto.clip1.ConfigUpdate;
+import org.openhab.binding.hue.internal.api.dto.clip1.FullGroup;
+import org.openhab.binding.hue.internal.api.dto.clip1.FullLight;
+import org.openhab.binding.hue.internal.api.dto.clip1.FullSensor;
+import org.openhab.binding.hue.internal.api.dto.clip1.StateUpdate;
import org.openhab.binding.hue.internal.discovery.HueDeviceDiscoveryService;
-import org.openhab.binding.hue.internal.dto.ConfigUpdate;
-import org.openhab.binding.hue.internal.dto.FullGroup;
-import org.openhab.binding.hue.internal.dto.FullLight;
-import org.openhab.binding.hue.internal.dto.FullSensor;
-import org.openhab.binding.hue.internal.dto.StateUpdate;
/**
* Access to the Hue system for light handlers.
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.hue.internal.dto.ColorTemperature;
-import org.openhab.binding.hue.internal.dto.FullGroup;
-import org.openhab.binding.hue.internal.dto.Scene;
-import org.openhab.binding.hue.internal.dto.State;
-import org.openhab.binding.hue.internal.dto.StateUpdate;
+import org.openhab.binding.hue.internal.api.dto.clip1.ColorTemperature;
+import org.openhab.binding.hue.internal.api.dto.clip1.FullGroup;
+import org.openhab.binding.hue.internal.api.dto.clip1.Scene;
+import org.openhab.binding.hue.internal.api.dto.clip1.State;
+import org.openhab.binding.hue.internal.api.dto.clip1.StateUpdate;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.HSBType;
import org.openhab.core.library.types.IncreaseDecreaseType;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.hue.internal.dto.Capabilities;
-import org.openhab.binding.hue.internal.dto.ColorTemperature;
-import org.openhab.binding.hue.internal.dto.FullLight;
-import org.openhab.binding.hue.internal.dto.State;
-import org.openhab.binding.hue.internal.dto.StateUpdate;
+import org.openhab.binding.hue.internal.api.dto.clip1.Capabilities;
+import org.openhab.binding.hue.internal.api.dto.clip1.ColorTemperature;
+import org.openhab.binding.hue.internal.api.dto.clip1.FullLight;
+import org.openhab.binding.hue.internal.api.dto.clip1.State;
+import org.openhab.binding.hue.internal.api.dto.clip1.StateUpdate;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.HSBType;
import org.openhab.core.library.types.IncreaseDecreaseType;
package org.openhab.binding.hue.internal.handler;
import static org.openhab.binding.hue.internal.HueBindingConstants.*;
-import static org.openhab.binding.hue.internal.dto.FullSensor.*;
+import static org.openhab.binding.hue.internal.api.dto.clip1.FullSensor.*;
import static org.openhab.core.thing.Thing.*;
import java.time.LocalDateTime;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.hue.internal.dto.FullSensor;
-import org.openhab.binding.hue.internal.dto.SensorConfigUpdate;
-import org.openhab.binding.hue.internal.dto.StateUpdate;
+import org.openhab.binding.hue.internal.api.dto.clip1.FullSensor;
+import org.openhab.binding.hue.internal.api.dto.clip1.SensorConfigUpdate;
+import org.openhab.binding.hue.internal.api.dto.clip1.StateUpdate;
import org.openhab.core.config.core.Configuration;
import org.openhab.core.library.types.DateTimeType;
import org.openhab.core.library.types.DecimalType;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.hue.internal.dto.ColorTemperature;
-import org.openhab.binding.hue.internal.dto.State;
-import org.openhab.binding.hue.internal.dto.State.AlertMode;
-import org.openhab.binding.hue.internal.dto.State.ColorMode;
-import org.openhab.binding.hue.internal.dto.State.Effect;
-import org.openhab.binding.hue.internal.dto.StateUpdate;
+import org.openhab.binding.hue.internal.api.dto.clip1.ColorTemperature;
+import org.openhab.binding.hue.internal.api.dto.clip1.State;
+import org.openhab.binding.hue.internal.api.dto.clip1.State.AlertMode;
+import org.openhab.binding.hue.internal.api.dto.clip1.State.ColorMode;
+import org.openhab.binding.hue.internal.api.dto.clip1.State.Effect;
+import org.openhab.binding.hue.internal.api.dto.clip1.StateUpdate;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.HSBType;
import org.openhab.core.library.types.IncreaseDecreaseType;
package org.openhab.binding.hue.internal.handler;
import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.openhab.binding.hue.internal.dto.FullLight;
+import org.openhab.binding.hue.internal.api.dto.clip1.FullLight;
/**
* The {@link LightStatusListener} is notified when a light status has changed or a light has been removed or added.
package org.openhab.binding.hue.internal.handler;
import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.openhab.binding.hue.internal.dto.FullSensor;
+import org.openhab.binding.hue.internal.api.dto.clip1.FullSensor;
/**
* The {@link SensorStatusListener} is notified when a sensor status has changed or a sensor has been removed or added.
import java.util.stream.Stream;
import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.openhab.binding.hue.internal.dto.FullSensor;
-import org.openhab.binding.hue.internal.dto.SensorConfigUpdate;
+import org.openhab.binding.hue.internal.api.dto.clip1.FullSensor;
+import org.openhab.binding.hue.internal.api.dto.clip1.SensorConfigUpdate;
import org.openhab.binding.hue.internal.handler.HueSensorHandler;
import org.openhab.core.config.core.Configuration;
import org.openhab.core.thing.Thing;
import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.openhab.binding.hue.internal.dto.FullSensor;
-import org.openhab.binding.hue.internal.dto.SensorConfigUpdate;
+import org.openhab.binding.hue.internal.api.dto.clip1.FullSensor;
+import org.openhab.binding.hue.internal.api.dto.clip1.SensorConfigUpdate;
import org.openhab.binding.hue.internal.handler.HueSensorHandler;
import org.openhab.core.config.core.Configuration;
import org.openhab.core.library.types.DecimalType;
package org.openhab.binding.hue.internal.handler.sensors;
import static org.openhab.binding.hue.internal.HueBindingConstants.*;
-import static org.openhab.binding.hue.internal.dto.FullSensor.STATE_PRESENCE;
+import static org.openhab.binding.hue.internal.api.dto.clip1.FullSensor.STATE_PRESENCE;
import java.util.Map;
import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.openhab.binding.hue.internal.dto.FullSensor;
-import org.openhab.binding.hue.internal.dto.SensorConfigUpdate;
+import org.openhab.binding.hue.internal.api.dto.clip1.FullSensor;
+import org.openhab.binding.hue.internal.api.dto.clip1.SensorConfigUpdate;
import org.openhab.binding.hue.internal.handler.HueSensorHandler;
import org.openhab.core.config.core.Configuration;
import org.openhab.core.library.types.OnOffType;
package org.openhab.binding.hue.internal.handler.sensors;
import static org.openhab.binding.hue.internal.HueBindingConstants.*;
-import static org.openhab.binding.hue.internal.dto.FullSensor.*;
+import static org.openhab.binding.hue.internal.api.dto.clip1.FullSensor.*;
import java.math.BigDecimal;
import java.util.Map;
import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.openhab.binding.hue.internal.dto.FullSensor;
-import org.openhab.binding.hue.internal.dto.LightLevelConfigUpdate;
-import org.openhab.binding.hue.internal.dto.SensorConfigUpdate;
+import org.openhab.binding.hue.internal.api.dto.clip1.FullSensor;
+import org.openhab.binding.hue.internal.api.dto.clip1.LightLevelConfigUpdate;
+import org.openhab.binding.hue.internal.api.dto.clip1.SensorConfigUpdate;
import org.openhab.binding.hue.internal.handler.HueSensorHandler;
import org.openhab.core.config.core.Configuration;
import org.openhab.core.library.types.DecimalType;
package org.openhab.binding.hue.internal.handler.sensors;
import static org.openhab.binding.hue.internal.HueBindingConstants.*;
-import static org.openhab.binding.hue.internal.dto.FullSensor.*;
+import static org.openhab.binding.hue.internal.api.dto.clip1.FullSensor.*;
import java.util.Map;
import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.openhab.binding.hue.internal.dto.FullSensor;
-import org.openhab.binding.hue.internal.dto.PresenceConfigUpdate;
-import org.openhab.binding.hue.internal.dto.SensorConfigUpdate;
+import org.openhab.binding.hue.internal.api.dto.clip1.FullSensor;
+import org.openhab.binding.hue.internal.api.dto.clip1.PresenceConfigUpdate;
+import org.openhab.binding.hue.internal.api.dto.clip1.SensorConfigUpdate;
import org.openhab.binding.hue.internal.handler.HueClient;
import org.openhab.binding.hue.internal.handler.HueSensorHandler;
import org.openhab.core.config.core.Configuration;
import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.openhab.binding.hue.internal.dto.FullSensor;
-import org.openhab.binding.hue.internal.dto.SensorConfigUpdate;
+import org.openhab.binding.hue.internal.api.dto.clip1.FullSensor;
+import org.openhab.binding.hue.internal.api.dto.clip1.SensorConfigUpdate;
import org.openhab.binding.hue.internal.handler.HueSensorHandler;
import org.openhab.core.config.core.Configuration;
import org.openhab.core.library.types.DecimalType;
package org.openhab.binding.hue.internal.handler.sensors;
import static org.openhab.binding.hue.internal.HueBindingConstants.*;
-import static org.openhab.binding.hue.internal.dto.FullSensor.*;
+import static org.openhab.binding.hue.internal.api.dto.clip1.FullSensor.*;
import java.math.BigDecimal;
import java.util.Map;
import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.openhab.binding.hue.internal.dto.FullSensor;
-import org.openhab.binding.hue.internal.dto.SensorConfigUpdate;
-import org.openhab.binding.hue.internal.dto.TemperatureConfigUpdate;
+import org.openhab.binding.hue.internal.api.dto.clip1.FullSensor;
+import org.openhab.binding.hue.internal.api.dto.clip1.SensorConfigUpdate;
+import org.openhab.binding.hue.internal.api.dto.clip1.TemperatureConfigUpdate;
import org.openhab.binding.hue.internal.handler.HueSensorHandler;
import org.openhab.core.config.core.Configuration;
import org.openhab.core.library.types.QuantityType;
+++ /dev/null
-/**
- * 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.serialization;
-
-import java.lang.reflect.Type;
-import java.time.Instant;
-import java.time.format.DateTimeParseException;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-import com.google.gson.JsonDeserializationContext;
-import com.google.gson.JsonDeserializer;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonParseException;
-
-/**
- * The {@link InstantDeserializer} converts a formatted UTC string to {@link Instant}.
- *
- * @author Jacob Laursen - Initial contribution
- */
-@NonNullByDefault
-public class InstantDeserializer implements JsonDeserializer<Instant> {
-
- @Override
- public @Nullable Instant deserialize(JsonElement element, Type arg1, JsonDeserializationContext arg2)
- throws JsonParseException {
- String content = element.getAsString();
- try {
- return Instant.parse(content);
- } catch (DateTimeParseException e) {
- throw new JsonParseException("Could not parse as Instant: " + content, e);
- }
- }
-}
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.junit.jupiter.api.Test;
-import org.openhab.binding.hue.internal.dto.ApiVersion;
+import org.openhab.binding.hue.internal.api.dto.clip1.ApiVersion;
/**
* @author Samuel Leisering - Initial contribution
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.http.HttpStatus;
import org.junit.jupiter.api.Test;
+import org.openhab.binding.hue.internal.api.dto.clip1.Scene;
import org.openhab.binding.hue.internal.config.HueBridgeConfig;
import org.openhab.binding.hue.internal.connection.HueBridge;
-import org.openhab.binding.hue.internal.dto.Scene;
import org.openhab.binding.hue.internal.exceptions.ApiException;
import org.openhab.core.i18n.CommunicationException;
import org.openhab.core.i18n.ConfigurationException;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.junit.jupiter.api.Test;
-import org.openhab.binding.hue.internal.dto.ColorTemperature;
-import org.openhab.binding.hue.internal.dto.State;
-import org.openhab.binding.hue.internal.dto.State.ColorMode;
-import org.openhab.binding.hue.internal.dto.StateUpdate;
+import org.openhab.binding.hue.internal.api.dto.clip1.ColorTemperature;
+import org.openhab.binding.hue.internal.api.dto.clip1.State;
+import org.openhab.binding.hue.internal.api.dto.clip1.State.ColorMode;
+import org.openhab.binding.hue.internal.api.dto.clip1.StateUpdate;
import org.openhab.binding.hue.internal.handler.LightStateConverter;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.HSBType;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.junit.jupiter.api.Test;
-import org.openhab.binding.hue.internal.dto.FullGroup;
-import org.openhab.binding.hue.internal.dto.Scene;
-import org.openhab.binding.hue.internal.dto.State;
+import org.openhab.binding.hue.internal.api.dto.clip1.FullGroup;
+import org.openhab.binding.hue.internal.api.dto.clip1.Scene;
+import org.openhab.binding.hue.internal.api.dto.clip1.State;
/**
* @author HJiang - initial contribution
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.junit.jupiter.api.Test;
-import org.openhab.binding.hue.internal.dto.clip2.ActionEntry;
-import org.openhab.binding.hue.internal.dto.clip2.Alerts;
-import org.openhab.binding.hue.internal.dto.clip2.Button;
-import org.openhab.binding.hue.internal.dto.clip2.ContactReport;
-import org.openhab.binding.hue.internal.dto.clip2.Dimming;
-import org.openhab.binding.hue.internal.dto.clip2.Effects;
-import org.openhab.binding.hue.internal.dto.clip2.Event;
-import org.openhab.binding.hue.internal.dto.clip2.LightLevel;
-import org.openhab.binding.hue.internal.dto.clip2.MetaData;
-import org.openhab.binding.hue.internal.dto.clip2.MirekSchema;
-import org.openhab.binding.hue.internal.dto.clip2.Motion;
-import org.openhab.binding.hue.internal.dto.clip2.Power;
-import org.openhab.binding.hue.internal.dto.clip2.ProductData;
-import org.openhab.binding.hue.internal.dto.clip2.RelativeRotary;
-import org.openhab.binding.hue.internal.dto.clip2.Resource;
-import org.openhab.binding.hue.internal.dto.clip2.ResourceReference;
-import org.openhab.binding.hue.internal.dto.clip2.Resources;
-import org.openhab.binding.hue.internal.dto.clip2.Rotation;
-import org.openhab.binding.hue.internal.dto.clip2.RotationEvent;
-import org.openhab.binding.hue.internal.dto.clip2.TamperReport;
-import org.openhab.binding.hue.internal.dto.clip2.Temperature;
-import org.openhab.binding.hue.internal.dto.clip2.TimedEffects;
-import org.openhab.binding.hue.internal.dto.clip2.enums.ActionType;
-import org.openhab.binding.hue.internal.dto.clip2.enums.Archetype;
-import org.openhab.binding.hue.internal.dto.clip2.enums.BatteryStateType;
-import org.openhab.binding.hue.internal.dto.clip2.enums.ButtonEventType;
-import org.openhab.binding.hue.internal.dto.clip2.enums.DirectionType;
-import org.openhab.binding.hue.internal.dto.clip2.enums.EffectType;
-import org.openhab.binding.hue.internal.dto.clip2.enums.ResourceType;
-import org.openhab.binding.hue.internal.dto.clip2.enums.RotationEventType;
-import org.openhab.binding.hue.internal.dto.clip2.enums.ZigbeeStatus;
-import org.openhab.binding.hue.internal.dto.clip2.helper.Setters;
-import org.openhab.binding.hue.internal.serialization.InstantDeserializer;
+import org.openhab.binding.hue.internal.api.dto.clip2.ActionEntry;
+import org.openhab.binding.hue.internal.api.dto.clip2.Alerts;
+import org.openhab.binding.hue.internal.api.dto.clip2.Button;
+import org.openhab.binding.hue.internal.api.dto.clip2.ContactReport;
+import org.openhab.binding.hue.internal.api.dto.clip2.Dimming;
+import org.openhab.binding.hue.internal.api.dto.clip2.Effects;
+import org.openhab.binding.hue.internal.api.dto.clip2.Event;
+import org.openhab.binding.hue.internal.api.dto.clip2.LightLevel;
+import org.openhab.binding.hue.internal.api.dto.clip2.MetaData;
+import org.openhab.binding.hue.internal.api.dto.clip2.MirekSchema;
+import org.openhab.binding.hue.internal.api.dto.clip2.Motion;
+import org.openhab.binding.hue.internal.api.dto.clip2.Power;
+import org.openhab.binding.hue.internal.api.dto.clip2.ProductData;
+import org.openhab.binding.hue.internal.api.dto.clip2.RelativeRotary;
+import org.openhab.binding.hue.internal.api.dto.clip2.Resource;
+import org.openhab.binding.hue.internal.api.dto.clip2.ResourceReference;
+import org.openhab.binding.hue.internal.api.dto.clip2.Resources;
+import org.openhab.binding.hue.internal.api.dto.clip2.Rotation;
+import org.openhab.binding.hue.internal.api.dto.clip2.RotationEvent;
+import org.openhab.binding.hue.internal.api.dto.clip2.TamperReport;
+import org.openhab.binding.hue.internal.api.dto.clip2.Temperature;
+import org.openhab.binding.hue.internal.api.dto.clip2.TimedEffects;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.ActionType;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.Archetype;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.BatteryStateType;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.ButtonEventType;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.DirectionType;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.EffectType;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.ResourceType;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.RotationEventType;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.ZigbeeStatus;
+import org.openhab.binding.hue.internal.api.dto.clip2.helper.Setters;
+import org.openhab.binding.hue.internal.api.serialization.InstantDeserializer;
import org.openhab.core.library.types.DateTimeType;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.HSBType;
import org.eclipse.jdt.annotation.Nullable;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
-import org.openhab.binding.hue.internal.dto.FullConfig;
-import org.openhab.binding.hue.internal.dto.FullLight;
-import org.openhab.binding.hue.internal.dto.State.ColorMode;
-import org.openhab.binding.hue.internal.dto.StateUpdate;
+import org.openhab.binding.hue.internal.api.dto.clip1.FullConfig;
+import org.openhab.binding.hue.internal.api.dto.clip1.FullLight;
+import org.openhab.binding.hue.internal.api.dto.clip1.State.ColorMode;
+import org.openhab.binding.hue.internal.api.dto.clip1.StateUpdate;
import org.openhab.core.config.core.Configuration;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.HSBType;
package org.openhab.binding.hue.internal.handler;
import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.openhab.binding.hue.internal.dto.State.ColorMode;
+import org.openhab.binding.hue.internal.api.dto.clip1.State.ColorMode;
/**
* Builder for the current state of a hue light.
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import org.openhab.binding.hue.internal.api.dto.clip1.FullLight;
import org.openhab.binding.hue.internal.config.HueBridgeConfig;
import org.openhab.binding.hue.internal.connection.HueBridge;
import org.openhab.binding.hue.internal.discovery.HueDeviceDiscoveryService;
-import org.openhab.binding.hue.internal.dto.FullLight;
import org.openhab.binding.hue.internal.exceptions.ApiException;
import org.openhab.binding.hue.internal.handler.HueBridgeHandler;
import org.openhab.core.config.core.Configuration;