- [Security Camera 360](#security-camera-360)
- [Security Camera Eyes](#security-camera-eyes)
- [Intrusion Detection System](#intrusion-detection-system)
+ - [Smart Bulb](#smart-bulb)
- [Limitations](#limitations)
- [Discovery](#discovery)
- [Bridge Configuration](#bridge-configuration)
| disarm-action | Switch | ☑ | Disarms the intrusion detection system when an ON command is received. |
| mute-action | Switch | ☑ | Mutes the alarm when an ON command is received. |
+### Smart Bulb
+
+A smart bulb connected to the bridge via Zigbee such as a Ledvance Smart+ bulb.
+
+**Thing Type ID**: `smart-bulb`
+
+| Channel Type ID | Item Type | Writable | Description |
+| ----------------| --------- | :------: | -------------------------------------------------------------- |
+| power-switch | Switch | ☑ | Switches the light on or off. |
+| brightness | Dimmer | ☑ | Regulates the brightness on a percentage scale from 0 to 100%. |
+| color | Color | ☑ | The color of the emitted light. |
+
## Limitations
- Discovery of Things
* @author Stefan Kästle - Initial contribution
* @author Christian Oeing - added Shutter Control, ThermostatHandler
* @author Christian Oeing - Added WallThermostatHandler
- * @author David Pace - Added cameras and intrusion detection system
+ * @author David Pace - Added cameras, intrusion detection system, smart plugs, battery state support and smart bulbs
*/
@NonNullByDefault
public class BoschSHCBindingConstants {
public static final ThingTypeUID THING_TYPE_INTRUSION_DETECTION_SYSTEM = new ThingTypeUID(BINDING_ID,
"intrusion-detection-system");
public static final ThingTypeUID THING_TYPE_SMART_PLUG_COMPACT = new ThingTypeUID(BINDING_ID, "smart-plug-compact");
+ public static final ThingTypeUID THING_TYPE_SMART_BULB = new ThingTypeUID(BINDING_ID, "smart-bulb");
// List of all Channel IDs
// Auto-generated from thing-types.xml via script, don't modify
public static final String CHANNEL_MUTE_ACTION = "mute-action";
public static final String CHANNEL_BATTERY_LEVEL = "battery-level";
public static final String CHANNEL_LOW_BATTERY = "low-battery";
+ public static final String CHANNEL_COLOR = "color";
+ public static final String CHANNEL_BRIGHTNESS = "brightness";
// static device/service names
public static final String SERVICE_INTRUSION_DETECTION = "intrusionDetectionSystem";
import org.openhab.binding.boschshc.internal.devices.motiondetector.MotionDetectorHandler;
import org.openhab.binding.boschshc.internal.devices.plug.PlugHandler;
import org.openhab.binding.boschshc.internal.devices.shuttercontrol.ShutterControlHandler;
+import org.openhab.binding.boschshc.internal.devices.smartbulb.SmartBulbHandler;
import org.openhab.binding.boschshc.internal.devices.thermostat.ThermostatHandler;
import org.openhab.binding.boschshc.internal.devices.twinguard.TwinguardHandler;
import org.openhab.binding.boschshc.internal.devices.wallthermostat.WallThermostatHandler;
new ThingTypeHandlerMapping(THING_TYPE_CAMERA_360, CameraHandler::new),
new ThingTypeHandlerMapping(THING_TYPE_CAMERA_EYES, CameraHandler::new),
new ThingTypeHandlerMapping(THING_TYPE_INTRUSION_DETECTION_SYSTEM, IntrusionDetectionHandler::new),
- new ThingTypeHandlerMapping(THING_TYPE_SMART_PLUG_COMPACT, PlugHandler::new));
+ new ThingTypeHandlerMapping(THING_TYPE_SMART_PLUG_COMPACT, PlugHandler::new),
+ new ThingTypeHandlerMapping(THING_TYPE_SMART_BULB, SmartBulbHandler::new));
@Override
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
--- /dev/null
+/**
+ * Copyright (c) 2010-2022 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.boschshc.internal.devices.smartbulb;
+
+import static org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants.*;
+
+import java.util.List;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.binding.boschshc.internal.devices.BoschSHCDeviceHandler;
+import org.openhab.binding.boschshc.internal.exceptions.BoschSHCException;
+import org.openhab.binding.boschshc.internal.services.binaryswitch.BinarySwitchService;
+import org.openhab.binding.boschshc.internal.services.binaryswitch.dto.BinarySwitchServiceState;
+import org.openhab.binding.boschshc.internal.services.hsbcoloractuator.HSBColorActuatorService;
+import org.openhab.binding.boschshc.internal.services.hsbcoloractuator.dto.HSBColorActuatorServiceState;
+import org.openhab.binding.boschshc.internal.services.multilevelswitch.MultiLevelSwitchService;
+import org.openhab.binding.boschshc.internal.services.multilevelswitch.dto.MultiLevelSwitchServiceState;
+import org.openhab.core.library.types.HSBType;
+import org.openhab.core.library.types.OnOffType;
+import org.openhab.core.library.types.PercentType;
+import org.openhab.core.thing.ChannelUID;
+import org.openhab.core.thing.Thing;
+import org.openhab.core.types.Command;
+
+/**
+ * Handler for smart light bulbs connected via Zigbee, e.g. Ledvance Smart+ bulbs
+ *
+ * @author David Pace - Initial contribution
+ *
+ */
+@NonNullByDefault
+public class SmartBulbHandler extends BoschSHCDeviceHandler {
+
+ private BinarySwitchService binarySwitchService;
+ private HSBColorActuatorService hsbColorActuatorService;
+ private MultiLevelSwitchService multiLevelSwitchService;
+
+ public SmartBulbHandler(Thing thing) {
+ super(thing);
+
+ this.binarySwitchService = new BinarySwitchService();
+ this.multiLevelSwitchService = new MultiLevelSwitchService();
+ this.hsbColorActuatorService = new HSBColorActuatorService();
+ }
+
+ @Override
+ protected void initializeServices() throws BoschSHCException {
+ super.initializeServices();
+
+ this.registerService(binarySwitchService, this::updateChannels, List.of(CHANNEL_POWER_SWITCH), true);
+ this.registerService(multiLevelSwitchService, this::updateChannels, List.of(CHANNEL_BRIGHTNESS), true);
+ this.registerService(hsbColorActuatorService, this::updateChannels, List.of(CHANNEL_COLOR), true);
+ }
+
+ @Override
+ public void handleCommand(ChannelUID channelUID, Command command) {
+ super.handleCommand(channelUID, command);
+
+ switch (channelUID.getId()) {
+ case CHANNEL_POWER_SWITCH:
+ if (command instanceof OnOffType) {
+ updateBinarySwitchState((OnOffType) command);
+ }
+ break;
+ case CHANNEL_BRIGHTNESS:
+ if (command instanceof PercentType) {
+ updateMultiLevelSwitchState((PercentType) command);
+ }
+ break;
+ case CHANNEL_COLOR:
+ if (command instanceof HSBType) {
+ updateColorState((HSBType) command);
+ }
+ break;
+ }
+ }
+
+ private void updateBinarySwitchState(OnOffType command) {
+ BinarySwitchServiceState serviceState = new BinarySwitchServiceState();
+ serviceState.on = command == OnOffType.ON;
+ this.updateServiceState(binarySwitchService, serviceState);
+ }
+
+ private void updateMultiLevelSwitchState(PercentType command) {
+ MultiLevelSwitchServiceState serviceState = new MultiLevelSwitchServiceState();
+ serviceState.level = command.intValue();
+ this.updateServiceState(multiLevelSwitchService, serviceState);
+ }
+
+ private void updateColorState(HSBType command) {
+ HSBColorActuatorServiceState serviceState = new HSBColorActuatorServiceState();
+ serviceState.rgb = command.getRGB();
+ this.updateServiceState(hsbColorActuatorService, serviceState);
+ }
+
+ private void updateChannels(BinarySwitchServiceState serviceState) {
+ super.updateState(CHANNEL_POWER_SWITCH, serviceState.toOnOffType());
+ }
+
+ private void updateChannels(MultiLevelSwitchServiceState serviceState) {
+ super.updateState(CHANNEL_BRIGHTNESS, serviceState.toPercentType());
+ }
+
+ private void updateChannels(HSBColorActuatorServiceState serviceState) {
+ super.updateState(CHANNEL_COLOR, serviceState.toHSBType());
+ }
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2022 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.boschshc.internal.services.binaryswitch;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.binding.boschshc.internal.services.BoschSHCService;
+import org.openhab.binding.boschshc.internal.services.binaryswitch.dto.BinarySwitchServiceState;
+
+/**
+ * Service for devices and services that can be turned on and off.
+ *
+ * @author David Pace - Initial contribution
+ *
+ */
+@NonNullByDefault
+public class BinarySwitchService extends BoschSHCService<BinarySwitchServiceState> {
+
+ public BinarySwitchService() {
+ super("BinarySwitch", BinarySwitchServiceState.class);
+ }
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2022 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.boschshc.internal.services.binaryswitch.dto;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.openhab.binding.boschshc.internal.services.dto.BoschSHCServiceState;
+import org.openhab.core.library.types.OnOffType;
+
+/**
+ * State for devices and services that can be turned on and off.
+ *
+ * @author David Pace - Initial contribution
+ *
+ */
+public class BinarySwitchServiceState extends BoschSHCServiceState {
+
+ public BinarySwitchServiceState() {
+ super("binarySwitchState");
+ }
+
+ public boolean on;
+
+ public @NonNull OnOffType toOnOffType() {
+ return OnOffType.from(on);
+ }
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2022 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.boschshc.internal.services.hsbcoloractuator;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.binding.boschshc.internal.services.BoschSHCService;
+import org.openhab.binding.boschshc.internal.services.hsbcoloractuator.dto.HSBColorActuatorServiceState;
+
+/**
+ * Service for devices that can emit colored light.
+ *
+ * @author David Pace - Initial contribution
+ *
+ */
+@NonNullByDefault
+public class HSBColorActuatorService extends BoschSHCService<HSBColorActuatorServiceState> {
+
+ public HSBColorActuatorService() {
+ super("HSBColorActuator", HSBColorActuatorServiceState.class);
+ }
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2022 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.boschshc.internal.services.hsbcoloractuator.dto;
+
+/**
+ * State representing the color temperature range of light bulbs.
+ *
+ * @author David Pace - Initial contribution
+ *
+ */
+public class ColorTemperatureRange {
+ public int minCt;
+ public int maxCt;
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2022 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.boschshc.internal.services.hsbcoloractuator.dto;
+
+import java.awt.Color;
+
+import org.openhab.binding.boschshc.internal.services.dto.BoschSHCServiceState;
+import org.openhab.core.library.types.HSBType;
+
+/**
+ * State representing colors of light bulbs.
+ *
+ * @author David Pace - Initial contribution
+ *
+ */
+public class HSBColorActuatorServiceState extends BoschSHCServiceState {
+
+ public HSBColorActuatorServiceState() {
+ super("colorState");
+ }
+
+ /**
+ * RGB value modeled as an sRGB integer value (bits 24-31 are alpha, 16-23 are red, 8-15 are green, 0-7 are blue).
+ * Alpha is set to the fixed value <code>255</code>.
+ */
+ public int rgb;
+
+ public String gamut;
+
+ public ColorTemperatureRange colorTemperatureRange;
+
+ /**
+ * Converts the combined {@link #rgb} value to an openHAB-compliant HSB state.
+ *
+ * @return color as {@link HSBType}
+ */
+ public HSBType toHSBType() {
+ Color color = new Color(rgb);
+ return HSBType.fromRGB(color.getRed(), color.getGreen(), color.getBlue());
+ }
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2022 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.boschshc.internal.services.multilevelswitch;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.binding.boschshc.internal.services.BoschSHCService;
+import org.openhab.binding.boschshc.internal.services.multilevelswitch.dto.MultiLevelSwitchServiceState;
+
+/**
+ * Service for devices with switches that can have multiple different levels.
+ * <p>
+ * Example: light bulbs with controllable brightness levels from 0 to 100%.
+ *
+ * @author David Pace - Initial contribution
+ *
+ */
+@NonNullByDefault
+public class MultiLevelSwitchService extends BoschSHCService<MultiLevelSwitchServiceState> {
+
+ public MultiLevelSwitchService() {
+ super("MultiLevelSwitch", MultiLevelSwitchServiceState.class);
+ }
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2022 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.boschshc.internal.services.multilevelswitch.dto;
+
+import org.openhab.binding.boschshc.internal.services.dto.BoschSHCServiceState;
+import org.openhab.core.library.types.PercentType;
+
+/**
+ * State for devices with switches that can have multiple different levels.
+ *
+ * @author David Pace - Initial contribution
+ *
+ */
+public class MultiLevelSwitchServiceState extends BoschSHCServiceState {
+
+ public MultiLevelSwitchServiceState() {
+ super("multiLevelSwitchState");
+ }
+
+ /**
+ * Represents a percentage level between 0 and 100
+ */
+ public int level;
+
+ public PercentType toPercentType() {
+ return new PercentType(level);
+ }
+}
thing-type.boschshc.climate-control.description = This is a virtual device which is automatically created for all rooms that have thermostats in it.
thing-type.boschshc.in-wall-switch.label = In-wall Switch
thing-type.boschshc.in-wall-switch.description = A simple light control.
+thing-type.boschshc.intrusion-detection-system.label = Intrusion Detection System
+thing-type.boschshc.intrusion-detection-system.description = Allows to retrieve and control the state of the intrusion detection alarm system.
thing-type.boschshc.motion-detector.label = Motion Detector
thing-type.boschshc.motion-detector.description = Detects every movement through an intelligent combination of passive infra-red technology and an additional temperature sensor.
+thing-type.boschshc.security-camera-360.label = Security Camera 360
+thing-type.boschshc.security-camera-360.description = Indoor security camera with 360° view and motion detection.
+thing-type.boschshc.security-camera-eyes.label = Security Camera Eyes
+thing-type.boschshc.security-camera-eyes.description = Outdoor security camera with motion detection and light.
thing-type.boschshc.shc.label = Smart Home Controller
thing-type.boschshc.shc.description = The Bosch Smart Home Bridge representing the Bosch Smart Home Controller.
thing-type.boschshc.shutter-control.label = Shutter Control
thing-type.boschshc.shutter-control.description = Control of your shutter to take any position you desire.
+thing-type.boschshc.smart-bulb.label = Smart Bulb
+thing-type.boschshc.smart-bulb.description = A smart bulb connected via Zigbee.
+thing-type.boschshc.smart-plug-compact.label = Compact Smart Plug
+thing-type.boschshc.smart-plug-compact.description = A compact smart plug with energy monitoring capabilities.
thing-type.boschshc.thermostat.label = Thermostat
thing-type.boschshc.thermostat.description = Radiator thermostat
-thing-type.boschshc.twinguard.label = TwinGuard
+thing-type.boschshc.twinguard.label = Twinguard
thing-type.boschshc.twinguard.description = The Twinguard smoke detector warns you in case of fire and constantly monitors the air.
thing-type.boschshc.wall-thermostat.label = Wall Thermostat
thing-type.boschshc.wall-thermostat.description = Display of the current room temperature as well as the relative humidity in the room.
# channel types
+channel-type.boschshc.active-configuration-profile.label = Active Configuration Profile
+channel-type.boschshc.active-configuration-profile.description = The name of the active configuration profile used for the intrusion detection system.
channel-type.boschshc.air-description.label = Description
channel-type.boschshc.air-description.description = Overall description of the air quality.
+channel-type.boschshc.alarm-state.label = Alarm State
+channel-type.boschshc.alarm-state.description = The alarm state of the intrusion detection system. Possible values are ALARM_OFF, PRE_ALARM, ALARM_ON, ALARM_MUTED and UNKNOWN.
+channel-type.boschshc.alarm-state.state.option.ALARM_OFF = No alarm
+channel-type.boschshc.alarm-state.state.option.PRE_ALARM = Alarm is about to go off
+channel-type.boschshc.alarm-state.state.option.ALARM_ON = Alarm was triggered
+channel-type.boschshc.alarm-state.state.option.ALARM_MUTED = Alarm is muted
+channel-type.boschshc.alarm-state.state.option.UNKNOWN = Alarm status is unknown
+channel-type.boschshc.arm-action.label = Arm Action
+channel-type.boschshc.arm-action.description = Arms the intrusion detection system using the given profile ID.
+channel-type.boschshc.arming-state.label = Arming State
+channel-type.boschshc.arming-state.description = The arming state of the intrusion detection system. Possible values are SYSTEM_ARMING, SYSTEM_ARMED and SYSTEM_DISARMED. This channel is read-only. Use the arm-action and disarm-action channels to arm and disarm the system.
+channel-type.boschshc.arming-state.state.option.SYSTEM_ARMING = System is currently arming
+channel-type.boschshc.arming-state.state.option.SYSTEM_ARMED = System is armed
+channel-type.boschshc.arming-state.state.option.SYSTEM_DISARMED = System is disarmed
+channel-type.boschshc.camera-notification.label = Camera Notifications
+channel-type.boschshc.camera-notification.description = Enables or disables notifications for the camera.
+channel-type.boschshc.camera-notification.state.option.ENABLED = Enable notifications
+channel-type.boschshc.camera-notification.state.option.DISABLED = Disable notifications
channel-type.boschshc.child-lock.label = Child Lock
channel-type.boschshc.child-lock.description = Indicates if it is possible to set the desired temperature on the device.
channel-type.boschshc.combined-rating.label = Combined Rating
channel-type.boschshc.combined-rating.state.option.BAD = Bad Quality
channel-type.boschshc.contact.label = Window/Door contact
channel-type.boschshc.contact.description = A window and door contact.
+channel-type.boschshc.disarm-action.label = Disarm Action
+channel-type.boschshc.disarm-action.description = Disarms the intrusion detection system when an ON command is received.
channel-type.boschshc.energy-consumption.label = Energy consumption (Wh)
channel-type.boschshc.energy-consumption.description = Energy consumption of the device.
channel-type.boschshc.humidity-rating.label = Humidity Rating
channel-type.boschshc.latest-motion.description = Timestamp of the latest motion.
channel-type.boschshc.level.label = Level
channel-type.boschshc.level.description = Current open ratio (0 to 100).
+channel-type.boschshc.mute-action.label = Mute Action
+channel-type.boschshc.mute-action.description = Mutes the alarm when an ON command is received.
channel-type.boschshc.power-consumption.label = Power consumption (W)
channel-type.boschshc.power-consumption.description = Current power consumption of the device.
+channel-type.boschshc.privacy-mode.label = Privacy Mode
+channel-type.boschshc.privacy-mode.description = If privacy mode is enabled, the camera is disabled and vice versa.
+channel-type.boschshc.privacy-mode.state.option.ENABLED = Privacy mode enabled (camera disabled)
+channel-type.boschshc.privacy-mode.state.option.DISABLED = Privacy mode disabled (camera enabled)
channel-type.boschshc.purity-rating.label = Purity Rating
channel-type.boschshc.purity-rating.description = Rating of the air purity.
channel-type.boschshc.purity.label = Purity
channel-type.boschshc.purity.description = Purity of the air. A higher value indicates a higher pollution.
channel-type.boschshc.setpoint-temperature.label = Setpoint Temperature
channel-type.boschshc.setpoint-temperature.description = Desired temperature.
+channel-type.boschshc.system-availability.label = System Availability
+channel-type.boschshc.system-availability.description = Indicates whether the intrusion detection system is available.
channel-type.boschshc.temperature-rating.label = Temperature Rating
channel-type.boschshc.temperature-rating.description = Rating of the currently measured temperature.
channel-type.boschshc.temperature-rating.state.option.GOOD = Good Temperature
</thing-type>
+ <thing-type id="smart-bulb">
+ <supported-bridge-type-refs>
+ <bridge-type-ref id="shc"/>
+ </supported-bridge-type-refs>
+
+ <label>Smart Bulb</label>
+ <description>A smart bulb connected via Zigbee.</description>
+
+ <channels>
+ <channel id="power-switch" typeId="system.power"/>
+ <channel id="brightness" typeId="system.brightness"/>
+ <channel id="color" typeId="system.color"/>
+ </channels>
+
+ <config-description-ref uri="thing-type:boschshc:device"/>
+
+ </thing-type>
+
<channel-type id="system-availability">
<item-type>Switch</item-type>
<label>System Availability</label>
--- /dev/null
+/**
+ * Copyright (c) 2010-2022 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.boschshc.internal.devices.smartbulb;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.*;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
+
+import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.openhab.binding.boschshc.internal.devices.AbstractBoschSHCDeviceHandlerTest;
+import org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants;
+import org.openhab.binding.boschshc.internal.exceptions.BoschSHCException;
+import org.openhab.binding.boschshc.internal.services.binaryswitch.dto.BinarySwitchServiceState;
+import org.openhab.binding.boschshc.internal.services.hsbcoloractuator.dto.HSBColorActuatorServiceState;
+import org.openhab.binding.boschshc.internal.services.multilevelswitch.dto.MultiLevelSwitchServiceState;
+import org.openhab.core.library.types.HSBType;
+import org.openhab.core.library.types.OnOffType;
+import org.openhab.core.library.types.PercentType;
+import org.openhab.core.thing.ChannelUID;
+import org.openhab.core.thing.ThingTypeUID;
+import org.openhab.core.thing.ThingUID;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParser;
+
+/**
+ * Unit tests for {@link SmartBulbHandler}.
+ *
+ * @author David Pace - Initial contribution
+ *
+ */
+public class SmartBulbHandlerTest extends AbstractBoschSHCDeviceHandlerTest<SmartBulbHandler> {
+
+ @Captor
+ private ArgumentCaptor<BinarySwitchServiceState> binarySwitchServiceStateCaptor;
+
+ @Captor
+ private ArgumentCaptor<MultiLevelSwitchServiceState> multiLevelSwitchServiceStateCaptor;
+
+ @Captor
+ private ArgumentCaptor<HSBColorActuatorServiceState> hsbColorActuatorServiceStateCaptor;
+
+ @Override
+ protected SmartBulbHandler createFixture() {
+ return new SmartBulbHandler(getThing());
+ }
+
+ @Override
+ protected String getDeviceID() {
+ return "hdm:ZigBee:f0d1b80000f2a3e9";
+ }
+
+ @Override
+ protected ThingTypeUID getThingTypeUID() {
+ return BoschSHCBindingConstants.THING_TYPE_SMART_BULB;
+ }
+
+ @Test
+ public void testHandleCommand_BinarySwitch()
+ throws InterruptedException, TimeoutException, ExecutionException, BoschSHCException {
+
+ getFixture().handleCommand(new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_POWER_SWITCH),
+ OnOffType.ON);
+ verify(getBridgeHandler()).putState(eq(getDeviceID()), eq("BinarySwitch"),
+ binarySwitchServiceStateCaptor.capture());
+ BinarySwitchServiceState state = binarySwitchServiceStateCaptor.getValue();
+ assertTrue(state.on);
+
+ getFixture().handleCommand(new ChannelUID(new ThingUID(getThingTypeUID(), "abcdef"),
+ BoschSHCBindingConstants.CHANNEL_POWER_SWITCH), OnOffType.OFF);
+ verify(getBridgeHandler(), times(2)).putState(eq(getDeviceID()), eq("BinarySwitch"),
+ binarySwitchServiceStateCaptor.capture());
+ state = binarySwitchServiceStateCaptor.getValue();
+ assertFalse(state.on);
+ }
+
+ @Test
+ public void testHandleCommand_MultiLevelSwitch()
+ throws InterruptedException, TimeoutException, ExecutionException, BoschSHCException {
+
+ getFixture().handleCommand(new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_BRIGHTNESS),
+ new PercentType(42));
+ verify(getBridgeHandler()).putState(eq(getDeviceID()), eq("MultiLevelSwitch"),
+ multiLevelSwitchServiceStateCaptor.capture());
+ MultiLevelSwitchServiceState state = multiLevelSwitchServiceStateCaptor.getValue();
+ assertEquals(42, state.level);
+ }
+
+ @Test
+ public void testHandleCommand_HSBColorActuator()
+ throws InterruptedException, TimeoutException, ExecutionException, BoschSHCException {
+
+ getFixture().handleCommand(new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_COLOR),
+ HSBType.BLUE);
+ verify(getBridgeHandler()).putState(eq(getDeviceID()), eq("HSBColorActuator"),
+ hsbColorActuatorServiceStateCaptor.capture());
+ HSBColorActuatorServiceState state = hsbColorActuatorServiceStateCaptor.getValue();
+ assertEquals(-16776961, state.rgb);
+ }
+
+ @Test
+ public void testUpdateChannel_BinarySwitchState() {
+ JsonElement jsonObject = JsonParser.parseString("{\"@type\":\"binarySwitchState\",\"on\":true}");
+ getFixture().processUpdate("BinarySwitch", jsonObject);
+ verify(getCallback()).stateUpdated(
+ new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_POWER_SWITCH), OnOffType.ON);
+
+ jsonObject = JsonParser.parseString("{\"@type\":\"binarySwitchState\",\"on\":false}");
+ getFixture().processUpdate("BinarySwitch", jsonObject);
+ verify(getCallback()).stateUpdated(
+ new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_POWER_SWITCH), OnOffType.OFF);
+ }
+
+ @Test
+ public void testUpdateChannel_MultiLevelSwitchState() {
+ JsonElement jsonObject = JsonParser.parseString("{\"@type\":\"multiLevelSwitchState\",\"level\":16}");
+ getFixture().processUpdate("MultiLevelSwitch", jsonObject);
+ verify(getCallback()).stateUpdated(
+ new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_BRIGHTNESS), new PercentType(16));
+ }
+
+ @Test
+ public void testUpdateChannel_HSBColorActuatorState() {
+ JsonElement jsonObject = JsonParser.parseString("{\"colorTemperatureRange\": {\n" + " \"minCt\": 153,\n"
+ + " \"maxCt\": 526\n" + " },\n" + " \"@type\": \"colorState\",\n"
+ + " \"gamut\": \"LEDVANCE_GAMUT_A\",\n" + " \"rgb\": -12427}");
+ getFixture().processUpdate("HSBColorActuator", jsonObject);
+ verify(getCallback()).stateUpdated(new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_COLOR),
+ HSBType.fromRGB(255, 207, 117));
+ }
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2022 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.boschshc.internal.services.binaryswitch.dto;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+import org.openhab.core.library.types.OnOffType;
+
+/**
+ * Unit tests for {@link BinarySwitchServiceState}.
+ *
+ * @author David Pace - Initial contribution
+ *
+ */
+public class BinarySwitchServiceStateTest {
+
+ @Test
+ void testToOnOffType() {
+ BinarySwitchServiceState binarySwitchServiceState = new BinarySwitchServiceState();
+ assertEquals(OnOffType.OFF, binarySwitchServiceState.toOnOffType());
+ binarySwitchServiceState.on = true;
+ assertEquals(OnOffType.ON, binarySwitchServiceState.toOnOffType());
+ }
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2022 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.boschshc.internal.services.hsbcoloractuator.dto;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+import org.openhab.core.library.types.HSBType;
+
+/**
+ * Unit tests for {@link HSBColorActuatorServiceState}.
+ *
+ * @author David Pace - Initial contribution
+ *
+ */
+public class HSBColorActuatorServiceStateTest {
+
+ @Test
+ void testToHSBType() {
+ HSBColorActuatorServiceState hsbColorActuatorState = new HSBColorActuatorServiceState();
+ hsbColorActuatorState.rgb = -12427; // r = 255, g = 207, b = 117
+ assertEquals(HSBType.fromRGB(255, 207, 117), hsbColorActuatorState.toHSBType());
+ }
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2022 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.boschshc.internal.services.multilevelswitch.dto;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+import org.openhab.core.library.types.PercentType;
+
+/**
+ * Unit tests for {@link MultiLevelSwitchServiceState}.
+ *
+ * @author David Pace - Initial contribution
+ *
+ */
+public class MultiLevelSwitchServiceStateTest {
+
+ @Test
+ void testToPercentType() {
+ MultiLevelSwitchServiceState multiLevelSwitchState = new MultiLevelSwitchServiceState();
+ multiLevelSwitchState.level = 42;
+ assertEquals(new PercentType(42), multiLevelSwitchState.toPercentType());
+ }
+}