- [Compact Smart Plug](#compact-smart-plug)
- [Twinguard Smoke Detector](#twinguard-smoke-detector)
- [Door/Window Contact](#door-window-contact)
+ - [Door/Window Contact II](#door-window-contact-ii)
- [Motion Detector](#motion-detector)
- [Shutter Control](#shutter-control)
- [Thermostat](#thermostat)
| 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`). |
+### Door/Window Contact II
+
+Detects open windows and doors and features an additional button.
+
+**Thing Type ID**: `window-contact`
+
+| Channel Type ID | Item Type | Writable | Description |
+| ----------------| --------- | :------: | ---------------------------- |
+| contact | Contact | ☐ | Contact state of the device. |
+| 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`). |
+| bypass | Switch | ☐ | Indicates whether the device is currently bypassed. Possible values are `ON`,`OFF` and `UNDEF` if the bypass state cannot be determined. |
+| signal-strength | Number | ☐ | Communication quality between the device and the Smart Home Controller. Possible values range between 0 (unknown) and 4 (best signal strength). |
+
### Motion Detector
Detects every movement through an intelligent combination of passive infra-red technology and an additional temperature sensor.
public static final ThingTypeUID THING_TYPE_INWALL_SWITCH = new ThingTypeUID(BINDING_ID, "in-wall-switch");
public static final ThingTypeUID THING_TYPE_TWINGUARD = new ThingTypeUID(BINDING_ID, "twinguard");
public static final ThingTypeUID THING_TYPE_WINDOW_CONTACT = new ThingTypeUID(BINDING_ID, "window-contact");
+ public static final ThingTypeUID THING_TYPE_WINDOW_CONTACT_2 = new ThingTypeUID(BINDING_ID, "window-contact-2");
public static final ThingTypeUID THING_TYPE_MOTION_DETECTOR = new ThingTypeUID(BINDING_ID, "motion-detector");
public static final ThingTypeUID THING_TYPE_SHUTTER_CONTROL = new ThingTypeUID(BINDING_ID, "shutter-control");
public static final ThingTypeUID THING_TYPE_THERMOSTAT = new ThingTypeUID(BINDING_ID, "thermostat");
public static final String CHANNEL_SMOKE_CHECK = "smoke-check";
public static final String CHANNEL_SILENT_MODE = "silent-mode";
public static final String CHANNEL_ILLUMINANCE = "illuminance";
+ public static final String CHANNEL_BYPASS_STATE = "bypass-state";
+ public static final String CHANNEL_SIGNAL_STRENGTH = "signal-strength";
public static final String CHANNEL_USER_DEFINED_STATE = "user-state";
import org.openhab.binding.boschshc.internal.devices.twinguard.TwinguardHandler;
import org.openhab.binding.boschshc.internal.devices.userdefinedstate.UserStateHandler;
import org.openhab.binding.boschshc.internal.devices.wallthermostat.WallThermostatHandler;
+import org.openhab.binding.boschshc.internal.devices.windowcontact.WindowContact2Handler;
import org.openhab.binding.boschshc.internal.devices.windowcontact.WindowContactHandler;
import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.Thing;
new ThingTypeHandlerMapping(THING_TYPE_INWALL_SWITCH, LightControlHandler::new),
new ThingTypeHandlerMapping(THING_TYPE_TWINGUARD, TwinguardHandler::new),
new ThingTypeHandlerMapping(THING_TYPE_WINDOW_CONTACT, WindowContactHandler::new),
+ new ThingTypeHandlerMapping(THING_TYPE_WINDOW_CONTACT_2, WindowContact2Handler::new),
new ThingTypeHandlerMapping(THING_TYPE_MOTION_DETECTOR, MotionDetectorHandler::new),
new ThingTypeHandlerMapping(THING_TYPE_SHUTTER_CONTROL, ShutterControlHandler::new),
new ThingTypeHandlerMapping(THING_TYPE_THERMOSTAT, ThermostatHandler::new),
--- /dev/null
+/**
+ * Copyright (c) 2010-2023 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.windowcontact;
+
+import static org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants.CHANNEL_BYPASS_STATE;
+import static org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants.CHANNEL_SIGNAL_STRENGTH;
+
+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.bypass.BypassService;
+import org.openhab.binding.boschshc.internal.services.bypass.dto.BypassServiceState;
+import org.openhab.binding.boschshc.internal.services.communicationquality.CommunicationQualityService;
+import org.openhab.binding.boschshc.internal.services.communicationquality.dto.CommunicationQualityServiceState;
+import org.openhab.core.thing.Thing;
+
+/**
+ * Handler for Door/Window Contact II
+ *
+ * @author David Pace - Initial contribution
+ *
+ */
+@NonNullByDefault
+public class WindowContact2Handler extends WindowContactHandler {
+
+ public WindowContact2Handler(Thing thing) {
+ super(thing);
+ }
+
+ @Override
+ protected void initializeServices() throws BoschSHCException {
+ super.initializeServices();
+
+ this.createService(BypassService::new, this::updateChannels, List.of(CHANNEL_BYPASS_STATE), true);
+ this.createService(CommunicationQualityService::new, this::updateChannels, List.of(CHANNEL_SIGNAL_STRENGTH),
+ true);
+ }
+
+ private void updateChannels(BypassServiceState bypassServiceState) {
+ updateState(CHANNEL_BYPASS_STATE, bypassServiceState.state.toOnOffTypeOrUndef());
+ }
+
+ private void updateChannels(CommunicationQualityServiceState communicationQualityServiceState) {
+ updateState(CHANNEL_SIGNAL_STRENGTH, communicationQualityServiceState.quality.toSystemSignalStrength());
+ }
+}
protected static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Set.of(
BoschSHCBindingConstants.THING_TYPE_INWALL_SWITCH, BoschSHCBindingConstants.THING_TYPE_TWINGUARD,
- BoschSHCBindingConstants.THING_TYPE_WINDOW_CONTACT, BoschSHCBindingConstants.THING_TYPE_MOTION_DETECTOR,
- BoschSHCBindingConstants.THING_TYPE_SHUTTER_CONTROL, BoschSHCBindingConstants.THING_TYPE_THERMOSTAT,
- BoschSHCBindingConstants.THING_TYPE_CLIMATE_CONTROL, BoschSHCBindingConstants.THING_TYPE_WALL_THERMOSTAT,
- BoschSHCBindingConstants.THING_TYPE_CAMERA_360, BoschSHCBindingConstants.THING_TYPE_CAMERA_EYES,
+ BoschSHCBindingConstants.THING_TYPE_WINDOW_CONTACT, BoschSHCBindingConstants.THING_TYPE_WINDOW_CONTACT_2,
+ BoschSHCBindingConstants.THING_TYPE_MOTION_DETECTOR, BoschSHCBindingConstants.THING_TYPE_SHUTTER_CONTROL,
+ BoschSHCBindingConstants.THING_TYPE_THERMOSTAT, BoschSHCBindingConstants.THING_TYPE_CLIMATE_CONTROL,
+ BoschSHCBindingConstants.THING_TYPE_WALL_THERMOSTAT, BoschSHCBindingConstants.THING_TYPE_CAMERA_360,
+ BoschSHCBindingConstants.THING_TYPE_CAMERA_EYES,
BoschSHCBindingConstants.THING_TYPE_INTRUSION_DETECTION_SYSTEM,
BoschSHCBindingConstants.THING_TYPE_SMART_PLUG_COMPACT, BoschSHCBindingConstants.THING_TYPE_SMART_BULB,
BoschSHCBindingConstants.THING_TYPE_SMOKE_DETECTOR);
new AbstractMap.SimpleEntry<>("HUE_LIGHT", BoschSHCBindingConstants.THING_TYPE_SMART_BULB),
new AbstractMap.SimpleEntry<>("LEDVANCE_LIGHT", BoschSHCBindingConstants.THING_TYPE_SMART_BULB),
new AbstractMap.SimpleEntry<>("SWD", BoschSHCBindingConstants.THING_TYPE_WINDOW_CONTACT),
+ new AbstractMap.SimpleEntry<>("SWD2", BoschSHCBindingConstants.THING_TYPE_WINDOW_CONTACT_2),
new AbstractMap.SimpleEntry<>("TRV", BoschSHCBindingConstants.THING_TYPE_THERMOSTAT)
// Future Extension: map deviceModel names to BoschSHC Thing Types when they are supported
// new AbstractMap.SimpleEntry<>("SMOKE_DETECTION_SYSTEM", BoschSHCBindingConstants.),
--- /dev/null
+/**
+ * Copyright (c) 2010-2023 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.bypass;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.binding.boschshc.internal.services.BoschSHCService;
+import org.openhab.binding.boschshc.internal.services.bypass.dto.BypassServiceState;
+
+/**
+ * Service for the bypass state of devices such as the Door/Window Contact II
+ *
+ * @author David Pace - Initial contribution
+ *
+ */
+@NonNullByDefault
+public class BypassService extends BoschSHCService<BypassServiceState> {
+
+ public BypassService() {
+ super("Bypass", BypassServiceState.class);
+ }
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2023 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.bypass.dto;
+
+/**
+ * Configuration object of a bypass configuration.
+ * <p>
+ * Example JSON:
+ *
+ * <pre>
+ * "configuration": {
+ * "enabled": false,
+ * "timeout": 5,
+ * "infinite": false
+ * }
+ * </pre>
+ *
+ * @author David Pace - Initial contribution
+ *
+ */
+public class BypassConfiguration {
+
+ public boolean enabled;
+
+ public int timeout;
+
+ public boolean infinite;
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2023 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.bypass.dto;
+
+import org.openhab.binding.boschshc.internal.services.dto.BoschSHCServiceState;
+
+/**
+ * Bypass service state for Door/Window Contact II
+ * <p>
+ * Example JSON:
+ *
+ * <pre>
+ * {
+ * "@type": "bypassState",
+ * "state": "BYPASS_INACTIVE",
+ * "configuration": {
+ * "enabled": false,
+ * "timeout": 5,
+ * "infinite": false
+ * }
+ * }
+ * </pre>
+ *
+ * @author David Pace - Initial contribution
+ *
+ */
+public class BypassServiceState extends BoschSHCServiceState {
+
+ public BypassServiceState() {
+ super("bypassState");
+ }
+
+ public BypassState state;
+
+ public BypassConfiguration configuration;
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2023 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.bypass.dto;
+
+import org.openhab.core.library.types.OnOffType;
+import org.openhab.core.types.State;
+import org.openhab.core.types.UnDefType;
+
+/**
+ * State indicating whether a device is currently bypassed.
+ *
+ * @author David Pace - Initial contribution
+ *
+ */
+public enum BypassState {
+ BYPASS_INACTIVE,
+ BYPASS_ACTIVE,
+ UNKNOWN;
+
+ /**
+ * Converts this Bosch-specific bypass state to an openHAB-compliant state for a switch.
+ *
+ * @return <code>ON</code>, <code>OFF</code> or <code>UNDEF</code>
+ */
+ public State toOnOffTypeOrUndef() {
+ return switch (this) {
+ case BYPASS_ACTIVE -> OnOffType.ON;
+ case BYPASS_INACTIVE -> OnOffType.OFF;
+ default -> UnDefType.UNDEF;
+ };
+ }
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2023 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.communicationquality;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.binding.boschshc.internal.services.BoschSHCService;
+import org.openhab.binding.boschshc.internal.services.communicationquality.dto.CommunicationQualityServiceState;
+
+/**
+ * Service for querying the communication quality between a device and the Smart Home Controller.
+ *
+ * @author David Pace - Initial contribution
+ *
+ */
+@NonNullByDefault
+public class CommunicationQualityService extends BoschSHCService<CommunicationQualityServiceState> {
+
+ public CommunicationQualityService() {
+ super("CommunicationQuality", CommunicationQualityServiceState.class);
+ }
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2023 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.communicationquality.dto;
+
+import org.openhab.binding.boschshc.internal.services.dto.BoschSHCServiceState;
+
+/**
+ * State of the communication quality service.
+ * <p>
+ * Example JSON:
+ *
+ * <pre>
+ * {
+ * "@type": "communicationQualityState",
+ * "quality": "UNKNOWN"
+ * }
+ * </pre>
+ *
+ * @author David Pace - Initial contribution
+ *
+ */
+public class CommunicationQualityServiceState extends BoschSHCServiceState {
+
+ public CommunicationQualityServiceState() {
+ super("communicationQualityState");
+ }
+
+ public CommunicationQualityState quality;
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2023 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.communicationquality.dto;
+
+import org.openhab.core.library.types.DecimalType;
+
+/**
+ * Possible states for the communication quality between a device and the
+ * bridge.
+ *
+ * @author David Pace - Initial contribution
+ *
+ */
+public enum CommunicationQualityState {
+ BAD,
+ MEDIUM,
+ NORMAL,
+ GOOD,
+ UNKNOWN,
+ FETCHING;
+
+ /**
+ * Converts this Bosch-specific communication quality state into a numeric state
+ * for the system channel of type <code>signal-strength</code>.
+ *
+ * @return
+ */
+ public DecimalType toSystemSignalStrength() {
+ switch (this) {
+ case BAD:
+ return new DecimalType(1);
+ case MEDIUM:
+ return new DecimalType(2);
+ case NORMAL:
+ return new DecimalType(3);
+ case GOOD:
+ return new DecimalType(4);
+ default:
+ // includes UNKNOWN and FETCHING
+ return new DecimalType(0);
+ }
+ }
+}
thing-type.boschshc.user-defined-state.description = A User-defined state.
thing-type.boschshc.wall-thermostat.label = Wall Thermostat
thing-type.boschshc.wall-thermostat.description = Display of the current room temperature as well as the relative humidity in the room.
+thing-type.boschshc.window-contact-2.label = Door/Window Contact II
+thing-type.boschshc.window-contact-2.description = Detects open windows and doors and features an additional button.
thing-type.boschshc.window-contact.label = Door/Window Contact
thing-type.boschshc.window-contact.description = Detects open windows and doors.
channel-type.boschshc.arming-state.state.option.SYSTEM_ARMING = System is currently arming
channel-type.boschshc.arming-state.state.option.SYSTEM_ARMED = System is armed
channel-type.boschshc.arming-state.state.option.SYSTEM_DISARMED = System is disarmed
+channel-type.boschshc.bypass-state.label = Bypass State
+channel-type.boschshc.bypass-state.description = Indicates whether the device is currently bypassed.
+channel-type.boschshc.bypass-state.state.option.OFF = Device is currently not bypassed
+channel-type.boschshc.bypass-state.state.option.ON = Device is currently bypassed
channel-type.boschshc.camera-notification.label = Camera Notifications
channel-type.boschshc.camera-notification.description = Enables or disables notifications for the camera.
channel-type.boschshc.camera-notification.state.option.ENABLED = Enable notifications
channel-type.boschshc.humidity-rating.state.option.BAD = Bad Humidity
channel-type.boschshc.humidity.label = Humidity
channel-type.boschshc.humidity.description = Current measured humidity.
+channel-type.boschshc.illuminance.label = Illuminance
+channel-type.boschshc.illuminance.description = The illuminance level measured by the sensor (0 to 1000).
channel-type.boschshc.latest-motion.label = Latest motion
channel-type.boschshc.latest-motion.description = Timestamp of the latest motion.
channel-type.boschshc.level.label = Level
</thing-type>
+ <thing-type id="window-contact-2">
+ <supported-bridge-type-refs>
+ <bridge-type-ref id="shc"/>
+ </supported-bridge-type-refs>
+
+ <label>Door/Window Contact II</label>
+ <description>Detects open windows and doors and features an additional button.</description>
+
+ <channels>
+ <channel id="contact" typeId="contact"/>
+ <channel id="battery-level" typeId="system.battery-level"/>
+ <channel id="low-battery" typeId="system.low-battery"/>
+ <channel id="bypass-state" typeId="bypass-state"/>
+ <channel id="signal-strength" typeId="system.signal-strength"/>
+ </channels>
+
+ <config-description-ref uri="thing-type:boschshc:device"/>
+
+ </thing-type>
+
<thing-type id="motion-detector">
<supported-bridge-type-refs>
<bridge-type-ref id="shc"/>
<description>State of user-defined state</description>
</channel-type>
+ <channel-type id="bypass-state">
+ <item-type>Switch</item-type>
+ <label>Bypass State</label>
+ <description>Indicates whether the device is currently bypassed.</description>
+ <state readOnly="true">
+ <options>
+ <option value="OFF">Device is currently not bypassed</option>
+ <option value="ON">Device is currently bypassed</option>
+ </options>
+ </state>
+ </channel-type>
+
</thing:thing-descriptions>
--- /dev/null
+/**
+ * Copyright (c) 2010-2023 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.windowcontact;
+
+import static org.mockito.Mockito.verify;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.junit.jupiter.api.Test;
+import org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants;
+import org.openhab.core.library.types.DecimalType;
+import org.openhab.core.library.types.OnOffType;
+import org.openhab.core.thing.ChannelUID;
+import org.openhab.core.thing.ThingTypeUID;
+import org.openhab.core.types.UnDefType;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParser;
+
+/**
+ * Unit tests for {@link WindowContact2Handler}.
+ *
+ * @author David Pace - Initial contribution
+ *
+ */
+@NonNullByDefault
+class WindowContact2HandlerTest extends WindowContactHandlerTest {
+
+ @Override
+ protected WindowContactHandler createFixture() {
+ return new WindowContact2Handler(getThing());
+ }
+
+ @Override
+ protected ThingTypeUID getThingTypeUID() {
+ return BoschSHCBindingConstants.THING_TYPE_WINDOW_CONTACT_2;
+ }
+
+ @Test
+ void testUpdateChannelsBypassService() {
+ String json = """
+ {
+ "@type": "bypassState",
+ "state": "BYPASS_INACTIVE",
+ "configuration": {
+ "enabled": false,
+ "timeout": 5,
+ "infinite": false
+ }
+ }
+ """;
+
+ JsonElement jsonObject = JsonParser.parseString(json);
+ getFixture().processUpdate("Bypass", jsonObject);
+ verify(getCallback()).stateUpdated(
+ new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_BYPASS_STATE), OnOffType.OFF);
+
+ json = """
+ {
+ "@type": "bypassState",
+ "state": "BYPASS_ACTIVE",
+ "configuration": {
+ "enabled": false,
+ "timeout": 5,
+ "infinite": false
+ }
+ }
+ """;
+
+ jsonObject = JsonParser.parseString(json);
+ getFixture().processUpdate("Bypass", jsonObject);
+ verify(getCallback()).stateUpdated(
+ new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_BYPASS_STATE), OnOffType.ON);
+
+ json = """
+ {
+ "@type": "bypassState",
+ "state": "UNKNOWN",
+ "configuration": {
+ "enabled": false,
+ "timeout": 5,
+ "infinite": false
+ }
+ }
+ """;
+
+ jsonObject = JsonParser.parseString(json);
+ getFixture().processUpdate("Bypass", jsonObject);
+ verify(getCallback()).stateUpdated(
+ new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_BYPASS_STATE), UnDefType.UNDEF);
+ }
+
+ @Test
+ void testUpdateChannelsCommunicationQualityService() {
+ String json = """
+ {
+ "@type": "communicationQualityState",
+ "quality": "UNKNOWN"
+ }
+ """;
+ JsonElement jsonObject = JsonParser.parseString(json);
+
+ getFixture().processUpdate("CommunicationQuality", jsonObject);
+ verify(getCallback()).stateUpdated(
+ new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_SIGNAL_STRENGTH),
+ new DecimalType(0));
+
+ json = """
+ {
+ "@type": "communicationQualityState",
+ "quality": "GOOD"
+ }
+ """;
+ jsonObject = JsonParser.parseString(json);
+
+ getFixture().processUpdate("CommunicationQuality", jsonObject);
+ verify(getCallback()).stateUpdated(
+ new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_SIGNAL_STRENGTH),
+ new DecimalType(4));
+ }
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2023 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.bypass.dto;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+import org.openhab.core.library.types.OnOffType;
+import org.openhab.core.types.UnDefType;
+
+/**
+ * Unit tests for {@link BypassState}.
+ *
+ * @author David Pace - Initial contribution
+ *
+ */
+class BypassStateTest {
+
+ @Test
+ void testToOnOffTypeOrUndef() {
+ assertEquals(OnOffType.ON, BypassState.BYPASS_ACTIVE.toOnOffTypeOrUndef());
+ assertEquals(OnOffType.OFF, BypassState.BYPASS_INACTIVE.toOnOffTypeOrUndef());
+ assertEquals(UnDefType.UNDEF, BypassState.UNKNOWN.toOnOffTypeOrUndef());
+ }
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2023 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.communicationquality.dto;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+import org.openhab.core.library.types.DecimalType;
+
+/**
+ * Unit tests for {@link CommunicationQualityState}.
+ *
+ * @author David Pace - Initial contribution
+ *
+ */
+class CommunicationQualityStateTest {
+
+ @Test
+ void testToSystemSignalStrength() {
+ assertEquals(new DecimalType(0), CommunicationQualityState.UNKNOWN.toSystemSignalStrength());
+ assertEquals(new DecimalType(0), CommunicationQualityState.FETCHING.toSystemSignalStrength());
+ assertEquals(new DecimalType(1), CommunicationQualityState.BAD.toSystemSignalStrength());
+ assertEquals(new DecimalType(2), CommunicationQualityState.MEDIUM.toSystemSignalStrength());
+ assertEquals(new DecimalType(3), CommunicationQualityState.NORMAL.toSystemSignalStrength());
+ assertEquals(new DecimalType(4), CommunicationQualityState.GOOD.toSystemSignalStrength());
+ }
+}