mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 15:11:59 +01:00
* add thing definition with ID "smart-plug-compact" * add constant for thing type UID * extract abstract implementation for devices with power switch and energy monitoring * let in-wall switch handler and smart plug handler extend the abstract implementation * register new handler * add method with boolean parameter to fetch initial state actively * make BoschSHCDeviceHandler abstract * add documentation * add unit tests closes #13528 Signed-off-by: David Pace <dev@davidpace.de>
This commit is contained in:
parent
e528564bb6
commit
71da06dac7
@ -4,9 +4,10 @@ Binding for the Bosch Smart Home.
|
||||
|
||||
- [Bosch Smart Home Binding](#bosch-smart-home-binding)
|
||||
- [Supported Things](#supported-things)
|
||||
- [In-Wall switches & Smart Plugs](#in-wall-switches-smart-plugs)
|
||||
- [TwinGuard smoke detector](#twinguard-smoke-detector)
|
||||
- [Door/Window contact](#door-window-contact)
|
||||
- [In-Wall Switch](#in-wall-switch)
|
||||
- [Compact Smart Plug](#compact-smart-plug)
|
||||
- [Twinguard Smoke Detector](#twinguard-smoke-detector)
|
||||
- [Door/Window Contact](#door-window-contact)
|
||||
- [Motion Detector](#motion-detector)
|
||||
- [Shutter Control](#shutter-control)
|
||||
- [Thermostat](#thermostat)
|
||||
@ -24,19 +25,31 @@ Binding for the Bosch Smart Home.
|
||||
|
||||
## Supported Things
|
||||
|
||||
### In-Wall switches & Smart Plugs
|
||||
### In-Wall Switch
|
||||
|
||||
A simple light control.
|
||||
|
||||
**Thing Type ID**: `in-wall-switch`
|
||||
|
||||
| Channel Type ID | Item Type | Writable | Description |
|
||||
| ------------------ | ------------- | :------: | -------------------------------------------- |
|
||||
| power-switch | Switch | ☑ | Current state of the switch. |
|
||||
| power-consumption | Number:Power | ☐ | Current power consumption (W) of the device. |
|
||||
| energy-consumption | Number:Energy | ☐ | Energy consumption of the device. |
|
||||
| Channel Type ID | Item Type | Writable | Description |
|
||||
| ------------------ | ------------- | :------: | ------------------------------------------------ |
|
||||
| power-switch | Switch | ☑ | Current state of the switch. |
|
||||
| power-consumption | Number:Power | ☐ | Current power consumption (W) of the device. |
|
||||
| energy-consumption | Number:Energy | ☐ | Cumulated energy consumption (Wh) of the device. |
|
||||
|
||||
### TwinGuard smoke detector
|
||||
### Compact Smart Plug
|
||||
|
||||
A compact smart plug with energy monitoring capabilities.
|
||||
|
||||
**Thing Type ID**: `smart-plug-compact`
|
||||
|
||||
| Channel Type ID | Item Type | Writable | Description |
|
||||
| ------------------ | ------------- | :------: | ------------------------------------------------ |
|
||||
| power-switch | Switch | ☑ | Current state of the switch. |
|
||||
| power-consumption | Number:Power | ☐ | Current power consumption (W) of the device. |
|
||||
| energy-consumption | Number:Energy | ☐ | Cumulated energy consumption (Wh) of the device. |
|
||||
|
||||
### Twinguard smoke detector
|
||||
|
||||
The Twinguard smoke detector warns you in case of fire and constantly monitors the air.
|
||||
|
||||
@ -53,7 +66,7 @@ The Twinguard smoke detector warns you in case of fire and constantly monitors t
|
||||
| air-description | String | ☐ | Overall description of the air quality. |
|
||||
| combined-rating | String | ☐ | Combined rating of the air quality. |
|
||||
|
||||
### Door/Window contact
|
||||
### Door/Window Contact
|
||||
|
||||
Detects open windows and doors.
|
||||
|
||||
|
@ -0,0 +1,110 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
import static org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.measure.quantity.Energy;
|
||||
import javax.measure.quantity.Power;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.boschshc.internal.exceptions.BoschSHCException;
|
||||
import org.openhab.binding.boschshc.internal.services.powermeter.PowerMeterService;
|
||||
import org.openhab.binding.boschshc.internal.services.powermeter.dto.PowerMeterServiceState;
|
||||
import org.openhab.binding.boschshc.internal.services.powerswitch.PowerSwitchService;
|
||||
import org.openhab.binding.boschshc.internal.services.powerswitch.PowerSwitchState;
|
||||
import org.openhab.binding.boschshc.internal.services.powerswitch.dto.PowerSwitchServiceState;
|
||||
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.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.State;
|
||||
|
||||
/**
|
||||
* Abstract handler implementation for devices with power switches and energy monitoring.
|
||||
* <p>
|
||||
* This implementation provides the functionality to
|
||||
* <ul>
|
||||
* <li>Switch the device on and off using the <code>PowerSwitch</code> service</li>
|
||||
* <li>Measuring the current power consumption and the overall energy consumption using the <code>PowerMeter</code>
|
||||
* service</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author David Pace - Initial contribution (extracted from LightControlHandler)
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public abstract class AbstractPowerSwitchHandler extends BoschSHCDeviceHandler {
|
||||
|
||||
/**
|
||||
* Service for switching the device on and off
|
||||
*/
|
||||
private final PowerSwitchService powerSwitchService;
|
||||
|
||||
protected AbstractPowerSwitchHandler(Thing thing) {
|
||||
super(thing);
|
||||
this.powerSwitchService = new PowerSwitchService();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initializeServices() throws BoschSHCException {
|
||||
super.initializeServices();
|
||||
|
||||
this.registerService(this.powerSwitchService, this::updateChannels, List.of(CHANNEL_POWER_SWITCH), true);
|
||||
this.createService(PowerMeterService::new, this::updateChannels,
|
||||
List.of(CHANNEL_POWER_CONSUMPTION, CHANNEL_ENERGY_CONSUMPTION), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
super.handleCommand(channelUID, command);
|
||||
|
||||
switch (channelUID.getId()) {
|
||||
case CHANNEL_POWER_SWITCH:
|
||||
if (command instanceof OnOffType) {
|
||||
updatePowerSwitchState((OnOffType) command);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the channels which are linked to the {@link PowerMeterService} of the device.
|
||||
*
|
||||
* @param state Current state of {@link PowerMeterService}.
|
||||
*/
|
||||
private void updateChannels(PowerMeterServiceState state) {
|
||||
super.updateState(CHANNEL_POWER_CONSUMPTION, new QuantityType<Power>(state.powerConsumption, Units.WATT));
|
||||
super.updateState(CHANNEL_ENERGY_CONSUMPTION,
|
||||
new QuantityType<Energy>(state.energyConsumption, Units.WATT_HOUR));
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the channels which are linked to the {@link PowerSwitchService} of the device.
|
||||
*
|
||||
* @param state Current state of {@link PowerSwitchService}.
|
||||
*/
|
||||
private void updateChannels(PowerSwitchServiceState state) {
|
||||
State powerState = OnOffType.from(state.switchState.toString());
|
||||
super.updateState(CHANNEL_POWER_SWITCH, powerState);
|
||||
}
|
||||
|
||||
private void updatePowerSwitchState(OnOffType command) {
|
||||
PowerSwitchServiceState state = new PowerSwitchServiceState();
|
||||
state.switchState = PowerSwitchState.valueOf(command.toFullString());
|
||||
this.updateServiceState(this.powerSwitchService, state);
|
||||
}
|
||||
}
|
@ -44,6 +44,7 @@ public class BoschSHCBindingConstants {
|
||||
public static final ThingTypeUID THING_TYPE_CAMERA_EYES = new ThingTypeUID(BINDING_ID, "security-camera-eyes");
|
||||
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");
|
||||
|
||||
// List of all Channel IDs
|
||||
// Auto-generated from thing-types.xml via script, don't modify
|
||||
|
@ -28,19 +28,19 @@ import org.openhab.core.thing.ThingStatusDetail;
|
||||
* The device ID of physical devices has to be configured in the thing configuration.
|
||||
* <p>
|
||||
* Examples for physical device IDs are:
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
* hdm:Cameras:d20354de-44b5-3acc-924c-24c98d59da42
|
||||
* hdm:ZigBee:000d6f0016d1cdae
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* @author Stefan Kästle - Initial contribution
|
||||
* @author Christian Oeing - refactorings of e.g. server registration
|
||||
* @author David Pace - Handler abstraction
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class BoschSHCDeviceHandler extends BoschSHCHandler {
|
||||
public abstract class BoschSHCDeviceHandler extends BoschSHCHandler {
|
||||
|
||||
/**
|
||||
* Bosch SHC configuration loaded from openHAB configuration.
|
||||
@ -85,6 +85,7 @@ public class BoschSHCDeviceHandler extends BoschSHCHandler {
|
||||
*
|
||||
* @return Unique id of the Bosch device.
|
||||
*/
|
||||
@Override
|
||||
public @Nullable String getBoschID() {
|
||||
if (config != null) {
|
||||
return config.id;
|
||||
|
@ -100,14 +100,14 @@ public abstract class BoschSHCHandler extends BaseThingHandler {
|
||||
* Returns the unique id of the Bosch device or service.
|
||||
* <p>
|
||||
* For physical devices, the ID looks like
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
* hdm:Cameras:d20354de-44b5-3acc-924c-24c98d59da42
|
||||
* hdm:ZigBee:000d6f0016d1c087
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* For virtual devices / services, static IDs like the following are used:
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
* ventilationService
|
||||
* smokeDetectionSystem
|
||||
@ -241,8 +241,29 @@ public abstract class BoschSHCHandler extends BaseThingHandler {
|
||||
protected <TService extends BoschSHCService<TState>, TState extends BoschSHCServiceState> TService createService(
|
||||
Supplier<TService> newService, Consumer<TState> stateUpdateListener, Collection<String> affectedChannels)
|
||||
throws BoschSHCException {
|
||||
return createService(newService, stateUpdateListener, affectedChannels, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and registers a new service for this device.
|
||||
*
|
||||
* @param <TService> Type of service.
|
||||
* @param <TState> Type of service state.
|
||||
* @param newService Supplier function to create a new instance of the service.
|
||||
* @param stateUpdateListener Function to call when a state update was received
|
||||
* from the device.
|
||||
* @param affectedChannels Channels which are affected by the state of this
|
||||
* service.
|
||||
* @param shouldFetchInitialState indicates whether the initial state should be actively requested from the device
|
||||
* or service. Useful if state updates are not included in long poll results.
|
||||
* @return Instance of registered service.
|
||||
* @throws BoschSHCException
|
||||
*/
|
||||
protected <TService extends BoschSHCService<TState>, TState extends BoschSHCServiceState> TService createService(
|
||||
Supplier<TService> newService, Consumer<TState> stateUpdateListener, Collection<String> affectedChannels,
|
||||
boolean shouldFetchInitialState) throws BoschSHCException {
|
||||
TService service = newService.get();
|
||||
this.registerService(service, stateUpdateListener, affectedChannels);
|
||||
this.registerService(service, stateUpdateListener, affectedChannels, shouldFetchInitialState);
|
||||
return service;
|
||||
}
|
||||
|
||||
@ -296,7 +317,7 @@ public abstract class BoschSHCHandler extends BaseThingHandler {
|
||||
/**
|
||||
* Actively requests the initial state for the given service. This is required if long poll results do not contain
|
||||
* status updates for the given service.
|
||||
*
|
||||
*
|
||||
* @param <TService> Type of the service for which the state should be obtained
|
||||
* @param <TState> Type of the objects to serialize and deserialize the service state
|
||||
* @param service Service for which the state should be requested
|
||||
@ -325,7 +346,7 @@ public abstract class BoschSHCHandler extends BaseThingHandler {
|
||||
* Registers a write-only service that does not receive states from the bridge.
|
||||
* <p>
|
||||
* Examples for such services are the actions of the intrusion detection service.
|
||||
*
|
||||
*
|
||||
* @param <TService> Type of service.
|
||||
* @param service Service to register.
|
||||
* @throws BoschSHCException If no device ID is set.
|
||||
@ -340,7 +361,7 @@ public abstract class BoschSHCHandler extends BaseThingHandler {
|
||||
|
||||
/**
|
||||
* Verifies that a Bosch device or service ID is set and throws an exception if this is not the case.
|
||||
*
|
||||
*
|
||||
* @return the Bosch ID, if present
|
||||
* @throws BoschSHCException if no Bosch ID is set
|
||||
*/
|
||||
@ -404,7 +425,7 @@ public abstract class BoschSHCHandler extends BaseThingHandler {
|
||||
/**
|
||||
* Requests a service to refresh its state.
|
||||
* Sets the device offline if request fails.
|
||||
*
|
||||
*
|
||||
* @param <TService> Type of service.
|
||||
* @param <TState> Type of service state.
|
||||
* @param service Service to refresh state for.
|
||||
@ -438,7 +459,7 @@ public abstract class BoschSHCHandler extends BaseThingHandler {
|
||||
|
||||
/**
|
||||
* Sends a HTTP POST request with empty body.
|
||||
*
|
||||
*
|
||||
* @param <TService> Type of service.
|
||||
* @param service Service implementing the action
|
||||
*/
|
||||
@ -457,7 +478,7 @@ public abstract class BoschSHCHandler extends BaseThingHandler {
|
||||
|
||||
/**
|
||||
* Sends a HTTP POST request with the given request body.
|
||||
*
|
||||
*
|
||||
* @param <TService> Type of service.
|
||||
* @param <TState> Type of the request to be sent.
|
||||
* @param service Service implementing the action
|
||||
|
@ -26,6 +26,7 @@ import org.openhab.binding.boschshc.internal.devices.climatecontrol.ClimateContr
|
||||
import org.openhab.binding.boschshc.internal.devices.intrusion.IntrusionDetectionHandler;
|
||||
import org.openhab.binding.boschshc.internal.devices.lightcontrol.LightControlHandler;
|
||||
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.thermostat.ThermostatHandler;
|
||||
import org.openhab.binding.boschshc.internal.devices.twinguard.TwinguardHandler;
|
||||
@ -47,7 +48,7 @@ import org.osgi.service.component.annotations.Component;
|
||||
* @author Stefan Kästle - Initial contribution
|
||||
* @author Christian Oeing - Added Shutter Control and ThermostatHandler; refactored handler mapping
|
||||
* @author Christian Oeing - Added WallThermostatHandler
|
||||
* @author David Pace - Added cameras and intrusion detection system
|
||||
* @author David Pace - Added cameras, intrusion detection system and smart plugs
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(configurationPid = "binding.boschshc", service = ThingHandlerFactory.class)
|
||||
@ -75,7 +76,8 @@ public class BoschSHCHandlerFactory extends BaseThingHandlerFactory {
|
||||
new ThingTypeHandlerMapping(THING_TYPE_WALL_THERMOSTAT, WallThermostatHandler::new),
|
||||
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_INTRUSION_DETECTION_SYSTEM, IntrusionDetectionHandler::new),
|
||||
new ThingTypeHandlerMapping(THING_TYPE_SMART_PLUG_COMPACT, PlugHandler::new));
|
||||
|
||||
@Override
|
||||
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
|
||||
|
@ -12,28 +12,9 @@
|
||||
*/
|
||||
package org.openhab.binding.boschshc.internal.devices.lightcontrol;
|
||||
|
||||
import static org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.measure.quantity.Energy;
|
||||
import javax.measure.quantity.Power;
|
||||
|
||||
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.powermeter.PowerMeterService;
|
||||
import org.openhab.binding.boschshc.internal.services.powermeter.dto.PowerMeterServiceState;
|
||||
import org.openhab.binding.boschshc.internal.services.powerswitch.PowerSwitchService;
|
||||
import org.openhab.binding.boschshc.internal.services.powerswitch.PowerSwitchState;
|
||||
import org.openhab.binding.boschshc.internal.services.powerswitch.dto.PowerSwitchServiceState;
|
||||
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.thing.ChannelUID;
|
||||
import org.openhab.binding.boschshc.internal.devices.AbstractPowerSwitchHandler;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.State;
|
||||
|
||||
/**
|
||||
* A simple light control.
|
||||
@ -41,61 +22,9 @@ import org.openhab.core.types.State;
|
||||
* @author Stefan Kästle - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class LightControlHandler extends BoschSHCDeviceHandler {
|
||||
|
||||
private final PowerSwitchService powerSwitchService;
|
||||
public class LightControlHandler extends AbstractPowerSwitchHandler {
|
||||
|
||||
public LightControlHandler(Thing thing) {
|
||||
super(thing);
|
||||
this.powerSwitchService = new PowerSwitchService();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initializeServices() throws BoschSHCException {
|
||||
super.initializeServices();
|
||||
|
||||
this.registerService(this.powerSwitchService, this::updateChannels, List.of(CHANNEL_POWER_SWITCH));
|
||||
this.createService(PowerMeterService::new, this::updateChannels,
|
||||
List.of(CHANNEL_POWER_CONSUMPTION, CHANNEL_ENERGY_CONSUMPTION));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
super.handleCommand(channelUID, command);
|
||||
|
||||
switch (channelUID.getId()) {
|
||||
case CHANNEL_POWER_SWITCH:
|
||||
if (command instanceof OnOffType) {
|
||||
updatePowerSwitchState((OnOffType) command);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the channels which are linked to the {@link PowerMeterService} of the device.
|
||||
*
|
||||
* @param state Current state of {@link PowerMeterService}.
|
||||
*/
|
||||
private void updateChannels(PowerMeterServiceState state) {
|
||||
super.updateState(CHANNEL_POWER_CONSUMPTION, new QuantityType<Power>(state.powerConsumption, Units.WATT));
|
||||
super.updateState(CHANNEL_ENERGY_CONSUMPTION,
|
||||
new QuantityType<Energy>(state.energyConsumption, Units.WATT_HOUR));
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the channels which are linked to the {@link PowerSwitchService} of the device.
|
||||
*
|
||||
* @param state Current state of {@link PowerSwitchService}.
|
||||
*/
|
||||
private void updateChannels(PowerSwitchServiceState state) {
|
||||
State powerState = OnOffType.from(state.switchState.toString());
|
||||
super.updateState(CHANNEL_POWER_SWITCH, powerState);
|
||||
}
|
||||
|
||||
private void updatePowerSwitchState(OnOffType command) {
|
||||
PowerSwitchServiceState state = new PowerSwitchServiceState();
|
||||
state.switchState = PowerSwitchState.valueOf(command.toFullString());
|
||||
this.updateServiceState(this.powerSwitchService, state);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,30 @@
|
||||
/**
|
||||
* 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.plug;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.boschshc.internal.devices.AbstractPowerSwitchHandler;
|
||||
import org.openhab.core.thing.Thing;
|
||||
|
||||
/**
|
||||
* A handler for compact smart plugs.
|
||||
*
|
||||
* @author David Pace - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class PlugHandler extends AbstractPowerSwitchHandler {
|
||||
|
||||
public PlugHandler(Thing thing) {
|
||||
super(thing);
|
||||
}
|
||||
}
|
@ -30,6 +30,24 @@
|
||||
|
||||
</thing-type>
|
||||
|
||||
<thing-type id="smart-plug-compact">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="shc"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>Compact Smart Plug</label>
|
||||
<description>A compact smart plug with energy monitoring capabilities.</description>
|
||||
|
||||
<channels>
|
||||
<channel id="power-switch" typeId="system.power"/>
|
||||
<channel id="power-consumption" typeId="power-consumption"/>
|
||||
<channel id="energy-consumption" typeId="energy-consumption"/>
|
||||
</channels>
|
||||
|
||||
<config-description-ref uri="thing-type:boschshc:device"/>
|
||||
|
||||
</thing-type>
|
||||
|
||||
<thing-type id="twinguard">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="shc"/>
|
||||
|
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
|
||||
/**
|
||||
* Abstract unit test implementation for device handlers.
|
||||
*
|
||||
* @author David Pace - Initial contribution
|
||||
*
|
||||
* @param <T> type of the device handler to be tested
|
||||
*/
|
||||
public abstract class AbstractBoschSHCDeviceHandlerTest<T extends BoschSHCDeviceHandler>
|
||||
extends AbstractSHCHandlerTest<T> {
|
||||
|
||||
@Override
|
||||
protected Configuration getConfiguration() {
|
||||
Configuration configuration = super.getConfiguration();
|
||||
configuration.put("id", getDeviceID());
|
||||
return configuration;
|
||||
}
|
||||
|
||||
protected abstract String getDeviceID();
|
||||
}
|
@ -0,0 +1,118 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
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 javax.measure.quantity.Energy;
|
||||
import javax.measure.quantity.Power;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.openhab.binding.boschshc.internal.exceptions.BoschSHCException;
|
||||
import org.openhab.binding.boschshc.internal.services.powerswitch.PowerSwitchState;
|
||||
import org.openhab.binding.boschshc.internal.services.powerswitch.dto.PowerSwitchServiceState;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Abstract unit test implementation for devices with power switches and energy monitoring.
|
||||
*
|
||||
* @author David Pace - Initial contribution
|
||||
*
|
||||
* @param <T> type of the handler to be tested
|
||||
*/
|
||||
public abstract class AbstractPowerSwitchHandlerTest<T extends AbstractPowerSwitchHandler>
|
||||
extends AbstractBoschSHCDeviceHandlerTest<T> {
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<PowerSwitchServiceState> serviceStateCaptor;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<QuantityType<Power>> powerCaptor;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<QuantityType<Energy>> energyCaptor;
|
||||
|
||||
@Test
|
||||
public void testHandleCommand()
|
||||
throws InterruptedException, TimeoutException, ExecutionException, BoschSHCException {
|
||||
|
||||
when(getThing().getUID()).thenReturn(new ThingUID("boschshc", "abcdef"));
|
||||
|
||||
getFixture().handleCommand(new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_POWER_SWITCH),
|
||||
OnOffType.ON);
|
||||
verify(getBridgeHandler()).putState(eq(getDeviceID()), eq("PowerSwitch"), serviceStateCaptor.capture());
|
||||
PowerSwitchServiceState state = serviceStateCaptor.getValue();
|
||||
assertSame(PowerSwitchState.ON, state.switchState);
|
||||
|
||||
getFixture().handleCommand(new ChannelUID(new ThingUID(getThingTypeUID(), "abcdef"),
|
||||
BoschSHCBindingConstants.CHANNEL_POWER_SWITCH), OnOffType.OFF);
|
||||
verify(getBridgeHandler(), times(2)).putState(eq(getDeviceID()), eq("PowerSwitch"),
|
||||
serviceStateCaptor.capture());
|
||||
state = serviceStateCaptor.getValue();
|
||||
assertSame(PowerSwitchState.OFF, state.switchState);
|
||||
}
|
||||
|
||||
protected abstract ThingTypeUID getThingTypeUID();
|
||||
|
||||
@Test
|
||||
public void testUpdateChannel_PowerSwitchState() {
|
||||
when(getThing().getUID()).thenReturn(new ThingUID("boschshc", "abcdef"));
|
||||
|
||||
JsonElement jsonObject = JsonParser
|
||||
.parseString("{\n" + " \"@type\": \"powerSwitchState\",\n" + " \"switchState\": \"ON\"\n" + "}");
|
||||
getFixture().processUpdate("PowerSwitch", jsonObject);
|
||||
verify(getCallback()).stateUpdated(
|
||||
new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_POWER_SWITCH), OnOffType.ON);
|
||||
|
||||
jsonObject = JsonParser
|
||||
.parseString("{\n" + " \"@type\": \"powerSwitchState\",\n" + " \"switchState\": \"OFF\"\n" + "}");
|
||||
getFixture().processUpdate("PowerSwitch", jsonObject);
|
||||
verify(getCallback()).stateUpdated(
|
||||
new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_POWER_SWITCH), OnOffType.OFF);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateChannel_PowerMeterServiceState() {
|
||||
when(getThing().getUID()).thenReturn(new ThingUID("boschshc", "abcdef"));
|
||||
|
||||
JsonElement jsonObject = JsonParser.parseString("{\n" + " \"@type\": \"powerMeterState\",\n"
|
||||
+ " \"powerConsumption\": \"23\",\n" + " \"energyConsumption\": 42\n" + "}");
|
||||
getFixture().processUpdate("PowerMeter", jsonObject);
|
||||
|
||||
verify(getCallback()).stateUpdated(
|
||||
eq(new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_POWER_CONSUMPTION)),
|
||||
powerCaptor.capture());
|
||||
QuantityType<Power> powerValue = powerCaptor.getValue();
|
||||
assertEquals(23, powerValue.intValue());
|
||||
|
||||
verify(getCallback()).stateUpdated(
|
||||
eq(new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_ENERGY_CONSUMPTION)),
|
||||
energyCaptor.capture());
|
||||
QuantityType<Energy> energyValue = energyCaptor.getValue();
|
||||
assertEquals(42, energyValue.intValue());
|
||||
}
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.openhab.binding.boschshc.internal.devices.bridge.BridgeHandler;
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.ThingStatusInfo;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
import org.openhab.core.thing.binding.ThingHandlerCallback;
|
||||
|
||||
/**
|
||||
* Abstract unit test implementation for all types of handlers.
|
||||
*
|
||||
* @author David Pace - Initial contribution
|
||||
*
|
||||
* @param <T> type of the handler to be tested
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public abstract class AbstractSHCHandlerTest<T extends BoschSHCHandler> {
|
||||
|
||||
private T fixture;
|
||||
|
||||
@Mock
|
||||
private Thing thing;
|
||||
|
||||
@Mock
|
||||
private Bridge bridge;
|
||||
|
||||
@Mock
|
||||
private BridgeHandler bridgeHandler;
|
||||
|
||||
@Mock
|
||||
private ThingHandlerCallback callback;
|
||||
|
||||
@BeforeEach
|
||||
public void beforeEach() {
|
||||
fixture = createFixture();
|
||||
when(thing.getBridgeUID()).thenReturn(new ThingUID("boschshc", "shc", "myBridgeUID"));
|
||||
when(callback.getBridge(any())).thenReturn(bridge);
|
||||
fixture.setCallback(callback);
|
||||
when(bridge.getHandler()).thenReturn(bridgeHandler);
|
||||
when(thing.getConfiguration()).thenReturn(getConfiguration());
|
||||
|
||||
fixture.initialize();
|
||||
}
|
||||
|
||||
protected abstract T createFixture();
|
||||
|
||||
protected T getFixture() {
|
||||
return fixture;
|
||||
}
|
||||
|
||||
protected Configuration getConfiguration() {
|
||||
return new Configuration();
|
||||
}
|
||||
|
||||
protected Thing getThing() {
|
||||
return thing;
|
||||
}
|
||||
|
||||
public BridgeHandler getBridgeHandler() {
|
||||
return bridgeHandler;
|
||||
}
|
||||
|
||||
public ThingHandlerCallback getCallback() {
|
||||
return callback;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitialize() {
|
||||
ThingStatusInfo expectedStatusInfo = new ThingStatusInfo(ThingStatus.ONLINE, ThingStatusDetail.NONE, null);
|
||||
verify(callback).statusUpdated(same(thing), eq(expectedStatusInfo));
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/**
|
||||
* 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.lightcontrol;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.boschshc.internal.devices.AbstractPowerSwitchHandlerTest;
|
||||
import org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link LightControlHandler}.
|
||||
*
|
||||
* @author David Pace - Initial contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class LightControlHandlerTest extends AbstractPowerSwitchHandlerTest<LightControlHandler> {
|
||||
|
||||
@Override
|
||||
protected ThingTypeUID getThingTypeUID() {
|
||||
return BoschSHCBindingConstants.THING_TYPE_INWALL_SWITCH;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDeviceID() {
|
||||
return "hdm:ZigBee:50325ffffe61d7b9c6e";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LightControlHandler createFixture() {
|
||||
return new LightControlHandler(getThing());
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/**
|
||||
* 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.plug;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.boschshc.internal.devices.AbstractPowerSwitchHandlerTest;
|
||||
import org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link PlugHandler}.
|
||||
*
|
||||
* @author David Pace - Initial contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class PlugHandlerTest extends AbstractPowerSwitchHandlerTest<PlugHandler> {
|
||||
|
||||
@Override
|
||||
protected PlugHandler createFixture() {
|
||||
return new PlugHandler(getThing());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDeviceID() {
|
||||
return "hdm:ZigBee:50325ffffe61d7b9c6e";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ThingTypeUID getThingTypeUID() {
|
||||
return BoschSHCBindingConstants.THING_TYPE_SMART_PLUG_COMPACT;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user