Skip to content

Commit 243ec27

Browse files
committed
zwave-siren ZSE50 more fixes
* Merged upstream and updated for lazy-load * Consolidated tones_list and tones_duration maps as suggested * Removed debug logs and commented out code
1 parent d602722 commit 243ec27

File tree

4 files changed

+45
-61
lines changed

4 files changed

+45
-61
lines changed

drivers/SmartThings/zwave-siren/src/sub_drivers.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
local lazy_load_if_possible = require "lazy_load_subdriver"
55
local sub_drivers = {
66
lazy_load_if_possible("multifunctional-siren"),
7+
lazy_load_if_possible("zooz-zse50"),
78
lazy_load_if_possible("zwave-sound-sensor"),
89
lazy_load_if_possible("ecolink-wireless-siren"),
910
lazy_load_if_possible("philio-sound-siren"),
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
-- Copyright 2026 SmartThings, Inc.
2+
-- Licensed under the Apache License, Version 2.0
3+
4+
local function can_handle_multifunctional_siren(opts, driver, device, ...)
5+
local FINGERPRINTS = require("zooz-zse50.fingerprints")
6+
for _, fingerprint in ipairs(FINGERPRINTS) do
7+
if device:id_match(fingerprint.manufacturerId, fingerprint.productType, fingerprint.productId) then
8+
return true, require("zooz-zse50")
9+
end
10+
end
11+
return false
12+
end
13+
14+
return can_handle_multifunctional_siren
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
-- Copyright 2026 SmartThings, Inc.
2+
-- Licensed under the Apache License, Version 2.0
3+
4+
local ZSE50_FINGERPRINTS = {
5+
{ manufacturerId = 0x027A, productType = 0x0004, productId = 0x0369 } -- Zooz ZSE50 Siren & Chime
6+
}
7+
8+
return ZSE50_FINGERPRINTS

drivers/SmartThings/zwave-siren/src/zooz-zse50/init.lua

Lines changed: 22 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,5 @@
11
-- Copyright 2026 SmartThings
2-
--
3-
-- Licensed under the Apache License, Version 2.0 (the "License");
4-
-- you may not use this file except in compliance with the License.
5-
-- You may obtain a copy of the License at
6-
--
7-
-- http://www.apache.org/licenses/LICENSE-2.0
8-
--
9-
-- Unless required by applicable law or agreed to in writing, software
10-
-- distributed under the License is distributed on an "AS IS" BASIS,
11-
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12-
-- See the License for the specific language governing permissions and
13-
-- limitations under the License.
2+
-- Licensed under the Apache License, Version 2.0
143

154
local preferencesMap = require "preferences"
165

@@ -26,22 +15,6 @@ local Notification = (require "st.zwave.CommandClass.Notification")({ version =
2615
local SoundSwitch = (require "st.zwave.CommandClass.SoundSwitch")({ version = 1 })
2716
local Version = (require "st.zwave.CommandClass.Version")({ version = 1 })
2817

29-
local ZSE50_FINGERPRINTS = {
30-
{ manufacturerId = 0x027A, productType = 0x0004, productId = 0x0369 } -- Zooz ZSE50 Siren & Chime
31-
}
32-
33-
--- @param driver Driver driver instance
34-
--- @param device Device device instance
35-
--- @return boolean true if the device proper, else false
36-
local function can_handle_zooz_zse50(opts, driver, device, ...)
37-
for _, fingerprint in ipairs(ZSE50_FINGERPRINTS) do
38-
if device:id_match(fingerprint.manufacturerId, fingerprint.productType, fingerprint.productId) then
39-
return true
40-
end
41-
end
42-
return false
43-
end
44-
4518
--- @param self st.zwave.Driver
4619
--- @param device st.zwave.Device
4720
local function update_firmwareUpdate_capability(self, device, component, major, minor)
@@ -65,30 +38,36 @@ local function updateFirmwareVersion(self, device)
6538
end
6639
end
6740

41+
local function getModeName(toneId, toneInfo)
42+
return string.format("%s: %s (%ss)", toneId, toneInfo.name, toneInfo.duration)
43+
end
44+
6845
local function playTone(device, tone_id)
69-
local tones_duration = device:get_field("TONES_DURATION")
46+
local tones_list = device:get_field("TONES_LIST")
7047
local default_tone = device:get_field("TONE_DEFAULT")
71-
local duration = tones_duration[tonumber(tone_id)]
7248
local playbackMode = tonumber(device.preferences.playbackMode)
49+
local duration
7350
if tone_id > 0 then
7451
if tone_id == 0xFF then
75-
duration = tones_duration[tonumber(default_tone)]
52+
duration = tones_list[tonumber(default_tone)].duration
53+
else
54+
duration = tones_list[tonumber(tone_id)].duration
7655
end
7756
if playbackMode == 1 then
7857
duration = device.preferences.playbackDuration
7958
elseif playbackMode == 2 then
8059
duration = duration * device.preferences.playbackLoop
8160
end
8261
end
83-
log.debug(string.format("Playing Tone: %s, playbackMode %s, duration %ss", tone_id, playbackMode, duration))
62+
log.info(string.format("Playing Tone: %s, playbackMode %s, duration %ss", tone_id, playbackMode, duration))
8463

8564
device:send(SoundSwitch:TonePlaySet({ tone_identifier = tone_id }))
8665
device:send(SoundSwitch:TonePlayGet({}))
8766

8867
local soundSwitch_refresh = function()
8968
local chime = device:get_latest_state("main", capabilities.chime.ID, capabilities.chime.chime.NAME)
9069
local mode = device:get_latest_state("main", capabilities.mode.ID, capabilities.mode.mode.NAME)
91-
log.debug(string.format("soundSwitch_refresh: %s | %s", chime, mode))
70+
log.info(string.format("Running SoundSwitch Refresh: %s | %s", chime, mode))
9271
if chime ~= "off" or mode ~= "Off" then
9372
device:send(SoundSwitch:TonePlayGet({}))
9473
end
@@ -108,7 +87,6 @@ local function rebuildTones(device)
10887
end
10988

11089
local function refresh_handler(self, device)
111-
log.debug("***DEBUG*** refresh_handler (zse50)")
11290
device:default_refresh()
11391
device:send(Version:Get({}))
11492
device:send(Notification:Get({
@@ -127,7 +105,7 @@ local function setMode_handler(self, device, command)
127105
if mode_split ~= nil then
128106
mode_value = string.sub(mode_value, 1, mode_split - 1)
129107
end
130-
log.debug(string.format("***DEBUG*** setMode_handler (%s)", mode_value))
108+
log.info(string.format("Command: setMode (%s)", mode_value))
131109

132110
if mode_value == 'Rebuild List' then
133111
rebuildTones(device)
@@ -165,18 +143,15 @@ end
165143

166144
local function tones_number_report_handler(self, device, cmd)
167145
local total_tones = cmd.args.supported_tones
168-
log.debug("***DEBUG*** tones_number_report_handler... " .. total_tones)
169146

170147
--Max 50 tones per Zooz settings
171148
if total_tones > 50 then
172149
total_tones = 50
173150
end
174151

175152
local tones_list = { }
176-
local tones_duration = { }
177153
device:set_field("TOTAL_TONES", total_tones)
178154
device:set_field("TONES_LIST_TMP", tones_list)
179-
device:set_field("TONES_DURATION_TMP", tones_duration)
180155

181156
--Get info on all tones
182157
for tone = 1, total_tones do
@@ -190,37 +165,28 @@ local function tone_info_report_handler(self, device, cmd)
190165
local duration = cmd.args.tone_duration
191166
local total_tones = device:get_field("TOTAL_TONES")
192167
local tones_list = device:get_field("TONES_LIST_TMP") or {}
193-
local tones_duration = device:get_field("TONES_DURATION_TMP") or {}
194-
log.debug(string.format("***DEBUG*** tone_info_report_handler... %s:%s (%ss)", tone_id, tone_name, duration))
195168

196-
--table.insert(tones_list, string.format("%s: %s (%ss)", tone_id, tone_name, duration))
197-
tones_list[tone_id] = string.format("%s: %s (%ss)", tone_id, tone_name, duration)
198-
tones_duration[tone_id] = duration
169+
tones_list[tone_id] = { name = tone_name, duration = duration }
199170
device:set_field("TONES_LIST_TMP", tones_list)
200-
device:set_field("TONES_DURATION_TMP", tones_duration)
201171

202-
if tone_id >= total_tones or #tones_duration >= total_tones then
203-
log.debug(string.format("Got info on all tones... #tones_duration %s, #tones_list %s, total_tones %s", #tones_duration, #tones_list, total_tones))
172+
if tone_id >= total_tones or #tones_list >= total_tones then
173+
log.info(string.format("Received info on all tones: tone_id %s, #tones_list %s, total_tones %s", tone_id, #tones_list, total_tones))
204174
device:set_field("TONES_LIST", tones_list, { persist = true })
205-
device:set_field("TONES_DURATION", tones_duration, { persist = true })
206175

207176
local tones_arguments = { "Off" }
208177
for il, vl in ipairs(tones_list) do
209-
--log.debug(string.format("#%s:: '%s' // '%s'", il, tones_list[il], vl))
210-
table.insert(tones_arguments, vl)
178+
table.insert(tones_arguments, getModeName(il, vl))
211179
end
212180

213181
device:emit_event(capabilities.mode.supportedModes({ "Rebuild List", table.unpack(tones_arguments) }))
214182
device:emit_event(capabilities.mode.supportedArguments(tones_arguments))
215183
device:send(SoundSwitch:TonePlayGet({}))
216-
217184
end
218185
end
219186

220187
--- Handle when tone is played (TONE_PLAY_REPORT or BASIC_REPORT)
221188
local function tone_playing(self, device, tone_id)
222189
local tones_list = device:get_field("TONES_LIST")
223-
log.debug(string.format("***DEBUG*** tone_playing... id: %s", tone_id))
224190

225191
if device:get_latest_state("main", capabilities.mode.ID, capabilities.mode.supportedModes.NAME) == nil then
226192
rebuildTones(device)
@@ -231,31 +197,28 @@ local function tone_playing(self, device, tone_id)
231197
device:emit_event(capabilities.chime.chime.off())
232198
device:emit_event(capabilities.mode.mode("Off"))
233199
else
234-
local tone_name = tones_list[tone_id] or tostring(tone_id)
200+
local toneInfo = tones_list[tone_id] or { name = "Unknown", duration = "0" }
201+
local modeName = getModeName(tone_id, toneInfo)
235202
device:emit_event(capabilities.alarm.alarm.both())
236203
device:emit_event(capabilities.chime.chime.chime())
237-
device:emit_event(capabilities.mode.mode(tone_name))
204+
device:emit_event(capabilities.mode.mode(modeName))
238205
end
239206
end
240207

241208
local function tone_play_report_handler(self, device, cmd)
242209
local tone_id = tonumber(cmd.args.tone_identifier)
243-
local tone_volume = cmd.args.play_command_tone_volume
244-
log.debug(string.format("***DEBUG*** tone_play_report_handler... id: %s, vol: %s", tone_id, tone_volume))
245210
tone_playing(self, device, tone_id)
246211
end
247212

248213
local function basic_report_handler(self, device, cmd)
249214
local tone_id = tonumber(cmd.args.value)
250-
log.debug(string.format("***DEBUG*** basic_report_handler... value: %s", tone_id))
251215
tone_playing(self, device, tone_id)
252216
end
253217

254218
--- Handle SoundSwitch Config Reports (volume)
255219
local function soundSwitch_configuration_report(self, device, cmd)
256220
local volume = st_utils.clamp_value(cmd.args.volume, 0, 100)
257221
local default_tone = cmd.args.default_tone_identifer
258-
log.debug(string.format("***DEBUG*** soundSwitch_configuration_report... vol: %s", volume))
259222
device:emit_event(capabilities.audioVolume.volume(volume))
260223
device:set_field("TONE_DEFAULT", default_tone, { persist = true })
261224
end
@@ -278,7 +241,6 @@ end
278241
--- @param device st.zwave.Device
279242
--- @param cmd st.zwave.CommandClass.Version.Report
280243
local function version_report_handler(driver, device, cmd)
281-
log.debug("***DEBUG*** version_report_handler...")
282244
local major = cmd.args.application_version
283245
local minor = cmd.args.application_sub_version
284246

@@ -291,7 +253,7 @@ end
291253
local function device_init(driver, device)
292254
device:send(Version:Get({}))
293255

294-
if (device:get_field("TONES_DURATION") == nil or device:get_field("TONE_DEFAULT") == nil) then
256+
if (device:get_field("TONES_LIST") == nil or device:get_field("TONE_DEFAULT") == nil) then
295257
rebuildTones(device)
296258
end
297259
end
@@ -305,7 +267,6 @@ local function device_added(driver, device)
305267
end
306268

307269
--- Handle preference changes (same as default but added hack for unsigned parameters)
308-
---
309270
--- @param driver st.zwave.Driver
310271
--- @param device st.zwave.Device
311272
--- @param event table
@@ -341,7 +302,7 @@ end
341302

342303
local zooz_zse50 = {
343304
NAME = "Zooz ZSE50",
344-
can_handle = can_handle_zooz_zse50,
305+
can_handle = require("zooz-zse50.can_handle"),
345306

346307
supported_capabilities = {
347308
capabilities.battery,

0 commit comments

Comments
 (0)