diff --git a/devicetypes/alarmdecoder/alarmdecoder-network-appliance.src/alarmdecoder-network-appliance.groovy b/devicetypes/alarmdecoder/alarmdecoder-network-appliance.src/alarmdecoder-network-appliance.groovy index 35df681..704c6d0 100644 --- a/devicetypes/alarmdecoder/alarmdecoder-network-appliance.src/alarmdecoder-network-appliance.groovy +++ b/devicetypes/alarmdecoder/alarmdecoder-network-appliance.src/alarmdecoder-network-appliance.groovy @@ -83,6 +83,8 @@ metadata { "armed", "armed_stay", "armed_stay_exit", + "armed_night", + "armed_night_exit", "disarmed", "alarming", "fire", @@ -171,6 +173,16 @@ metadata { "armed_stay_exit", label: 'Armed (exit-now)', icon: "st.nest.nest-away", + backgroundColor: "#ffa81e") + attributeState( + "armed_night", + label: 'Armed (night)', + icon: "st.security.alarm.on", + backgroundColor: "#ffa81e") + attributeState( + "armed_night_exit", + label: 'Armed (exit-now)', + icon: "st.nest.nest-away", backgroundColor: "#ffa81e") attributeState( "disarmed", @@ -227,6 +239,16 @@ metadata { action: "disarm", icon: "st.security.alarm.off", label: "DISARM") + state( + "armed_night", + action: "disarm", + icon: "st.security.alarm.off", + label: "DISARM") + state( + "armed_night_exit", + action: "disarm", + icon: "st.security.alarm.off", + label: "DISARM") state( "disarmed", action: "arm_away", @@ -280,6 +302,16 @@ metadata { action: "disarm", icon: "st.security.alarm.off", label: "DISARM") + state( + "armed_night", + action: "exit", + icon: "st.nest.nest-away", + label: "EXIT") + state( + "armed_night_exit", + action: "disarm", + icon: "st.security.alarm.off", + label: "DISARM") state( "disarmed", action: "arm_stay", @@ -675,6 +707,7 @@ def updated() { state.panel_ready = true state.panel_armed = false state.panel_armed_stay = false + state.panel_armed_night = false state.panel_exit = false state.panel_fire_detected = false state.panel_alarming = false @@ -881,6 +914,23 @@ def arm_stay() { return send_keys(keys) } +/** + * arm_night() + * Sends an arm night command to the panel + */ +def arm_night() { + log.trace("--- arm_night") + if (settings.panel_type == "ADEMCO") { + return send_keys("${user_code}33") + } + else if (settings.panel_type == "DSC") { + arm_stay() + return send_keys("*1") + } + else + log.warn("--- arm_night: unknown panel_type.") +} + /** * fire() * Sends an fire alarm command to the panel @@ -1167,11 +1217,16 @@ def update_state(data) { if (data.panel_exit) { if (data.panel_armed_stay) { panel_state = "armed_stay_exit" + if (data.panel_entry_delay_off == false && data.panel_perimeter_only == true) + panel_state = "armed_night_exit" } else { panel_state = "armed_exit" } } else { - panel_state = (data.panel_armed_stay ? "armed_stay" : "armed") + if (data.panel_armed_stay && data.panel_entry_delay_off == false && data.panel_perimeter_only == true) + panel_state = "armed_night" + else + panel_state = (data.panel_armed_stay ? "armed_stay" : "armed") } } @@ -1196,18 +1251,45 @@ def update_state(data) { isStateChange: true) // If armed STAY changes data.panel_armed_stay - if (forceguiUpdate || data.panel_armed_stay != state.panel_armed_stay) { + if (forceguiUpdate || data.panel_armed_stay != state.panel_armed_stay) { if (data.panel_armed_stay) { - events << createEvent( - name: "arm-stay-set", - value: "on", - displayed: true, - isStateChange: true) - events << createEvent( - name: "arm-away-set", - value: "off", - displayed: true, - isStateChange: true) + + if (data.panel_entry_delay_off == false && data.panel_perimeter_only) + { + events << createEvent( + name: "arm-stay-set", + value: "off", + displayed: true, + isStateChange: true) + events << createEvent( + name: "arm-away-set", + value: "off", + displayed: true, + isStateChange: true) + events << createEvent( + name: "arm-night-set", + value: "on", + displayed: true, + isStateChange: true) + } + else + { + events << createEvent( + name: "arm-stay-set", + value: "on", + displayed: true, + isStateChange: true) + events << createEvent( + name: "arm-away-set", + value: "off", + displayed: true, + isStateChange: true) + events << createEvent( + name: "arm-night-set", + value: "off", + displayed: true, + isStateChange: true) + } } } @@ -1223,6 +1305,11 @@ def update_state(data) { name: "arm-stay-set", value: "off", displayed: true, + isStateChange: true) + events << createEvent( + name: "arm-night-set", + value: "off", + displayed: true, isStateChange: true) events << createEvent( name: "disarm-set", @@ -1289,7 +1376,11 @@ def update_state(data) { if (armed) { alarm_status = "away" if (data.panel_armed_stay == true) + { alarm_status = "stay" + if (!data.panel_entry_delay_off && data.panel_perimeter_only) + alarm_status = "night" + } } // Create an event to notify Smart Home Monitor in our service. @@ -1334,6 +1425,7 @@ def update_state(data) { state.panel_chime = data.chime state.panel_perimeter_only = data.panel_perimeter_only state.panel_entry_delay_off = data.panel_entry_delay_off + state.panel_armed_night = data.panel_armed_stay && data.panel_perimeter_only && !data.panel_entry_delay_off } return events } @@ -1685,4 +1777,4 @@ def _get_api_key() { */ def getStateValue(key) { return state[key] -} +} \ No newline at end of file diff --git a/smartapps/alarmdecoder/alarmdecoder-service.src/alarmdecoder-service.groovy b/smartapps/alarmdecoder/alarmdecoder-service.src/alarmdecoder-service.groovy index 1e4a9cd..74c7881 100644 --- a/smartapps/alarmdecoder/alarmdecoder-service.src/alarmdecoder-service.groovy +++ b/smartapps/alarmdecoder/alarmdecoder-service.src/alarmdecoder-service.groovy @@ -1770,6 +1770,31 @@ def armStaySet(evt) { } } +/** + * send event to armNight device to set state + */ +def armNightSet(evt) { + if (debug) log.debug("armStaySet ${evt.value}") + def d = getChildDevice("${getDeviceKey()}:armNight") + if (!d) { + log.info("armNightSet: Could not find 'armNight' device.") + } else { + d.sendEvent( + name: "switch", + value: evt.value, + isStateChange: true, + filtered: true + ) + } + + d = getChildDevice("${getDeviceKey()}:armNightStatus") + if (!d) { + log.info("armNightSet: Could not find 'armNightStatus' device.") + } else { + _sendEventTranslate(d, evt.value) + } +} + /** * send event to alarmbell indicator device to set state */ @@ -2199,7 +2224,15 @@ def monitorAlarmHandler(evt) { } else { log.trace "monitorAlarmHandler -- no send arm_stay already set" } - } else if (evt.value == "disarmed") { + } else if (evt.value == "armedNight") { + // do not send if already in that state. + if (!device.getStateValue("panel_armed") && + !device.getStateValue("panel_armed_night")) { + device.arm_night() + } else { + log.trace "monitorAlarmHandler -- no send arm_night already set" + } + } else if (evt.value == "disarmed") { // do not send if already in that state. if (device.getStateValue("panel_armed") || device.getStateValue("panel_armed_stay")) { @@ -2233,14 +2266,18 @@ def alarmdecoderAlarmHandler(evt) { state.lastAlarmDecoderStatus = evt.value if (isSmartThings()) { - /* no traslation needed already [stay,away,off] */ + /* no traslation needed for [stay,away,off] but night has to be translated to stay */ if (debug) log.debug("alarmdecoderAlarmHandler alarmSystemStatus ${evt.value}") + msg = evt.value + + if (evt.value == "night") + msg = "stay" // Update last known MON state - state.lastMONStatus = evt.value + state.lastMONStatus = msg - sendLocationEvent(name: "alarmSystemStatus", value: evt.value) + sendLocationEvent(name: "alarmSystemStatus", value: msg) } else if (isHubitat()) { /* translate to HSM */ msg = "" @@ -2253,6 +2290,10 @@ def alarmdecoderAlarmHandler(evt) { msg = "armAway" nstate = "armedAway" // prevent loop } + if (evt.value == "night") { + msg = "armNight" + nstate = "armedNight" // prevent loop + } if (evt.value == "off") { msg = "disarm" nstate = "disarmed" // prevent loop @@ -2564,6 +2605,9 @@ def addExistingDevices() { // Add Arm Away switch/indicator combo if it does not exist. addAD2VirtualDevices("armAway", "Away", false, true, true) + // Add Arm Night switch/indicator combo if it does not exist. + addAD2VirtualDevices("armNight", "Night", false, true, true) + // Add Exit switch/indicator combo if it does not exist. addAD2VirtualDevices("exit", "Exit", false, true, true) @@ -2716,6 +2760,9 @@ private def configureDeviceSubscriptions() { // subscribe to arm-stay handler subscribe(device, "arm-stay-set", armStaySet, [filterEvents: false]) + + // subscribe to arm-night handler + subscribe(device, "arm-night-set", armNightSet, [filterEvents: false]) // subscribe to chime handler subscribe(device, "chime-set", chimeSet, [filterEvents: false])