defmodule Grizzly.ZWave.DeviceClasses do
@moduledoc """
Z-Wave device classes
"""
defmodule Generate do
@moduledoc false
@basic_mappings [
{0x01, :controller},
{0x02, :static_controller},
{0x03, :slave},
{0x04, :routing_slave}
]
@generic_mappings [
{0x01, :generic_controller},
{0x02, :static_controller},
{0x03, :av_control_point},
{0x04, :display},
{0x05, :network_extender},
{0x06, :appliance},
{0x07, :sensor_notification},
{0x08, :thermostat},
{0x09, :window_covering},
{0x0F, :repeater_slave},
{0x10, :switch_binary},
{0x11, :switch_multilevel},
{0x12, :switch_remote},
{0x13, :switch_toggle},
{0x15, :zip_node},
{0x16, :ventilation},
{0x17, :security_panel},
{0x18, :wall_controller},
{0x20, :sensor_binary},
{0x21, :sensor_multilevel},
{0x30, :meter_pulse},
{0x31, :meter},
{0x40, :entry_control},
{0x50, :semi_interoperable},
{0xA1, :sensor_alarm},
{0xFF, :non_interoperable}
]
@specific_mappings [
# generic controller (0x01)
{:generic_controller, 0x00, :not_used},
{:generic_controller, 0x01, :portable_remote_controller},
{:generic_controller, 0x02, :portable_scene_controller},
{:generic_controller, 0x03, :installer_tool},
{:generic_controller, 0x04, :remote_control_av},
{:generic_controller, 0x06, :remote_control_simple},
# static controller (0x02)
{:static_controller, 0x00, :not_used},
{:static_controller, 0x01, :pc_controller},
{:static_controller, 0x02, :scene_controller},
{:static_controller, 0x03, :static_installer_tool},
{:static_controller, 0x04, :set_top_box},
{:static_controller, 0x05, :sub_system_controller},
{:static_controller, 0x06, :tv},
{:static_controller, 0x07, :gateway},
# av control point (0x03)
{:av_control_point, 0x00, :not_used},
{:av_control_point, 0x04, :satellite_receiver},
{:av_control_point, 0x11, :satellite_receiver_v2},
{:av_control_point, 0x12, :doorbell},
# display
{:display, 0x00, :not_used},
{:display, 0x01, :simple_display},
# network_extender
{:network_extender, 0x00, :not_used},
{:network_extender, 0x01, :secure_extender},
# appliance
{:appliance, 0x00, :not_used},
{:appliance, 0x01, :general_appliance},
{:appliance, 0x02, :kitchen_appliance},
{:appliance, 0x03, :laundry_appliance},
# sensor_notification
{:sensor_notification, 0x00, :not_used},
{:sensor_notification, 0x01, :notification_sensor},
# thermostat
{:thermostat, 0x00, :not_used},
{:thermostat, 0x01, :thermostat_heating},
{:thermostat, 0x02, :thermostat_general},
{:thermostat, 0x03, :setback_schedule_thermostat},
{:thermostat, 0x04, :setpoint_thermostat},
{:thermostat, 0x05, :setback_thermostat},
{:thermostat, 0x06, :thermostat_general_v2},
# window covering
{:window_covering, 0x00, :not_used},
{:window_covering, 0x01, :simple_window_covering},
# switch_binary
{:switch_binary, 0x00, :not_used},
{:switch_binary, 0x01, :power_switch_binary},
{:switch_binary, 0x02, :color_tunable_binary},
{:switch_binary, 0x03, :scene_switch_binary},
{:switch_binary, 0x04, :power_strip},
{:switch_binary, 0x05, :siren},
{:switch_binary, 0x06, :valve_open_close},
{:switch_binary, 0x07, :irrigation_controller},
# switch multilevel
{:switch_multilevel, 0x00, :not_used},
{:switch_multilevel, 0x01, :power_switch_multilevel},
{:switch_multilevel, 0x02, :color_tunable_multilevel},
{:switch_multilevel, 0x03, :motor_multipositions},
{:switch_multilevel, 0x04, :scene_switch_multilevel},
{:switch_multilevel, 0x05, :class_a_motor_control},
{:switch_multilevel, 0x06, :class_b_motor_control},
{:switch_multilevel, 0x07, :class_c_motor_control},
{:switch_multilevel, 0x08, :fan_switch},
# repeater slave
{:repeater_slave, 0x00, :not_used},
{:repeater_slave, 0x01, :repeater_slave},
{:repeater_slave, 0x02, :virtual_node},
# switch remote (0x13)
{:switch_remote, 0x00, :not_used},
{:switch_remote, 0x01, :switch_remote_binary},
{:switch_remote, 0x02, :switch_remote_multilevel},
{:switch_remote, 0x03, :switch_remote_toggle_binary},
{:switch_remote, 0x04, :switch_remote_toggle_multilevel},
# switch toggle (0x14)
{:switch_toggle, 0x00, :not_used},
{:switch_toggle, 0x01, :switch_toggle_binary},
{:switch_toggle, 0x02, :switch_toggle_multilevel},
# zip node (0x15)
{:zip_node, 0x00, :not_used},
{:zip_node, 0x01, :zip_adv_node},
{:zip_node, 0x02, :zip_tun_node},
# security_panel (0x17)
{:security_panel, 0x00, :not_used},
{:security_panel, 0x01, :zoned_security_panel},
# wall controller (0x18)
{:wall_controller, 0x00, :not_used},
{:wall_controller, 0x01, :basic_wall_controller},
# sensor binary (0x20)
{:sensor_binary, 0x00, :not_used},
{:sensor_binary, 0x01, :routing_sensor_binary},
# sensor multilevel (0x21)
{:sensor_multilevel, 0x00, :not_used},
{:sensor_multilevel, 0x01, :routing_sensor_multilevel},
{:sensor_multilevel, 0x02, :chimney_fan},
# meter pulse (0x30)
{:meter_pulse, 0x00, :not_used},
# meter (0x31)
{:meter, 0x00, :not_used},
{:meter, 0x01, :simple_meter},
{:meter, 0x02, :adv_energy_meter},
{:meter, 0x03, :whole_home_meter_simple},
# entry control (0x40)
{:entry_control, 0x00, :not_used},
{:entry_control, 0x01, :door_lock},
{:entry_control, 0x02, :advanced_door_lock},
{:entry_control, 0x03, :secure_keypad_door_lock},
{:entry_control, 0x04, :secure_keypad_door_lock_deadbolt},
{:entry_control, 0x05, :secure_door},
{:entry_control, 0x06, :secure_gate},
{:entry_control, 0x07, :secure_barrier_addon},
{:entry_control, 0x08, :secure_barrier_open_only},
{:entry_control, 0x09, :secure_barrier_close_only},
{:entry_control, 0x0A, :secure_lockbox},
{:entry_control, 0x0B, :secure_keypad},
# semi interoperable (0x50)
{:semi_interoperable, 0x00, :not_used},
{:semi_interoperable, 0x01, :energy_production},
# sensor alarm (0xA1)
{:sensor_alarm, 0x00, :not_used},
{:sensor_alarm, 0x01, :basic_routing_alarm_sensor},
{:sensor_alarm, 0x02, :routing_alarm_sensor},
{:sensor_alarm, 0x03, :basic_zensor_net_alarm_sensor},
{:sensor_alarm, 0x04, :zensor_net_alarm_sensor},
{:sensor_alarm, 0x05, :adv_zensor_net_alarm_sensor},
{:sensor_alarm, 0x06, :basic_routing_smoke_sensor},
{:sensor_alarm, 0x07, :routing_smoke_sensor},
{:sensor_alarm, 0x08, :basic_zensor_net_smoke_sensor},
{:sensor_alarm, 0x09, :zensor_net_smoke_sensor},
{:sensor_alarm, 0x0A, :adv_zensor_net_smoke_sensor},
{:sensor_alarm, 0x0B, :alarm_sensor},
# non interoperable (0xFF)
{:non_interoperable, 0x00, :not_used}
]
defmacro __before_compile__(_) do
basic_device_class_from_byte =
for {byte, device_class} <- @basic_mappings do
quote do
def basic_device_class_from_byte(unquote(byte)), do: {:ok, unquote(device_class)}
end
end
basic_device_class_to_byte =
for {byte, device_class} <- @basic_mappings do
quote do
def basic_device_class_to_byte(unquote(device_class)), do: unquote(byte)
end
end
generic_device_class_from_byte =
for {byte, device_class} <- @generic_mappings do
quote do
def generic_device_class_from_byte(unquote(byte)), do: {:ok, unquote(device_class)}
end
end
generic_device_class_to_byte =
for {byte, device_class} <- @generic_mappings do
quote do
def generic_device_class_to_byte(unquote(device_class)), do: unquote(byte)
end
end
specific_device_class_from_byte =
for {gen_class, byte, spec_class} <- @specific_mappings do
quote do
def specific_device_class_from_byte(unquote(gen_class), unquote(byte)),
do: {:ok, unquote(spec_class)}
end
end
specific_device_class_to_byte =
for {gen_class, byte, spec_class} <- @specific_mappings do
quote do
def specific_device_class_to_byte(unquote(gen_class), unquote(spec_class)),
do: unquote(byte)
end
end
quote do
@type basic_device_class :: :controller | :static_controller | :slave | :routing_slave
@type generic_device_class ::
:generic_controller
| :static_controller
| :av_control_point
| :display
| :network_extender
| :appliance
| :sensor_notification
| :thermostat
| :window_covering
| :repeater_slave
| :switch_binary
| :switch_multilevel
| :switch_remote
| :switch_toggle
| :zip_node
| :ventilation
| :security_panel
| :wall_controller
| :sensor_binary
| :sensor_multilevel
| :meter_pulse
| :meter
| :entry_control
| :semi_interoperable
| :sensor_alarm
| :non_interoperable
@type specific_device_class ::
:not_used
| :portable_remote_controller
| :portable_scene_controller
| :installer_tool
| :remote_control_av
| :remote_control_simple
| :pc_controller
| :scene_controller
| :static_installer_tool
| :set_top_box
| :sub_system_controller
| :tv
| :gateway
| :satellite_receiver
| :satellite_receiver_v2
| :doorbell
| :simple_display
| :secure_extender
| :general_appliance
| :kitchen_appliance
| :laundry_appliance
| :notification_sensor
| :thermostat_heating
| :thermostat_general
| :setback_schedule_thermostat
| :setpoint_thermostat
| :setback_thermostat
| :thermostat_general_v2
| :simple_window_covering
| :power_switch_binary
| :color_tunable_binary
| :scene_switch_binary
| :power_strip
| :siren
| :valve_open_close
| :irrigation_controller
| :power_switch_multilevel
| :color_tunable_multilevel
| :motor_multipositions
| :scene_switch_multilevel
| :class_a_motor_control
| :class_b_motor_control
| :class_c_motor_control
| :fan_switch
| :switch_remote_binary
| :switch_remote_multilevel
| :switch_remote_toggle_binary
| :switch_remote_toggle_multilevel
| :switch_toggle_binary
| :switch_toggle_multilevel
| :zip_adv_node
| :zip_tun_node
| :zoned_security_panel
| :basic_wall_controller
| :routing_sensor_binary
| :routing_sensor_multilevel
| :chimney_fan
| :simple_meter
| :adv_energy_meter
| :whole_home_meter_simple
| :door_lock
| :advanced_door_lock
| :secure_door_lock
| :secure_keypad_door_lock
| :secure_keypad_door_lock_deadbolt
| :secure_door
| :secure_gate
| :secure_barrier_addon
| :secure_barrier_open_only
| :secure_barrier_close_only
| :secure_lockbox
| :energy_production
| :basic_routing_alarm_sensor
| :routing_alarm_sensor
| :basic_zensor_net_alarm_sensor
| :zensor_net_alarm_sensor
| :adv_zensor_net_alarm_sensor
| :basic_routing_smoke_sensor
| :routing_smoke_sensor
| :basic_zensor_net_smoke_sensor
| :zensor_net_smoke_sensor
| :adv_zensor_net_smoke_sensor
| :alarm_sensor
| :portable_scene_controller
| :repeater_slave
| :virtual_node
@doc """
Try to make a basic device class from a byte
"""
@spec basic_device_class_from_byte(byte()) ::
{:ok, basic_device_class()} | {:error, :unsupported_device_class}
unquote(basic_device_class_from_byte)
def basic_device_class_from_byte(_byte), do: {:error, :unsupported_device_class}
@doc """
Make a byte from a device class
"""
@spec basic_device_class_to_byte(basic_device_class()) :: byte()
unquote(basic_device_class_to_byte)
@doc """
Try to get the generic device class for the byte
"""
@spec generic_device_class_from_byte(byte()) ::
{:ok, generic_device_class()} | {:error, :unsupported_device_class}
unquote(generic_device_class_from_byte)
def generic_device_class_from_byte(_byte), do: {:error, :unsupported_device_class}
@doc """
Turn the generic device class into a byte
"""
@spec generic_device_class_to_byte(generic_device_class()) :: byte()
unquote(generic_device_class_to_byte)
@doc """
Try to get the specific device class from the byte given the generic device class
"""
@spec specific_device_class_from_byte(generic_device_class(), byte()) ::
{:ok, specific_device_class()} | {:error, :unsupported_device_class}
unquote(specific_device_class_from_byte)
def specific_device_class_from_byte(_, _byte), do: {:error, :unsupported_device_class}
@doc """
Make the specific device class into a byte
"""
@spec specific_device_class_to_byte(generic_device_class(), specific_device_class()) ::
byte()
unquote(specific_device_class_to_byte)
end
end
end
@before_compile Generate
end