[boschshc] Support smoke detector ()

* 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 <christian.oeing@slashgames.org>
Signed-off-by: Gerd Zanker <gerd.zanker@web.de>
Signed-off-by: David Pace <dev@davidpace.de>
This commit is contained in:
Gerd Zanker 2022-12-10 11:18:13 +01:00 committed by GitHub
parent db86d291da
commit 584f637126
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 488 additions and 6 deletions

@ -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 | &#9744; | Combined rating of the air quality. |
| battery-level | Number | &#9744; | 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 | &#9744; | Indicates whether the battery is low (`ON`) or OK (`OFF`). |
| smoke-check | String | &#9745; | 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 | &#9745; | Regulates the brightness on a percentage scale from 0 to 100%. |
| color | Color | &#9745; | 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 | &#9745; | State of the smoke check. Also used to request a new smoke check. |
## Limitations
- Discovery of Things

@ -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

@ -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()));
}
}

@ -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";

@ -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) {

@ -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);
}
}

@ -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);

@ -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<SmokeDetectorCheckServiceState> {
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);
}
}

@ -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;
}
}
}

@ -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;
}

@ -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

@ -12,6 +12,8 @@
<config-description-ref uri="thing-type:boschshc:bridge"/>
</bridge-type>
<!-- Things -->
<thing-type id="in-wall-switch">
<supported-bridge-type-refs>
<bridge-type-ref id="shc"/>
@ -67,6 +69,7 @@
<channel id="combined-rating" typeId="combined-rating"/>
<channel id="battery-level" typeId="system.battery-level"/>
<channel id="low-battery" typeId="system.low-battery"/>
<channel id="smoke-check" typeId="smoke-check"/>
</channels>
<config-description-ref uri="thing-type:boschshc:device"/>
@ -255,6 +258,25 @@
</thing-type>
<thing-type id="smoke-detector">
<supported-bridge-type-refs>
<bridge-type-ref id="shc"/>
</supported-bridge-type-refs>
<label>Smoke Detector</label>
<description>The smoke detector warns you in case of fire.</description>
<channels>
<channel id="smoke-check" typeId="smoke-check"/>
<channel id="battery-level" typeId="system.battery-level"/>
<channel id="low-battery" typeId="system.low-battery"/>
</channels>
<config-description-ref uri="thing-type:boschshc:device"/>
</thing-type>
<!-- Channels -->
<channel-type id="system-availability">
<item-type>Switch</item-type>
<label>System Availability</label>
@ -430,6 +452,20 @@
</state>
</channel-type>
<channel-type id="smoke-check">
<item-type>String</item-type>
<label>Smoke Check State</label>
<description>State of last smoke detector check.</description>
<state readOnly="false">
<options>
<option value="NONE">None</option>
<option value="SMOKE_TEST_REQUESTED">Test requested</option>
<option value="SMOKE_TEST_OK">Test successful</option>
<option value="SMOKE_TEST_FAILED">Test failed</option>
</options>
</state>
</channel-type>
<channel-type id="contact">
<item-type>Contact</item-type>
<label>Window/Door contact</label>

@ -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<T extends AbstractSmokeDetectorHandler>
extends AbstractBatteryPoweredDeviceHandlerTest<T> {
@Captor
private @NonNullByDefault({}) ArgumentCaptor<SmokeDetectorCheckServiceState> 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"));
}
}

@ -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<SmokeDetectorHandler> {
@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;
}
}

@ -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<TwinguardHandler> {
public class TwinguardHandlerTest extends AbstractSmokeDetectorHandlerTest<TwinguardHandler> {
@Override
protected TwinguardHandler createFixture() {

@ -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"));
}
}