Z-Wave Device Class
The st.zwave.Device
class inherits from Device
, extending behavior
with Z-Wave-specific functionality. Device objects are instantiated by the framework and passed to drivers as parameters
for device-related methods.
Sleepy devices
Sleepy devices present unique use cases for a Z-Wave controller since communication can only occur when the device is awake.
One particular case is when a sleepy device’s preferences are updated and it is asleep, any configuration commands for the
device cannot be sent until the device wakes up. To allow for sending device configuration commands when the device wakes up,
a driver can set an update_preferences
function on a device which will get called when the device wakes up. The function is provided
args
which are similar to the args on the infoChanged
lifecycle event and contain the old_st_store.preferences
with the
preferences that were present the last time the device woke up. Note that there will still be an infoChanged
event for
sleepy devices, and this automatic preference update mechanism only works for devices that support the WakeUp command class.
The following is an example of how this functionality should be handled in a driver that supports both listening and
sleepy devices:
local capabilities = require "st.capabilities"
--- @type st.zwave.Driver
local ZwaveDriver = require "st.zwave"
--- @type st.zwave.defaults
local defaults = require "st.zwave.defaults"
local cc = require "st.zwave.CommandClass"
local function update_preferences(self, device, args)
if args.old_st_store.prefrences["my_pref"] ~= device.preferences["my_pref"] then
-- send commands if you need
end
end
local function device_init(self, device)
device:set_update_preferences_fn(update_preferences)
end
local function info_changed(self, device, event, args)
-- only update preferences for devices we know are awake
-- if this driver only supports sleepy devices, an infoChanged handler may not be needed at all.
if ~device:is_cc_supported(cc.WAKE_UP) then
update_preferences(self, device, args)
end
end
local zwave_contact_driver = {
supported_capabilities = {
capabilities.contactSensor,
capabilities.battery
},
lifecycle_handlers = {
init = device_init,
infoChanged = info_changed,
},
}
defaults.register_for_default_handlers(zwave_contact_driver, zwave_contact_driver.supported_capabilities)
--- @type st.zwave.Driver
local contact_sensor = ZwaveDriver("zwave_contact_sensor", zwave_contact_driver)
contact_sensor:run()
Parent/Child Devices
There may be some situations where you prefer to model a single network device as multiple SmartThings device records. This can be done by creating “Child” devices to represent individual endpoints on the device. NOTE: If you aren’t modeling each child as an endpoint, you won’t be able to use the library abstractions, but you can build your own handling of messages for whatever model you desire.
You can define a find_child
function using the set_find_child
method on device objects. Then any use of
emit_event_for_endpoint
including the default capability handlers will use this to emit events on the appropriate
children. The find_child
function you define will be passed the source channel a message came from and should then
return the device object representing the child device that is responsible for that source channel, or nil
if there
isn’t one.
When deleting devices in a parent/child relationship, deleting the parent will result in the removal of all of the children as well as all communication goes through the parent device. However, you can delete individual children without affecting the others. It should be noted though that typically the only way to create the children is on device join so if deleted getting the child devices back will often require deleting and re-onboarding the parent.
example
Profile:
name: outlet
components:
- id: main
capabilities:
- id: switch
version: 1
- id: refresh
version: 1
categories:
- name: Outlet
Driver:
local capabilities = require "st.capabilities"
local ZwaveDriver = require "st.zwave.driver"
local defaults = require "st.zwave.defaults"
local device_lib = require "st.device"
local constants = require "st.zwave.constants"
local cc = require "st.zwave.CommandClass"
local SwitchBinary = (require "st.zwave.CommandClass.SwitchBinary")({version=2,strict=true})
-- These same handlers will work for both the parent and child devices
local function report_handler(driver, device, cmd)
local event
if cmd.args.value == SwitchBinary.value.OFF_DISABLE then
event = capabilities.switch.switch.off()
else
event = capabilities.switch.switch.on()
end
-- This device will _always_ be the parent because the parent is the only one actually on the network sending
-- messages but this call to `emit_event_for_endpoint` will use the `find_child` function set below to find the
-- child and emit the event for that SmartThings device instead
device:emit_event_for_endpoint(cmd.src_channel, event)
end
local function on_handler(driver, device, command)
-- Since we will receive commands separately for the different children, the device object here could be a parent
-- or child. The message building will work the same as the child will defer to the parent for addressing
-- information. And similarly `send_to_component` on the child device will ultimately call send on the parent as
-- that is the actual network device.
device:send_to_component(
SwitchBinary:Set({ target_value = SwitchBinary.value.ON_ENABLE, duration = 0}),
command.component
)
local query_device = function()
device:send_to_component(SwitchBinary:Get({}), command.component)
end
device.thread:call_with_delay(constants.DEFAULT_GET_STATUS_DELAY, query_device)
end
local capability_handlers = {}
local function added(driver, device, event)
-- Only create children for the actual Z-Wave device and not the children
if device.network_type == device_lib.NETWORK_TYPE_ZWAVE then
for i = 2, 5, 1 do
local name = string.format("%s outlet %d", device.label, i)
local metadata = {
type = "EDGE_CHILD",
label = name,
profile = "outlet",
parent_device_id = device.id,
parent_assigned_child_key = string.format("%02X", i),
vendor_provided_label = name,
}
driver:try_create_device(metadata)
end
end
end
local function find_child(parent, src_channel)
return parent:get_child_by_parent_assigned_key(string.format("%02X", src_channel))
end
local function init(driver, device, event)
if device.network_type == device_lib.NETWORK_TYPE_ZWAVE then
device:set_find_child(find_child)
end
end
local zwave_parent_child_switch_template = {
supported_capabilities = {
capabilities.switch,
},
zwave_handlers = {
[cc.SWITCH_BINARY] = {
[SwitchBinary.REPORT] = report_handler
},
},
capability_handlers = {
[capabilities.switch.ID] = {
[capabilities.switch.commands.on.NAME] = on_handler,
-- Off handler provided by defaults
},
},
lifecycle_handlers = {
added = added,
init = init,
},
}
-- The on_handler and on_off_attr_handler above would be covered by these defaults, but are included for example purposes
defaults.register_for_default_handlers(zwave_parent_child_switch_template, zwave_parent_child_switch_template.supported_capabilities)
local zwave_parent_child_switch = ZwaveDriver("child_device_example", zwave_parent_child_switch_template)
zwave_parent_child_switch:run()
Class Documentation
- class st.zwave.Device: st.Device
- zwave_endpoints: table
store Z-Wave endpoints
- collect_default_refresh_commands(self)
Collect and return the list of refresh commands for self device as provided
by registered default modules, removing duplicates.
- Parameters
self (
st.zwave.Device
) –
- set_component_to_endpoint_fn(comp_ep_fn)
Set a function to map this devices SmartThings components to Zwave endpoints
- Parameters
comp_ep_fn (
CompToEp
) – Component to Endpoint function to do the mapping for this device
- set_endpoint_to_component_fn(ep_comp_fn)
Set a function to map this devices Zwave endpoints to SmartThings components
- Parameters
ep_comp_fn (
EpToComp
) – function to do the mapping for this device
- set_update_preferences_fn(update_pref_fn)
Set a function to be called with with previous preferences when this device wakes up. Should be used to update preferences on sleepy devices.
- Parameters
update_pref_fn (
UpdatePreference
) – function to update preferences when a device wakes up.
- default_refresh(self)
Collect device-specific refresh commands from registered default modules
and send these to the associated Z-Wave device.
- Parameters
self (
st.zwave.Device
) –
- refresh(self)
Use the capability dispatcher to execute refresh as appropriate for
the particular device instance.
- Parameters
self (
st.zwave.Device
) –
- default_configure(self)
Default device configure function. Execute refresh to bootstrap state
for all capability event listeners.
- Parameters
self (
st.zwave.Device
) –
- emit_event_for_endpoint(endpoint, event)
Emit event for Z-Wave endpoint(channel), mapped to component.
- Parameters
endpoint (
number
) – the endpoint(Z-Wave channel) ID to find the component forevent (
table
) – the endpoint(Z-Wave channel) ID to find the component for
- send(cmd)
Send a Z-Wave command to the associated Z-Wave device.
The command will be logged in the live logs when it is sent from the driver. There will also be logs to trace when the command is queued in the hub, and when the transmission has completed on the radio.
- Parameters
cmd (
st.zwave.Command
) –
- send_to_component(cmd, component_id)
Send a Z-Wave command to the specific component of associated Z-Wave device.
The command will be logged in the live logs when it is sent from the driver. There will also be logs to trace when the command is queued in the hub, and when the transmission has completed on the radio.
- Parameters
cmd (
st.zwave.Command
) –component_id (
str
) –
- component_to_endpoint(component_id)
Map component to end_points(channels)
e.g. {} - map component to un-encapsulated {2} - map to specific Z-Wave endpoint(channel) {1,2,3} - map to more then one Z-Wave endpoint (channels)
e.g. {2} for Z-Wave channel 2 or {} for unencapsulated
- Parameters
component_id (
str
) – ID- Returns
dst_channels destination channels
- Return type
- endpoint_to_component(endpoint)
Map end_point(channel) to Z-Wave endpoint(channel)
- Parameters
endpoint (
number
) – the endpoint(Z-Wave channel) ID to find the component for- Returns
the component ID the endpoint matches to
- Return type
str
- is_cc_supported(cc_value, endpoint)
Interrogate the device’s profile to determine whether a particular command class is supported.
- Parameters
cc_value (
number
) – the command class id as defined in cc.lua, e.g cc.SWITCH_BINARY = 0x25endpoint (
number
) – of the endpoint to check, if nil we check the first endpoint
- Returns
true if the command class is supported, false if not
- Return type
boolean
- id_match(mfr_id, product_type, product_id)
Determine whether device self is a match to the passed manufacturer ID(s),
product ID(s) and product type(s). Filter arguments can be numerical literals or arrays of numerical literals.
In the case that a filter argument is an array, matching uses OR logic. Match against any single array item is considered a device match.
- Parameters
mfr_id (
number or table
) – numerical manufacturer ID or array of IDsproduct_type (
number or table
) – numerical product type ( aka product in DTH namespace) or array of types.product_id (
number or table
) – numerical product ID ( aka model in DTH namespace) or array of IDs
- Returns
true if device self matches the passed all filter arguments
- Return type
boolean
- static init(cls, driver, raw_device)
Initialize an st.zwave.Device instance
- Parameters
cls (
st.zwave.Device
) – st.zwave.Device class definition tabledriver (
st.zwave.Driver
) –raw_device (
table
) – cloud-published device instance data
- debug_pretty_print()
Return a string representation of device model and supported command class information
- Returns
string containing the device model and supported command class information
- Return type
A
- pretty_print()
Get a string with the ID, DNI and label of the device.
- Returns
a short string representation of the device
- Return type
str
- class st.zwave.ChildDevice: st.Device
- get_dst_channel()
Get the dst_channels array used to address a message to this child through the parent
The default implementation here assumes that this device has a parent assigned child key of the child endpoint
- Returns
<number> the dst channels to address a message to this child device
- Return type
- send(cmd)
Send a Z-Wave command to the associated Z-Wave device.
The command will be logged in the live logs when it is sent from the driver. There will also be logs to trace when the command is queued in the hub, and when the transmission has completed on the radio.
- Parameters
cmd (
st.zwave.Command
) –
- component_to_endpoint(component_id)
Map component to end_points(channels)
e.g. {} - map component to un-encapsulated {2} - map to specific Z-Wave endpoint(channel) {1,2,3} - map to more then one Z-Wave endpoint (channels)
e.g. {2} for Z-Wave channel 2 or {} for unencapsulated
- Parameters
component_id (
str
) – ID- Returns
dst_channels destination channels
- Return type
- is_cc_supported(cc_value, endpoint)
Interrogate the device’s profile to determine whether a particular command class is supported.
- Parameters
cc_value (
number
) – the command class id as defined in cc.lua, e.g cc.SWITCH_BINARY = 0x25endpoint (
number
) – of the endpoint to check, if nil we check the first endpoint
- Returns
true if the command class is supported, false if not
- Return type
boolean
- id_match(mfr_id, product_type, product_id)
Determine whether device self is a match to the passed manufacturer ID(s),
product ID(s) and product type(s). Filter arguments can be numerical literals or arrays of numerical literals.
In the case that a filter argument is an array, matching uses OR logic. Match against any single array item is considered a device match.
- Parameters
mfr_id (
number or table
) – numerical manufacturer ID or array of IDsproduct_type (
number or table
) – numerical product type ( aka product in DTH namespace) or array of types.product_id (
number or table
) – numerical product ID ( aka model in DTH namespace) or array of IDs
- Returns
true if device self matches the passed all filter arguments
- Return type
boolean
- static init(cls, driver, raw_device)
Initialize an st.zwave.Device instance
- Parameters
cls (
st.zwave.Device
) – st.zwave.Device class definition tabledriver (
st.zwave.Driver
) –raw_device (
table
) – cloud-published device instance data
- debug_pretty_print()
Return a string representation of device model and supported command class information
- Returns
A string containing the device newtwork ID and the parent device ID of this child
- Return type
str
- pretty_print()
Get a string with the ID, DNI and label of the device.
- Returns
a short string representation of the device
- Return type
str