-
Notifications
You must be signed in to change notification settings - Fork 463
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Aqara] Presence Sensor FP2 #1546
Conversation
Duplicate profile check: Passed - no duplicate profiles detected. |
Invitation URL: |
Test Results 62 files 375 suites 0s ⏱️ Results for commit 640f066. ♻️ This comment has been updated with latest results. |
Minimum allowed coverage is Generated by 🐒 cobertura-action against 640f066 |
For LAN devices we need to include a |
I have an FP2 so I decided to try to discover it. Currently I am just getting:
I made sure to update the FP2 to the latest firmware, but if there is anything else needed to test let me know. |
I added it. |
You'll need to use the firmware that will be released in August to enroll in the SmartThings Hub. If you need that firmware, please let me know the information below in the Aqara Home app.
You give me the information and our developers will request Equipment diagnosis permission application authorization. You'll have to approve it. After that, our developers will update your FP2 to that firmware.(FP2 must be online to be updated.) How to connect to your SmartThings hub after the FP2 firmware update.
|
@seojune79 Can you please clarify, what testing have you completed to date? I noticed this was missing from the original message in this PR, can you please add or share more details? |
We tested with Samsung to ensure that the following events are handled the same as in the Aqara Home app.
|
end | ||
|
||
function device_manager.movement_handler(driver, device, zone, evt_value) | ||
if not device:supports_capability(PresenceSensor) then return end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this is probably a copy-paste issue and should be checking for MovementSensor
instead of PresenceSensor
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll fix it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a couple of minor issues I suggest addressing before merging
local device_info = fp2_api.get_info(device_ip, fp2_api.labeled_socket_builder(device_dni)) | ||
|
||
if not device_info then | ||
log.error(string.format("failed to create device create msg. device_info is nil. dni = %s")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is attempting to format a string with an argument but the argument isn't provided
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed the argument because it is nil
table.remove(mzp.zoneInfoTable, index) | ||
deletedId = id | ||
else | ||
err = string.format("id %s doesn't exists", id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:
err = string.format("id %s doesn't exists", id) | |
err = string.format("id %s doesn't exist", id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll fix it.
zoneInfo.name = name | ||
changedId = id | ||
else | ||
err = string.format("id %s doesn't exists", id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit
err = string.format("id %s doesn't exists", id) | |
err = string.format("id %s doesn't exist", id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see.
zoneInfo.state = state | ||
changedId = id | ||
else | ||
err = string.format("id %s doesn't exists", id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:
err = string.format("id %s doesn't exists", id) | |
err = string.format("id %s doesn't exist", id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll fix it.
One issue I ran into was I edited the names of my Zones last week, however when looking today I see that the names have reverted to Zone 1, Zone 2, Zone 3. I don't know if that is due to ongoing development or something else. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Please add type hints/doc comments using the ldoc format
- All functions that may fail should return
nil, "<error message>"
to aid in debugging - Error logs are reserved for fatal conditions, please use warn for know points of failure
- Consider using
%q
when usingstring.format
with non-table/userdata values to get better formatting
local device_discovery_cache = {} | ||
|
||
local function set_device_field(driver, device) | ||
local device_cache_value = device_discovery_cache[device.device_network_id] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: should check for nil
here
local function try_add_device(driver, device_dni, device_ip) | ||
log.trace(string.format("try_add_device : dni= %s, ip= %s", device_dni, device_ip)) | ||
|
||
local credential = driver.discovery_helper.get_credential(driver, device_dni, device_ip) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: error messages are typically included after the value, this will make line 34 more helpful
function discovery.device_added(driver, device) | ||
set_device_field(driver, device) | ||
device_discovery_cache[device.device_network_id] = nil | ||
driver.lifecycle_handlers.init(driver, device) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't believe you should be calling lifecycle handlers directly, this will be called by the framework
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like this is needed in order to make sure init is called after added. Init requires the device fields to have been populated.
local ip_table = discovery_mdns.find_ip_table_by_mdns(driver) | ||
return ip_table |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
needless assignment
local ip_table = discovery_mdns.find_ip_table_by_mdns(driver) | |
return ip_table | |
return discovery_mdns.find_ip_table_by_mdns(driver) |
local ip_table = discovery.find_ip_table(driver) | ||
|
||
for dni, ip in pairs(ip_table) do | ||
if not known_devices or not known_devices[dni] then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why wold known_devices
be nil here?
|
||
if not driver.device_manager.is_valid_connection(driver, device, conn_info) then | ||
log.error("create_sse : invalid connection") | ||
return |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nil return w/o error in 2nd position
-- sync | ||
-- status_update(driver, device) -- for test | ||
-- end of sync |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
stale comments, please remove
local function find_new_connetion(driver, device) | ||
local ip_table = discovery.find_ip_table(driver) | ||
local ip = ip_table[device.device_network_id] | ||
if ip then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warn if nil
?
end | ||
|
||
local function configure_handler(driver, device, event, args) | ||
-- no action |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need for this function to be defined
) | ||
|
||
lan_driver:run() | ||
log.warn("lan driver exiting") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this will never execute, please remove
I'm seeing an issue with zone names reverting
I saw this too and reproduced it by rebooting my hub. The first |
Did it happen even though you didn't change the zone? If you experience that issue again, please share how to reproduce it. |
Thanks. I've reproduced the issue on my FP2, I'll check it out. |
I fixed it. |
local conn_info = device:get_field(fields.CONN_INFO) | ||
if not driver.device_manager.is_valid_connection(driver, device, conn_info) then | ||
device:offline() | ||
find_new_connetion(driver, device) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
find_new_connection
end | ||
|
||
|
||
local function find_new_connetion(driver, device) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
find_new_connection
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you tell me more on this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's just a minor spelling mistake. Just wanted to make sure the function name matches.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay. I fixed it.
I did have my Zone names disappear again. Otherwise the device has been working great for me. I don't know how the zone names were lost I just opened up the app and they were gone. There was a hub firmware update so there was a hub reboot. But I did re-name them and manually reboot the hub and the name persisted. Was the fix you added something that would only take affect the next time I named them? |
Can someone let me know how this PR is going? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please pull in the latest lunchbox version that exists in the philips hue driver. This will help with maintenance in the future when we add the library to the lua libs and no longer need to put it in these lan drivers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that broke the REST communication - at least in my case.
The very first GET for /authcode fails with error wantread now.
2024-09-27T22:46:41.855930580Z INFO Aqara Presence Sensor 54:EF:44:5C:4C:98 Performing SSL handshake for for REST Connection
2024-09-27T22:46:45.358401372Z INFO Aqara Presence Sensor 54:EF:44:5C:4C:98 Successfully created TCP connection
2024-09-27T22:47:45.440063966Z ERROR Aqara Presence Sensor get_credential : ip = 192.168.1.121, failed to get token, error = wantread
2024-09-27T22:47:45.445295882Z WARN Aqara Presence Sensor credential is nil
2024-09-27T22:47:45.450356841Z ERROR Aqara Presence Sensor failed to get credential. dni= 54:EF:44:5C:4C:98, ip= 192.168.1.121
From the luasec documentation:
"wantread" and "wantwrite" indicates that a timeout occurred during the operation. Also, after the error message, the function returns the partial result of the transmission.
In the case of "wantread" or "wantwrite" errors, you should wait the connection to be ready for reading or writing, respectively, and call conn:receive again.
So the whole partial result handling wasn't that useless...
Also:
wantread" indicates that the operation was not finished because a timeout in the underline TCP connection prevents it of sending data.
This is rather cryptic, but it says that "I'm sending data, and I want my counterpart to READ; wantread"
else | ||
log.error(string.format("handle_sse_event : unknown event type. dni = %s, event_type = '%s'", | ||
device.device_network_id, event_type)) | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any handling that is needed for an error event type? https://github.com/seojune79/SmartThingsEdgeDrivers/blob/a3857c286f60a04997eb39cd2e8583be93e2cd43/drivers/Aqara/aqara-presence-sensor/src/lunchbox/sse/eventsource.lua#L44-L48
function discovery.device_added(driver, device) | ||
set_device_field(driver, device) | ||
device_discovery_cache[device.device_network_id] = nil | ||
driver.lifecycle_handlers.init(driver, device) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like this is needed in order to make sure init is called after added. Init requires the device fields to have been populated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice discovery module. Very easy to review and understand what is happening.
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) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this something that should be included in do_refresh
it seems like it has a similar purpose to the init_presence
, init_movement
, and init_activity
functions that are called there. Its not clear why zones aren't refreshed, and this is done via init.
Hey @seojune79 - @cjswedes just did a review of the new commit. Please feel welcome to review. As a result - This device will proceed through the WWST Certification process. I hope I have answered your question. |
We made some code changes based on his comments. |
Edit: latest commit (mainly rest.lua) broke it.
Can't add the device anymore! Removed the device, deleted the driver, added driver, tried to add the device. Tried it with main, beta, and this channel to make sure. It worked about a month ago. Since then, changes were made to discovery.lua, init.lua, device_manager.lua... Can someone please check if adding the device still works? Device firmware: 1.2.7_0011.0080 Device works with the Aqara Home app.
This is the complete log and it looks like the driver lifecycle ends? |
Proposal for a fix for the wantread, socket not ready issue: |
Check all that apply
Type of Change
Checklist
Description of Change
Summary of Completed Tests