Skip to content
Draft
6 changes: 6 additions & 0 deletions drivers/SmartThings/zwave-safety-shutoff/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
name: 'Z-Wave Appliance Safety'
packageKey: 'zwave-appliance-safety'
permissions:
zwave: {}
description: "SmartThings driver for Z-Wave appliance safety devices."
vendorSupportInformation: "https://support.smartthings.com"
26 changes: 26 additions & 0 deletions drivers/SmartThings/zwave-safety-shutoff/fingerprints.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
zwaveManufacturer:
- id: "FireAvert/Shutoff/Gas"
deviceLabel: FireAvert Shutoff for Gas Appliances
manufacturerId: 0x045D
productType: 0x0004
productId: 0x1601
deviceProfileName: fireavert-appliance-shutoff-gas
- id: "FireAvert/Shutoff/120v"
deviceLabel: FireAvert Shutoff for Electric Appliances
manufacturerId: 0x045D
productType: 0x0004
productId: 0x0601
deviceProfileName: fireavert-appliance-shutoff-electric
- id: "FireAvert/Shutoff/240v3"
deviceLabel: FireAvert Shutoff for Electric Appliances
manufacturerId: 0x045D
productType: 0x0004
productId: 0x0602
deviceProfileName: fireavert-appliance-shutoff-electric
- id: "FireAvert/Shutoff/240v4"
deviceLabel: FireAvert Shutoff for Electric Appliances
manufacturerId: 0x045D
productType: 0x0004
productId: 0x0603
deviceProfileName: fireavert-appliance-shutoff-electric

Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: fireavert-appliance-shutoff-electric
components:
- id: main
label: "Appliance Information"
capabilities:
- id: soundDetection
version: 1
config:
values:
- key: supportedSoundTypes.value
enabledValues:
- noSound
- fireAlarm
- id: switch
version: 1
- id: applianceUtilization
version: 1
- id: remoteControlStatus
version: 1
categories:
- name: SmokeDetector
deviceConfig:
dashboard:
states:
- component: main
capability: soundDetection
version: 1
detailView:
- component: main
capability: soundDetection
version: 1
- component: main
capability: switch
version: 1
- component: main
capability: applianceUtilization
version: 1
label: "Appliance Power"
values:
- key: status.value
alternatives:
- key: inUse
value: "Appliance Powered On"
type: active
- key: notInUse
value: "Appliance Powered Off"
type: inactive
- component: main
capability: remoteControlStatus
version: 1
label: "Safety Control"
values:
- key: remoteControlStatus.value
alternatives:
- key: "true"
value: "Unlocked"
type: active
- key: "false"
value: "Device Locked"
type: inactive
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: fireavert-appliance-shutoff-gas
components:
- id: main
label: "Appliance Control"
capabilities:
- id: soundDetection
version: 1
config:
values:
- key: supportedSoundTypes.value
enabledValues:
- noSound
- fireAlarm
- id: switch
version: 1
categories:
- name: SmokeDetector
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
-- Copyright 2022 SmartThings
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.

local capabilities = require "st.capabilities"
--- @type st.zwave.CommandClass
local cc = require "st.zwave.CommandClass"
--- @type st.zwave.CommandClass.Notification
local Notification = (require "st.zwave.CommandClass.Notification")({ version = 3 })

--- This is a notification type that is not available in SmartThings but does exist in the Z-Wave Specification (2025B +).
local APPLIANCE_SAFETY_INTERLOCK_ENGAGED = 0x16

local FIREAVERT_APPLIANCE_SHUTOFF_FINGERPRINTS = {
{ manufacturerId = 0x045D, productType = 0x0004, productId = 0x0601 }, -- FireAvert Appliance Shutoff - 120V
{ manufacturerId = 0x045D, productType = 0x0004, productId = 0x0602 }, -- FireAvert Appliance Shutoff - 240V 3 Prong
{ manufacturerId = 0x045D, productType = 0x0004, productId = 0x0603 }, -- FireAvert Appliance Shutoff - 240V 4 Prong
}
--- Determine whether the passed device is a FireAvert shutoff device. All devices use the same driver.
local function can_handle_fireavert_appliance_shutoff_e(opts, driver, device, ...)
local isDevice = false
for _, fingerprint in ipairs(FIREAVERT_APPLIANCE_SHUTOFF_FINGERPRINTS) do
if device:id_match(fingerprint.manufacturerId, fingerprint.productType, fingerprint.productId) then
isDevice = true
break
end
end
if true == isDevice then
local subdriver = require("fireavert-appliance-shutoff-electric")
return true, subdriver
else return false end
end

--- Handler for notification report command class from sensor
---
--- @param self st.zwave.Driver
--- @param device st.zwave.Device
--- @param cmd st.zwave.CommandClass.Notification.Report
local function notification_report_handler(self, device, cmd)
local event = nil
if cmd.args.notification_type == Notification.notification_type.SMOKE then
if cmd.args.event == Notification.event.smoke.DETECTED then
event = capabilities.soundDetection.soundDetected.fireAlarm()
elseif cmd.args.event == Notification.event.smoke.STATE_IDLE then
event = capabilities.soundDetection.soundDetected.noSound()
end
elseif cmd.args.notification_type == Notification.notification_type.APPLIANCE then
if cmd.args.event == APPLIANCE_SAFETY_INTERLOCK_ENGAGED then
event = capabilities.remoteControlStatus.remoteControlEnabled("false")
print("Device cannot be remote controlled")
else
event = capabilities.remoteControlStatus.remoteControlEnabled("true")
print("Device can be remote controlled")
end
elseif cmd.args.notification_type == Notification.notification_type.POWER_MANAGEMENT then
print("Power Notification: Notification payload: ", cmd.args.event_parameter)
if (cmd.args.event == Notification.event.power_management.POWER_HAS_BEEN_APPLIED) then
event = capabilities.applianceUtilization.status.inUse()
elseif (cmd.args.event == Notification.event.power_management.STATE_IDLE) then
event = capabilities.applianceUtilization.status.notInUse()
end
end
if event ~= nil then
print("notification event: %s", event)
device:emit_event(event)
end
end

--- Configuration lifecycle event handler.
---
--- Send refresh GETs and manufacturer-specific configuration for
--- the FireAvert Appliance Shutoff device
---
--- @param self st.zwave.Driver
--- @param device st.zwave.Device
local function do_configure(self, device)
device:refresh()
end

local fireavert_appliance_shutoff_e = {
zwave_handlers = {
[cc.NOTIFICATION] = {
[Notification.REPORT] = notification_report_handler
},
},
lifecycle_handlers = {
doConfigure = do_configure,
},
NAME = "FireAvert Appliance Shutoff - Electric",
can_handle = can_handle_fireavert_appliance_shutoff_e
}

return fireavert_appliance_shutoff_e
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
-- Copyright 2022 SmartThings
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.

local capabilities = require "st.capabilities"
--- @type st.zwave.CommandClass
local cc = require "st.zwave.CommandClass"
--- @type st.zwave.CommandClass.Notification
local Notification = (require "st.zwave.CommandClass.Notification")({ version = 3 })

local FIREAVERT_APPLIANCE_SHUTOFF_FINGERPRINTS = {
{ manufacturerId = 0x045D, productType = 0x0004, productId = 0x1601 } -- FireAvert Appliance Shutoff - Gas
}
--- Determine whether the passed device is a FireAvert shutoff device. All devices use the same driver.
local function can_handle_fireavert_appliance_shutoff_gas(opts, driver, device, ...)
local isDevice = false
for _, fingerprint in ipairs(FIREAVERT_APPLIANCE_SHUTOFF_FINGERPRINTS) do
if device:id_match(fingerprint.manufacturerId, fingerprint.productType, fingerprint.productId) then
isDevice = true
break
end
end
if true == isDevice then
local subdriver = require("fireavert-appliance-shutoff-gas")
return true, subdriver
else return false end
end

--- Handler for notification report command class from sensor
---
--- @param self st.zwave.Driver
--- @param device st.zwave.Device
--- @param cmd st.zwave.CommandClass.Notification.Report
local function notification_report_handler(self, device, cmd)
local event = nil
--- Z-Wave's closest match is a smoke detection notification, but this more
--- cleanly maps to Sound Detection in SmartThings.
if cmd.args.notification_type == Notification.notification_type.SMOKE then
if cmd.args.event == Notification.event.smoke.DETECTED then
event = capabilities.soundDetection.soundDetected.fireAlarm()
elseif cmd.args.event == Notification.event.smoke.STATE_IDLE then
event = capabilities.soundDetection.soundDetected.noSound()
end
end
if event ~= nil then device:emit_event(event) end
end

--- Configuration lifecycle event handler.
---
--- Send refresh GETs and manufacturer-specific configuration for
--- the FireAvert Appliance Shutoff device
---
--- @param self st.zwave.Driver
--- @param device st.zwave.Device
local function do_configure(self, device)
device:refresh()
end

local fireavert_appliance_shutoff_g = {
zwave_handlers = {
[cc.NOTIFICATION] = {
[Notification.REPORT] = notification_report_handler
},
},
lifecycle_handlers = {
doConfigure = do_configure,
},
NAME = "FireAvert Appliance Shutoff - Gas",
can_handle = can_handle_fireavert_appliance_shutoff_gas
}

return fireavert_appliance_shutoff_g
Loading