diff --git a/bundles/org.openhab.binding.boschshc/README.md b/bundles/org.openhab.binding.boschshc/README.md index 7758c2d52ae..56be053b448 100644 --- a/bundles/org.openhab.binding.boschshc/README.md +++ b/bundles/org.openhab.binding.boschshc/README.md @@ -21,6 +21,8 @@ Binding for the Bosch Smart Home. - [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) @@ -246,6 +248,31 @@ Individual states can be activated/deactivated and can be used as triggers, cond |-----------------|-----------| :------: |--------------------------------------------| | 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 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 158c37acad7..b2aee2d8248 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 @@ -49,6 +49,8 @@ public class BoschSHCBindingConstants { 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"); @@ -91,6 +93,10 @@ public class BoschSHCBindingConstants { 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"; 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 486f471d3bc..b5664588eec 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 @@ -12,7 +12,25 @@ */ 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; @@ -32,10 +50,13 @@ 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.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; @@ -43,7 +64,9 @@ import org.openhab.core.thing.binding.BaseThingHandler; 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 @@ -59,6 +82,13 @@ import org.osgi.service.component.annotations.Component; @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 handlerSupplier; @@ -69,7 +99,7 @@ public class BoschSHCHandlerFactory extends BaseThingHandlerFactory { } } - private static final Collection SUPPORTED_THING_TYPES = List.of( + private final Collection 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), @@ -86,11 +116,15 @@ public class BoschSHCHandlerFactory extends BaseThingHandlerFactory { 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 @@ -98,7 +132,7 @@ public class BoschSHCHandlerFactory extends BaseThingHandlerFactory { 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); } } diff --git a/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/universalswitch/UniversalSwitch2Handler.java b/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/universalswitch/UniversalSwitch2Handler.java new file mode 100644 index 00000000000..86628d3e337 --- /dev/null +++ b/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/universalswitch/UniversalSwitch2Handler.java @@ -0,0 +1,31 @@ +/** + * 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); + } +} diff --git a/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/universalswitch/UniversalSwitchHandler.java b/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/universalswitch/UniversalSwitchHandler.java new file mode 100644 index 00000000000..fc15f72222a --- /dev/null +++ b/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/universalswitch/UniversalSwitchHandler.java @@ -0,0 +1,68 @@ +/** + * 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()))); + } +} diff --git a/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/discovery/ThingDiscoveryService.java b/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/discovery/ThingDiscoveryService.java index 3766ece6ebe..1a7a6bbe571 100644 --- a/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/discovery/ThingDiscoveryService.java +++ b/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/discovery/ThingDiscoveryService.java @@ -86,7 +86,9 @@ public class ThingDiscoveryService extends AbstractThingHandlerDiscoveryService< 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.), diff --git a/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/services/keypad/KeypadService.java b/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/services/keypad/KeypadService.java new file mode 100644 index 00000000000..ac0c1d85be5 --- /dev/null +++ b/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/services/keypad/KeypadService.java @@ -0,0 +1,31 @@ +/** + * 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 { + + public KeypadService() { + super("Keypad", KeypadServiceState.class); + } +} diff --git a/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/services/keypad/dto/KeyEventType.java b/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/services/keypad/dto/KeyEventType.java new file mode 100644 index 00000000000..36b2a85240d --- /dev/null +++ b/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/services/keypad/dto/KeyEventType.java @@ -0,0 +1,25 @@ +/** + * 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 +} diff --git a/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/services/keypad/dto/KeyName.java b/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/services/keypad/dto/KeyName.java new file mode 100644 index 00000000000..284468a378e --- /dev/null +++ b/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/services/keypad/dto/KeyName.java @@ -0,0 +1,28 @@ +/** + * 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 +} diff --git a/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/services/keypad/dto/KeypadServiceState.java b/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/services/keypad/dto/KeypadServiceState.java new file mode 100644 index 00000000000..e05e5b8edd5 --- /dev/null +++ b/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/services/keypad/dto/KeypadServiceState.java @@ -0,0 +1,49 @@ +/** + * 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}. + *

+ * Example JSON: + * + *

+ * {
+ *   "@type":"keypadState",
+ *   "keyCode":1,
+ *   "keyName":"UPPER_LEFT_BUTTON",
+ *   "eventType":"PRESS_SHORT",
+ *   "eventTimestamp":1705130891435
+ * }
+ * 
+ * + * @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; +} 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 4734e7eaaa5..c5fc3174f5f 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 @@ -31,6 +31,10 @@ thing-type.boschshc.thermostat.label = Thermostat 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 @@ -101,6 +105,23 @@ 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.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 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 f7460859dd5..ea8b6510232 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 @@ -325,6 +325,42 @@ + + + + + + + Universally configurable switch with two buttons. + + + + + + + + + + + + + + + + + + Universally configurable switch with four buttons. + + + + + + + + + + + @@ -606,4 +642,47 @@ + + Number:Dimensionless + + Integer code of the key that was pressed. + + + + + String + + Name of the key that was pressed. + + + + + + + + + + + + + + String + + Indicates how the key was pressed. + + + + + + + + + + + DateTime + + Timestamp indicating when the key was pressed. + + + diff --git a/bundles/org.openhab.binding.boschshc/src/test/java/org/openhab/binding/boschshc/internal/devices/BoschSHCHandlerFactoryTest.java b/bundles/org.openhab.binding.boschshc/src/test/java/org/openhab/binding/boschshc/internal/devices/BoschSHCHandlerFactoryTest.java index a1bdcd657cd..6a526a22ced 100644 --- a/bundles/org.openhab.binding.boschshc/src/test/java/org/openhab/binding/boschshc/internal/devices/BoschSHCHandlerFactoryTest.java +++ b/bundles/org.openhab.binding.boschshc/src/test/java/org/openhab/binding/boschshc/internal/devices/BoschSHCHandlerFactoryTest.java @@ -12,8 +12,12 @@ */ 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; @@ -35,7 +39,7 @@ class BoschSHCHandlerFactoryTest { @BeforeEach public void setUp() throws Exception { - fixture = new BoschSHCHandlerFactory(); + fixture = new BoschSHCHandlerFactory(() -> ZoneId.systemDefault()); } @Test diff --git a/bundles/org.openhab.binding.boschshc/src/test/java/org/openhab/binding/boschshc/internal/devices/universalswitch/UniversalSwitchHandler2Test.java b/bundles/org.openhab.binding.boschshc/src/test/java/org/openhab/binding/boschshc/internal/devices/universalswitch/UniversalSwitchHandler2Test.java new file mode 100644 index 00000000000..df1bf9d7ad6 --- /dev/null +++ b/bundles/org.openhab.binding.boschshc/src/test/java/org/openhab/binding/boschshc/internal/devices/universalswitch/UniversalSwitchHandler2Test.java @@ -0,0 +1,39 @@ +/** + * 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; + } +} diff --git a/bundles/org.openhab.binding.boschshc/src/test/java/org/openhab/binding/boschshc/internal/devices/universalswitch/UniversalSwitchHandlerTest.java b/bundles/org.openhab.binding.boschshc/src/test/java/org/openhab/binding/boschshc/internal/devices/universalswitch/UniversalSwitchHandlerTest.java new file mode 100644 index 00000000000..8e37ed93516 --- /dev/null +++ b/bundles/org.openhab.binding.boschshc/src/test/java/org/openhab/binding/boschshc/internal/devices/universalswitch/UniversalSwitchHandlerTest.java @@ -0,0 +1,89 @@ +/** + * 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 { + + @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)); + } +}