Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions drivers/SmartThings/philips-hue/src/handlers/commands.lua
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ end
---@param device HueChildDevice
---@param args table
local function do_color_temp_action(driver, device, args)
local capabilities = require "st.capabilities"
local kelvin = args.args.temperature
local id = device.parent_device_id or device:get_field(Fields.PARENT_DEVICE_ID)
local bridge_device = utils.get_hue_bridge_for_device(driver, device, id)
Expand Down Expand Up @@ -238,6 +239,16 @@ local function do_color_temp_action(driver, device, args)
local clamped_kelvin = st_utils.clamp_value(kelvin, min, Consts.MAX_TEMP_KELVIN)
local mirek = math.floor(utils.kelvin_to_mirek(clamped_kelvin))

local current_color_temp = device:get_latest_state("main", capabilities.colorTemperature.ID, capabilities.colorTemperature.colorTemperature.NAME)
if current_color_temp then
local current_mirek = math.floor(utils.kelvin_to_mirek(current_color_temp))
if current_mirek == mirek then
log.debug(string.format("Color temp change from %dK to %dK results in same mirek value (%d), emitting event directly", current_color_temp, clamped_kelvin, mirek))
device:emit_event(capabilities.colorTemperature.colorTemperature(clamped_kelvin))
return
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should still send the command to the bridge and not return early here. It might be possible that the user changed the temp in the hue app and we never emitted an event for the change so we might actually be changing it here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah good point!

end
end

local resp, err = hue_api:set_light_color_temp(light_id, mirek)

if not resp or (resp.errors and #resp.errors == 0) then
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ end
---@param bridge_device HueBridgeDevice
---@param group table
---@param args table
---@param aux table auxilary data needed for the command that the devices all had in common
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

at least I am a consistent bad speller 🥲

---@param aux table auxiliary data needed for the command that the devices all had in common
local function do_color_action(driver, bridge_device, group, args, aux)
local hue, sat = (args.args.color.hue / 100), (args.args.color.saturation / 100)
if hue == 1 then -- 0 and 360 degrees are equivalent in HSV, but not in our conversion function
Expand Down Expand Up @@ -135,7 +135,7 @@ end
---@param bridge_device HueBridgeDevice
---@param group table
---@param args table
---@param aux table auxilary data needed for the command that the devices all had in common
---@param aux table auxiliary data needed for the command that the devices all had in common
local function do_setHue_action(driver, bridge_device, group, args, aux)
local currentSaturation = aux[Fields.COLOR_SATURATION] or 0
args.args.color = {
Expand All @@ -149,7 +149,7 @@ end
---@param bridge_device HueBridgeDevice
---@param group table
---@param args table
---@param aux table auxilary data needed for the command that the devices all had in common
---@param aux table auxiliary data needed for the command that the devices all had in common
local function do_setSaturation_action(driver, bridge_device, group, args, aux)
local currentHue = aux[Fields.COLOR_HUE] or 0
args.args.color = {
Expand All @@ -163,8 +163,9 @@ end
---@param bridge_device HueBridgeDevice
---@param group table
---@param args table
---@param aux table auxilary data needed for the command that the devices all had in common
---@param aux table auxiliary data needed for the command that the devices all had in common
local function do_color_temp_action(driver, bridge_device, group, args, aux)
local capabilities = require "st.capabilities"
local kelvin = args.args.temperature

local grouped_light_id = group.grouped_light_rid
Expand All @@ -185,6 +186,29 @@ local function do_color_temp_action(driver, bridge_device, group, args, aux)
local clamped_kelvin = st_utils.clamp_value(kelvin, min, Consts.MAX_TEMP_KELVIN)
local mirek = math.floor(utils.kelvin_to_mirek(clamped_kelvin))

local all_same_mirek = true
for _, device in ipairs(group.devices) do
local current_color_temp = device:get_latest_state("main", capabilities.colorTemperature.ID, capabilities.colorTemperature.colorTemperature.NAME)
if current_color_temp then
local current_mirek = math.floor(utils.kelvin_to_mirek(current_color_temp))
if current_mirek ~= mirek then
all_same_mirek = false
break
end
else
all_same_mirek = false
break
end
end

if all_same_mirek and #group.devices > 0 then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather then checking if they are all the same mirek, I wonder if we want to track all the devices that have the same mirek and then emit the event for all of those devices. I'm not sure how this interaction works with the grouped lighting but it seems like if only one device had the same mirek then the bridge might not send anything for that specific device.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah good call. When I was testing it I had all my bulbs at the same color temp value and neglected to think of the case where they are at different values initially.

log.debug(string.format("Color temp change to %dK results in same mirek value (%d) for all devices in group, emitting events directly", clamped_kelvin, mirek))
for _, device in ipairs(group.devices) do
device:emit_event(capabilities.colorTemperature.colorTemperature(clamped_kelvin))
end
return
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar reasoning as above for not returning early here.

end

local resp, err = hue_api:set_grouped_light_color_temp(grouped_light_id, mirek)

if not resp or (resp.errors and #resp.errors == 0) then
Expand All @@ -203,7 +227,7 @@ end
---@param bridge_device HueBridgeDevice
---@param group table
---@param args table
---@param aux table auxilary data needed for the command that the devices all had in common
---@param aux table auxiliary data needed for the command that the devices all had in common
function GroupedLightCommandHandlers.switch_on_handler(driver, bridge_device, group, args, aux)
do_switch_action(driver, bridge_device, group, args)
end
Expand All @@ -212,7 +236,7 @@ end
---@param bridge_device HueBridgeDevice
---@param group table
---@param args table
---@param aux table auxilary data needed for the command that the devices all had in common
---@param aux table auxiliary data needed for the command that the devices all had in common
function GroupedLightCommandHandlers.switch_off_handler(driver, bridge_device, group, args, aux)
do_switch_action(driver, bridge_device, group, args)
end
Expand All @@ -221,7 +245,7 @@ end
---@param bridge_device HueBridgeDevice
---@param group table
---@param args table
---@param aux table auxilary data needed for the command that the devices all had in common
---@param aux table auxiliary data needed for the command that the devices all had in common
function GroupedLightCommandHandlers.switch_level_handler(driver, bridge_device, group, args, aux)
do_switch_level_action(driver, bridge_device, group, args)
end
Expand All @@ -230,7 +254,7 @@ end
---@param bridge_device HueBridgeDevice
---@param group table
---@param args table
---@param aux table auxilary data needed for the command that the devices all had in common
---@param aux table auxiliary data needed for the command that the devices all had in common
function GroupedLightCommandHandlers.set_color_handler(driver, bridge_device, group, args, aux)
do_color_action(driver, bridge_device, group, args, aux)
end
Expand All @@ -239,7 +263,7 @@ end
---@param bridge_device HueBridgeDevice
---@param group table
---@param args table
---@param aux table auxilary data needed for the command that the devices all had in common
---@param aux table auxiliary data needed for the command that the devices all had in common
function GroupedLightCommandHandlers.set_hue_handler(driver, bridge_device, group, args, aux)
do_setHue_action(driver, bridge_device, group, args, aux)
end
Expand All @@ -248,7 +272,7 @@ end
---@param bridge_device HueBridgeDevice
---@param group table
---@param args table
---@param aux table auxilary data needed for the command that the devices all had in common
---@param aux table auxiliary data needed for the command that the devices all had in common
function GroupedLightCommandHandlers.set_saturation_handler(driver, bridge_device, group, args, aux)
do_setSaturation_action(driver, bridge_device, group, args, aux)
end
Expand All @@ -257,7 +281,7 @@ end
---@param bridge_device HueBridgeDevice
---@param group table
---@param args table
---@param aux table auxilary data needed for the command that the devices all had in common
---@param aux table auxiliary data needed for the command that the devices all had in common
function GroupedLightCommandHandlers.set_color_temp_handler(driver, bridge_device, group, args, aux)
do_color_temp_action(driver, bridge_device, group, args, aux)
end
Expand Down
Loading