From 584f6371260afa0d643a8c497e10089674c1624c Mon Sep 17 00:00:00 2001 From: Gerd Zanker Date: Sat, 10 Dec 2022 11:18:13 +0100 Subject: [PATCH] [boschshc] Support smoke detector (#13760) * Add smoke detector service and add it to twinguard handler * Add handler for smoke detector * Support for smoke detector added smoke detector device with SmokeDetectorCheckService added SmokeDetectorCheckService to TwinguardHandler added tests for smoke detector code updated smoke detector code to latest boschshc version after cherry-picks of initial code from Christian Oeing * re-generate i18n file, refactoring of smoke detector code to use abstract base classes * Fix typos * Add unit test for PlayPauseType commands * Add unit test for SmokeDetectorCheckState * Re-add null annotation * Fix warning Signed-off-by: Christian Oeing Signed-off-by: Gerd Zanker Signed-off-by: David Pace --- .../org.openhab.binding.boschshc/README.md | 13 ++ .../AbstractBatteryPoweredDeviceHandler.java | 2 +- .../devices/AbstractSmokeDetectorHandler.java | 65 ++++++++++ .../devices/BoschSHCBindingConstants.java | 3 + .../devices/BoschSHCHandlerFactory.java | 5 +- .../smokedetector/SmokeDetectorHandler.java | 31 +++++ .../devices/twinguard/TwinguardHandler.java | 6 +- .../SmokeDetectorCheckService.java | 55 +++++++++ .../SmokeDetectorCheckState.java | 37 ++++++ .../dto/SmokeDetectorCheckServiceState.java | 34 ++++++ .../resources/OH-INF/i18n/boschshc.properties | 8 ++ .../resources/OH-INF/thing/thing-types.xml | 36 ++++++ .../AbstractSmokeDetectorHandlerTest.java | 115 ++++++++++++++++++ .../SmokeDetectorHandlerTest.java | 43 +++++++ .../twinguard/TwinguardHandlerTest.java | 4 +- .../SmokeDetectorCheckStateTest.java | 37 ++++++ 16 files changed, 488 insertions(+), 6 deletions(-) create mode 100644 bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/AbstractSmokeDetectorHandler.java create mode 100644 bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/smokedetector/SmokeDetectorHandler.java create mode 100644 bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/services/smokedetectorcheck/SmokeDetectorCheckService.java create mode 100644 bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/services/smokedetectorcheck/SmokeDetectorCheckState.java create mode 100644 bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/services/smokedetectorcheck/dto/SmokeDetectorCheckServiceState.java create mode 100644 bundles/org.openhab.binding.boschshc/src/test/java/org/openhab/binding/boschshc/internal/devices/AbstractSmokeDetectorHandlerTest.java create mode 100644 bundles/org.openhab.binding.boschshc/src/test/java/org/openhab/binding/boschshc/internal/devices/smokedetector/SmokeDetectorHandlerTest.java create mode 100644 bundles/org.openhab.binding.boschshc/src/test/java/org/openhab/binding/boschshc/internal/services/smokedetectorcheck/SmokeDetectorCheckStateTest.java diff --git a/bundles/org.openhab.binding.boschshc/README.md b/bundles/org.openhab.binding.boschshc/README.md index f93813689..cd2fe0b83 100644 --- a/bundles/org.openhab.binding.boschshc/README.md +++ b/bundles/org.openhab.binding.boschshc/README.md @@ -17,6 +17,7 @@ Binding for the Bosch Smart Home. - [Security Camera Eyes](#security-camera-eyes) - [Intrusion Detection System](#intrusion-detection-system) - [Smart Bulb](#smart-bulb) + - [Smoke Detector](#smoke-detector) - [Limitations](#limitations) - [Discovery](#discovery) - [Bridge Configuration](#bridge-configuration) @@ -68,6 +69,7 @@ The Twinguard smoke detector warns you in case of fire and constantly monitors t | combined-rating | String | ☐ | Combined rating of the air quality. | | battery-level | Number | ☐ | Current battery level percentage as integer number. Bosch-specific battery levels are mapped to numbers as follows: `OK`: 100, `LOW_BATTERY`: 10, `CRITICAL_LOW`: 1, `CRITICALLY_LOW_BATTERY`: 1, `NOT_AVAILABLE`: `UNDEF`. | | low-battery | Switch | ☐ | Indicates whether the battery is low (`ON`) or OK (`OFF`). | +| smoke-check | String | ☑ | State of the smoke check. Also used to request a new smoke check. | ### Door/Window Contact @@ -191,6 +193,17 @@ A smart bulb connected to the bridge via Zigbee such as a Ledvance Smart+ bulb. | brightness | Dimmer | ☑ | Regulates the brightness on a percentage scale from 0 to 100%. | | color | Color | ☑ | The color of the emitted light. | +### Smoke detector + +The smoke detector warns you in case of fire. + +**Thing Type ID**: `smoke-detector` + +| Channel Type ID | Item Type | Writable | Description | +| ------------------ | -------------------- | :------: | ------------------------------------------------------------------------------------------------- | +| smoke-check | String | ☑ | State of the smoke check. Also used to request a new smoke check. | + + ## Limitations - Discovery of Things diff --git a/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/AbstractBatteryPoweredDeviceHandler.java b/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/AbstractBatteryPoweredDeviceHandler.java index 4e87b1084..56729066c 100644 --- a/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/AbstractBatteryPoweredDeviceHandler.java +++ b/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/AbstractBatteryPoweredDeviceHandler.java @@ -30,7 +30,7 @@ import org.openhab.core.thing.Thing; * */ @NonNullByDefault -public class AbstractBatteryPoweredDeviceHandler extends BoschSHCDeviceHandler { +public abstract class AbstractBatteryPoweredDeviceHandler extends BoschSHCDeviceHandler { /** * Service to monitor the battery level of the device diff --git a/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/AbstractSmokeDetectorHandler.java b/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/AbstractSmokeDetectorHandler.java new file mode 100644 index 000000000..e51067c5d --- /dev/null +++ b/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/AbstractSmokeDetectorHandler.java @@ -0,0 +1,65 @@ +/** + * 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.CHANNEL_SMOKE_CHECK; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.binding.boschshc.internal.exceptions.BoschSHCException; +import org.openhab.binding.boschshc.internal.services.smokedetectorcheck.SmokeDetectorCheckService; +import org.openhab.binding.boschshc.internal.services.smokedetectorcheck.dto.SmokeDetectorCheckServiceState; +import org.openhab.core.library.types.StringType; +import org.openhab.core.thing.ChannelUID; +import org.openhab.core.thing.Thing; +import org.openhab.core.types.Command; + +/** + * Abstract handler implementation for devices with a smoke detector. + * + * @author Christian Oeing - Initial contribution + * @author Gerd Zanker - AbstractSmokeDetectorHandler refactoring for reuse + */ +@NonNullByDefault +public abstract class AbstractSmokeDetectorHandler extends AbstractBatteryPoweredDeviceHandler { + + private SmokeDetectorCheckService smokeDetectorCheckService; + + public AbstractSmokeDetectorHandler(Thing thing) { + super(thing); + this.smokeDetectorCheckService = new SmokeDetectorCheckService(); + } + + @Override + protected void initializeServices() throws BoschSHCException { + super.initializeServices(); + + this.registerService(smokeDetectorCheckService, this::updateChannels, List.of(CHANNEL_SMOKE_CHECK)); + } + + @Override + public void handleCommand(ChannelUID channelUID, Command command) { + super.handleCommand(channelUID, command); + + switch (channelUID.getId()) { + case CHANNEL_SMOKE_CHECK: + this.handleServiceCommand(this.smokeDetectorCheckService, command); + break; + } + } + + private void updateChannels(SmokeDetectorCheckServiceState state) { + updateState(CHANNEL_SMOKE_CHECK, new StringType(state.value.toString())); + } +} diff --git a/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/BoschSHCBindingConstants.java b/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/BoschSHCBindingConstants.java index 4425b7690..9f62e8cce 100644 --- a/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/BoschSHCBindingConstants.java +++ b/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/BoschSHCBindingConstants.java @@ -23,6 +23,7 @@ import org.openhab.core.thing.ThingTypeUID; * @author Christian Oeing - added Shutter Control, ThermostatHandler * @author Christian Oeing - Added WallThermostatHandler * @author David Pace - Added cameras, intrusion detection system, smart plugs, battery state support and smart bulbs + * @author Christian Oeing - Added smoke detector */ @NonNullByDefault public class BoschSHCBindingConstants { @@ -46,6 +47,7 @@ public class BoschSHCBindingConstants { "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"); + public static final ThingTypeUID THING_TYPE_SMOKE_DETECTOR = new ThingTypeUID(BINDING_ID, "smoke-detector"); // List of all Channel IDs // Auto-generated from thing-types.xml via script, don't modify @@ -79,6 +81,7 @@ public class BoschSHCBindingConstants { public static final String CHANNEL_LOW_BATTERY = "low-battery"; public static final String CHANNEL_COLOR = "color"; public static final String CHANNEL_BRIGHTNESS = "brightness"; + public static final String CHANNEL_SMOKE_CHECK = "smoke-check"; // static device/service names public static final String SERVICE_INTRUSION_DETECTION = "intrusionDetectionSystem"; diff --git a/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/BoschSHCHandlerFactory.java b/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/BoschSHCHandlerFactory.java index 1de772882..01b75eab7 100644 --- a/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/BoschSHCHandlerFactory.java +++ b/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/BoschSHCHandlerFactory.java @@ -29,6 +29,7 @@ import org.openhab.binding.boschshc.internal.devices.motiondetector.MotionDetect 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.smokedetector.SmokeDetectorHandler; 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; @@ -50,6 +51,7 @@ import org.osgi.service.component.annotations.Component; * @author Christian Oeing - Added Shutter Control and ThermostatHandler; refactored handler mapping * @author Christian Oeing - Added WallThermostatHandler * @author David Pace - Added cameras, intrusion detection system and smart plugs + * @author Christian Oeing - Added smoke detector */ @NonNullByDefault @Component(configurationPid = "binding.boschshc", service = ThingHandlerFactory.class) @@ -79,7 +81,8 @@ public class BoschSHCHandlerFactory extends BaseThingHandlerFactory { 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_BULB, SmartBulbHandler::new)); + new ThingTypeHandlerMapping(THING_TYPE_SMART_BULB, SmartBulbHandler::new), + new ThingTypeHandlerMapping(THING_TYPE_SMOKE_DETECTOR, SmokeDetectorHandler::new)); @Override public boolean supportsThingType(ThingTypeUID thingTypeUID) { diff --git a/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/smokedetector/SmokeDetectorHandler.java b/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/smokedetector/SmokeDetectorHandler.java new file mode 100644 index 000000000..fc38527ad --- /dev/null +++ b/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/smokedetector/SmokeDetectorHandler.java @@ -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.devices.smokedetector; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.binding.boschshc.internal.devices.AbstractSmokeDetectorHandler; +import org.openhab.core.thing.Thing; + +/** + * The smoke detector warns you in case of fire. + * + * @author Christian Oeing - Initial contribution + * @author Gerd Zanker - AbstractSmokeDetectorHandler refactoring for reuse + */ +@NonNullByDefault +public class SmokeDetectorHandler extends AbstractSmokeDetectorHandler { + + public SmokeDetectorHandler(Thing thing) { + super(thing); + } +} diff --git a/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/twinguard/TwinguardHandler.java b/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/twinguard/TwinguardHandler.java index a4b0f3ac8..bcb01292a 100644 --- a/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/twinguard/TwinguardHandler.java +++ b/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/twinguard/TwinguardHandler.java @@ -20,7 +20,7 @@ import javax.measure.quantity.Dimensionless; import javax.measure.quantity.Temperature; import org.eclipse.jdt.annotation.NonNullByDefault; -import org.openhab.binding.boschshc.internal.devices.AbstractBatteryPoweredDeviceHandler; +import org.openhab.binding.boschshc.internal.devices.AbstractSmokeDetectorHandler; import org.openhab.binding.boschshc.internal.exceptions.BoschSHCException; import org.openhab.binding.boschshc.internal.services.airqualitylevel.AirQualityLevelService; import org.openhab.binding.boschshc.internal.services.airqualitylevel.dto.AirQualityLevelServiceState; @@ -35,9 +35,11 @@ import org.openhab.core.thing.Thing; * * @author Stefan Kästle - Initial contribution * @author Christian Oeing - Use service instead of custom logic + * @author Christian Oeing - Add smoke detector service + * @author Gerd Zanker - AbstractSmokeDetectorHandler refactoring for reuse */ @NonNullByDefault -public class TwinguardHandler extends AbstractBatteryPoweredDeviceHandler { +public class TwinguardHandler extends AbstractSmokeDetectorHandler { public TwinguardHandler(Thing thing) { super(thing); diff --git a/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/services/smokedetectorcheck/SmokeDetectorCheckService.java b/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/services/smokedetectorcheck/SmokeDetectorCheckService.java new file mode 100644 index 000000000..8fa26d90b --- /dev/null +++ b/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/services/smokedetectorcheck/SmokeDetectorCheckService.java @@ -0,0 +1,55 @@ +/** + * 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.smokedetectorcheck; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.binding.boschshc.internal.exceptions.BoschSHCException; +import org.openhab.binding.boschshc.internal.services.BoschSHCService; +import org.openhab.binding.boschshc.internal.services.smokedetectorcheck.dto.SmokeDetectorCheckServiceState; +import org.openhab.core.library.types.PlayPauseType; +import org.openhab.core.library.types.StringType; +import org.openhab.core.types.Command; + +/** + * Returns the result of the last smoke test and is used to request a new smoke test. + * + * @author Christian Oeing - Initial contribution + */ +@NonNullByDefault +public class SmokeDetectorCheckService extends BoschSHCService { + + public SmokeDetectorCheckService() { + super("SmokeDetectorCheck", SmokeDetectorCheckServiceState.class); + } + + @Override + public SmokeDetectorCheckServiceState handleCommand(Command command) throws BoschSHCException { + if (command instanceof StringType) { + var stringCommand = (StringType) command; + var state = new SmokeDetectorCheckServiceState(); + state.value = SmokeDetectorCheckState.from(stringCommand.toString()); + return state; + } + + if (command instanceof PlayPauseType) { + var playPauseCommand = (PlayPauseType) command; + if (playPauseCommand.equals(PlayPauseType.PLAY)) { + var state = new SmokeDetectorCheckServiceState(); + state.value = SmokeDetectorCheckState.SMOKE_TEST_REQUESTED; + return state; + } + } + + return super.handleCommand(command); + } +} diff --git a/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/services/smokedetectorcheck/SmokeDetectorCheckState.java b/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/services/smokedetectorcheck/SmokeDetectorCheckState.java new file mode 100644 index 000000000..4b6fab5cd --- /dev/null +++ b/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/services/smokedetectorcheck/SmokeDetectorCheckState.java @@ -0,0 +1,37 @@ +/** + * 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.smokedetectorcheck; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * Possible states for a smoke detector. + * + * @author Christian Oeing - Initial contribution + */ +@NonNullByDefault +public enum SmokeDetectorCheckState { + NONE, + SMOKE_TEST_REQUESTED, + SMOKE_TEST_OK, + SMOKE_TEST_FAILED; + + public static SmokeDetectorCheckState from(String stateString) { + + try { + return SmokeDetectorCheckState.valueOf(stateString); + } catch (Exception a) { + return NONE; + } + } +} diff --git a/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/services/smokedetectorcheck/dto/SmokeDetectorCheckServiceState.java b/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/services/smokedetectorcheck/dto/SmokeDetectorCheckServiceState.java new file mode 100644 index 000000000..6ae80cb7a --- /dev/null +++ b/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/services/smokedetectorcheck/dto/SmokeDetectorCheckServiceState.java @@ -0,0 +1,34 @@ +/** + * 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.smokedetectorcheck.dto; + +import org.openhab.binding.boschshc.internal.services.dto.BoschSHCServiceState; +import org.openhab.binding.boschshc.internal.services.smokedetectorcheck.SmokeDetectorCheckState; + +/** + * State for {@link org.openhab.binding.boschshc.internal.services.smokedetectorcheck.SmokeDetectorCheckService} + * to get the current smoke test state and request a new smoke test. + * + * @author Christian Oeing - Initial contribution + */ +public class SmokeDetectorCheckServiceState extends BoschSHCServiceState { + + public SmokeDetectorCheckServiceState() { + super("smokeDetectorCheckState"); + } + + /** + * Current state. + */ + public SmokeDetectorCheckState value; +} diff --git a/bundles/org.openhab.binding.boschshc/src/main/resources/OH-INF/i18n/boschshc.properties b/bundles/org.openhab.binding.boschshc/src/main/resources/OH-INF/i18n/boschshc.properties index a634c7e3e..b6d037df3 100644 --- a/bundles/org.openhab.binding.boschshc/src/main/resources/OH-INF/i18n/boschshc.properties +++ b/bundles/org.openhab.binding.boschshc/src/main/resources/OH-INF/i18n/boschshc.properties @@ -25,6 +25,8 @@ 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.smoke-detector.label = Smoke Detector +thing-type.boschshc.smoke-detector.description = The smoke detector warns you in case of fire. thing-type.boschshc.thermostat.label = Thermostat thing-type.boschshc.thermostat.description = Radiator thermostat thing-type.boschshc.twinguard.label = Twinguard @@ -105,6 +107,12 @@ 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.smoke-check.label = Smoke Check State +channel-type.boschshc.smoke-check.description = State of last smoke detector check. +channel-type.boschshc.smoke-check.state.option.NONE = None +channel-type.boschshc.smoke-check.state.option.SMOKE_TEST_REQUESTED = Test requested +channel-type.boschshc.smoke-check.state.option.SMOKE_TEST_OK = Test successful +channel-type.boschshc.smoke-check.state.option.SMOKE_TEST_FAILED = Test failed 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 diff --git a/bundles/org.openhab.binding.boschshc/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.boschshc/src/main/resources/OH-INF/thing/thing-types.xml index ab84a6fea..17cd2baaf 100644 --- a/bundles/org.openhab.binding.boschshc/src/main/resources/OH-INF/thing/thing-types.xml +++ b/bundles/org.openhab.binding.boschshc/src/main/resources/OH-INF/thing/thing-types.xml @@ -12,6 +12,8 @@ + + @@ -67,6 +69,7 @@ + @@ -255,6 +258,25 @@ + + + + + + + The smoke detector warns you in case of fire. + + + + + + + + + + + + Switch @@ -430,6 +452,20 @@ + + String + + State of last smoke detector check. + + + + + + + + + + Contact diff --git a/bundles/org.openhab.binding.boschshc/src/test/java/org/openhab/binding/boschshc/internal/devices/AbstractSmokeDetectorHandlerTest.java b/bundles/org.openhab.binding.boschshc/src/test/java/org/openhab/binding/boschshc/internal/devices/AbstractSmokeDetectorHandlerTest.java new file mode 100644 index 000000000..9a6514a5a --- /dev/null +++ b/bundles/org.openhab.binding.boschshc/src/test/java/org/openhab/binding/boschshc/internal/devices/AbstractSmokeDetectorHandlerTest.java @@ -0,0 +1,115 @@ +/** + * 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.assertSame; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeoutException; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.openhab.binding.boschshc.internal.devices.smokedetector.SmokeDetectorHandler; +import org.openhab.binding.boschshc.internal.exceptions.BoschSHCException; +import org.openhab.binding.boschshc.internal.services.smokedetectorcheck.SmokeDetectorCheckState; +import org.openhab.binding.boschshc.internal.services.smokedetectorcheck.dto.SmokeDetectorCheckServiceState; +import org.openhab.core.library.types.PlayPauseType; +import org.openhab.core.library.types.StringType; +import org.openhab.core.thing.ChannelUID; + +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; + +/** + * Unit Tests for {@link SmokeDetectorHandler}. + * + * @author Gerd Zanker - Initial contribution + * + */ +@NonNullByDefault +public abstract class AbstractSmokeDetectorHandlerTest + extends AbstractBatteryPoweredDeviceHandlerTest { + + @Captor + private @NonNullByDefault({}) ArgumentCaptor smokeDetectorCheckStateCaptor; + + @Test + public void testHandleCommand() + throws InterruptedException, TimeoutException, ExecutionException, BoschSHCException { + + // valid commands with valid thing & channel + getFixture().handleCommand(new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_SMOKE_CHECK), + new StringType(SmokeDetectorCheckState.SMOKE_TEST_REQUESTED.toString())); + verify(getBridgeHandler()).putState(eq(getDeviceID()), eq("SmokeDetectorCheck"), + smokeDetectorCheckStateCaptor.capture()); + SmokeDetectorCheckServiceState state = smokeDetectorCheckStateCaptor.getValue(); + assertSame(SmokeDetectorCheckState.SMOKE_TEST_REQUESTED, state.value); + + getFixture().handleCommand(new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_SMOKE_CHECK), + new StringType(SmokeDetectorCheckState.NONE.toString())); + verify(getBridgeHandler(), times(2)).putState(eq(getDeviceID()), eq("SmokeDetectorCheck"), + smokeDetectorCheckStateCaptor.capture()); + state = smokeDetectorCheckStateCaptor.getValue(); + assertSame(SmokeDetectorCheckState.NONE, state.value); + + getFixture().handleCommand(new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_SMOKE_CHECK), + new StringType(SmokeDetectorCheckState.SMOKE_TEST_OK.toString())); + verify(getBridgeHandler(), times(3)).putState(eq(getDeviceID()), eq("SmokeDetectorCheck"), + smokeDetectorCheckStateCaptor.capture()); + state = smokeDetectorCheckStateCaptor.getValue(); + assertSame(SmokeDetectorCheckState.SMOKE_TEST_OK, state.value); + + getFixture().handleCommand(new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_SMOKE_CHECK), + new StringType(SmokeDetectorCheckState.SMOKE_TEST_FAILED.toString())); + verify(getBridgeHandler(), times(4)).putState(eq(getDeviceID()), eq("SmokeDetectorCheck"), + smokeDetectorCheckStateCaptor.capture()); + state = smokeDetectorCheckStateCaptor.getValue(); + assertSame(SmokeDetectorCheckState.SMOKE_TEST_FAILED, state.value); + } + + @Test + public void testHandleCommand_PlayPauseType() + throws InterruptedException, TimeoutException, ExecutionException, BoschSHCException { + + getFixture().handleCommand(new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_SMOKE_CHECK), + PlayPauseType.PLAY); + verify(getBridgeHandler()).putState(eq(getDeviceID()), eq("SmokeDetectorCheck"), + smokeDetectorCheckStateCaptor.capture()); + SmokeDetectorCheckServiceState state = smokeDetectorCheckStateCaptor.getValue(); + assertSame(SmokeDetectorCheckState.SMOKE_TEST_REQUESTED, state.value); + } + + @Test + public void testUpdateChannel_SmokeDetectorCheckServiceState_none() { + JsonElement jsonObject = JsonParser.parseString("{\"@type\":\"smokeDetectorCheckState\",\"value\":NONE}"); + getFixture().processUpdate("SmokeDetectorCheck", jsonObject); + verify(getCallback()).stateUpdated( + new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_SMOKE_CHECK), + new StringType("NONE")); + } + + @Test + public void testUpdateChannel_SmokeDetectorCheckServiceState_Requests() { + JsonElement jsonObject = JsonParser + .parseString("{\"@type\":\"smokeDetectorCheckState\",\"value\":SMOKE_TEST_REQUESTED}"); + getFixture().processUpdate("SmokeDetectorCheck", jsonObject); + verify(getCallback()).stateUpdated( + new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_SMOKE_CHECK), + new StringType("SMOKE_TEST_REQUESTED")); + } +} diff --git a/bundles/org.openhab.binding.boschshc/src/test/java/org/openhab/binding/boschshc/internal/devices/smokedetector/SmokeDetectorHandlerTest.java b/bundles/org.openhab.binding.boschshc/src/test/java/org/openhab/binding/boschshc/internal/devices/smokedetector/SmokeDetectorHandlerTest.java new file mode 100644 index 000000000..314a77ff2 --- /dev/null +++ b/bundles/org.openhab.binding.boschshc/src/test/java/org/openhab/binding/boschshc/internal/devices/smokedetector/SmokeDetectorHandlerTest.java @@ -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.smokedetector; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.binding.boschshc.internal.devices.AbstractSmokeDetectorHandlerTest; +import org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants; +import org.openhab.core.thing.ThingTypeUID; + +/** + * Unit Tests for {@link SmokeDetectorHandler}. + * + * @author Gerd Zanker - Initial contribution + * + */ +@NonNullByDefault +public class SmokeDetectorHandlerTest extends AbstractSmokeDetectorHandlerTest { + + @Override + protected SmokeDetectorHandler createFixture() { + return new SmokeDetectorHandler(getThing()); + } + + @Override + protected String getDeviceID() { + return "hdm:HomeMaticIP:3014F711A00004DBB85C1234"; + } + + @Override + protected ThingTypeUID getThingTypeUID() { + return BoschSHCBindingConstants.THING_TYPE_SMOKE_DETECTOR; + } +} diff --git a/bundles/org.openhab.binding.boschshc/src/test/java/org/openhab/binding/boschshc/internal/devices/twinguard/TwinguardHandlerTest.java b/bundles/org.openhab.binding.boschshc/src/test/java/org/openhab/binding/boschshc/internal/devices/twinguard/TwinguardHandlerTest.java index 0b22f87c0..49272f84f 100644 --- a/bundles/org.openhab.binding.boschshc/src/test/java/org/openhab/binding/boschshc/internal/devices/twinguard/TwinguardHandlerTest.java +++ b/bundles/org.openhab.binding.boschshc/src/test/java/org/openhab/binding/boschshc/internal/devices/twinguard/TwinguardHandlerTest.java @@ -13,7 +13,7 @@ package org.openhab.binding.boschshc.internal.devices.twinguard; import org.eclipse.jdt.annotation.NonNullByDefault; -import org.openhab.binding.boschshc.internal.devices.AbstractBatteryPoweredDeviceHandlerTest; +import org.openhab.binding.boschshc.internal.devices.AbstractSmokeDetectorHandlerTest; import org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants; import org.openhab.core.thing.ThingTypeUID; @@ -24,7 +24,7 @@ import org.openhab.core.thing.ThingTypeUID; * */ @NonNullByDefault -public class TwinguardHandlerTest extends AbstractBatteryPoweredDeviceHandlerTest { +public class TwinguardHandlerTest extends AbstractSmokeDetectorHandlerTest { @Override protected TwinguardHandler createFixture() { diff --git a/bundles/org.openhab.binding.boschshc/src/test/java/org/openhab/binding/boschshc/internal/services/smokedetectorcheck/SmokeDetectorCheckStateTest.java b/bundles/org.openhab.binding.boschshc/src/test/java/org/openhab/binding/boschshc/internal/services/smokedetectorcheck/SmokeDetectorCheckStateTest.java new file mode 100644 index 000000000..42a3a73c3 --- /dev/null +++ b/bundles/org.openhab.binding.boschshc/src/test/java/org/openhab/binding/boschshc/internal/services/smokedetectorcheck/SmokeDetectorCheckStateTest.java @@ -0,0 +1,37 @@ +/** + * 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.smokedetectorcheck; + +import static org.junit.jupiter.api.Assertions.assertSame; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.junit.jupiter.api.Test; + +/** + * Unit tests for {@link SmokeDetectorCheckState}. + * + * @author David Pace - Initial contribution + * + */ +@NonNullByDefault +public class SmokeDetectorCheckStateTest { + + @Test + void testFrom() { + assertSame(SmokeDetectorCheckState.SMOKE_TEST_OK, SmokeDetectorCheckState.from("SMOKE_TEST_OK")); + assertSame(SmokeDetectorCheckState.SMOKE_TEST_REQUESTED, SmokeDetectorCheckState.from("SMOKE_TEST_REQUESTED")); + assertSame(SmokeDetectorCheckState.SMOKE_TEST_FAILED, SmokeDetectorCheckState.from("SMOKE_TEST_FAILED")); + assertSame(SmokeDetectorCheckState.NONE, SmokeDetectorCheckState.from("NONE")); + assertSame(SmokeDetectorCheckState.NONE, SmokeDetectorCheckState.from("invalid string")); + } +}