diff --git a/drivers/SinuxSoft/britzyhub/fingerprints.yml b/drivers/SinuxSoft/britzyhub/fingerprints.yml index 904b544db8..4de46bdfe6 100644 --- a/drivers/SinuxSoft/britzyhub/fingerprints.yml +++ b/drivers/SinuxSoft/britzyhub/fingerprints.yml @@ -1,3 +1,15 @@ +matterManufacturer: + - id: "4673/32846" + deviceLabel: AIHomeKit + vendorId: 0x1241 + productId: 0x804E + deviceProfileName: matter-bridge + - id: "5174/32780" + deviceLabel: BritzyHub + vendorId: 0x1436 + productId: 0x800C + deviceProfileName: matter-bridge + matterGeneric: - id: "elevator" deviceLabel: Elevator diff --git a/drivers/SinuxSoft/britzyhub/profiles/matter-bridge.yml b/drivers/SinuxSoft/britzyhub/profiles/matter-bridge.yml new file mode 100644 index 0000000000..b2e31f3c17 --- /dev/null +++ b/drivers/SinuxSoft/britzyhub/profiles/matter-bridge.yml @@ -0,0 +1,10 @@ +name: matter-bridge +components: + - id: main + capabilities: + - id: firmwareUpdate + version: 1 + - id: refresh + version: 1 + categories: + - name: Bridges \ No newline at end of file diff --git a/drivers/SinuxSoft/britzyhub/src/elevator/init.lua b/drivers/SinuxSoft/britzyhub/src/elevator/init.lua index 51aa1d8e0e..6f4771fa2c 100644 --- a/drivers/SinuxSoft/britzyhub/src/elevator/init.lua +++ b/drivers/SinuxSoft/britzyhub/src/elevator/init.lua @@ -4,6 +4,8 @@ local capabilities = require "st.capabilities" local clusters = require "st.matter.clusters" local log = require "log" +local britz_utils = require "utils" + local elevator_cap = capabilities.elevatorCall local onoff_cluster = clusters.OnOff @@ -39,8 +41,11 @@ local function component_to_endpoint(device, component_name, cluster_id) end local function device_init(driver, device) - device:subscribe() device:set_component_to_endpoint_fn(component_to_endpoint) + device:extend_device("subscribe", britz_utils.make_subscribe({ + [elevator_cap.ID] = { onoff_cluster.attributes.OnOff } + })) + device:subscribe() end local function info_changed(driver, device, event, args) diff --git a/drivers/SinuxSoft/britzyhub/src/gas-valve/init.lua b/drivers/SinuxSoft/britzyhub/src/gas-valve/init.lua index 52dd3cafb6..7f802db429 100644 --- a/drivers/SinuxSoft/britzyhub/src/gas-valve/init.lua +++ b/drivers/SinuxSoft/britzyhub/src/gas-valve/init.lua @@ -4,6 +4,7 @@ local capabilities = require "st.capabilities" local clusters = require "st.matter.clusters" local log = require "log" +local britz_utils = require "utils" local valve_cap = capabilities.safetyValve local onoff_cluster = clusters.OnOff @@ -39,8 +40,11 @@ local function component_to_endpoint(device, component_name, cluster_id) end local function device_init(driver, device) - device:subscribe() device:set_component_to_endpoint_fn(component_to_endpoint) + device:extend_device("subscribe", britz_utils.make_subscribe({ + [valve_cap.ID] = { onoff_cluster.attributes.OnOff } + })) + device:subscribe() end local function info_changed(driver, device, event, args) diff --git a/drivers/SinuxSoft/britzyhub/src/init.lua b/drivers/SinuxSoft/britzyhub/src/init.lua index 60f3cb90ce..9194560e9c 100644 --- a/drivers/SinuxSoft/britzyhub/src/init.lua +++ b/drivers/SinuxSoft/britzyhub/src/init.lua @@ -4,7 +4,14 @@ local MatterDriver = require "st.matter.driver" local log = require "log" +local function bridge_init(driver, device) + device:subscribe() +end + local matter_driver = MatterDriver("britzyhub-matter", { + lifecycle_handlers = { + init = bridge_init, + }, sub_drivers = { require ("elevator"), require ("gas-valve"), diff --git a/drivers/SinuxSoft/britzyhub/src/utils.lua b/drivers/SinuxSoft/britzyhub/src/utils.lua new file mode 100644 index 0000000000..d69acc5a69 --- /dev/null +++ b/drivers/SinuxSoft/britzyhub/src/utils.lua @@ -0,0 +1,33 @@ +-- SinuxSoft (c) 2025 +-- Licensed under the Apache License, Version 2.0 + +local im = require "st.matter.interaction_model" +local log = require "log" + +local utils = {} + +-- Sends subscription request directly via device:send(), following the matter-switch pattern. +-- The default device:subscribe() reuses cached sessions, which causes timeout after hub +-- replacement because the hub Node ID changes and all sessions expire. +-- device:send() creates a new session directly, so it works correctly after hub replacement. +function utils.make_subscribe(subscribed_attributes) + return function(device) + local subscribe_request = im.InteractionRequest(im.InteractionRequest.RequestType.SUBSCRIBE, {}) + for cap_id, attributes in pairs(subscribed_attributes) do + if device:supports_capability_by_id(cap_id) then + for _, attr in ipairs(attributes) do + local cluster_id = (attr._cluster and attr._cluster.ID) or attr.cluster + local attr_id = attr.ID or attr.attribute + local ib = im.InteractionInfoBlock(nil, cluster_id, attr_id) + subscribe_request:with_info_block(ib) + end + end + end + if #subscribe_request.info_blocks > 0 then + log.info_with({hub_logs=true}, string.format("[britzyhub] subscribe via send: %d blocks", #subscribe_request.info_blocks)) + device:send(subscribe_request) + end + end +end + +return utils diff --git a/drivers/SinuxSoft/britzyhub/src/vent/init.lua b/drivers/SinuxSoft/britzyhub/src/vent/init.lua index 93e11f40c6..0624cfba9b 100644 --- a/drivers/SinuxSoft/britzyhub/src/vent/init.lua +++ b/drivers/SinuxSoft/britzyhub/src/vent/init.lua @@ -4,6 +4,7 @@ local capabilities = require "st.capabilities" local clusters = require "st.matter.clusters" local log = require "log" +local britz_utils = require "utils" local VENTILATOR_DEVICE_TYPE_ID = 0xFF03 @@ -101,9 +102,10 @@ local function set_fan_mode(driver, device, cmd) end local function device_init(driver, device) - device:subscribe() device:set_component_to_endpoint_fn(component_to_endpoint) device:set_endpoint_to_component_fn(endpoint_to_component) + device:extend_device("subscribe", britz_utils.make_subscribe(subscribed_attributes)) + device:subscribe() end local function info_changed(driver, device, event, args)