Skip to content

Commit

Permalink
Merge pull request #1810 from SmartThingsCommunity/beta
Browse files Browse the repository at this point in the history
rolling up beta to production
  • Loading branch information
ctowns authored Dec 9, 2024
2 parents c3b150e + 3661e29 commit 3f9dd75
Show file tree
Hide file tree
Showing 16 changed files with 154 additions and 55 deletions.
9 changes: 7 additions & 2 deletions drivers/Aqara/aqara-presence-sensor/src/discovery.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@ function discovery.set_device_field(driver, device)

-- persistent fields
if device_cache_value ~= nil then
log.info_with({ hub_logs = true }, string.format("device found in cache. dni= %s", device.device_network_id))
device:set_field(fields.CREDENTIAL, device_cache_value.credential, { persist = true })
device:set_field(fields.DEVICE_IPV4, device_cache_value.ip, { persist = true })
device:set_field(fields.DEVICE_INFO, device_cache_value.device_info, { persist = true })
else
log.error_with({ hub_logs = true }, string.format("device not found in cache. dni= %s", device.device_network_id))
end

driver.datastore.discovery_cache[device.device_network_id] = nil
Expand All @@ -40,21 +43,22 @@ local function try_add_device(driver, device_dni, device_ip)
if driver.datastore.discovery_cache[device_dni] and driver.datastore.discovery_cache[device_dni].credential then
log.info(string.format("use stored credential. This may have expired. dni= %s, ip= %s", device_dni, device_ip))
else
log.error(string.format("Failed to get credential. dni= %s, ip= %s", device_dni, device_ip))
log.error_with({ hub_logs = true }, string.format("Failed to get credential. The device appears to have already generated a credential. In that case, a device reset is needed to generate a new credential. dni= %s, ip= %s", device_dni, device_ip))
return "credential not found"
end
else
log.info(string.format("success to get credential. dni= %s, ip= %s", device_dni, device_ip))
driver.datastore.discovery_cache[device_dni].credential = credential
end

log.info(string.format("try_create_device. dni= %s, ip= %s", device_dni, device_ip))
log.info_with({ hub_logs = true }, string.format("try_create_device. dni= %s, ip= %s", device_dni, device_ip))
processing_devices[device_dni] = true
driver:try_create_device(create_device_msg)
return nil
end

function discovery.device_added(driver, device)
log.info_with({ hub_logs = true }, string.format("device_added. dni= %s", device.device_network_id))
discovery.set_device_field(driver, device)
processing_devices[device.device_network_id] = nil
driver.lifecycle_handlers.init(driver, device)
Expand Down Expand Up @@ -96,6 +100,7 @@ local function discovery_device(driver)
end

function discovery.do_network_discovery(driver, _, should_continue)
log.info_with({ hub_logs = true }, string.format("discovery start for Aqara FP2"))
while should_continue() do
discovery_device(driver)
socket.sleep(1)
Expand Down
15 changes: 4 additions & 11 deletions drivers/Aqara/aqara-presence-sensor/src/fp2/api.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ local log = require "log"
local json = require "st.json"
local RestClient = require "lunchbox.rest"
local utils = require "utils"
local st_utils = require "st.utils"

local fp2_api = {}
fp2_api.__index = fp2_api
Expand Down Expand Up @@ -39,25 +40,17 @@ local function process_rest_response(response, err, partial)
end
end

local function retry_fn(retry_attempts)
local count = 0
return function()
count = count + 1
return count < retry_attempts
end
end

local function do_get(api_instance, path)
return process_rest_response(api_instance.client:get(path, api_instance.headers, retry_fn(5)))
return process_rest_response(RestClient.one_shot_get(api_instance.base_url .. path, api_instance.headers, api_instance.socket_builder))
end

function fp2_api.new_device_manager(device_ip, bridge_info, socket_builder)
local base_url = get_base_url(device_ip)

return setmetatable(
{
headers = ADDITIONAL_HEADERS,
client = RestClient.new(base_url, socket_builder),
headers = st_utils.deep_copy(ADDITIONAL_HEADERS),
socket_builder = socket_builder,
base_url = base_url,
}, fp2_api
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ function device_manager.is_valid_connection(driver, device, conn_info)
device.device_network_id))
return false
end

local _, err, status = conn_info:get_attr()
if err or status ~= 200 then
log.warn(string.format(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,17 @@ function discovery_helper.get_device_create_msg(driver, device_dni, device_ip)
return nil
end

local device_label = device_info.label or "Aqara-FP2"
if device_dni then
-- To make it easier to distinguish devices, add the last four letters of dni to the label
-- for example, if device_info.label is "Aqara-FP2" and device_dni is "00:11:22:33:44:55", then device_label will be "Aqara-FP2 (4455)"
device_label = string.format("%s (%s)", device_label, string.sub(string.gsub(tostring(device_dni), ":", ""), -4))
end

local create_device_msg = {
type = "LAN",
device_network_id = device_dni,
label = device_info.label,
label = device_label,
profile = "aqara-fp2-zoneDetection",
manufacturer = device_info.manufacturerName,
model = device_info.modelName,
Expand Down
51 changes: 27 additions & 24 deletions drivers/Aqara/aqara-presence-sensor/src/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -20,32 +20,27 @@ local function status_update(driver, device)
local conn_info = device:get_field(fields.CONN_INFO)
if not conn_info then
log.warn(string.format("refresh : failed to find conn_info, dni = %s", device.device_network_id))
return false, "failed to find conn_info"
else
local resp, err, status = conn_info:get_attr()

if err or status ~= 200 then
log.error(string.format("refresh : failed to get attr, dni= %s, err= %s, status= %s", device.device_network_id, err,
status))
if status == 404 then
device:offline()
end
return false, "failed to get attr"
else
driver.device_manager.handle_status(driver, device, resp)
end
end
return true
end

local function create_sse(driver, device, credential)
local conn_info = device:get_field(fields.CONN_INFO)

if not driver.device_manager.is_valid_connection(driver, device, conn_info) then
log.warn("create_sse : invalid connection")
return
end

local sse_url = driver.device_manager.get_sse_url(driver, device, conn_info)
if not sse_url then
log.error("failed to get sse_url")
log.error_with({ hub_logs = true }, "failed to get sse_url")
else
log.trace(string.format("Creating SSE EventSource for %s, sse_url= %s", device.device_network_id, sse_url))
local label = string.format("%s-SSE", device.device_network_id)
Expand All @@ -64,7 +59,16 @@ local function create_sse(driver, device, credential)
end

eventsource.onopen = function()
log.info_with({ hub_logs = true }, string.format("Eventsource open: dni= %s", device.device_network_id))
device:online()
local success, err = status_update(driver, device)
if not success then
log.warn(string.format("Failed to status_update during eventsource.onopen, err = %s dni= %s", err, device.device_network_id))
success, err = status_update(driver, device)
if not success then
log.error_with({ hub_logs = true }, string.format("Failed to status_update during eventsource.onopen again, err = %s dni= %s", err, device.device_network_id))
end
end
end

local old_eventsource = device:get_field(fields.EVENT_SOURCE)
Expand Down Expand Up @@ -104,14 +108,11 @@ end

local function check_and_update_connection(driver, device)
local conn_info = device:get_field(fields.CONN_INFO)
if not driver.device_manager.is_valid_connection(driver, device, conn_info) then
device:offline()
local eventsource = device:get_field(fields.EVENT_SOURCE)
if eventsource and eventsource.ready_state == eventsource.ReadyStates.OPEN then
log.info(string.format("SSE connection is being maintained well, dni = %s", device.device_network_id))
elseif not driver.device_manager.is_valid_connection(driver, device, conn_info) then
find_new_connection(driver, device)
conn_info = device:get_field(fields.CONN_INFO)
end

if driver.device_manager.is_valid_connection(driver, device, conn_info) then
device:online()
end
end

Expand All @@ -132,8 +133,11 @@ end


local function do_refresh(driver, device, cmd)
check_and_update_connection(driver, device)
status_update(driver, device)
local success, err = status_update(driver, device)
if not success then
log.info(string.format("Failed to status_update during do_refresh, err = %s dni= %s", err, device.device_network_id))
check_and_update_connection(driver, device)
end
driver.device_manager.init_presence(driver, device)
driver.device_manager.init_movement(driver, device)
driver.device_manager.init_activity(driver, device)
Expand Down Expand Up @@ -163,6 +167,7 @@ local function device_init(driver, device)
if device:get_field(fields._INIT) then
return
end
device:set_field(fields._INIT, true, { persist = false })

local device_dni = device.device_network_id
driver.controlled_devices[device_dni] = device
Expand All @@ -177,19 +182,19 @@ local function device_init(driver, device)
local credential = device:get_field(fields.CREDENTIAL)

if not credential then
log.error("failed to find credential.")
log.error_with({ hub_logs = true }, "failed to find credential.")
device:offline()
return
end

driver.device_manager.set_zone_info_to_latest_state(driver, device)

log.trace(string.format("Creating device monitoring for %s", device.device_network_id))
create_monitoring_thread(driver, device, device_info)
update_connection(driver, device, device_ip, device_info)

driver.device_manager.set_zone_info_to_latest_state(driver, device)
update_connection(driver, device, device_ip, device_info)

do_refresh(driver, device, nil)
device:set_field(fields._INIT, true, { persist = false })
end

local function device_info_changed(driver, device, event, args)
Expand All @@ -210,8 +215,6 @@ local lan_driver = Driver("aqara-fp2",
[capabilities.refresh.commands.refresh.NAME] = do_refresh,
},
[multipleZonePresence.id] = {
[multipleZonePresence.commands.createZone.name] = multipleZonePresence.commands.createZone.handler,
[multipleZonePresence.commands.deleteZone.name] = multipleZonePresence.commands.deleteZone.handler,
[multipleZonePresence.commands.updateZoneName.name] = multipleZonePresence.commands.updateZoneName.handler,
}
},
Expand Down
1 change: 1 addition & 0 deletions drivers/Aqara/aqara-presence-sensor/src/lunchbox/rest.lua
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ local function handle_response(sock)
if api_version >= 9 then
local response, err = Response.tcp_source(sock)
if err or (not response) then return response, (err or "unknown error") end
if response.status == 403 then return response, "403 Forbidden" end
return response, response:fill_body()
end
-- called select right before passing in so we receive immediately
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -343,8 +343,10 @@ local function open_action(source)
return
else
--- real error, close the connection.
source._sock:close()
source._sock = nil
if source._sock ~= nil then
source._sock:close()
source._sock = nil
end
source.ready_state = EventSource.ReadyStates.CLOSED
return nil, err, partial
end
Expand All @@ -360,8 +362,10 @@ local function open_action(source)
return
else
--- real error, close the connection.
source._sock:close()
source._sock = nil
if source._sock ~= nil then
source._sock:close()
source._sock = nil
end
source.ready_state = EventSource.ReadyStates.CLOSED
return nil, err, partial
end
Expand All @@ -373,8 +377,10 @@ local function open_action(source)
return
else
--- real error, close the connection.
source._sock:close()
source._sock = nil
if source._sock ~= nil then
source._sock:close()
source._sock = nil
end
source.ready_state = EventSource.ReadyStates.CLOSED
return nil, err, partial
end
Expand Down
5 changes: 5 additions & 0 deletions drivers/SmartThings/matter-sensor/fingerprints.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ matterManufacturer:
vendorId: 0x120B
productId: 0x1003
deviceProfileName: smoke
- id: "4619/4103"
deviceLabel: Smart co sensor
vendorId: 0x120B
productId: 0x1007
deviceProfileName: co
# Legrand
- id: "Legrand/Netatmo/Smart-2-in-1-Sensor"
deviceLabel: Netatmo Smart 2-in-1 Sensor
Expand Down
26 changes: 26 additions & 0 deletions drivers/SmartThings/matter-switch/fingerprints.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
matterManufacturer:
#Aqara
- id: "4447/6145"
deviceLabel: Aqara LED Bulb T2 RGB CCT
vendorId: 0x115F
productId: 0x1801
deviceProfileName: light-color-level
- id: "4447/6146"
deviceLabel: Aqara LED Bulb T2 CCT
vendorId: 0x115F
productId: 0x1802
deviceProfileName: light-level-colorTemperature-2700K-6500K
#Chengdu
- id: "5218/8197"
deviceLabel: Magic Cube DS001
Expand Down Expand Up @@ -165,6 +176,11 @@ matterManufacturer:
vendorId: 0x1339
productId: 0x007B
deviceProfileName: light-color-level-2000K-7000K
- id: "4921/109"
deviceLabel: Cync Reveal Full Color A21
vendorId: 0x1339
productId: 0x006D
deviceProfileName: light-color-level-2000K-7000K
- id: "4921/111"
deviceLabel: Cync Outdoor Plug
vendorId: 0x1339
Expand Down Expand Up @@ -2379,6 +2395,11 @@ matterManufacturer:
vendorId: 0x139C
productId: 0xD003
deviceProfileName: light-color-level
- id: "5020/43784"
deviceLabel: Zemismart WiFi Smart Switch
vendorId: 0x139C
productId: 0xAB08
deviceProfileName: switch-binary
- id: "5020/43825"
deviceLabel: Zemismart WiFi Smart Switch
vendorId: 0x139C
Expand All @@ -2394,6 +2415,11 @@ matterManufacturer:
vendorId: 0x139C
productId: 0xAB01
deviceProfileName: switch-binary
- id: "5020/43843"
deviceLabel: Zemismart WiFi Smart Switch
vendorId: 0x139C
productId: 0xAB43
deviceProfileName: switch-binary
#TUO
- id: "5150/1"
deviceLabel: "TUO Smart Button"
Expand Down
18 changes: 18 additions & 0 deletions drivers/SmartThings/matter-switch/profiles/plug-button.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: plug-button
components:
- id: main
capabilities:
- id: switch
version: 1
- id: firmwareUpdate
version: 1
- id: refresh
version: 1
categories:
- name: SmartPlug
- id: button
capabilities:
- id: button
version: 1
categories:
- name: RemoteController
5 changes: 5 additions & 0 deletions drivers/SmartThings/matter-window-covering/fingerprints.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ matterManufacturer:
vendorId: 0x139C
productId: 0xFF15
deviceProfileName: window-covering
- id: "5020/64050"
deviceLabel: Zemismart ZM02 Smart Curtain
vendorId: 0x139C
productId: 0xFA32
deviceProfileName: window-covering
- id: "5020/64017"
deviceLabel: Zemismart ZM25C Smart Curtain
vendorId: 0x139C
Expand Down
Loading

0 comments on commit 3f9dd75

Please sign in to comment.