-
Notifications
You must be signed in to change notification settings - Fork 448
/
init.lua
200 lines (176 loc) · 6.99 KB
/
init.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
-- 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.Configuration
local Configuration = (require "st.zwave.CommandClass.Configuration")({version=1})
--- @type st.zwave.CommandClass.Association
local Association = (require "st.zwave.CommandClass.Association")({version=2})
--- @type st.zwave.CommandClass.SwitchMultilevel
local SwitchMultilevel = (require "st.zwave.CommandClass.SwitchMultilevel")({version=3})
--- @type st.zwave.CommandClass.Meter
local Meter = (require "st.zwave.CommandClass.Meter")({version=3})
local preferencesMap = require "preferences"
local utils = require "st.utils"
-- configuration parameters
local OPERATING_MODE_CONFIGURATION = 71
-- preference IDs
local SLATS_TURN_TIME = "slatsTurnTime"
-- fieldnames
local BLINDS_LAST_COMMAND = "blinds_last_command"
local SHADE_TARGET = "shade_target"
local ENERGY_UNIT_KWH = "kWh"
local POWER_UNIT_WATT = "W"
local QUBINO_FLUSH_SHUTTER_FINGERPRINTS = {
{mfr = 0x0159, prod = 0x0003, model = 0x0052}, -- Qubino Flush Shutter AC
{mfr = 0x0159, prod = 0x0003, model = 0x0053}, -- Qubino Flush Shutter DC
}
local function can_handle_qubino_flush_shutter(opts, self, device, ...)
for _, fingerprint in ipairs(QUBINO_FLUSH_SHUTTER_FINGERPRINTS) do
if device:id_match( fingerprint.mfr, fingerprint.prod, fingerprint.model) then
return true
end
end
return false
end
local function configuration_report(self, device, cmd)
local parameter_number = cmd.args.parameter_number
local configuration_value = cmd.args.configuration_value
if parameter_number == OPERATING_MODE_CONFIGURATION then
if configuration_value == 0 then
device:try_update_metadata({profile = "qubino-flush-shutter"})
elseif configuration_value == 1 then
device:try_update_metadata({profile = "qubino-flush-shutter-venetian"})
end
end
end
local function window_shade_level_change(self, device, level, cmd)
device:send_to_component(SwitchMultilevel:Set({value = level}), cmd.component)
if cmd.component ~= "main" then
local slatsMoveTime = preferencesMap.to_numeric_value(device.preferences[SLATS_TURN_TIME])
local delay = utils.round(slatsMoveTime / 100 * 1.1)
device.thread:call_with_delay(delay,
function()
device:send_to_component(SwitchMultilevel:Get({}), cmd.component)
end
)
end
end
local function set_shade_level(self, device, cmd)
local level = math.max(math.min(cmd.args.shadeLevel, 99), 0)
window_shade_level_change(self, device, level, cmd)
end
local function open(driver, device, cmd)
window_shade_level_change(driver, device, 99, cmd)
end
local function close(driver, device, cmd)
window_shade_level_change(driver, device, 0, cmd)
end
local function multilevel_set_handler(self, device, cmd)
local targetLevel = cmd.args.value
local currentLevel = device:get_latest_state("main", capabilities.windowShadeLevel.ID, capabilities.windowShadeLevel.shadeLevel.NAME) or 0
local blindsCommand
if currentLevel > targetLevel then
blindsCommand = capabilities.windowShade.windowShade.closing()
else
blindsCommand = capabilities.windowShade.windowShade.opening()
end
device:set_field(BLINDS_LAST_COMMAND, blindsCommand)
device:set_field(SHADE_TARGET, targetLevel)
device.thread:call_with_delay(4,
function()
device:send(Meter:Get({scale = Meter.scale.electric_meter.WATTS}))
end
)
end
local function meter_report_handler(self, device, cmd)
local event = nil
local event_arguments
if cmd.args.scale == Meter.scale.electric_meter.WATTS then
event_arguments = {
value = cmd.args.meter_value,
unit = POWER_UNIT_WATT
}
event = capabilities.powerMeter.power(event_arguments)
if event_arguments.value > 1 and device:get_field(BLINDS_LAST_COMMAND) ~= nil then
device:emit_event(device:get_field(BLINDS_LAST_COMMAND))
device:emit_event(capabilities.windowShadeLevel.shadeLevel(device:get_field(SHADE_TARGET)))
else
device:send(SwitchMultilevel:Get({}))
device:send(Meter:Get({scale = Meter.scale.electric_meter.KILOWATT_HOURS}))
end
elseif cmd.args.scale == Meter.scale.electric_meter.KILOWATT_HOURS then
event_arguments = {
value = cmd.args.meter_value,
unit = ENERGY_UNIT_KWH
}
event = capabilities.energyMeter.energy(event_arguments)
end
if event ~= nil then
device:emit_event(event)
end
end
local function info_changed(driver, device, event, args)
local preferences = preferencesMap.get_device_parameters(device)
if preferences then
for id, value in pairs(device.preferences) do
if preferences[id] and args.old_st_store.preferences[id] ~= value then
local new_parameter_value = preferencesMap.to_numeric_value(device.preferences[id])
device:send(Configuration:Set({parameter_number = preferences[id].parameter_number, size = preferences[id].size, configuration_value = new_parameter_value}))
device.thread:call_with_delay(1,
function()
device:send(Configuration:Get({parameter_number = preferences[id].parameter_number}))
end
)
end
end
end
end
local function device_added(self, device)
device:send(Association:Set({grouping_identifier = 7, node_ids = {self.environment_info.hub_zwave_id}}))
device:send(Configuration:Set({parameter_number = 40, size = 1, configuration_value = 1}))
device:send(Configuration:Set({parameter_number = 71, size = 1, configuration_value = 0}))
device:emit_event(capabilities.windowShade.supportedWindowShadeCommands({"open", "close", "pause"}, { visibility = { displayed = false } }))
device:refresh()
end
local qubino_flush_shutter = {
NAME = "qubino flush shutter",
zwave_handlers = {
[cc.CONFIGURATION] = {
[Configuration.REPORT] = configuration_report
},
[cc.SWITCH_MULTILEVEL] = {
[SwitchMultilevel.SET] = multilevel_set_handler,
},
[cc.METER] = {
[Meter.REPORT] = meter_report_handler
}
},
capability_handlers = {
[capabilities.windowShadeLevel.ID] = {
[capabilities.windowShadeLevel.commands.setShadeLevel.NAME] = set_shade_level
},
[capabilities.windowShade.ID] = {
[capabilities.windowShade.commands.open.NAME] = open,
[capabilities.windowShade.commands.close.NAME] = close
},
},
can_handle = can_handle_qubino_flush_shutter,
lifecycle_handlers = {
added = device_added,
infoChanged = info_changed
},
}
return qubino_flush_shutter