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