Skip to content

Commit e662320

Browse files
authored
[livisismarthome] Support for the indoor siren device added (openhab#16914)
Signed-off-by: Sven Strohschein <[email protected]> Signed-off-by: Sven Strohschein <[email protected]>
1 parent 33a9894 commit e662320

File tree

12 files changed

+198
-12
lines changed

12 files changed

+198
-12
lines changed

bundles/org.openhab.binding.livisismarthome/README.md

+2
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ The channels are described in detail in the next chapter.
4141
| WSC2 | Wall Mounted Smart Controller | button1, button2, button1Count, button2Count, batteryLow |
4242
| WSD | Wall Mounted Smoke Detector, old version | smoke, alarm, batteryLow |
4343
| WSD2 | Wall Mounted Smoke Detector, new version | smoke, alarm, batteryLow |
44+
| SIR | Wall Mounted Siren, indoor | siren, batteryLow |
4445

4546
Powermeter devices
4647

@@ -94,6 +95,7 @@ However, only devices will appear that are added in the LIVISI SmartHome app bef
9495
| operationMode | String | The mode of a thermostat (auto/manual) | RST, RST2, WRT |
9596
| rollershutter | Rollershutter | Controls a roller shutter | ISR2 |
9697
| targetTemperature | Number | Sets the target temperature in °C (min 6 °C, max 30 °C) | RST, RST2, WRT |
98+
| siren | Switch | Switches the siren (ON/OFF) | SIR |
9799
| smoke | Switch | Indicates, if smoke was detected (ON/OFF) | WSD, WSD2 |
98100
| status | String | Status of the SHC (ACTIVE/NORMAL, INITIALIZING/REBOOTING or SHUTTINGDOWN) | SHC (bridge) |
99101
| switch | Switch | A switch to turn the device or variable on/off (ON/OFF) | ISS2, PSS, PSSO, VariableActuator |

bundles/org.openhab.binding.livisismarthome/src/main/java/org/openhab/binding/livisismarthome/internal/LivisiBindingConstants.java

+12-6
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ public class LivisiBindingConstants {
7373
public static final String DEVICE_ISS2 = "ISS2"; // inwall smart switch
7474
public static final String DEVICE_WSD = "WSD"; // wall mounted smoke detector
7575
public static final String DEVICE_WSD2 = "WSD2"; // wall mounted smoke detector
76+
public static final String DEVICE_SIR = "SIR"; // wall mounted siren indoor
7677
public static final String DEVICE_WMD = "WMD"; // wall mounted motion detector indoor
7778
public static final String DEVICE_WMDO = "WMDO"; // wall mounted motion detector outdoor
7879
public static final String DEVICE_WSC2 = "WSC2"; // wall mounted smart controller (2 buttons)
@@ -88,12 +89,12 @@ public class LivisiBindingConstants {
8889

8990
public static final Set<String> SUPPORTED_DEVICES = Set.of(DEVICE_SHC, DEVICE_SHCA, DEVICE_PSS, DEVICE_PSSO,
9091
DEVICE_BT_PSS, DEVICE_VARIABLE_ACTUATOR, DEVICE_RST, DEVICE_RST2, DEVICE_WRT, DEVICE_WDS, DEVICE_ISS2,
91-
DEVICE_WSD, DEVICE_WSD2, DEVICE_WMD, DEVICE_WMDO, DEVICE_WSC2, DEVICE_BRC8, DEVICE_ISC2, DEVICE_ISD2,
92-
DEVICE_ISR2, DEVICE_PSD, DEVICE_ANALOG_METER, DEVICE_GENERATION_METER, DEVICE_SMART_METER,
92+
DEVICE_WSD, DEVICE_WSD2, DEVICE_SIR, DEVICE_WMD, DEVICE_WMDO, DEVICE_WSC2, DEVICE_BRC8, DEVICE_ISC2,
93+
DEVICE_ISD2, DEVICE_ISR2, DEVICE_PSD, DEVICE_ANALOG_METER, DEVICE_GENERATION_METER, DEVICE_SMART_METER,
9394
DEVICE_TWO_WAY_METER);
9495

9596
public static final Set<String> BATTERY_POWERED_DEVICES = Set.of(DEVICE_ISC2, DEVICE_RST, DEVICE_RST2, DEVICE_WRT,
96-
DEVICE_WDS, DEVICE_WSD, DEVICE_WSD2, DEVICE_WMD, DEVICE_WMDO, DEVICE_WSC2, DEVICE_BRC8);
97+
DEVICE_WDS, DEVICE_WSD, DEVICE_WSD2, DEVICE_SIR, DEVICE_WMD, DEVICE_WMDO, DEVICE_WSC2, DEVICE_BRC8);
9798

9899
// List of all Thing Type UIDs
99100
public static final ThingTypeUID THING_TYPE_BRIDGE = new ThingTypeUID(BINDING_ID, "bridge");
@@ -109,6 +110,7 @@ public class LivisiBindingConstants {
109110
public static final ThingTypeUID THING_TYPE_ISS2 = new ThingTypeUID(BINDING_ID, DEVICE_ISS2);
110111
public static final ThingTypeUID THING_TYPE_WSD = new ThingTypeUID(BINDING_ID, DEVICE_WSD);
111112
public static final ThingTypeUID THING_TYPE_WSD2 = new ThingTypeUID(BINDING_ID, DEVICE_WSD2);
113+
public static final ThingTypeUID THING_TYPE_SIR = new ThingTypeUID(BINDING_ID, DEVICE_SIR);
112114
public static final ThingTypeUID THING_TYPE_WMD = new ThingTypeUID(BINDING_ID, DEVICE_WMD);
113115
public static final ThingTypeUID THING_TYPE_WMDO = new ThingTypeUID(BINDING_ID, DEVICE_WMDO);
114116
public static final ThingTypeUID THING_TYPE_WSC2 = new ThingTypeUID(BINDING_ID, DEVICE_WSC2);
@@ -125,9 +127,10 @@ public class LivisiBindingConstants {
125127

126128
public static final Set<ThingTypeUID> SUPPORTED_DEVICE_THING_TYPES = Set.of(THING_TYPE_PSS, THING_TYPE_PSSO,
127129
THING_TYPE_BT_PSS, THING_TYPE_VARIABLE_ACTUATOR, THING_TYPE_RST, THING_TYPE_RST2, THING_TYPE_WRT,
128-
THING_TYPE_WDS, THING_TYPE_ISS2, THING_TYPE_WSD, THING_TYPE_WSD2, THING_TYPE_WMD, THING_TYPE_WMDO,
129-
THING_TYPE_WSC2, THING_TYPE_BRC8, THING_TYPE_ISC2, THING_TYPE_ISD2, THING_TYPE_ISR2, THING_TYPE_PSD,
130-
THING_TYPE_ANALOG_METER, THING_TYPE_GENERATION_METER, THING_TYPE_SMART_METER, THING_TYPE_TWO_WAY_METER);
130+
THING_TYPE_WDS, THING_TYPE_ISS2, THING_TYPE_WSD, THING_TYPE_WSD2, THING_TYPE_SIR, THING_TYPE_WMD,
131+
THING_TYPE_WMDO, THING_TYPE_WSC2, THING_TYPE_BRC8, THING_TYPE_ISC2, THING_TYPE_ISD2, THING_TYPE_ISR2,
132+
THING_TYPE_PSD, THING_TYPE_ANALOG_METER, THING_TYPE_GENERATION_METER, THING_TYPE_SMART_METER,
133+
THING_TYPE_TWO_WAY_METER);
131134

132135
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Stream
133136
.concat(Stream.of(THING_TYPE_BRIDGE), SUPPORTED_DEVICE_THING_TYPES.stream()).collect(Collectors.toSet());
@@ -140,6 +143,9 @@ public class LivisiBindingConstants {
140143
public static final String CHANNEL_CONTACT = "contact";
141144
public static final String CHANNEL_SMOKE = "smoke";
142145
public static final String CHANNEL_ALARM = "alarm";
146+
public static final String CHANNEL_SIREN_ALARM = "sirenAlarm";
147+
public static final String CHANNEL_SIREN_NOTIFICATION = "sirenNotification";
148+
public static final String CHANNEL_SIREN_FEEDBACK = "sirenFeedback";
143149
public static final String CHANNEL_MOTION_COUNT = "motionCount";
144150
public static final String CHANNEL_LUMINANCE = "luminance";
145151
public static final String CHANNEL_OPERATION_MODE = "operationMode";

bundles/org.openhab.binding.livisismarthome/src/main/java/org/openhab/binding/livisismarthome/internal/client/LivisiClient.java

+8
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,14 @@ public void setAlarmActuatorState(final String capabilityId, final boolean alarm
297297
new StateActionSetterDTO(capabilityId, CapabilityDTO.TYPE_ALARMACTUATOR, alarmState));
298298
}
299299

300+
/**
301+
* Sets the siren state.
302+
*/
303+
public void setSirenActuatorState(final String capabilityId, final String activeChannel) throws IOException {
304+
executePost(createActionURL(),
305+
new StateActionSetterDTO(capabilityId, CapabilityDTO.TYPE_SIRENACTUATOR, activeChannel));
306+
}
307+
300308
/**
301309
* Load the device and returns a {@link List} of {@link DeviceDTO}s.
302310
* VariableActuators are returned additionally (independent from the device ids),

bundles/org.openhab.binding.livisismarthome/src/main/java/org/openhab/binding/livisismarthome/internal/client/api/entity/action/ActionParamsDTO.java

+15
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ public class ActionParamsDTO {
2828
private IntegerActionParamDTO shutterLevel;
2929
private StringActionParamDTO operationMode;
3030
private StringActionParamDTO rampDirection;
31+
private StringActionParamDTO activeChannel;
3132

3233
/**
3334
* @return the onState
@@ -126,4 +127,18 @@ public StringActionParamDTO getRampDirection() {
126127
public void setRampDirection(StringActionParamDTO rampDirection) {
127128
this.rampDirection = rampDirection;
128129
}
130+
131+
/**
132+
* @return the activeChannel
133+
*/
134+
public StringActionParamDTO getActiveChannel() {
135+
return activeChannel;
136+
}
137+
138+
/**
139+
* @param activeChannel the operationMode to set
140+
*/
141+
public void setActiveChannel(StringActionParamDTO activeChannel) {
142+
this.activeChannel = activeChannel;
143+
}
129144
}

bundles/org.openhab.binding.livisismarthome/src/main/java/org/openhab/binding/livisismarthome/internal/client/api/entity/action/StateActionSetterDTO.java

+17-6
Original file line numberDiff line numberDiff line change
@@ -31,22 +31,22 @@ public class StateActionSetterDTO extends ActionDTO {
3131
* @param capabilityId String of the 32 character capability id
3232
* @param capabilityType the type of the {@link CapabilityDTO}, {@link CapabilityDTO#TYPE_SWITCHACTUATOR} or
3333
* {@link CapabilityDTO#TYPE_VARIABLEACTUATOR}
34-
* @param state the new state as boolean (true=on, false=off)
34+
* @param newState the new newState as boolean (true=on, false=off)
3535
*/
36-
public StateActionSetterDTO(String capabilityId, String capabilityType, boolean state) {
36+
public StateActionSetterDTO(String capabilityId, String capabilityType, boolean newState) {
3737
setType(ACTION_TYPE_SETSTATE);
3838
setTargetCapabilityById(capabilityId);
3939
final ActionParamsDTO params = new ActionParamsDTO();
4040

4141
if (CapabilityDTO.TYPE_SWITCHACTUATOR.equals(capabilityType)) {
42-
params.setOnState(new BooleanActionParamDTO(CONSTANT, state));
42+
params.setOnState(new BooleanActionParamDTO(CONSTANT, newState));
4343
} else if (CapabilityDTO.TYPE_VARIABLEACTUATOR.equals(capabilityType)) {
44-
params.setValue(new BooleanActionParamDTO(CONSTANT, state));
44+
params.setValue(new BooleanActionParamDTO(CONSTANT, newState));
4545
} else if (CapabilityDTO.TYPE_ALARMACTUATOR.equals(capabilityType)) {
46-
params.setOnState(new BooleanActionParamDTO(CONSTANT, state));
46+
params.setOnState(new BooleanActionParamDTO(CONSTANT, newState));
4747
} else if (CapabilityDTO.TYPE_THERMOSTATACTUATOR.equals(capabilityType)) {
4848
final String operationMode;
49-
if (state) {
49+
if (newState) {
5050
operationMode = CapabilityStateDTO.STATE_VALUE_OPERATION_MODE_AUTO;
5151
} else {
5252
operationMode = CapabilityStateDTO.STATE_VALUE_OPERATION_MODE_MANUAL;
@@ -56,6 +56,17 @@ public StateActionSetterDTO(String capabilityId, String capabilityType, boolean
5656
setParams(params);
5757
}
5858

59+
public StateActionSetterDTO(String capabilityId, String capabilityType, String newState) {
60+
setType(ACTION_TYPE_SETSTATE);
61+
setTargetCapabilityById(capabilityId);
62+
final ActionParamsDTO params = new ActionParamsDTO();
63+
64+
if (CapabilityDTO.TYPE_SIRENACTUATOR.equals(capabilityType)) {
65+
params.setActiveChannel(new StringActionParamDTO(CONSTANT, newState));
66+
}
67+
setParams(params);
68+
}
69+
5970
/**
6071
* Constructs a new {@link StateActionSetterDTO}.
6172
*

bundles/org.openhab.binding.livisismarthome/src/main/java/org/openhab/binding/livisismarthome/internal/client/api/entity/capability/CapabilityDTO.java

+10
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ public class CapabilityDTO {
2929
public static final String TYPE_WINDOWDOORSENSOR = "WindowDoorSensor";
3030
public static final String TYPE_SMOKEDETECTORSENSOR = "SmokeDetectorSensor";
3131
public static final String TYPE_ALARMACTUATOR = "AlarmActuator";
32+
public static final String TYPE_SIRENACTUATOR = "SirenActuator";
3233
public static final String TYPE_MOTIONDETECTIONSENSOR = "MotionDetectionSensor";
3334
public static final String TYPE_LUMINANCESENSOR = "LuminanceSensor";
3435
public static final String TYPE_PUSHBUTTONSENSOR = "PushButtonSensor";
@@ -221,6 +222,15 @@ public boolean isTypeAlarmActuator() {
221222
return TYPE_ALARMACTUATOR.equals(getType());
222223
}
223224

225+
/**
226+
* Returns true, if the {@link CapabilityDTO} is of type SirenActuator.
227+
*
228+
* @return true if it is an SirenActuator, otherwise false
229+
*/
230+
public boolean isTypeSirenActuator() {
231+
return TYPE_SIRENACTUATOR.equals(getType());
232+
}
233+
224234
/**
225235
* Returns true, if the {@link CapabilityDTO} is of type MotionDetectionSensor.
226236
*

bundles/org.openhab.binding.livisismarthome/src/main/java/org/openhab/binding/livisismarthome/internal/client/api/entity/capability/CapabilityStateDTO.java

+8
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,14 @@ public void setAlarmActuatorState(final Boolean on) {
164164
getState().getOnState().setValue(on);
165165
}
166166

167+
public String getSirenActuatorState() {
168+
return getState().getActiveChannelState().getValue();
169+
}
170+
171+
public void setSirenActuatorState(final String activeChannel) {
172+
getState().getActiveChannelState().setValue(activeChannel);
173+
}
174+
167175
public Integer getMotionDetectionSensorState() {
168176
return getState().getMotionDetectedCountState().getValue();
169177
}

bundles/org.openhab.binding.livisismarthome/src/main/java/org/openhab/binding/livisismarthome/internal/client/api/entity/event/EventPropertiesDTO.java

+15
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public class EventPropertiesDTO {
2626
/** Writable capability properties **/
2727
private Integer dimLevel;
2828
private Boolean onState;
29+
private String activeChannel;
2930
private String operationMode;
3031
private String operationStatus;
3132
private Double pointTemperature;
@@ -128,6 +129,20 @@ public void setOnState(final Boolean onState) {
128129
this.onState = onState;
129130
}
130131

132+
/**
133+
* @return the activeChannel
134+
*/
135+
public String getActiveChannel() {
136+
return activeChannel;
137+
}
138+
139+
/**
140+
* @param activeChannel the activeChannel to set
141+
*/
142+
public void setActiveChannel(final String activeChannel) {
143+
this.activeChannel = activeChannel;
144+
}
145+
131146
/**
132147
* @return the operationMode
133148
*/

bundles/org.openhab.binding.livisismarthome/src/main/java/org/openhab/binding/livisismarthome/internal/handler/LivisiBridgeHandler.java

+12
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,18 @@ public void commandSwitchAlarm(final String deviceId, final boolean alarmState)
761761
(capabilityId) -> client.setAlarmActuatorState(capabilityId, alarmState));
762762
}
763763

764+
/**
765+
* Sends the command to turn the siren of the {@link DeviceDTO} with the given id on or off. Is called by the
766+
* {@link LivisiDeviceHandler} for siren {@link DeviceDTO}s like SIR.
767+
*
768+
* @param deviceId device id
769+
* @param sirenState siren state (boolean)
770+
*/
771+
public void commandSwitchSiren(final String deviceId, final String sirenState) {
772+
executeCommand(deviceId, CapabilityDTO.TYPE_SIRENACTUATOR,
773+
(capabilityId) -> client.setSirenActuatorState(capabilityId, sirenState));
774+
}
775+
764776
/**
765777
* Sends the command to set the operation mode of the {@link DeviceDTO} with the given deviceId to auto (or manual,
766778
* if

bundles/org.openhab.binding.livisismarthome/src/main/java/org/openhab/binding/livisismarthome/internal/handler/LivisiDeviceHandler.java

+49
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ public class LivisiDeviceHandler extends BaseThingHandler implements DeviceStatu
6868
private static final int MAX_TEMPERATURE_CELSIUS = 30;
6969
private static final String LONG_PRESS = "LongPress";
7070
private static final String SHORT_PRESS = "ShortPress";
71+
private static final String SIREN_ALARM = "Alarm";
72+
private static final String SIREN_NOTIFICATION = "Notification";
73+
private static final String SIREN_FEEDBACK = "Feedback";
74+
private static final String SIREN_NONE = "None";
7175

7276
private final Logger logger = LoggerFactory.getLogger(LivisiDeviceHandler.class);
7377
private final Object lock = new Object();
@@ -120,6 +124,12 @@ private void executeCommand(ChannelUID channelUID, Command command, LivisiBridge
120124
commandSetOperationMode(command, bridgeHandler);
121125
} else if (CHANNEL_ALARM.equals(channelUID.getId())) {
122126
commandSwitchAlarm(command, bridgeHandler);
127+
} else if (CHANNEL_SIREN_ALARM.equals(channelUID.getId())) {
128+
commandSwitchSiren(command, SIREN_ALARM, bridgeHandler);
129+
} else if (CHANNEL_SIREN_NOTIFICATION.equals(channelUID.getId())) {
130+
commandSwitchSiren(command, SIREN_NOTIFICATION, bridgeHandler);
131+
} else if (CHANNEL_SIREN_FEEDBACK.equals(channelUID.getId())) {
132+
commandSwitchSiren(command, SIREN_FEEDBACK, bridgeHandler);
123133
} else {
124134
logger.debug("UNSUPPORTED channel {} for device {}.", channelUID.getId(), deviceId);
125135
}
@@ -214,6 +224,14 @@ private void commandSwitchAlarm(Command command, LivisiBridgeHandler bridgeHandl
214224
}
215225
}
216226

227+
private void commandSwitchSiren(Command command, String notificationSound, LivisiBridgeHandler bridgeHandler) {
228+
if (command instanceof OnOffType && OnOffType.ON.equals(command)) {
229+
bridgeHandler.commandSwitchSiren(deviceId, notificationSound);
230+
} else {
231+
bridgeHandler.commandSwitchSiren(deviceId, SIREN_NONE);
232+
}
233+
}
234+
217235
@Override
218236
public void initialize() {
219237
logger.debug("Initializing LIVISI SmartHome device handler.");
@@ -473,6 +491,10 @@ private boolean updateDevice(EventDTO event, CapabilityDTO capability) {
473491
} else if (capability.isTypeAlarmActuator()) {
474492
capabilityState.setAlarmActuatorState(event.getProperties().getOnState());
475493

494+
// SirenActuator
495+
} else if (capability.isTypeSirenActuator()) {
496+
capabilityState.setSirenActuatorState(event.getProperties().getActiveChannel());
497+
476498
// MotionDetectionSensor
477499
} else if (capability.isTypeMotionDetectionSensor()) {
478500
capabilityState.setMotionDetectionSensorState(event.getProperties().getMotionDetectedCount());
@@ -638,6 +660,9 @@ private void updateCapabilityChannels(DeviceDTO device, CapabilityDTO capability
638660
case CapabilityDTO.TYPE_ALARMACTUATOR:
639661
updateAlarmActuatorChannels(capability);
640662
break;
663+
case CapabilityDTO.TYPE_SIRENACTUATOR:
664+
updateSirenActuatorChannels(capability);
665+
break;
641666
case CapabilityDTO.TYPE_MOTIONDETECTIONSENSOR:
642667
updateMotionDetectionSensorChannels(capability);
643668
break;
@@ -812,6 +837,30 @@ private void updateAlarmActuatorChannels(CapabilityDTO capability) {
812837
}
813838
}
814839

840+
private void updateSirenActuatorChannels(CapabilityDTO capability) {
841+
final String sirenState = capability.getCapabilityState().getSirenActuatorState();
842+
if (sirenState != null) {
843+
switch (sirenState) {
844+
case SIREN_ALARM:
845+
updateState(CHANNEL_SIREN_ALARM, OnOffType.ON);
846+
break;
847+
case SIREN_NOTIFICATION:
848+
updateState(CHANNEL_SIREN_NOTIFICATION, OnOffType.ON);
849+
break;
850+
case SIREN_FEEDBACK:
851+
updateState(CHANNEL_SIREN_FEEDBACK, OnOffType.ON);
852+
break;
853+
default:
854+
// "None" and everything else switches the siren sound off
855+
updateState(CHANNEL_SIREN_ALARM, OnOffType.OFF);
856+
updateState(CHANNEL_SIREN_NOTIFICATION, OnOffType.OFF);
857+
updateState(CHANNEL_SIREN_FEEDBACK, OnOffType.OFF);
858+
}
859+
} else {
860+
logStateNull(capability);
861+
}
862+
}
863+
815864
private void updateMotionDetectionSensorChannels(CapabilityDTO capability) {
816865
final Integer motionCount = capability.getCapabilityState().getMotionDetectionSensorState();
817866
if (motionCount != null) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<thing:thing-descriptions bindingId="livisismarthome"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
5+
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
6+
7+
<thing-type id="SIR">
8+
<supported-bridge-type-refs>
9+
<bridge-type-ref id="bridge"/>
10+
</supported-bridge-type-refs>
11+
12+
<label>Wall Mounted Siren Indoor (SIR)</label>
13+
<description>A battery powered indoor siren.</description>
14+
15+
<channels>
16+
<channel id="sirenAlarm" typeId="sirenAlarmActuator"/>
17+
<channel id="sirenNotification" typeId="sirenNotificationActuator"/>
18+
<channel id="sirenFeedback" typeId="sirenFeedbackActuator"/>
19+
<channel id="batteryLow" typeId="system.low-battery"/>
20+
</channels>
21+
22+
<representation-property>id</representation-property>
23+
24+
<config-description-ref uri="thing-type:livisismarthome:config"/>
25+
</thing-type>
26+
</thing:thing-descriptions>

0 commit comments

Comments
 (0)