mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 15:11:59 +01:00
- Add new channel definition for silent mode - Implement silent mode service - Add unit tests - Add documentation - Fix some minor documentation issues Closes #14779 Signed-off-by: David Pace <dev@davidpace.de>
This commit is contained in:
parent
1a7a1251d4
commit
cc626de89a
@ -7,7 +7,7 @@ Binding for the Bosch Smart Home.
|
||||
- [In-Wall Switch](#in-wall-switch)
|
||||
- [Compact Smart Plug](#compact-smart-plug)
|
||||
- [Twinguard Smoke Detector](#twinguard-smoke-detector)
|
||||
- [Door/Window Contact](#doorwindow-contact)
|
||||
- [Door/Window Contact](#door-window-contact)
|
||||
- [Motion Detector](#motion-detector)
|
||||
- [Shutter Control](#shutter-control)
|
||||
- [Thermostat](#thermostat)
|
||||
@ -116,6 +116,7 @@ Radiator thermostat
|
||||
| temperature | Number:Temperature | ☐ | Current measured temperature. |
|
||||
| valve-tappet-position | Number:Dimensionless | ☐ | Current open ratio of valve tappet (0 to 100). |
|
||||
| child-lock | Switch | ☑ | Indicates if child lock is active. |
|
||||
| silent-mode | Switch | ☑ | Enables or disables silent mode on thermostats. When enabled, the battery usage is higher. |
|
||||
| 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`). |
|
||||
|
||||
@ -193,7 +194,7 @@ A smart bulb connected to the bridge via Zigbee such as a Ledvance Smart+ bulb.
|
||||
| brightness | Dimmer | ☑ | Regulates the brightness on a percentage scale from 0 to 100%. |
|
||||
| color | Color | ☑ | The color of the emitted light. |
|
||||
|
||||
### Smoke detector
|
||||
### Smoke Detector
|
||||
|
||||
The smoke detector warns you in case of fire.
|
||||
|
||||
|
@ -82,6 +82,7 @@ public class BoschSHCBindingConstants {
|
||||
public static final String CHANNEL_COLOR = "color";
|
||||
public static final String CHANNEL_BRIGHTNESS = "brightness";
|
||||
public static final String CHANNEL_SMOKE_CHECK = "smoke-check";
|
||||
public static final String CHANNEL_SILENT_MODE = "silent-mode";
|
||||
|
||||
// static device/service names
|
||||
public static final String SERVICE_INTRUSION_DETECTION = "intrusionDetectionSystem";
|
||||
|
@ -21,6 +21,8 @@ import org.openhab.binding.boschshc.internal.devices.AbstractBatteryPoweredDevic
|
||||
import org.openhab.binding.boschshc.internal.exceptions.BoschSHCException;
|
||||
import org.openhab.binding.boschshc.internal.services.childlock.ChildLockService;
|
||||
import org.openhab.binding.boschshc.internal.services.childlock.dto.ChildLockServiceState;
|
||||
import org.openhab.binding.boschshc.internal.services.silentmode.SilentModeService;
|
||||
import org.openhab.binding.boschshc.internal.services.silentmode.dto.SilentModeServiceState;
|
||||
import org.openhab.binding.boschshc.internal.services.temperaturelevel.TemperatureLevelService;
|
||||
import org.openhab.binding.boschshc.internal.services.temperaturelevel.dto.TemperatureLevelServiceState;
|
||||
import org.openhab.binding.boschshc.internal.services.valvetappet.ValveTappetService;
|
||||
@ -33,15 +35,18 @@ import org.openhab.core.types.Command;
|
||||
* Handler for a thermostat device.
|
||||
*
|
||||
* @author Christian Oeing - Initial contribution
|
||||
* @author David Pace - Added silent mode service
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public final class ThermostatHandler extends AbstractBatteryPoweredDeviceHandler {
|
||||
|
||||
private ChildLockService childLockService;
|
||||
private SilentModeService silentModeService;
|
||||
|
||||
public ThermostatHandler(Thing thing) {
|
||||
super(thing);
|
||||
this.childLockService = new ChildLockService();
|
||||
this.silentModeService = new SilentModeService();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -51,6 +56,7 @@ public final class ThermostatHandler extends AbstractBatteryPoweredDeviceHandler
|
||||
this.createService(TemperatureLevelService::new, this::updateChannels, List.of(CHANNEL_TEMPERATURE));
|
||||
this.createService(ValveTappetService::new, this::updateChannels, List.of(CHANNEL_VALVE_TAPPET_POSITION));
|
||||
this.registerService(this.childLockService, this::updateChannels, List.of(CHANNEL_CHILD_LOCK));
|
||||
this.registerService(this.silentModeService, this::updateChannels, List.of(CHANNEL_SILENT_MODE));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -61,6 +67,9 @@ public final class ThermostatHandler extends AbstractBatteryPoweredDeviceHandler
|
||||
case CHANNEL_CHILD_LOCK:
|
||||
this.handleServiceCommand(this.childLockService, command);
|
||||
break;
|
||||
case CHANNEL_SILENT_MODE:
|
||||
this.handleServiceCommand(this.silentModeService, command);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -93,4 +102,13 @@ public final class ThermostatHandler extends AbstractBatteryPoweredDeviceHandler
|
||||
private void updateChannels(ChildLockServiceState state) {
|
||||
super.updateState(CHANNEL_CHILD_LOCK, state.getActiveState());
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the channels which are linked to the {@link SilentModeService} of the device.
|
||||
*
|
||||
* @param state current state of {@link SilentModeService}
|
||||
*/
|
||||
private void updateChannels(SilentModeServiceState state) {
|
||||
super.updateState(CHANNEL_SILENT_MODE, state.toOnOffType());
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,44 @@
|
||||
/**
|
||||
* 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.silentmode;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.boschshc.internal.exceptions.BoschSHCException;
|
||||
import org.openhab.binding.boschshc.internal.services.BoschSHCService;
|
||||
import org.openhab.binding.boschshc.internal.services.silentmode.dto.SilentModeServiceState;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.types.Command;
|
||||
|
||||
/**
|
||||
* Service to get and set the silent mode of thermostats.
|
||||
*
|
||||
* @author David Pace - Initial contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class SilentModeService extends BoschSHCService<SilentModeServiceState> {
|
||||
|
||||
public SilentModeService() {
|
||||
super("SilentMode", SilentModeServiceState.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SilentModeServiceState handleCommand(Command command) throws BoschSHCException {
|
||||
if (command instanceof OnOffType onOffCommand) {
|
||||
SilentModeServiceState serviceState = new SilentModeServiceState();
|
||||
serviceState.mode = SilentModeState.fromOnOffType(onOffCommand);
|
||||
return serviceState;
|
||||
}
|
||||
return super.handleCommand(command);
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
/**
|
||||
* 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.silentmode;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
|
||||
/**
|
||||
* Enum for possible silent mode states.
|
||||
*
|
||||
* @author David Pace - Initial contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public enum SilentModeState {
|
||||
MODE_NORMAL,
|
||||
MODE_SILENT;
|
||||
|
||||
public static SilentModeState fromOnOffType(OnOffType onOffType) {
|
||||
return onOffType == OnOffType.ON ? SilentModeState.MODE_SILENT : SilentModeState.MODE_NORMAL;
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
/**
|
||||
* 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.silentmode.dto;
|
||||
|
||||
import org.openhab.binding.boschshc.internal.services.dto.BoschSHCServiceState;
|
||||
import org.openhab.binding.boschshc.internal.services.silentmode.SilentModeState;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
|
||||
/**
|
||||
* Represents the state of the silent mode for thermostats.
|
||||
* <p>
|
||||
* Example JSON for normal mode:
|
||||
*
|
||||
* <pre>
|
||||
* {
|
||||
* "@type": "silentModeState",
|
||||
* "mode": "MODE_NORMAL"
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* Example JSON for silent mode:
|
||||
*
|
||||
* <pre>
|
||||
* {
|
||||
* "@type": "silentModeState",
|
||||
* "mode": "MODE_SILENT"
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @author David Pace - Initial contribution
|
||||
*
|
||||
*/
|
||||
public class SilentModeServiceState extends BoschSHCServiceState {
|
||||
|
||||
public SilentModeServiceState() {
|
||||
super("silentModeState");
|
||||
}
|
||||
|
||||
public SilentModeState mode;
|
||||
|
||||
public OnOffType toOnOffType() {
|
||||
return mode == SilentModeState.MODE_SILENT ? OnOffType.ON : OnOffType.OFF;
|
||||
}
|
||||
}
|
@ -70,7 +70,7 @@ channel-type.boschshc.camera-notification.description = Enables or disables noti
|
||||
channel-type.boschshc.camera-notification.state.option.ENABLED = Enable notifications
|
||||
channel-type.boschshc.camera-notification.state.option.DISABLED = Disable notifications
|
||||
channel-type.boschshc.child-lock.label = Child Lock
|
||||
channel-type.boschshc.child-lock.description = Indicates if it is possible to set the desired temperature on the device.
|
||||
channel-type.boschshc.child-lock.description = Enables or disables the child lock on the device.
|
||||
channel-type.boschshc.combined-rating.label = Combined Rating
|
||||
channel-type.boschshc.combined-rating.description = Combined rating of the air quality.
|
||||
channel-type.boschshc.combined-rating.state.option.GOOD = Good Quality
|
||||
@ -107,6 +107,10 @@ channel-type.boschshc.purity.label = Purity
|
||||
channel-type.boschshc.purity.description = Purity of the air. A higher value indicates a higher pollution.
|
||||
channel-type.boschshc.setpoint-temperature.label = Setpoint Temperature
|
||||
channel-type.boschshc.setpoint-temperature.description = Desired temperature.
|
||||
channel-type.boschshc.silent-mode.label = Silent Mode
|
||||
channel-type.boschshc.silent-mode.description = Enables or disables silent mode on thermostats. When enabled, the battery usage is higher.
|
||||
channel-type.boschshc.silent-mode.state.option.MODE_NORMAL = Silent mode disabled (lower battery usage)
|
||||
channel-type.boschshc.silent-mode.state.option.MODE_SILENT = Silent mode enabled (higher battery usage)
|
||||
channel-type.boschshc.smoke-check.label = Smoke Check State
|
||||
channel-type.boschshc.smoke-check.description = State of last smoke detector check.
|
||||
channel-type.boschshc.smoke-check.state.option.NONE = None
|
||||
|
@ -141,6 +141,7 @@
|
||||
<channel id="temperature" typeId="temperature"/>
|
||||
<channel id="valve-tappet-position" typeId="valve-tappet-position"/>
|
||||
<channel id="child-lock" typeId="child-lock"/>
|
||||
<channel id="silent-mode" typeId="silent-mode"/>
|
||||
<channel id="battery-level" typeId="system.battery-level"/>
|
||||
<channel id="low-battery" typeId="system.low-battery"/>
|
||||
</channels>
|
||||
@ -504,7 +505,19 @@
|
||||
<channel-type id="child-lock">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Child Lock</label>
|
||||
<description>Indicates if it is possible to set the desired temperature on the device.</description>
|
||||
<description>Enables or disables the child lock on the device.</description>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="silent-mode">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Silent Mode</label>
|
||||
<description>Enables or disables silent mode on thermostats. When enabled, the battery usage is higher.</description>
|
||||
<state>
|
||||
<options>
|
||||
<option value="MODE_NORMAL">Silent mode disabled (lower battery usage)</option>
|
||||
<option value="MODE_SILENT">Silent mode enabled (higher battery usage)</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
|
@ -30,6 +30,8 @@ import org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants;
|
||||
import org.openhab.binding.boschshc.internal.exceptions.BoschSHCException;
|
||||
import org.openhab.binding.boschshc.internal.services.childlock.dto.ChildLockServiceState;
|
||||
import org.openhab.binding.boschshc.internal.services.childlock.dto.ChildLockState;
|
||||
import org.openhab.binding.boschshc.internal.services.silentmode.SilentModeState;
|
||||
import org.openhab.binding.boschshc.internal.services.silentmode.dto.SilentModeServiceState;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
@ -51,10 +53,12 @@ import com.google.gson.JsonParser;
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class ThermostatHandlerTest extends AbstractBatteryPoweredDeviceHandlerTest<ThermostatHandler> {
|
||||
class ThermostatHandlerTest extends AbstractBatteryPoweredDeviceHandlerTest<ThermostatHandler> {
|
||||
|
||||
private @Captor @NonNullByDefault({}) ArgumentCaptor<ChildLockServiceState> childLockServiceStateCaptor;
|
||||
|
||||
private @Captor @NonNullByDefault({}) ArgumentCaptor<SilentModeServiceState> silentModeServiceStateCaptor;
|
||||
|
||||
@Override
|
||||
protected ThermostatHandler createFixture() {
|
||||
return new ThermostatHandler(getThing());
|
||||
@ -71,7 +75,7 @@ public class ThermostatHandlerTest extends AbstractBatteryPoweredDeviceHandlerTe
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleCommand()
|
||||
void testHandleCommandChildLockService()
|
||||
throws InterruptedException, TimeoutException, ExecutionException, BoschSHCException {
|
||||
getFixture().handleCommand(new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_CHILD_LOCK),
|
||||
OnOffType.ON);
|
||||
@ -81,7 +85,18 @@ public class ThermostatHandlerTest extends AbstractBatteryPoweredDeviceHandlerTe
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleCommandUnknownCommand() {
|
||||
void testHandleCommandSilentModeService()
|
||||
throws InterruptedException, TimeoutException, ExecutionException, BoschSHCException {
|
||||
getFixture().handleCommand(new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_SILENT_MODE),
|
||||
OnOffType.ON);
|
||||
verify(getBridgeHandler()).putState(eq(getDeviceID()), eq("SilentMode"),
|
||||
silentModeServiceStateCaptor.capture());
|
||||
SilentModeServiceState state = silentModeServiceStateCaptor.getValue();
|
||||
assertSame(SilentModeState.MODE_SILENT, state.mode);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHandleCommandUnknownCommandChildLockService() {
|
||||
getFixture().handleCommand(new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_CHILD_LOCK),
|
||||
new DecimalType(42));
|
||||
ThingStatusInfo expectedThingStatusInfo = ThingStatusInfoBuilder
|
||||
@ -93,7 +108,19 @@ public class ThermostatHandlerTest extends AbstractBatteryPoweredDeviceHandlerTe
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateChannelsTemperatureLevelService() {
|
||||
void testHandleCommandUnknownCommandSilentModeService() {
|
||||
getFixture().handleCommand(new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_SILENT_MODE),
|
||||
new DecimalType(42));
|
||||
ThingStatusInfo expectedThingStatusInfo = ThingStatusInfoBuilder
|
||||
.create(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR)
|
||||
.withDescription(
|
||||
"Error when service SilentMode should handle command org.openhab.core.library.types.DecimalType: SilentMode: Can not handle command org.openhab.core.library.types.DecimalType")
|
||||
.build();
|
||||
verify(getCallback()).statusUpdated(getThing(), expectedThingStatusInfo);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdateChannelsTemperatureLevelService() {
|
||||
JsonElement jsonObject = JsonParser.parseString(
|
||||
"{\n" + " \"@type\": \"temperatureLevelState\",\n" + " \"temperature\": 21.5\n" + " }");
|
||||
getFixture().processUpdate("TemperatureLevel", jsonObject);
|
||||
@ -103,7 +130,7 @@ public class ThermostatHandlerTest extends AbstractBatteryPoweredDeviceHandlerTe
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateChannelsValveTappetService() {
|
||||
void testUpdateChannelsValveTappetService() {
|
||||
JsonElement jsonObject = JsonParser
|
||||
.parseString("{\n" + " \"@type\": \"valveTappetState\",\n" + " \"position\": 42\n" + " }");
|
||||
getFixture().processUpdate("ValveTappet", jsonObject);
|
||||
@ -113,11 +140,27 @@ public class ThermostatHandlerTest extends AbstractBatteryPoweredDeviceHandlerTe
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateChannelsChildLockService() {
|
||||
void testUpdateChannelsChildLockService() {
|
||||
JsonElement jsonObject = JsonParser
|
||||
.parseString("{\n" + " \"@type\": \"childLockState\",\n" + " \"childLock\": \"ON\"\n" + " }");
|
||||
getFixture().processUpdate("Thermostat", jsonObject);
|
||||
verify(getCallback()).stateUpdated(
|
||||
new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_CHILD_LOCK), OnOffType.ON);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdateChannelsSilentModeService() {
|
||||
JsonElement jsonObject = JsonParser.parseString("{\"@type\": \"silentModeState\", \"mode\": \"MODE_SILENT\"}");
|
||||
getFixture().processUpdate("SilentMode", jsonObject);
|
||||
verify(getCallback()).stateUpdated(
|
||||
new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_SILENT_MODE), OnOffType.ON);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdateChannelsSilentModeServiceNormal() {
|
||||
JsonElement jsonObject = JsonParser.parseString("{\"@type\": \"silentModeState\", \"mode\": \"MODE_NORMAL\"}");
|
||||
getFixture().processUpdate("SilentMode", jsonObject);
|
||||
verify(getCallback()).stateUpdated(
|
||||
new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_SILENT_MODE), OnOffType.OFF);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* 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.silentmode;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link SilentModeState}.
|
||||
*
|
||||
* @author David Pace - Initial contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
class SilentModeStateTest {
|
||||
|
||||
@Test
|
||||
void fromOnOffType() {
|
||||
assertSame(SilentModeState.MODE_NORMAL, SilentModeState.fromOnOffType(OnOffType.OFF));
|
||||
assertSame(SilentModeState.MODE_SILENT, SilentModeState.fromOnOffType(OnOffType.ON));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user