Skip to content

Commit

Permalink
[boschshc] Support smart light bulbs (openhab#13707)
Browse files Browse the repository at this point in the history
* add thing type definition for smart bulbs using system channels
* add constants for thing type and channels
* implement and register handler
* implement binary switch service (to switch on/off)
* implement multi-level switch service (allows to get/set brightness
from 0-100%)
* implement service to get and set colors
* add unit tests for handler and state classes

Signed-off-by: David Pace <dev@davidpace.de>
  • Loading branch information
david-pace committed Nov 15, 2022
1 parent 160e0c2 commit 50bb9d6
Show file tree
Hide file tree
Showing 15 changed files with 635 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
* @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 {
Expand All @@ -45,6 +45,7 @@ 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
Expand Down Expand Up @@ -76,6 +77,8 @@ public class BoschSHCBindingConstants {
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";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
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;
Expand Down Expand Up @@ -77,7 +78,8 @@ public ThingTypeHandlerMapping(ThingTypeUID thingTypeUID, Function<Thing, BaseTh
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) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/**
* 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());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* Copyright (c) 2010-2022 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.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);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* 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 on ? OnOffType.ON : OnOffType.OFF;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* Copyright (c) 2010-2022 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.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);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* 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;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/**
* 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());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* 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);
}
}
Loading

0 comments on commit 50bb9d6

Please sign in to comment.