Skip to content

Commit

Permalink
Merge pull request #1197 from SmartThingsCommunity/main
Browse files Browse the repository at this point in the history
Rolling up main to beta
  • Loading branch information
greens authored Jan 30, 2024
2 parents 196145b + d57f980 commit df506bd
Show file tree
Hide file tree
Showing 8 changed files with 260 additions and 19 deletions.
28 changes: 28 additions & 0 deletions drivers/SmartThings/matter-switch/fingerprints.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,33 @@ matterManufacturer:
productId: 0x9002
deviceProfileName: light-color-level-2700K-6500K

#AiDot
- id: "Linkind/Smart/Light/Bulb/A19/RGBTW"
deviceLabel: Linkind Smart Light Bulb A19 RGBTW
vendorId: 0x1168
productId: 0x03e8
deviceProfileName: light-color-level-1800K-6500K
- id: "OREiN/Smart/Light/Bulb/A19/RGBTW"
deviceLabel: OREiN Smart Light Bulb A19 RGBTW
vendorId: 0x1168
productId: 0x03ea
deviceProfileName: light-color-level-1800K-6500K
- id: "Linkind/Smart/Light/Bulb/BR30/RGBTW"
deviceLabel: Linkind Smart Light Bulb BR30 RGBTW
vendorId: 0x1168
productId: 0x03eb
deviceProfileName: light-color-level-1800K-6500K
- id: "OREiN/Smart/Light/Bulb/BR30/RGBTW"
deviceLabel: OREiN Smart Light Bulb BR30 RGBTW
vendorId: 0x1168
productId: 0x03ec
deviceProfileName: light-color-level-1800K-6500K
- id: "Consciot/Smart/Light/Bulb/A19/RGBT"
deviceLabel: Consciot Smart Light Bulb A19 RGBT
vendorId: 0x1168
productId: 0x0405
deviceProfileName: light-color-level-1800K-6500K

#WiZ
- id: "WiZ A19"
deviceLabel: WiZ A19
Expand Down Expand Up @@ -1884,6 +1911,7 @@ matterManufacturer:
productId: 0x228F
deviceProfileName: light-color-level-2200K-6500K


#Bridge devices need manufacturer specific fingerprints until
#bridge support is released to all hubs. This is because of the way generic
#fingerprints work for bridges joined prior to hubs being able to support them
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: light-color-level-1800K-6500K
components:
- id: main
capabilities:
- id: switch
version: 1
- id: switchLevel
version: 1
config:
values:
- key: "level.value"
range: [1, 100]
- id: colorTemperature
version: 1
config:
values:
- key: "colorTemperature.value"
range: [ 1800, 6500 ]
- id: colorControl
version: 1
- id: firmwareUpdate
version: 1
- id: refresh
version: 1
categories:
- name: Light
94 changes: 93 additions & 1 deletion drivers/SmartThings/zigbee-lock/src/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,12 @@ local UserStatusEnum = LockCluster.types.DrlkUserStatus
local UserTypeEnum = LockCluster.types.DrlkUserType
local ProgrammingEventCodeEnum = LockCluster.types.ProgramEventCode

local socket = require "cosock.socket"
local lock_utils = require "lock_utils"

local DELAY_LOCK_EVENT = "_delay_lock_event"
local MAX_DELAY = 10

local reload_all_codes = function(driver, device, command)
-- starts at first user code index then iterates through all lock codes as they come in
device:send(LockCluster.attributes.SendPINOverTheAir:write(device, true))
Expand Down Expand Up @@ -300,6 +304,92 @@ local function init(driver, device)
lock_utils.populate_state_from_data(device)
end

-- The following two functions are from the lock defaults. They are in the base driver temporarily
-- until the fix is widely released in the lua libs
local lock_state_handler = function(driver, device, value, zb_rx)
local attr = capabilities.lock.lock
local LOCK_STATE = {
[value.NOT_FULLY_LOCKED] = attr.unknown(),
[value.LOCKED] = attr.locked(),
[value.UNLOCKED] = attr.unlocked(),
[value.UNDEFINED] = attr.unknown(),
}

-- this is where we decide whether or not we need to delay our lock event because we've
-- observed it coming before the event (or we're starting to compute the timer)
local delay = device:get_field(DELAY_LOCK_EVENT) or 100
if (delay < MAX_DELAY) then
device.thread:call_with_delay(delay+.5, function ()
device:emit_event_for_endpoint(zb_rx.address_header.src_endpoint.value, LOCK_STATE[value.value])
end)
else
device:set_field(DELAY_LOCK_EVENT, socket.gettime())
device:emit_event_for_endpoint(zb_rx.address_header.src_endpoint.value, LOCK_STATE[value.value])
end
end

local lock_operation_event_handler = function(driver, device, zb_rx)
local event_code = zb_rx.body.zcl_body.operation_event_code.value
local source = zb_rx.body.zcl_body.operation_event_source.value
local OperationEventCode = require "st.zigbee.generated.zcl_clusters.DoorLock.types.OperationEventCode"
local METHOD = {
[0] = "keypad",
[1] = "command",
[2] = "manual",
[3] = "rfid",
[4] = "fingerprint",
[5] = "bluetooth"
}
local STATUS = {
[OperationEventCode.LOCK] = capabilities.lock.lock.locked(),
[OperationEventCode.UNLOCK] = capabilities.lock.lock.unlocked(),
[OperationEventCode.ONE_TOUCH_LOCK] = capabilities.lock.lock.locked(),
[OperationEventCode.KEY_LOCK] = capabilities.lock.lock.locked(),
[OperationEventCode.KEY_UNLOCK] = capabilities.lock.lock.unlocked(),
[OperationEventCode.AUTO_LOCK] = capabilities.lock.lock.locked(),
[OperationEventCode.MANUAL_LOCK] = capabilities.lock.lock.locked(),
[OperationEventCode.MANUAL_UNLOCK] = capabilities.lock.lock.unlocked(),
[OperationEventCode.SCHEDULE_LOCK] = capabilities.lock.lock.locked(),
[OperationEventCode.SCHEDULE_UNLOCK] = capabilities.lock.lock.unlocked()
}
local event = STATUS[event_code]
if (event ~= nil) then
event["data"] = {}
if (event_code == OperationEventCode.AUTO_LOCK or
event_code == OperationEventCode.SCHEDULE_LOCK or
event_code == OperationEventCode.SCHEDULE_UNLOCK
) then
event.data.method = "auto"
else
event.data.method = METHOD[source]
end
if (source == 0) then --keypad
local code_id = zb_rx.body.zcl_body.user_id.value
local code_name = "Code "..code_id
local lock_codes = device:get_field("lockCodes")
if (lock_codes ~= nil and
lock_codes[code_id] ~= nil) then
code_name = lock_codes[code_id]
end
event.data = {method = METHOD[0], codeId = code_id .. "", codeName = code_name}
end

-- if this is an event corresponding to a recently-received attribute report, we
-- want to set our delay timer for future lock attribute report events
if device:get_latest_state(
device:get_component_id_for_endpoint(zb_rx.address_header.src_endpoint.value),
capabilities.lock.ID,
capabilities.lock.lock.ID) == event.value.value then
local preceding_event_time = device:get_field(DELAY_LOCK_EVENT) or 0
local time_diff = socket.gettime() - preceding_event_time
if time_diff < MAX_DELAY then
device:set_field(DELAY_LOCK_EVENT, time_diff)
end
end

device:emit_event_for_endpoint(zb_rx.address_header.src_endpoint.value, event)
end
end

local zigbee_lock_driver = {
supported_capabilities = {
Expand All @@ -314,11 +404,13 @@ local zigbee_lock_driver = {
},
[LockCluster.ID] = {
[LockCluster.client.commands.GetPINCodeResponse.ID] = get_pin_response_handler,
[LockCluster.client.commands.ProgrammingEventNotification.ID] = programming_event_handler
[LockCluster.client.commands.ProgrammingEventNotification.ID] = programming_event_handler,
[LockCluster.client.commands.OperatingEventNotification.ID] = lock_operation_event_handler
}
},
attr = {
[LockCluster.ID] = {
[LockCluster.attributes.LockState.ID] = lock_state_handler,
[LockCluster.attributes.MaxPINCodeLength.ID] = handle_max_code_length,
[LockCluster.attributes.MinPINCodeLength.ID] = handle_min_code_length,
[LockCluster.attributes.NumberOfPINUsersSupported.ID] = handle_max_codes
Expand Down
7 changes: 6 additions & 1 deletion drivers/SmartThings/zigbee-lock/src/samsungsds/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ local function unlock_cmd_handler(driver, device, command)
"\x10\x04\x31\x32\x33\x35"))
end

local function lock_cmd_handler(driver, device, command)
--do nothing in lock command handler
end

local refresh = function(driver, device, cmd)
-- do nothing in refresh capability handler
end
Expand Down Expand Up @@ -95,7 +99,8 @@ local samsung_sds_driver = {
[capabilities.refresh.commands.refresh.NAME] = refresh
},
[capabilities.lock.ID] = {
[capabilities.lock.commands.unlock.NAME] = unlock_cmd_handler
[capabilities.lock.commands.unlock.NAME] = unlock_cmd_handler,
[capabilities.lock.commands.lock.NAME] = lock_cmd_handler
}
},
lifecycle_handlers = {
Expand Down
63 changes: 63 additions & 0 deletions drivers/SmartThings/zigbee-lock/src/test/test_zigbee_lock.lua
Original file line number Diff line number Diff line change
Expand Up @@ -721,4 +721,67 @@ test.register_coroutine_test(
end
)

test.register_coroutine_test(
"Lock state attribute reports (after the first) should be delayed if they come before event notifications ",
function()
init_code_slot(1, "Code 1", mock_device)
test.socket.capability:__expect_send(mock_device:generate_test_message("main",
capabilities.lockCodes.lockCodes(json.encode({["1"] = "Code 1"}), { visibility = { displayed = false } })))
test.socket.zigbee:__queue_receive({mock_device.id, DoorLock.attributes.LockState:build_test_attr_report(mock_device, DoorLockState.UNLOCKED)})
test.socket.capability:__expect_send(
mock_device:generate_test_message("main",
capabilities.lock.lock.unlocked()
)
)
test.mock_time.advance_time(2)
test.socket.zigbee:__queue_receive(
{
mock_device.id,
DoorLock.client.commands.OperatingEventNotification.build_test_rx(
mock_device,
0x00, -- 0 = keypad
OperationEventCode.UNLOCK,
0x0001,
"1234",
0x0000,
""
)
}
)
test.socket.capability:__expect_send(
mock_device:generate_test_message("main",
capabilities.lock.lock.unlocked({ data = { method = "keypad", codeId = "1", codeName = "Code 1" } })
)
)
test.mock_time.advance_time(2)
test.timer.__create_and_queue_test_time_advance_timer(2.5, "oneshot")
test.socket.zigbee:__queue_receive({mock_device.id, DoorLock.attributes.LockState:build_test_attr_report(mock_device, DoorLockState.LOCKED)})
test.socket.zigbee:__queue_receive(
{
mock_device.id,
DoorLock.client.commands.OperatingEventNotification.build_test_rx(
mock_device,
0x00, -- 0 = keypad
OperationEventCode.LOCK,
0x0001,
"1234",
0x0000,
""
)
}
)
test.socket.capability:__expect_send(
mock_device:generate_test_message("main",
capabilities.lock.lock.locked({ data = { method = "keypad", codeId = "1", codeName = "Code 1" } })
)
)
test.mock_time.advance_time(2.5)
test.socket.capability:__expect_send(
mock_device:generate_test_message("main",
capabilities.lock.lock.locked()
)
)
end
)

test.run_registered_tests()
Original file line number Diff line number Diff line change
Expand Up @@ -1349,6 +1349,19 @@ test.register_coroutine_test(
end
)

test.register_coroutine_test(
"Handle Lock cmd",
function()
test.socket.capability:__queue_receive(
{
mock_device.id,
{ capability = "lock", component = "main", command = "lock", args = {} }
}
)
test.wait_for_events()
end
)

test.register_coroutine_test(
"Device added function handler",
function()
Expand Down
36 changes: 21 additions & 15 deletions tools/localizations/cn.csv
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,24 @@ Zigbee Thermostat,Zigbee温控
Zigbee Thing,Zigbee设备
Zigbee Vent,Zigbee新风系统
Zigbee Window Treatment,Zigbee窗帘电机
Aqara Motion Sensor T1, Aqara 人体传感器 T1
Aqara High Precision Motion Sensor, Aqara高精度人体传感器
Aqara Door and Window Sensor T1, Aqara 门窗传感器T1
Aqara Temperature and Humidity Sensor T1, Aqara温湿度传感器 T1
Aqara Water Leak Sensor, Aqara 水浸传感器 T1
Aqara Illuminance Sensor T1, Aqara 光照传感器T1
Aqara Presence Sensor FP1, Aqara 人体存在传感器FP1
Aqara Smart Dimmer Controller T1 Pro, Aqara 双色温驱动器 T1 Pro
Aqara Single Switch Module T1 (With Neutral), Aqara 单路控制器T1 (零火版)
Aqara Curtain Controller, Agara智能窗帘电机 (Zigbee开合帘版)
Aqara Roller Shade Controller, Aqara智能管状电机
Aqara Smart Pet Feeder C1, Aqara智能宠物喂食器 C1
"Aqara Smart Wall Switch H1 (With Neutral, Single Rocker)", Aqara智能墙壁开关H1 (零火线单键版)
"Aqara Smart Wall Switch H1 (With Neutral, Double Rocker) 1", Aqara智能墙壁开关H1 (零火线双键版) 1
"Aqara Smart Wall Switch H1 (With Neutral, Triple Rocker) 1", Aqara智能墙壁开关H1 (零火线三键版) 1
Aqara Motion Sensor T1,Aqara 人体传感器 T1
Aqara High Precision Motion Sensor,Aqara高精度人体传感器
Aqara Door and Window Sensor T1,Aqara 门窗传感器T1
Aqara Temperature and Humidity Sensor T1,Aqara温湿度传感器 T1
Aqara Water Leak Sensor,Aqara 水浸传感器 T1
Aqara Illuminance Sensor T1,Aqara 光照传感器T1
Aqara Presence Sensor FP1,Aqara 人体存在传感器FP1
Aqara Smart Dimmer Controller T1 Pro,Aqara 双色温驱动器 T1 Pro
Aqara Single Switch Module T1 (With Neutral),Aqara 单路控制器T1 (零火版)
Aqara Curtain Controller,Agara智能窗帘电机 (Zigbee开合帘版)
Aqara Roller Shade Controller,Aqara智能管状电机
Aqara Smart Pet Feeder C1,Aqara智能宠物喂食器 C1
"Aqara Smart Wall Switch H1 (With Neutral,Single Rocker)",Aqara智能墙壁开关H1 (零火线单键版)
"Aqara Smart Wall Switch H1 (With Neutral,Double Rocker) 1",Aqara智能墙壁开关H1 (零火线双键版) 1
"Aqara Smart Wall Switch H1 (With Neutral,Triple Rocker) 1",Aqara智能墙壁开关H1 (零火线三键版) 1
Aqara Smart Gas Detector,Aqara天然气报警器
Aqara Smart Smoke Detector,Aqara烟雾报警器
Aqara Smart Plug T1,Aqara 智能插座 T1 (国标)
Aqara Wireless Mini Switch T1,Aqara 无线开关 T1
"Aqara Wireless Remote Switch E1 (Single Rocker)",Aqara 无线开关 E1 (贴墙式单键版)
"Aqara LED Light Bulb T1 (Tunable White)",Aqara LED灯泡 T1 (可调色温)
12 changes: 10 additions & 2 deletions tools/run_driver_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,14 @@ def run_tests(verbosity_level, filter, junit, coverage_files):
if m is not None:
test_title = line
in_progress_test_name = m.group(1)
test_case = junit_xml.TestCase(in_progress_test_name)
test_name_regex = re.compile(in_progress_test_name)
line_number = None
with open(test_file, 'r') as search_file:
for idx, line in enumerate(search_file, 1):
if test_name_regex.search(line) :
line_number = idx
break
test_case = junit_xml.TestCase(in_progress_test_name, line=line_number)
test_count += 1
elif re.search("PASSED", line) is not None:
test_done = True
Expand All @@ -84,7 +91,8 @@ def run_tests(verbosity_level, filter, junit, coverage_files):
elif re.search("FAILED", line) is not None:
test_done = True
test_status = line
failure_files[test_file].append(in_progress_test_name)
failure_string = f"{in_progress_test_name} [line {test_case.line}]"
failure_files[test_file].append(failure_string)
if "traceback" in test_case.stdout:
test_case.add_error_info(line, test_case.stdout)
else:
Expand Down

0 comments on commit df506bd

Please sign in to comment.