- [Smart Bulb](#smart-bulb)
- [Smoke Detector](#smoke-detector)
- [User-defined States](#user-defined-states)
+ - [Universal Switch](#universal-switch)
+ - [Universal Switch II](#universal-switch-ii)
- [Limitations](#limitations)
- [Discovery](#discovery)
- [Bridge Configuration](#bridge-configuration)
|-----------------|-----------| :------: |--------------------------------------------|
| user-state | Switch | ☑ | Switches the User-defined state on or off. |
+### Universal Switch
+
+A universally configurable switch with two buttons.
+
+**Thing Type ID**: `universal-switch`
+
+| Channel Type ID | Item Type | Writable | Description |
+| ------------------- | -------------------- | :------: | ----------------------------------------- |
+| key-code | Number:Dimensionless | ☐ | Integer code of the key that was pressed. |
+| key-name | String | ☐ | Name of a key pressed on a device. Possible values for Universal Switch: `LOWER_BUTTON`, `UPPER_BUTTON`. |
+| key-event-type | String | ☐ | Indicates how the key was pressed. Possible values are `PRESS_SHORT`, `PRESS_LONG` and `PRESS_LONG_RELEASED`. |
+| key-event-timestamp | DateTime | ☐ | Timestamp indicating when the key was pressed. |
+
+### Universal Switch II
+
+A universally configurable switch with four buttons.
+
+**Thing Type ID**: `universal-switch-2`
+
+| Channel Type ID | Item Type | Writable | Description |
+| ------------------- | -------------------- | :------: | ----------------------------------------- |
+| key-code | Number:Dimensionless | ☐ | Integer code of the key that was pressed. |
+| key-name | String | ☐ | Name of the key that was pressed. Possible values for Universal Switch II: `LOWER_LEFT_BUTTON`, `LOWER_RIGHT_BUTTON`, `UPPER_LEFT_BUTTON`, `UPPER_RIGHT_BUTTON`. |
+| key-event-type | String | ☐ | Indicates how the key was pressed. Possible values are `PRESS_SHORT`, `PRESS_LONG` and `PRESS_LONG_RELEASED`. |
+| key-event-timestamp | DateTime | ☐ | Timestamp indicating when the key was pressed. |
## Limitations
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");
+ public static final ThingTypeUID THING_TYPE_UNIVERSAL_SWITCH = new ThingTypeUID(BINDING_ID, "universal-switch");
+ public static final ThingTypeUID THING_TYPE_UNIVERSAL_SWITCH_2 = new ThingTypeUID(BINDING_ID, "universal-switch-2");
public static final ThingTypeUID THING_TYPE_USER_DEFINED_STATE = new ThingTypeUID(BINDING_ID, "user-defined-state");
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_KEY_CODE = "key-code";
+ public static final String CHANNEL_KEY_NAME = "key-name";
+ public static final String CHANNEL_KEY_EVENT_TYPE = "key-event-type";
+ public static final String CHANNEL_KEY_EVENT_TIMESTAMP = "key-event-timestamp";
public static final String CHANNEL_USER_DEFINED_STATE = "user-state";
*/
package org.openhab.binding.boschshc.internal.devices;
-import static org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants.*;
+import static org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants.THING_TYPE_CAMERA_360;
+import static org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants.THING_TYPE_CAMERA_EYES;
+import static org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants.THING_TYPE_CLIMATE_CONTROL;
+import static org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants.THING_TYPE_INTRUSION_DETECTION_SYSTEM;
+import static org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants.THING_TYPE_INWALL_SWITCH;
+import static org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants.THING_TYPE_MOTION_DETECTOR;
+import static org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants.THING_TYPE_SHC;
+import static org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants.THING_TYPE_SHUTTER_CONTROL;
+import static org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants.THING_TYPE_SMART_BULB;
+import static org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants.THING_TYPE_SMART_PLUG_COMPACT;
+import static org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants.THING_TYPE_SMOKE_DETECTOR;
+import static org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants.THING_TYPE_THERMOSTAT;
+import static org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants.THING_TYPE_TWINGUARD;
+import static org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants.THING_TYPE_UNIVERSAL_SWITCH;
+import static org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants.THING_TYPE_UNIVERSAL_SWITCH_2;
+import static org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants.THING_TYPE_USER_DEFINED_STATE;
+import static org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants.THING_TYPE_WALL_THERMOSTAT;
+import static org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants.THING_TYPE_WINDOW_CONTACT;
+import static org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants.THING_TYPE_WINDOW_CONTACT_2;
import java.util.Collection;
import java.util.List;
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.universalswitch.UniversalSwitch2Handler;
+import org.openhab.binding.boschshc.internal.devices.universalswitch.UniversalSwitchHandler;
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.i18n.TimeZoneProvider;
import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingTypeUID;
import org.openhab.core.thing.binding.BaseThingHandlerFactory;
import org.openhab.core.thing.binding.ThingHandler;
import org.openhab.core.thing.binding.ThingHandlerFactory;
+import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
/**
* The {@link BoschSHCHandlerFactory} is responsible for creating things and
@Component(configurationPid = "binding.boschshc", service = ThingHandlerFactory.class)
public class BoschSHCHandlerFactory extends BaseThingHandlerFactory {
+ private TimeZoneProvider timeZoneProvider;
+
+ @Activate
+ public BoschSHCHandlerFactory(final @Reference TimeZoneProvider timeZoneProvider) {
+ this.timeZoneProvider = timeZoneProvider;
+ }
+
private static class ThingTypeHandlerMapping {
public ThingTypeUID thingTypeUID;
public Function<Thing, BaseThingHandler> handlerSupplier;
}
}
- private static final Collection<ThingTypeHandlerMapping> SUPPORTED_THING_TYPES = List.of(
+ private final Collection<ThingTypeHandlerMapping> supportedThingTypes = List.of(
new ThingTypeHandlerMapping(THING_TYPE_SHC, thing -> new BridgeHandler((Bridge) thing)),
new ThingTypeHandlerMapping(THING_TYPE_INWALL_SWITCH, LightControlHandler::new),
new ThingTypeHandlerMapping(THING_TYPE_TWINGUARD, TwinguardHandler::new),
new ThingTypeHandlerMapping(THING_TYPE_SMART_PLUG_COMPACT, PlugHandler::new),
new ThingTypeHandlerMapping(THING_TYPE_SMART_BULB, SmartBulbHandler::new),
new ThingTypeHandlerMapping(THING_TYPE_SMOKE_DETECTOR, SmokeDetectorHandler::new),
- new ThingTypeHandlerMapping(THING_TYPE_USER_DEFINED_STATE, UserStateHandler::new));
+ new ThingTypeHandlerMapping(THING_TYPE_USER_DEFINED_STATE, UserStateHandler::new),
+ new ThingTypeHandlerMapping(THING_TYPE_UNIVERSAL_SWITCH,
+ thing -> new UniversalSwitchHandler(thing, timeZoneProvider)),
+ new ThingTypeHandlerMapping(THING_TYPE_UNIVERSAL_SWITCH_2,
+ thing -> new UniversalSwitch2Handler(thing, timeZoneProvider)));
@Override
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
- return SUPPORTED_THING_TYPES.stream().anyMatch(mapping -> mapping.thingTypeUID.equals(thingTypeUID));
+ return supportedThingTypes.stream().anyMatch(mapping -> mapping.thingTypeUID.equals(thingTypeUID));
}
@Override
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
// Search for mapping for thing type and return handler for it if found. Otherwise return null.
- return SUPPORTED_THING_TYPES.stream().filter(mapping -> mapping.thingTypeUID.equals(thingTypeUID)).findFirst()
+ return supportedThingTypes.stream().filter(mapping -> mapping.thingTypeUID.equals(thingTypeUID)).findFirst()
.<@Nullable BaseThingHandler> map(mapping -> mapping.handlerSupplier.apply(thing)).orElse(null);
}
}
--- /dev/null
+/**
+ * Copyright (c) 2010-2024 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.universalswitch;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.core.i18n.TimeZoneProvider;
+import org.openhab.core.thing.Thing;
+
+/**
+ * Handler for a universally configurable switch with four buttons.
+ *
+ * @author David Pace - Initial contribution
+ *
+ */
+@NonNullByDefault
+public class UniversalSwitch2Handler extends UniversalSwitchHandler {
+
+ public UniversalSwitch2Handler(Thing thing, TimeZoneProvider timeZoneProvider) {
+ super(thing, timeZoneProvider);
+ }
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2024 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.universalswitch;
+
+import static org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants.CHANNEL_KEY_CODE;
+import static org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants.CHANNEL_KEY_EVENT_TIMESTAMP;
+import static org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants.CHANNEL_KEY_EVENT_TYPE;
+import static org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants.CHANNEL_KEY_NAME;
+
+import java.time.Instant;
+import java.time.ZonedDateTime;
+import java.util.List;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.binding.boschshc.internal.devices.AbstractBatteryPoweredDeviceHandler;
+import org.openhab.binding.boschshc.internal.exceptions.BoschSHCException;
+import org.openhab.binding.boschshc.internal.services.keypad.KeypadService;
+import org.openhab.binding.boschshc.internal.services.keypad.dto.KeypadServiceState;
+import org.openhab.core.i18n.TimeZoneProvider;
+import org.openhab.core.library.types.DateTimeType;
+import org.openhab.core.library.types.DecimalType;
+import org.openhab.core.library.types.StringType;
+import org.openhab.core.thing.Thing;
+
+/**
+ * Handler for a universally configurable switch with two buttons.
+ *
+ * @author David Pace - Initial contribution
+ *
+ */
+@NonNullByDefault
+public class UniversalSwitchHandler extends AbstractBatteryPoweredDeviceHandler {
+
+ private TimeZoneProvider timeZoneProvider;
+
+ public UniversalSwitchHandler(Thing thing, TimeZoneProvider timeZoneProvider) {
+ super(thing);
+ this.timeZoneProvider = timeZoneProvider;
+ }
+
+ @Override
+ protected void initializeServices() throws BoschSHCException {
+ super.initializeServices();
+
+ createService(KeypadService::new, this::updateChannels,
+ List.of(CHANNEL_KEY_CODE, CHANNEL_KEY_NAME, CHANNEL_KEY_EVENT_TYPE, CHANNEL_KEY_EVENT_TIMESTAMP));
+ }
+
+ private void updateChannels(KeypadServiceState keypadServiceState) {
+ updateState(CHANNEL_KEY_CODE, new DecimalType(keypadServiceState.keyCode));
+ updateState(CHANNEL_KEY_NAME, new StringType(keypadServiceState.keyName.toString()));
+ updateState(CHANNEL_KEY_EVENT_TYPE, new StringType(keypadServiceState.eventType.toString()));
+
+ Instant instant = Instant.ofEpochMilli(keypadServiceState.eventTimestamp);
+ updateState(CHANNEL_KEY_EVENT_TIMESTAMP,
+ new DateTimeType(ZonedDateTime.ofInstant(instant, timeZoneProvider.getTimeZone())));
+ }
+}
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)
+ new AbstractMap.SimpleEntry<>("TRV", BoschSHCBindingConstants.THING_TYPE_THERMOSTAT),
+ new AbstractMap.SimpleEntry<>("WRC2", BoschSHCBindingConstants.THING_TYPE_UNIVERSAL_SWITCH),
+ new AbstractMap.SimpleEntry<>("SWITCH2", BoschSHCBindingConstants.THING_TYPE_UNIVERSAL_SWITCH_2)
// Future Extension: map deviceModel names to BoschSHC Thing Types when they are supported
// new AbstractMap.SimpleEntry<>("SMOKE_DETECTION_SYSTEM", BoschSHCBindingConstants.),
// new AbstractMap.SimpleEntry<>("PRESENCE_SIMULATION_SERVICE", BoschSHCBindingConstants.),
--- /dev/null
+/**
+ * Copyright (c) 2010-2024 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.keypad;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.binding.boschshc.internal.services.BoschSHCService;
+import org.openhab.binding.boschshc.internal.services.keypad.dto.KeypadServiceState;
+
+/**
+ * Service for the keypads for Universal Switches.
+ *
+ * @author David Pace - Initial contribution
+ *
+ */
+@NonNullByDefault
+public class KeypadService extends BoschSHCService<KeypadServiceState> {
+
+ public KeypadService() {
+ super("Keypad", KeypadServiceState.class);
+ }
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2024 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.keypad.dto;
+
+/**
+ * Event types of keys/buttons pressed on Universal Switches.
+ *
+ * @author David Pace - Initial contribution
+ *
+ */
+public enum KeyEventType {
+ PRESS_SHORT,
+ PRESS_LONG,
+ PRESS_LONG_RELEASED
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2024 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.keypad.dto;
+
+/**
+ * Key names of keys/buttons pressed on Universal Switches.
+ *
+ * @author David Pace - Initial contribution
+ *
+ */
+public enum KeyName {
+ LOWER_BUTTON,
+ UPPER_BUTTON,
+ LOWER_LEFT_BUTTON,
+ LOWER_RIGHT_BUTTON,
+ UPPER_LEFT_BUTTON,
+ UPPER_RIGHT_BUTTON
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2024 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.keypad.dto;
+
+import org.openhab.binding.boschshc.internal.services.dto.BoschSHCServiceState;
+import org.openhab.binding.boschshc.internal.services.keypad.KeypadService;
+
+/**
+ * State object of the {@link KeypadService}.
+ * <p>
+ * Example JSON:
+ *
+ * <pre>
+ * {
+ * "@type":"keypadState",
+ * "keyCode":1,
+ * "keyName":"UPPER_LEFT_BUTTON",
+ * "eventType":"PRESS_SHORT",
+ * "eventTimestamp":1705130891435
+ * }
+ * </pre>
+ *
+ * @author David Pace - Initial contribution
+ *
+ */
+public class KeypadServiceState extends BoschSHCServiceState {
+
+ public KeypadServiceState() {
+ super("keypadState");
+ }
+
+ public int keyCode;
+
+ public KeyName keyName;
+
+ public KeyEventType eventType;
+
+ public long eventTimestamp;
+}
thing-type.boschshc.thermostat.description = Radiator thermostat
thing-type.boschshc.twinguard.label = Twinguard
thing-type.boschshc.twinguard.description = The Twinguard smoke detector warns you in case of fire and constantly monitors the air.
+thing-type.boschshc.universal-switch-2.label = Universal Switch II
+thing-type.boschshc.universal-switch-2.description = Universally configurable switch with four buttons.
+thing-type.boschshc.universal-switch.label = Universal Switch
+thing-type.boschshc.universal-switch.description = Universally configurable switch with two buttons.
thing-type.boschshc.user-defined-state.label = User-defined State
thing-type.boschshc.user-defined-state.description = A User-defined state.
thing-type.boschshc.wall-thermostat.label = Wall Thermostat
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.key-code.label = Key Code
+channel-type.boschshc.key-code.description = Integer code of the key that was pressed.
+channel-type.boschshc.key-event-timestamp.label = Key Event Timestamp
+channel-type.boschshc.key-event-timestamp.description = Timestamp indicating when the key was pressed.
+channel-type.boschshc.key-event-type.label = Key Event Type
+channel-type.boschshc.key-event-type.description = Indicates how the key was pressed.
+channel-type.boschshc.key-event-type.state.option.PRESS_SHORT = Short
+channel-type.boschshc.key-event-type.state.option.PRESS_LONG = Long (pressed)
+channel-type.boschshc.key-event-type.state.option.PRESS_LONG_RELEASED = Long (released)
+channel-type.boschshc.key-name.label = Key Name
+channel-type.boschshc.key-name.description = Name of the key that was pressed.
+channel-type.boschshc.key-name.state.option.LOWER_BUTTON = Lower button
+channel-type.boschshc.key-name.state.option.UPPER_BUTTON = Upper button
+channel-type.boschshc.key-name.state.option.LOWER_LEFT_BUTTON = Lower left button
+channel-type.boschshc.key-name.state.option.LOWER_RIGHT_BUTTON = Lower right button
+channel-type.boschshc.key-name.state.option.UPPER_LEFT_BUTTON = Upper left button
+channel-type.boschshc.key-name.state.option.UPPER_RIGHT_BUTTON = Upper right button
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
<config-description-ref uri="thing-type:boschshc:user-defined-state"/>
</thing-type>
+ <thing-type id="universal-switch">
+ <supported-bridge-type-refs>
+ <bridge-type-ref id="shc"/>
+ </supported-bridge-type-refs>
+
+ <label>Universal Switch</label>
+ <description>Universally configurable switch with two buttons.</description>
+
+ <channels>
+ <channel id="key-code" typeId="key-code"/>
+ <channel id="key-name" typeId="key-name"/>
+ <channel id="key-event-type" typeId="key-event-type"/>
+ <channel id="key-event-timestamp" typeId="key-event-timestamp"/>
+ </channels>
+
+ <config-description-ref uri="thing-type:boschshc:user-defined-state"/>
+ </thing-type>
+
+ <thing-type id="universal-switch-2">
+ <supported-bridge-type-refs>
+ <bridge-type-ref id="shc"/>
+ </supported-bridge-type-refs>
+
+ <label>Universal Switch II</label>
+ <description>Universally configurable switch with four buttons.</description>
+
+ <channels>
+ <channel id="key-code" typeId="key-code"/>
+ <channel id="key-name" typeId="key-name"/>
+ <channel id="key-event-type" typeId="key-event-type"/>
+ <channel id="key-event-timestamp" typeId="key-event-timestamp"/>
+ </channels>
+
+ <config-description-ref uri="thing-type:boschshc:user-defined-state"/>
+ </thing-type>
+
<!-- Channels -->
<channel-type id="system-availability">
</state>
</channel-type>
+ <channel-type id="key-code">
+ <item-type>Number:Dimensionless</item-type>
+ <label>Key Code</label>
+ <description>Integer code of the key that was pressed.</description>
+ <state readOnly="true"/>
+ </channel-type>
+
+ <channel-type id="key-name">
+ <item-type>String</item-type>
+ <label>Key Name</label>
+ <description>Name of the key that was pressed.</description>
+ <state readOnly="true">
+ <options>
+ <option value="LOWER_BUTTON">Lower button</option>
+ <option value="UPPER_BUTTON">Upper button</option>
+ <option value="LOWER_LEFT_BUTTON">Lower left button</option>
+ <option value="LOWER_RIGHT_BUTTON">Lower right button</option>
+ <option value="UPPER_LEFT_BUTTON">Upper left button</option>
+ <option value="UPPER_RIGHT_BUTTON">Upper right button</option>
+ </options>
+ </state>
+ </channel-type>
+
+ <channel-type id="key-event-type">
+ <item-type>String</item-type>
+ <label>Key Event Type</label>
+ <description>Indicates how the key was pressed.</description>
+ <state readOnly="true">
+ <options>
+ <option value="PRESS_SHORT">Short</option>
+ <option value="PRESS_LONG">Long (pressed)</option>
+ <option value="PRESS_LONG_RELEASED">Long (released)</option>
+ </options>
+ </state>
+ </channel-type>
+
+ <channel-type id="key-event-timestamp">
+ <item-type>DateTime</item-type>
+ <label>Key Event Timestamp</label>
+ <description>Timestamp indicating when the key was pressed.</description>
+ <state readOnly="true"/>
+ </channel-type>
+
</thing:thing-descriptions>
*/
package org.openhab.binding.boschshc.internal.devices;
-import static org.junit.jupiter.api.Assertions.*;
-import static org.mockito.Mockito.*;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.time.ZoneId;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.junit.jupiter.api.BeforeEach;
@BeforeEach
public void setUp() throws Exception {
- fixture = new BoschSHCHandlerFactory();
+ fixture = new BoschSHCHandlerFactory(() -> ZoneId.systemDefault());
}
@Test
--- /dev/null
+/**
+ * Copyright (c) 2010-2024 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.universalswitch;
+
+import java.time.ZoneId;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants;
+import org.openhab.core.thing.ThingTypeUID;
+
+/**
+ * Unit tests for {@link UniversalSwitch2Handler}.
+ *
+ * @author David Pace - Initial contribution
+ *
+ */
+@NonNullByDefault
+class UniversalSwitchHandler2Test extends UniversalSwitchHandlerTest {
+
+ @Override
+ protected UniversalSwitchHandler createFixture() {
+ return new UniversalSwitch2Handler(getThing(), () -> ZoneId.systemDefault());
+ }
+
+ @Override
+ protected ThingTypeUID getThingTypeUID() {
+ return BoschSHCBindingConstants.THING_TYPE_UNIVERSAL_SWITCH_2;
+ }
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2024 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.universalswitch;
+
+import static org.mockito.Mockito.verify;
+
+import java.time.Instant;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.junit.jupiter.api.Test;
+import org.openhab.binding.boschshc.internal.devices.AbstractBatteryPoweredDeviceHandlerTest;
+import org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants;
+import org.openhab.core.library.types.DateTimeType;
+import org.openhab.core.library.types.DecimalType;
+import org.openhab.core.library.types.StringType;
+import org.openhab.core.thing.ChannelUID;
+import org.openhab.core.thing.ThingTypeUID;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParser;
+
+/**
+ * Unit tests for {@link UniversalSwitchHandler}.
+ *
+ * @author David Pace - Initial contribution
+ *
+ */
+@NonNullByDefault
+class UniversalSwitchHandlerTest extends AbstractBatteryPoweredDeviceHandlerTest<UniversalSwitchHandler> {
+
+ @Override
+ protected UniversalSwitchHandler createFixture() {
+ return new UniversalSwitchHandler(getThing(), () -> ZoneId.systemDefault());
+ }
+
+ @Override
+ protected String getDeviceID() {
+ return "hdm:ZigBee:001e43d085b91a96";
+ }
+
+ @Override
+ protected ThingTypeUID getThingTypeUID() {
+ return BoschSHCBindingConstants.THING_TYPE_UNIVERSAL_SWITCH;
+ }
+
+ @Test
+ void testUpdateChannelsKeypadService() {
+ JsonElement jsonObject = JsonParser.parseString("""
+ {
+ "@type":"keypadState",
+ "keyCode":1,
+ "keyName":"UPPER_LEFT_BUTTON",
+ "eventType":"PRESS_SHORT",
+ "eventTimestamp":1705130891435
+ }
+ """);
+
+ getFixture().processUpdate("Keypad", jsonObject);
+
+ verify(getCallback()).stateUpdated(
+ new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_KEY_CODE), new DecimalType(1));
+
+ verify(getCallback()).stateUpdated(
+ new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_KEY_NAME),
+ new StringType("UPPER_LEFT_BUTTON"));
+
+ verify(getCallback()).stateUpdated(
+ new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_KEY_EVENT_TYPE),
+ new StringType("PRESS_SHORT"));
+
+ ZonedDateTime expectedTime = ZonedDateTime.ofInstant(Instant.ofEpochMilli(1705130891435l),
+ ZoneId.systemDefault());
+ verify(getCallback()).stateUpdated(
+ new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_KEY_EVENT_TIMESTAMP),
+ new DateTimeType(expectedTime));
+ }
+}