[boschshc] Add support for motion detector illuminance sensor (#16021)

* [boschshc] Add support for motion detector illuminance sensor

- add channel and corresponding channel type
- add update description
- add state model
- implement service and handler
- add documentation
- add unit test

---------

Signed-off-by: David Pace <dev@davidpace.de>
This commit is contained in:
David Pace 2023-12-11 00:57:59 +01:00 committed by GitHub
parent 10a46a8039
commit 2b9b3dfa0f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 120 additions and 0 deletions

View File

@ -29,6 +29,7 @@ Binding for the Bosch Smart Home.
## Supported Things ## Supported Things
### Smart Home Controller ### Smart Home Controller
The Smart Home Controller is the central hub that allows you to monitor and control your smart home devices from one place. The Smart Home Controller is the central hub that allows you to monitor and control your smart home devices from one place.
**Bridge Type ID**: ``shc`` **Bridge Type ID**: ``shc``
@ -103,6 +104,7 @@ Detects every movement through an intelligent combination of passive infra-red t
| Channel Type ID | Item Type | Writable | Description | | Channel Type ID | Item Type | Writable | Description |
| --------------- | --------- | :------: | ------------------------------ | | --------------- | --------- | :------: | ------------------------------ |
| latest-motion | DateTime | &#9744; | The date of the latest motion. | | latest-motion | DateTime | &#9744; | The date of the latest motion. |
| illuminance | Number | &#9744; | The illuminance level measured by the sensor as integer value in the range 0 to 1000. Note that the sensor only reports the value if the motion light service is activated or if the illuminance state is used in a scenario trigger condition. |
| 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`. | | 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`). | | low-battery | Switch | &#9744; | Indicates whether the battery is low (`ON`) or OK (`OFF`). |

View File

@ -85,6 +85,7 @@ public class BoschSHCBindingConstants {
public static final String CHANNEL_BRIGHTNESS = "brightness"; public static final String CHANNEL_BRIGHTNESS = "brightness";
public static final String CHANNEL_SMOKE_CHECK = "smoke-check"; public static final String CHANNEL_SMOKE_CHECK = "smoke-check";
public static final String CHANNEL_SILENT_MODE = "silent-mode"; public static final String CHANNEL_SILENT_MODE = "silent-mode";
public static final String CHANNEL_ILLUMINANCE = "illuminance";
// static device/service names // static device/service names
public static final String SERVICE_INTRUSION_DETECTION = "intrusionDetectionSystem"; public static final String SERVICE_INTRUSION_DETECTION = "intrusionDetectionSystem";

View File

@ -12,6 +12,7 @@
*/ */
package org.openhab.binding.boschshc.internal.devices.motiondetector; package org.openhab.binding.boschshc.internal.devices.motiondetector;
import static org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants.CHANNEL_ILLUMINANCE;
import static org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants.CHANNEL_LATEST_MOTION; import static org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants.CHANNEL_LATEST_MOTION;
import java.util.List; import java.util.List;
@ -19,9 +20,12 @@ import java.util.List;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.boschshc.internal.devices.AbstractBatteryPoweredDeviceHandler; import org.openhab.binding.boschshc.internal.devices.AbstractBatteryPoweredDeviceHandler;
import org.openhab.binding.boschshc.internal.exceptions.BoschSHCException; import org.openhab.binding.boschshc.internal.exceptions.BoschSHCException;
import org.openhab.binding.boschshc.internal.services.illuminance.IlluminanceService;
import org.openhab.binding.boschshc.internal.services.illuminance.dto.IlluminanceServiceState;
import org.openhab.binding.boschshc.internal.services.latestmotion.LatestMotionService; import org.openhab.binding.boschshc.internal.services.latestmotion.LatestMotionService;
import org.openhab.binding.boschshc.internal.services.latestmotion.dto.LatestMotionServiceState; import org.openhab.binding.boschshc.internal.services.latestmotion.dto.LatestMotionServiceState;
import org.openhab.core.library.types.DateTimeType; import org.openhab.core.library.types.DateTimeType;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.thing.Thing; import org.openhab.core.thing.Thing;
/** /**
@ -30,6 +34,7 @@ import org.openhab.core.thing.Thing;
* *
* @author Stefan Kästle - Initial contribution * @author Stefan Kästle - Initial contribution
* @author Christian Oeing - Use service instead of custom logic * @author Christian Oeing - Use service instead of custom logic
* @author David Pace - Added illuminance channel
*/ */
@NonNullByDefault @NonNullByDefault
public class MotionDetectorHandler extends AbstractBatteryPoweredDeviceHandler { public class MotionDetectorHandler extends AbstractBatteryPoweredDeviceHandler {
@ -43,10 +48,16 @@ public class MotionDetectorHandler extends AbstractBatteryPoweredDeviceHandler {
super.initializeServices(); super.initializeServices();
this.createService(LatestMotionService::new, this::updateChannels, List.of(CHANNEL_LATEST_MOTION)); this.createService(LatestMotionService::new, this::updateChannels, List.of(CHANNEL_LATEST_MOTION));
this.createService(IlluminanceService::new, this::updateChannels, List.of(CHANNEL_ILLUMINANCE), true);
} }
private void updateChannels(LatestMotionServiceState state) { private void updateChannels(LatestMotionServiceState state) {
DateTimeType date = new DateTimeType(state.latestMotionDetected); DateTimeType date = new DateTimeType(state.latestMotionDetected);
updateState(CHANNEL_LATEST_MOTION, date); updateState(CHANNEL_LATEST_MOTION, date);
} }
private void updateChannels(IlluminanceServiceState state) {
DecimalType illuminance = new DecimalType(state.illuminance);
updateState(CHANNEL_ILLUMINANCE, illuminance);
}
} }

View File

@ -0,0 +1,31 @@
/**
* 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.illuminance;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.boschshc.internal.services.BoschSHCService;
import org.openhab.binding.boschshc.internal.services.illuminance.dto.IlluminanceServiceState;
/**
* Service for the illuminance state of the motion detector sensor.
*
* @author David Pace - Initial contribution
*
*/
@NonNullByDefault
public class IlluminanceService extends BoschSHCService<IlluminanceServiceState> {
public IlluminanceService() {
super("MultiLevelSensor", IlluminanceServiceState.class);
}
}

View File

@ -0,0 +1,39 @@
/**
* 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.illuminance.dto;
import org.openhab.binding.boschshc.internal.services.dto.BoschSHCServiceState;
/**
* Illuminance state of the motion detector sensor.
* <p>
* Example JSON:
*
* <pre>
* {
* "@type": "illuminanceLevelState",
* "illuminance": 32
* }
* </pre>
*
* @author David Pace - Initial contribution
*
*/
public class IlluminanceServiceState extends BoschSHCServiceState {
public IlluminanceServiceState() {
super("illuminanceLevelState");
}
public int illuminance;
}

View File

@ -114,10 +114,15 @@
<channels> <channels>
<channel id="latest-motion" typeId="latest-motion"/> <channel id="latest-motion" typeId="latest-motion"/>
<channel id="illuminance" typeId="illuminance"/>
<channel id="battery-level" typeId="system.battery-level"/> <channel id="battery-level" typeId="system.battery-level"/>
<channel id="low-battery" typeId="system.low-battery"/> <channel id="low-battery" typeId="system.low-battery"/>
</channels> </channels>
<properties>
<property name="thingTypeVersion">1</property>
</properties>
<config-description-ref uri="thing-type:boschshc:device"/> <config-description-ref uri="thing-type:boschshc:device"/>
</thing-type> </thing-type>
@ -490,6 +495,13 @@
<state readOnly="true"/> <state readOnly="true"/>
</channel-type> </channel-type>
<channel-type id="illuminance">
<item-type>Number</item-type>
<label>Illuminance</label>
<description>The illuminance level measured by the sensor (0 to 1000).</description>
<state min="0" max="1000" step="1" readOnly="true"/>
</channel-type>
<channel-type id="level"> <channel-type id="level">
<item-type>Rollershutter</item-type> <item-type>Rollershutter</item-type>
<label>Level</label> <label>Level</label>

View File

@ -2,6 +2,7 @@
<update:update-descriptions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <update:update-descriptions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:update="https://openhab.org/schemas/update-description/v1.0.0" xmlns:update="https://openhab.org/schemas/update-description/v1.0.0"
xsi:schemaLocation="https://openhab.org/schemas/update-description/v1.0.0 https://openhab.org/schemas/update-description-1.0.0.xsd"> xsi:schemaLocation="https://openhab.org/schemas/update-description/v1.0.0 https://openhab.org/schemas/update-description-1.0.0.xsd">
<thing-type uid="boschshc:shc"> <thing-type uid="boschshc:shc">
<instruction-set targetVersion="1"> <instruction-set targetVersion="1">
<add-channel id="scenario-triggered"> <add-channel id="scenario-triggered">
@ -12,4 +13,13 @@
</add-channel> </add-channel>
</instruction-set> </instruction-set>
</thing-type> </thing-type>
<thing-type uid="boschshc:motion-detector">
<instruction-set targetVersion="1">
<add-channel id="illuminance">
<type>boschshc:illuminance</type>
</add-channel>
</instruction-set>
</thing-type>
</update:update-descriptions> </update:update-descriptions>

View File

@ -19,6 +19,7 @@ import org.junit.jupiter.api.Test;
import org.openhab.binding.boschshc.internal.devices.AbstractBatteryPoweredDeviceHandlerTest; import org.openhab.binding.boschshc.internal.devices.AbstractBatteryPoweredDeviceHandlerTest;
import org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants; import org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants;
import org.openhab.core.library.types.DateTimeType; import org.openhab.core.library.types.DateTimeType;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.thing.ChannelUID; import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.ThingTypeUID; import org.openhab.core.thing.ThingTypeUID;
@ -62,4 +63,17 @@ class MotionDetectorHandlerTest extends AbstractBatteryPoweredDeviceHandlerTest<
new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_LATEST_MOTION), new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_LATEST_MOTION),
new DateTimeType("2020-04-03T19:02:19.054Z")); new DateTimeType("2020-04-03T19:02:19.054Z"));
} }
@Test
void testUpdateChannelsIlluminanceService() {
JsonElement jsonObject = JsonParser.parseString("""
{
"@type": "illuminanceLevelState",
"illuminance": 42
}\
""");
getFixture().processUpdate("MultiLevelSensor", jsonObject);
verify(getCallback()).stateUpdated(
new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_ILLUMINANCE), new DecimalType(42));
}
} }