1+ -- SinuxSoft (c) 2025
2+ -- Licensed under the Apache License, Version 2.0
3+
4+ local capabilities = require " st.capabilities"
5+ local clusters = require " st.matter.clusters"
6+ local log = require " log"
7+
8+ local valve_cap = capabilities .safetyValve
9+ local onoff_cluster = clusters .OnOff
10+
11+ local GAS_VALVE_DEVICE_TYPE_ID = 0xFF01
12+
13+ local function on_off_attr_handler (driver , device , ib , response )
14+ if ib .data .value then
15+ device :emit_event_for_endpoint (ib .endpoint_id , valve_cap .valve .open ())
16+ else
17+ device :emit_event_for_endpoint (ib .endpoint_id , valve_cap .valve .closed ())
18+ end
19+ end
20+
21+ local function handle_valve_close (driver , device , cmd )
22+ local endpoint_id = device :component_to_endpoint (cmd .component )
23+ local req = onoff_cluster .server .commands .Off (device , endpoint_id )
24+ device :send (req )
25+ end
26+
27+ local function find_default_endpoint (device , cluster )
28+ local eps = device :get_endpoints (cluster )
29+ table.sort (eps )
30+ for _ , ep in ipairs (eps ) do
31+ if ep ~= 0 then return ep end
32+ end
33+ log .warn (string.format (" No endpoint found, using default %d" , device .MATTER_DEFAULT_ENDPOINT ))
34+ return device .MATTER_DEFAULT_ENDPOINT
35+ end
36+
37+ local function component_to_endpoint (device , component_name , cluster_id )
38+ return find_default_endpoint (device , onoff_cluster .ID )
39+ end
40+
41+ local function device_init (driver , device )
42+ device :subscribe ()
43+ device :set_component_to_endpoint_fn (component_to_endpoint )
44+ end
45+
46+ local function info_changed (driver , device , event , args )
47+ device :add_subscribed_attribute (onoff_cluster .attributes .OnOff )
48+ device :subscribe ()
49+ end
50+
51+ local function is_matter_gas_valve (opts , driver , device )
52+ for _ , ep in ipairs (device .endpoints ) do
53+ for _ , dt in ipairs (ep .device_types ) do
54+ if dt .device_type_id == GAS_VALVE_DEVICE_TYPE_ID then
55+ return true
56+ end
57+ end
58+ end
59+ return false
60+ end
61+
62+ local gas_valve_handler = {
63+ NAME = " Gas Valve Handler" ,
64+ can_handle = is_matter_gas_valve ,
65+ lifecycle_handlers = {
66+ init = device_init ,
67+ infoChanged = info_changed ,
68+ },
69+ matter_handlers = {
70+ attr = {
71+ [onoff_cluster .ID ] = {
72+ [onoff_cluster .attributes .OnOff .ID ] = on_off_attr_handler ,
73+ }
74+ }
75+ },
76+ capability_handlers = {
77+ [valve_cap .ID ] = {
78+ [valve_cap .commands .close .NAME ] = handle_valve_close ,
79+ }
80+ },
81+ supported_capabilities = {
82+ valve_cap ,
83+ },
84+ subscribed_attributes = {
85+ [valve_cap .ID ] = {
86+ onoff_cluster .attributes .OnOff
87+ }
88+ },
89+ }
90+
91+ return gas_valve_handler
0 commit comments