diff --git a/drivers/SmartThings/bose/src/handlers.lua b/drivers/SmartThings/bose/src/handlers.lua index 9a06ba9c7a..4ea8018c4a 100644 --- a/drivers/SmartThings/bose/src/handlers.lua +++ b/drivers/SmartThings/bose/src/handlers.lua @@ -141,11 +141,11 @@ end function CapabilityHandlers.handle_audio_notification(driver, device, cmd) local ip = device:get_field("ip") - local DEFAULT_LEVEL = 30 + local default_level = device:get_latest_state("main", caps.audioVolume.ID, caps.audioVolume.volume.NAME, 30) log.info(string.format("[%s](%s) BoseCmd: audio notification with uri %s at level %d", bose_utils.get_serial_number(device), - device.label, cmd.args.uri, cmd.args.level or DEFAULT_LEVEL)) - local err = command.play_streaming_uri(ip, cmd.args.uri, cmd.args.level or DEFAULT_LEVEL) - if err then log.error_with({hub_logs=true}, string.format("failed to handle set volume: %s", err)) end + device.label, cmd.args.uri, cmd.args.level or default_level)) + local err = command.play_streaming_uri(ip, cmd.args.uri, cmd.args.level or default_level) + if err then log.error_with({hub_logs=true}, string.format("failed to handle audio notification: %s", err)) end end diff --git a/drivers/SmartThings/jbl/src/lunchbox/rest.lua b/drivers/SmartThings/jbl/src/lunchbox/rest.lua index 473e9abf6d..92df5441fb 100644 --- a/drivers/SmartThings/jbl/src/lunchbox/rest.lua +++ b/drivers/SmartThings/jbl/src/lunchbox/rest.lua @@ -94,6 +94,8 @@ local function parse_chunked_response(original_response, sock) if partial ~= nil and #partial >= 1 then full_response:append_body(partial) next_chunk_bytes = 0 + else + return nil, next_err end else return nil, ("unexpected error reading chunked transfer: " .. next_err) @@ -172,7 +174,11 @@ local function handle_response(sock) if headers:get_one("Content-Length") then full_response = recv_additional_response(initial_recv, sock) elseif headers:get_one("Transfer-Encoding") == "chunked" then - full_response = parse_chunked_response(initial_recv, sock) + local response, err = parse_chunked_response(initial_recv, sock) + if err ~= nil then + return nil, err + end + full_response = response else full_response = initial_recv end diff --git a/drivers/SmartThings/philips-hue/src/lunchbox/rest.lua b/drivers/SmartThings/philips-hue/src/lunchbox/rest.lua index 4963885bfd..7e0817524c 100644 --- a/drivers/SmartThings/philips-hue/src/lunchbox/rest.lua +++ b/drivers/SmartThings/philips-hue/src/lunchbox/rest.lua @@ -92,6 +92,8 @@ local function parse_chunked_response(original_response, sock) if partial ~= nil and #partial >= 1 then full_response:append_body(partial) next_chunk_bytes = 0 + else + return nil, next_err end else return nil, ("unexpected error reading chunked transfer: " .. next_err) @@ -136,7 +138,11 @@ local function handle_response(sock) local headers = initial_recv:get_headers() if headers:get_one("Transfer-Encoding") == "chunked" then - full_response = parse_chunked_response(initial_recv, sock) + local response, err = parse_chunked_response(initial_recv, sock) + if err ~= nil then + return nil, err + end + full_response = response else full_response = initial_recv end diff --git a/drivers/SmartThings/sonos/src/lunchbox/rest.lua b/drivers/SmartThings/sonos/src/lunchbox/rest.lua index 768d4346df..d0c4d413c4 100644 --- a/drivers/SmartThings/sonos/src/lunchbox/rest.lua +++ b/drivers/SmartThings/sonos/src/lunchbox/rest.lua @@ -95,6 +95,8 @@ local function parse_chunked_response(original_response, sock) if partial ~= nil and #partial >= 1 then full_response:append_body(partial) next_chunk_bytes = 0 + else + return nil, next_err end else return nil, ("unexpected error reading chunked transfer: " .. next_err) @@ -139,7 +141,11 @@ local function handle_response(sock) local headers = initial_recv:get_headers() if headers and headers:get_one("Transfer-Encoding") == "chunked" then - full_response = parse_chunked_response(initial_recv, sock) + local response, err = parse_chunked_response(initial_recv, sock) + if err ~= nil then + return nil, err + end + full_response = response else local content_length_header = (headers and headers:get_one("Content-length")) or nil if content_length_header then diff --git a/drivers/SmartThings/zwave-lock/fingerprints.yml b/drivers/SmartThings/zwave-lock/fingerprints.yml index 2c916760eb..b6ddfc13c9 100644 --- a/drivers/SmartThings/zwave-lock/fingerprints.yml +++ b/drivers/SmartThings/zwave-lock/fingerprints.yml @@ -223,6 +223,41 @@ zwaveManufacturer: deviceLabel: "Assure 2 Bio 450" manufacturerId: 0x0129 productId: 0x49D5 + - id: "Yale/YRD410-ZW3" + deviceLabel: Yale Door Lock + manufacturerId: 0x0129 + productType: 0x8104 + productId: 0x45D1 + deviceProfileName: base-lock + - id: "Yale/YRD420-ZW3" + deviceLabel: Yale Door Lock + manufacturerId: 0x0129 + productType: 0x8104 + productId: 0x45D2 + deviceProfileName: base-lock + - id: "Yale/YRD430-ZW3" + deviceLabel: Yale Door Lock + manufacturerId: 0x0129 + productType: 0x8104 + productId: 0x45D3 + deviceProfileName: base-lock + - id: "Yale/YRD450-ZW3" + deviceLabel: Yale Door Lock + manufacturerId: 0x0129 + productType: 0x8104 + productId: 0x45D5 + - id: "297/33031/18899" + deviceLabel: "Assure 2 Bio 430" + manufacturerId: 0x0129 + productId: 0x49D3 + - id: "297/33031/18897" + deviceLabel: "Assure 2 Biometric 410" + manufacturerId: 0x0129 + productId: 0x49D1 + - id: "297/33031/18898" + deviceLabel: "Yale Assure 2 Biometric" + manufacturerId: 0x0129 + productId: 0x49D2 productType: 0x8107 deviceProfileName: base-lock # Samsung diff --git a/drivers/SmartThings/zwave-lock/src/schlage-lock/init.lua b/drivers/SmartThings/zwave-lock/src/schlage-lock/init.lua index 6185e7b85b..67e649d869 100644 --- a/drivers/SmartThings/zwave-lock/src/schlage-lock/init.lua +++ b/drivers/SmartThings/zwave-lock/src/schlage-lock/init.lua @@ -78,7 +78,7 @@ local function set_code(self, device, cmd) ) end local current_code_length = device:get_latest_state("main", capabilities.lockCodes.ID, capabilities.lockCodes.codeLength.NAME) - if current_code_length ~= nil then + if current_code_length == nil then device:send(Configuration:Get({parameter_number = SCHLAGE_LOCK_CODE_LENGTH_PARAM.number})) device.thread:call_with_delay(DEFAULT_COMMANDS_DELAY, send_set_user_code) else @@ -119,7 +119,7 @@ local function is_user_code_report_mfr_specific(device, cmd) local code_id = cmd.args.user_identifier if reported_user_id_status == user_id_status.ENABLED_GRANT_ACCESS or -- OCCUPIED in UserCodeV1 - (user_code == user_id_status.STATUS_NOT_AVAILABLE and user_code ~= nil) then + (reported_user_id_status == user_id_status.STATUS_NOT_AVAILABLE and user_code ~= nil) then local code_state = device:get_field(constants.CODE_STATE) return user_code == "**********" or user_code == nil or (code_state ~= nil and code_state["setName"..cmd.args.user_identifier] ~= nil) else @@ -136,7 +136,7 @@ local function user_code_report_handler(self, device, cmd) local event if reported_user_id_status == user_id_status.ENABLED_GRANT_ACCESS or -- OCCUPIED in UserCodeV1 - (user_code == user_id_status.STATUS_NOT_AVAILABLE and user_code ~= nil) then + (reported_user_id_status == user_id_status.STATUS_NOT_AVAILABLE and user_code ~= nil) then local code_name = LockCodesDefaults.get_code_name(device, code_id) local change_type = LockCodesDefaults.get_change_type(device, code_id) event = capabilities.lockCodes.codeChanged(code_id..""..change_type, { state_change = true }) diff --git a/drivers/SmartThings/zwave-lock/src/test/test_schlage_lock.lua b/drivers/SmartThings/zwave-lock/src/test/test_schlage_lock.lua index 31d8fee7be..b1a5964502 100644 --- a/drivers/SmartThings/zwave-lock/src/test/test_schlage_lock.lua +++ b/drivers/SmartThings/zwave-lock/src/test/test_schlage_lock.lua @@ -50,6 +50,8 @@ local mock_device = test.mock_device.build_test_zwave_device( } ) +local SCHLAGE_LOCK_CODE_LENGTH_PARAM = {number = 16, size = 1} + local function test_init() test.mock_device.add_test_device(mock_device) end @@ -58,7 +60,16 @@ test.set_test_init_function(test_init) test.register_coroutine_test( "Setting a user code should result in the named code changed event firing", function() + test.timer.__create_and_queue_test_time_advance_timer(4.2, "oneshot") test.socket.capability:__queue_receive({ mock_device.id, { capability = capabilities.lockCodes.ID, command = "setCode", args = { 1, "1234", "test" } } }) + test.socket.zwave:__expect_send( + zw_test_utils.zwave_test_build_send_command( + mock_device, + Configuration:Get({parameter_number = SCHLAGE_LOCK_CODE_LENGTH_PARAM.number}) + ) + ) + test.wait_for_events() + test.mock_time.advance_time(4.2) test.socket.zwave:__expect_send( zw_test_utils.zwave_test_build_send_command( mock_device, @@ -66,7 +77,7 @@ test.register_coroutine_test( ) ) test.wait_for_events() - test.socket.zwave:__queue_receive({mock_device.id, UserCode:Report({user_identifier = 1, user_id_status = UserCode.user_id_status.ENABLED_GRANT_ACCESS}) }) + test.socket.zwave:__queue_receive({mock_device.id, UserCode:Report({user_identifier = 1, user_id_status = UserCode.user_id_status.STATUS_NOT_AVAILABLE, user_code="0000\n\r"}) }) test.socket.capability:__set_channel_ordering("relaxed") test.socket.capability:__expect_send(mock_device:generate_test_message("main", capabilities.lockCodes.lockCodes(json.encode({["1"] = "test"}), { visibility = { displayed = false } }) @@ -77,8 +88,6 @@ test.register_coroutine_test( end ) -local SCHLAGE_LOCK_CODE_LENGTH_PARAM = {number = 16, size = 1} - test.register_coroutine_test( "Setting a code length should be handled", function() @@ -112,6 +121,51 @@ test.register_coroutine_test( end ) +test.register_coroutine_test( + "Configuration report indicating code deletion should be handled", + function() + test.socket.zwave:__queue_receive({ + mock_device.id, + Configuration:Report({ + parameter_number = SCHLAGE_LOCK_CODE_LENGTH_PARAM.number, + configuration_value = 6 + }) + }) + test.socket.capability:__expect_send( + mock_device:generate_test_message("main", capabilities.lockCodes.codeLength(6)) + ) + test.socket.zwave:__queue_receive({ + mock_device.id, + Configuration:Report({ + parameter_number = SCHLAGE_LOCK_CODE_LENGTH_PARAM.number, + configuration_value = 4 + }) + }) + test.socket.capability:__expect_send( + mock_device:generate_test_message("main", capabilities.lockCodes.lockCodes(json.encode({}), {visibility = {displayed = false}})) + ) + test.socket.capability:__expect_send( + mock_device:generate_test_message("main", capabilities.lockCodes.codeLength(4)) + ) + end +) + +test.register_coroutine_test( + "User code report indicating master code is available should indicate code deletion", + function () + test.socket.zwave:__queue_receive({ + mock_device.id, + UserCode:Report({ + user_identifier = 0, + user_id_status = UserCode.user_id_status.AVAILABLE + }) + }) + test.socket.capability:__expect_send( + mock_device:generate_test_message("main", capabilities.lockCodes.lockCodes(json.encode({}), {visibility = {displayed = false}})) + ) + end +) + local expect_reload_all_codes_messages = function() test.socket.capability:__expect_send(mock_device:generate_test_message("main", capabilities.lockCodes.lockCodes(json.encode({} ), { visibility = { displayed = false } })