Skip to content

Commit

Permalink
Merge pull request #1254 from SmartThingsCommunity/beta
Browse files Browse the repository at this point in the history
Rolling up beta to production
  • Loading branch information
greens authored Mar 6, 2024
2 parents 6f4776b + faf3824 commit 53f86e0
Show file tree
Hide file tree
Showing 16 changed files with 209 additions and 88 deletions.
27 changes: 15 additions & 12 deletions drivers/SmartThings/matter-sensor/fingerprints.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,31 +21,34 @@ matterManufacturer:
vendorId: 0x130a
productId: 0x0057
deviceProfileName: temperature-humidity-battery

- id: "TUO/ContactDoorAndWindow"
deviceLabel: TUO Contact Sensor
vendorId: 0x141E
productId: 0x0002
deviceProfileName: contact-battery
#Heiman
- id: "Heiman/Motion"
deviceLabel: Heiman Motion Sensor
vendorId: 0x120B
productId: 0x1001
deviceProfileName: matter-motion-battery-illuminance
- id: "4619/4145"
deviceLabel: Heiman Door and Window D1-M
vendorId: 0x120B
productId: 0x1031
deviceProfileName: contact-battery
# Legrand
- id: "Legrand/Netatmo/Smart-2-in-1-Sensor"
deviceLabel: Netatmo Smart 2-in-1 Sensor
vendorId: 0x1021
productId: 0x0001
deviceProfileName: motion-contact-battery
# HEIMAN
- id: "4619/4145"
deviceLabel: Heiman Door and Window D1-M
vendorId: 0x120B
productId: 0x1031
#Tuo
- id: "5150/3"
deviceLabel: "TUO Temperature Sensor"
vendorId: 0x141E
productId: 0x0003
deviceProfileName: "temperature-humidity-battery"
- id: "TUO/ContactDoorAndWindow"
deviceLabel: TUO Contact Sensor
vendorId: 0x141E
productId: 0x0002
deviceProfileName: contact-battery

matterGeneric:
- id: "matter/contact/sensor"
deviceLabel: Matter Contact Sensor
Expand Down
10 changes: 10 additions & 0 deletions drivers/SmartThings/matter-switch/fingerprints.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@ matterManufacturer:
vendorId: 0x130A
productId: 0x69
deviceProfileName: power-energy-powerConsumption
- id: "4874/106"
deviceLabel: Eve Energy Switzerland
vendorId: 0x130A
productId: 0x006A
deviceProfileName: power-energy-powerConsumption
- id: "4874/107"
deviceLabel: Eve Energy Outdoor
vendorId: 0x130A
productId: 0x006B
deviceProfileName: power-energy-powerConsumption

#GE
- id: "4921/177"
Expand Down
5 changes: 5 additions & 0 deletions drivers/SmartThings/matter-switch/src/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ local COLOR_TEMPERATURE_MIRED_MAX = CONVERSION_CONSTANT/COLOR_TEMPERATURE_KELVIN
local COLOR_TEMPERATURE_MIRED_MIN = CONVERSION_CONSTANT/COLOR_TEMPERATURE_KELVIN_MAX

local SWITCH_INITIALIZED = "__switch_intialized"
-- COMPONENT_TO_ENDPOINT_MAP is here only to perserve the endpoint mapping for
-- devices that were joined to this driver as MCD devices before the transition
-- to join all matter-switch devices as parent-child. This value will only exist
-- in the device table for devices that joined prior to this transition, and it
-- will not be set for new devices.
local COMPONENT_TO_ENDPOINT_MAP = "__component_to_endpoint_map"
local AGGREGATOR_DEVICE_TYPE_ID = 0x000E
local detect_matter_thing
Expand Down
27 changes: 17 additions & 10 deletions drivers/SmartThings/philips-hue/src/disco.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@ local mdns = require "st.mdns"
local net_utils = require "st.net_utils"
local st_utils = require "st.utils"

local Fields = require "hue.fields"
local Fields = require "fields"
local HueApi = require "hue.api"
local utils = require "utils"

local SERVICE_TYPE = "_hue._tcp"
local DOMAIN = "local"

-- This `api_keys` table is an in-memory fall-back table. It gets overwritten
-- with a reference to a driver datastore table before the Driver's `run` loop
-- can get spun up in `init.lua`.
local HueDiscovery = {
api_keys = {},
disco_api_instances = {},
Expand Down Expand Up @@ -94,8 +97,8 @@ function HueDiscovery.scan_bridge_and_update_devices(driver, bridge_id)
end

local known_bridge_device = known_identifier_to_device_map[bridge_id]
if known_bridge_device and known_bridge_device:get_field(Fields.API_KEY) then
HueDiscovery.api_keys[bridge_id] = known_bridge_device:get_field(Fields.API_KEY)
if known_bridge_device and known_bridge_device:get_field(HueApi.APPLICATION_KEY_HEADER) then
HueDiscovery.api_keys[bridge_id] = known_bridge_device:get_field(HueApi.APPLICATION_KEY_HEADER)
end

HueDiscovery.search_bridge_for_supported_devices(driver, bridge_id, HueDiscovery.disco_api_instances[bridge_id],
Expand All @@ -116,8 +119,8 @@ discovered_bridge_callback = function(driver, bridge_ip, bridge_id, known_identi
if driver.ignored_bridges[bridge_id] then return end

local known_bridge_device = known_identifier_to_device_map[bridge_id]
if known_bridge_device and known_bridge_device:get_field(Fields.API_KEY) then
HueDiscovery.api_keys[bridge_id] = known_bridge_device:get_field(Fields.API_KEY)
if known_bridge_device and known_bridge_device:get_field(HueApi.APPLICATION_KEY_HEADER) then
HueDiscovery.api_keys[bridge_id] = known_bridge_device:get_field(HueApi.APPLICATION_KEY_HEADER)
end

if known_bridge_device ~= nil
Expand Down Expand Up @@ -253,14 +256,17 @@ function HueDiscovery.search_bridge_for_supported_devices(driver, bridge_id, api

if do_delete then
for _, device in ipairs(driver:get_devices()) do ---@cast device HueDevice
-- We're only interested in processing child/non-bridge devices here.
if utils.is_bridge(driver, device) then goto continue end
local not_known_to_bridge = device_is_joined_to_bridge[device:get_field(Fields.HUE_DEVICE_ID) or ""]
local parent_device_id = device.parent_device_id or device:get_field(Fields.PARENT_DEVICE_ID) or ""
local parent_bridge_device = driver:get_device_info(parent_device_id)
local is_child_of_bridge = parent_bridge_device and (parent_bridge_device:get_field(Fields.BRIDGE_ID) == bridge_id)
if is_child_of_bridge and not not_known_to_bridge then
if parent_bridge_device and is_child_of_bridge and not not_known_to_bridge then
device.log.info(string.format("Device is no longer joined to Hue Bridge %q, deleting", parent_bridge_device.label))
driver:do_hue_light_delete(device)
end
::continue::
end
end
end
Expand All @@ -283,7 +289,7 @@ end
---@param bridge_id string
---@param resource_id string
---@param device_info table
---@param known_identifier_to_device_map table<string,boolean>
---@param known_identifier_to_device_map table<string,HueDevice>
process_discovered_light = function(driver, bridge_id, resource_id, device_info, known_identifier_to_device_map)
local api_instance = HueDiscovery.disco_api_instances[bridge_id]
if not api_instance then
Expand Down Expand Up @@ -385,17 +391,17 @@ function HueDiscovery.do_mdns_scan(driver)
for _, info in ipairs(mdns_responses.found) do
if not net_utils.validate_ipv4_string(info.host_info.address) then -- we only care about the ipV4 types here.
log.trace("Invalid IPv4 address: " .. info.host_info.address)
return
goto continue
end

if info.service_info.service_type ~= HueDiscovery.ServiceType then -- response for a different service type. Shouldn't happen.
log.warn("Unexpected service type response: " .. info.service_info.service_type)
return
goto continue
end

if info.service_info.domain ~= HueDiscovery.Domain then -- response for a different domain. Shouldn't happen.
log.warn("Unexpected domain response: " .. info.service_info.domain)
return
goto continue
end

-- Hue *typically* formats the BridgeID as the uppercase MAC address, minus separators.
Expand Down Expand Up @@ -452,6 +458,7 @@ function HueDiscovery.do_mdns_scan(driver)
driver:update_bridge_netinfo(bridge_id, bridge_info)
end
end
::continue::
end
end

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
local APPLICATION_KEY_HEADER = require "hue.api".APPLICATION_KEY_HEADER
--- Table of constants used to index in to device store fields
--- @class Fields
--- @field IPV4 string the ipV4 address of a Hue bridge
Expand All @@ -14,7 +13,6 @@ local Fields = {
_ADDED = "added",
_INIT = "init",
_REFRESH_AFTER_INIT = "force_refresh",
API_KEY = APPLICATION_KEY_HEADER,
BRIDGE_API = "bridge_api",
BRIDGE_ID = "bridgeid",
BRIDGE_SW_VERSION = "swversion",
Expand Down
5 changes: 4 additions & 1 deletion drivers/SmartThings/philips-hue/src/handlers.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
local Fields = require "hue.fields"
local Fields = require "fields"
local HueApi = require "hue.api"
local HueColorUtils = require "hue.cie_utils"
local log = require "log"
Expand All @@ -7,6 +7,9 @@ local utils = require "utils"
local cosock = require "cosock"
local capabilities = require "st.capabilities"
local st_utils = require "st.utils"
-- trick to fix the VS Code Lua Language Server typechecking
---@type fun(val: table, name: string?, multi_line: boolean?): string
st_utils.stringify_table = st_utils.stringify_table

local handlers = {}

Expand Down
16 changes: 11 additions & 5 deletions drivers/SmartThings/philips-hue/src/hue/api.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ local json = require "st.json"
local log = require "log"
local RestClient = require "lunchbox.rest"
local st_utils = require "st.utils"
-- trick to fix the VS Code Lua Language Server typechecking
---@type fun(val: table, name: string?, multi_line: boolean?): string
st_utils.stringify_table = st_utils.stringify_table

local APPLICATION_KEY_HEADER = "hue-application-key"

Expand Down Expand Up @@ -35,9 +38,10 @@ end

--- Phillips Hue REST API Module
--- @class PhilipsHueApi
--- @field private client RestClient
--- @field private headers table<string,string>
--- @field private _ctrl_tx table
--- @field public headers table<string,string>
--- @field package client RestClient
--- @field package _ctrl_tx table
--- @field package _running boolean
local PhilipsHueApi = {}
PhilipsHueApi.__index = PhilipsHueApi

Expand Down Expand Up @@ -138,13 +142,15 @@ function PhilipsHueApi.new_bridge_manager(base_url, api_key, socket_builder)

local path, reply_tx = msg.path, msg.reply_tx
if msg._type == ControlMessageTypes.Get then
local get_resp, get_err, partial = self.client:get(path, self.headers, retry_fn(5))
reply_tx:send(
table.pack(process_rest_response(self.client:get(path, self.headers, retry_fn(5), rest_err_callback)))
table.pack(process_rest_response(get_resp, get_err, partial, rest_err_callback))
)
elseif msg._type == ControlMessageTypes.Put then
local payload = msg.payload
local put_resp, put_err, partial = self.client:put(path, payload, self.headers, retry_fn(5))
reply_tx:send(
table.pack(process_rest_response(self.client:put(path, payload, self.headers, retry_fn(5), rest_err_callback)))
table.pack(process_rest_response(put_resp, put_err, partial, rest_err_callback))
)
end
else
Expand Down
15 changes: 13 additions & 2 deletions drivers/SmartThings/philips-hue/src/hue/types.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
--- @meta

--- Hue Bridge Info as returned by the unauthenticated API endpoint `/api/config`
--- @class HueBridgeInfo
--- @field public name string
Expand All @@ -23,21 +25,30 @@
--- @field public update_bridge_netinfo fun(self: HueDriver, bridge_id: string, bridge_info: HueBridgeInfo)
--- @field public emit_light_status_events fun(light_device: HueChildDevice, light: table)
--- @field public get_device_by_dni fun(self: HueDriver, device_network_id: string, force_refresh?: boolean): HueDevice|nil
--- @field private _lights_pending_refresh table<string,HueChildDevice>
--- @field public do_hue_light_delete fun(self: HueDriver, light_device: HueDevice)
--- @field public get_device_info fun(self: HueDriver, device_id: string, force_refresh: boolean?): HueDevice?
--- @field public check_hue_repr_for_capability_support fun(hue_repr: table, capability_id: string): boolean
--- @field public _lights_pending_refresh table<string,HueChildDevice>

--- @class HueDevice:st.Device
--- @field public label string
--- @field public id string
--- @field public device_network_id string
--- @field public parent_device_id string
--- @field public parent_assigned_child_key string?
--- @field public manufacturer string
--- @field public model string
--- @field public vendor_provided_label string
--- @field public data table|nil migration data for a migrated device
--- @field public log table device-scoped logging module
--- @field public profile table
--- @field public get_field fun(self: HueDevice, key: string):any
--- @field public set_field fun(self: HueDevice, key: string, value: any, args?: table)
--- @field public emit_event fun(self: HueDevice, event: any)
--- @field public supports_capability_by_id fun(self: HueDevice, capability_id: string, component: string?): boolean

--- @class HueBridgeDevice:HueDevice
--- @field public device_network_id string

--- @class HueChildDevice:HueDevice
--- @field public parent_device_id string
--- @field public parent_assigned_child_key string
Loading

0 comments on commit 53f86e0

Please sign in to comment.