-
Notifications
You must be signed in to change notification settings - Fork 466
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
Requset to add a fingerprints for Kichler Zigbee fan light #1278
base: main
Are you sure you want to change the base?
Conversation
Add fingerprints for KICHLER
Create Profiles for kichler-fan-light
Add update init for Kichler
Add update configurations for Kichler
Add create init for Kichler fan light
Add create test kichler fan light
Duplicate profile check: Passed - no duplicate profiles detected. |
Invitation URL: |
Test Results 56 files 363 suites 0s ⏱️ Results for commit 584c4a9. ♻️ This comment has been updated with latest results. |
Minimum allowed coverage is Generated by 🐒 cobertura-action against 584c4a9 |
local last_level = device:get_field('LAST_DIM_LEVEL') or 100 | ||
local level = math.floor((last_level/100.0) * 254 ) |
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: these should be moved inside the if
statement
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 will change it.
|
||
-- CAPABILITY HANDLERS | ||
local function on_handler(driver, device, command) | ||
local last_level = device:get_field('LAST_DIM_LEVEL') or 100 |
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.
as far as I can tell, you maintain the level
value even when receiving an off
report. Unless the device separately reports a 0
level when turning off, you should be able to use device:get_latest_state
instead of setting an additional field here.
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.
When i apply the code that was guided to me, if i turn on the light after turning it off, i can't retrieve the last value (off), and instead retrieve the off state. so, I will continue to use the set/get_field as you are now.
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.
were you getting the latest value of the switch
capability or the switchLevel
capability?
device:get_latest_state("main", capabilities.switchLevel.ID, capabilities.switchLevel.level.NAME)
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.
The use of the switchlevel is because it is synchronized with the main switch.
The proposed get_lastest_state maintains "off" if you turn it on after turning it off, as the last state value is "off".
Therefore, we intend to use set/get field instead of using get_lastest_state.
device:emit_component_event(device.profile.components.light, capabilities.switchLevel.level(command.args.level)) | ||
device:send_to_component('light', Level.server.commands.MoveToLevelWithOnOff(device, level, command.args.rate or 0xFFFF)) | ||
device:emit_component_event(device.profile.components.light, capabilities.switchLevel.level(trim_level)) |
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.
What's the intent behind these two level
events from the same component here?
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 to use the Trim function. This trim is used to limit the minimum value of dimming.
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 understand the point of the trim function, but it seems like you'd want to only emit the trimmed value, not both the untrimmed and trimmed value.
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 would like to refresh the value below the trim setting value so that it is not reflected in the UI. If you set it to trim 25% and control it to 10%, it will be 25%.
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.
So why send both the 10% event and the 25% event? Wouldn't you want to just send the 25% event?
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 work to raise the code coverage to at least 90% |
Update init file
if old_trim < new_trim then | ||
if new_trim >= current_level then | ||
local newlevel = math.floor((new_trim/100.0) * 254 ) | ||
device:send_to_component('light', Level.server.commands.MoveToLevelWithOnOff(device, newlevel, 0)) | ||
else | ||
local newlevel = math.floor((current_level/100.0) * 254 ) | ||
device:send_to_component('light', Level.server.commands.MoveToLevelWithOnOff(device, newlevel, 0)) | ||
end | ||
else | ||
local newlevel = math.floor((current_level/100.0) * 254 ) | ||
device:send_to_component('light', Level.server.commands.MoveToLevelWithOnOff(device, newlevel, 0)) | ||
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.
if old_trim < new_trim then | |
if new_trim >= current_level then | |
local newlevel = math.floor((new_trim/100.0) * 254 ) | |
device:send_to_component('light', Level.server.commands.MoveToLevelWithOnOff(device, newlevel, 0)) | |
else | |
local newlevel = math.floor((current_level/100.0) * 254 ) | |
device:send_to_component('light', Level.server.commands.MoveToLevelWithOnOff(device, newlevel, 0)) | |
end | |
else | |
local newlevel = math.floor((current_level/100.0) * 254 ) | |
device:send_to_component('light', Level.server.commands.MoveToLevelWithOnOff(device, newlevel, 0)) | |
end | |
local newlevel = math.floor((current_level/100.0) * 254 ) | |
if old_trim < new_trim then | |
if new_trim >= current_level then | |
local newlevel = math.floor((new_trim/100.0) * 254 ) | |
end | |
device:send_to_component('light', Level.server.commands.MoveToLevelWithOnOff(device, newlevel, 0)) |
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 modified it with the code you suggested
Edit with suggested code
if old_trim < new_trim then | ||
if new_trim >= current_level then | ||
local newlevel = math.floor((new_trim/100.0) * 254 ) | ||
device:send_to_component('light', Level.server.commands.MoveToLevelWithOnOff(device, newlevel, 0)) | ||
else | ||
device:send_to_component('light', Level.server.commands.MoveToLevelWithOnOff(device, newlevel, 0)) | ||
end | ||
else | ||
device:send_to_component('light', Level.server.commands.MoveToLevelWithOnOff(device, newlevel, 0)) | ||
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.
if old_trim < new_trim then | |
if new_trim >= current_level then | |
local newlevel = math.floor((new_trim/100.0) * 254 ) | |
device:send_to_component('light', Level.server.commands.MoveToLevelWithOnOff(device, newlevel, 0)) | |
else | |
device:send_to_component('light', Level.server.commands.MoveToLevelWithOnOff(device, newlevel, 0)) | |
end | |
else | |
device:send_to_component('light', Level.server.commands.MoveToLevelWithOnOff(device, newlevel, 0)) | |
end | |
if old_trim < new_trim then | |
if new_trim >= current_level then | |
newlevel = math.floor((new_trim/100.0) * 254 ) | |
end | |
end | |
device:send_to_component('light', Level.server.commands.MoveToLevelWithOnOff(device, newlevel, 0)) |
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 changed it with the code you suggested.
- name: "trim" | ||
title: "Minimum Dimming Level" | ||
description: "Set the lowest dimming level" | ||
required: false | ||
preferenceType: enumeration | ||
definition: | ||
options: | ||
10 : "10%" | ||
15 : "15%" | ||
20 : "20%" | ||
25 : "25%" | ||
default: 10 |
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.
In relation to this preference, I'm happy to direct you to this new feature we added, which is the ability to set min/max values for the switch level attribute. You may find that using this is simpler than having to do the trimming yourself.
Here's an example of how to emit this event:
The min/max should be displayed and carried across automations as well.
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 is expected that there will be models derived from this model. We will try to use the code you suggested at that time. Thank you.
I changed it with the code you suggested.
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 looks good but could you write a test that verifies the setlevel command after setting the trim above 0?
Similarly a test that checks the events that are sent after the trim is set above the current level of the device?
We prefer to have code coverage over 90% and you're currently at 87%.
updated test code
Update init code
The test code has been modified. |
local time_difference = os.difftime(current_fandirection_time, send_fandirection_time) or 0 | ||
if time_difference >= 10 or send_fandirection_time == 0 then | ||
device:send(FanControl.attributes.FanMode:write(device, 6)) | ||
device:set_field('FANDIRECTION_SENDTIME', current_fandirection_time, {persist = true}) |
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 value doesn't need to persist
it takes more than 10s for the hub to reboot
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.
The purpose of using the following code, regardless of the hub, is to prevent sending commands if a command has been sent within 10 seconds. (This is related to protecting the fan driving circuit.)
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 understand, but the persist = true
makes the value durable through hub restarts.
Because hub restarts take more than 10s, you do not need to have this flag persist, because it is guaranteed to have been more than 10s since you last sent the write on hub restart. Just keeping it in memory should be enough.
device:send(FanControl.attributes.FanMode:write(device, 6)) | ||
device:set_field('FANDIRECTION_SENDTIME', current_fandirection_time, {persist = true}) | ||
else | ||
device:set_field('FANDIRECTION_FLAG', flag_direction + 1 , {persist = true}) |
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 unclear what this flag does. you don't use the value except here where you increment 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.
The test code has been modified.
240402_Update init
Update init
240403 update init file
This is new project for Kichler.
It's a Zigbee fan and the model no. is KICHLER-FANLIGHT-Z-301.
I want to add Kichler to the fingerprints of a Zigbee fan.
The function of the option has been added to the fan light
Please review it.