I wrote some helper functions to keep my KPLs in sync with the FanLincs, and also to allow fewer KPLs buttons but still allow full fan control.
The first keeps the KPL buttons in sync with the fan speed. You specify the KPL device ID, FanLinc device ID, and the button numbers. [code]bit = require(“bit”)
function setKplLedsFan(kplDeviceID, fanDeviceID, fanOff, fanLow, fanMed, fanHi)
luup.log("setKplLedsFan: Called setKplLedsFan( " … kplDeviceID … ", " … fanDeviceID … ", " … fanOff … ", " … fanLow … ", " … fanMed … ", " … fanHi)
local fanSpeed = luup.variable_get(“urn:geektaco-info:serviceId:FanLinc1”,“Speed”,fanDeviceID)
luup.log("setKplLedsFan: fanSpeed = " … fanSpeed)
– adjust all KPL buttons down by 1 since KPLs are 1-based
fanOff = fanOff - 1
fanLow = fanLow - 1
fanMed = fanMed - 1
fanHi = fanHi - 1
– create fan bitmap
local ledTargetGroup = 0
if (fanOff ~= -1) then ledTargetGroup = bit.bor(ledTargetGroup, bit.lshift (1, fanOff)) end
if (fanLow ~= -1) then ledTargetGroup = bit.bor(ledTargetGroup, bit.lshift (1, fanLow)) end
if (fanMed ~= -1) then ledTargetGroup = bit.bor(ledTargetGroup, bit.lshift (1, fanMed)) end
if (fanHi ~= -1) then ledTargetGroup = bit.bor(ledTargetGroup, bit.lshift (1, fanHi)) end
luup.log("setKplLedsFan: ledTargetGroup = " … ledTargetGroup)
if ((fanSpeed == “0”) and (fanOff ~= -1)) then
luup.log(“setKplLedsFan: Setting to Off”)
luup.call_action(“urn:geektaco-info:serviceId:InsteonOptions1”, “SetLedGroup”, {newStateValue = bit.lshift (1, fanOff),targetGroup = ledTargetGroup}, kplDeviceID)
elseif ((fanSpeed == “1”) and (fanLow ~= -1)) then
luup.log(“setKplLedsFan: Setting to Low”)
luup.call_action(“urn:geektaco-info:serviceId:InsteonOptions1”, “SetLedGroup”, {newStateValue = bit.lshift (1, fanLow),targetGroup = ledTargetGroup}, kplDeviceID)
elseif ((fanSpeed == “2”) and (fanMed ~= -1)) then
luup.log(“setKplLedsFan: Setting to Med”)
luup.call_action(“urn:geektaco-info:serviceId:InsteonOptions1”, “SetLedGroup”, {newStateValue = bit.lshift (1, fanMed),targetGroup = ledTargetGroup}, kplDeviceID)
elseif ((fanSpeed == “3”) and (fanHi ~= -1)) then
luup.log(“setKplLedsFan: Setting to Hi”)
luup.call_action(“urn:geektaco-info:serviceId:InsteonOptions1”, “SetLedGroup”, {newStateValue = bit.lshift (1, fanHi),targetGroup = ledTargetGroup}, kplDeviceID)
else
luup.log(“setKplLedsFan: Setting all LEDs to off”)
luup.call_action(“urn:geektaco-info:serviceId:InsteonOptions1”, “SetLedGroup”, {newStateValue = “0”,targetGroup = ledTargetGroup}, kplDeviceID)
end
end[/code]
Next is a function to increase fan speed 1 step. I assign a single KPL button as a trigger, and then call this from a scene, to bump the speed up a notch. It takes just the FanLinc device ID.
[code]function increaseFanSpeed(fanDeviceID)
luup.log("increaseFanSpeed: Called increaseFanSpeed( " … fanDeviceID … “)”)
local fanSpeed = luup.variable_get(“urn:geektaco-info:serviceId:FanLinc1”,“Speed”,fanDeviceID)
luup.log("increaseFanSpeed: current fanSpeed = " … fanSpeed)
if (fanSpeed == “0”) then
luup.log(“increaseFanSpeed: Setting to Low”)
luup.call_action(“urn:geektaco-info:serviceId:FanLinc1”, “SetFanSpeed”, {newTargetValue = “1”}, fanDeviceID)
elseif (fanSpeed == “1”) then
luup.log(“increaseFanSpeed: Setting to Med”)
luup.call_action(“urn:geektaco-info:serviceId:FanLinc1”, “SetFanSpeed”, {newTargetValue = “2”}, fanDeviceID)
elseif (fanSpeed == “2”) then
luup.log(“increaseFanSpeed: Setting to High”)
luup.call_action(“urn:geektaco-info:serviceId:FanLinc1”, “SetFanSpeed”, {newTargetValue = “3”}, fanDeviceID)
elseif (fanSpeed == “3”) then
luup.log(“increaseFanSpeed: Leaving unchanged”)
end
end[/code]
Conversely, I have a function to lower the fan speed:[code]function decreaseFanSpeed(fanDeviceID)
luup.log("decreaseFanSpeed: Called decreaseFanSpeed( " … fanDeviceID … “)”)
local fanSpeed = luup.variable_get(“urn:geektaco-info:serviceId:FanLinc1”,“Speed”,fanDeviceID)
luup.log("decreaseFanSpeed: current fanSpeed = " … fanSpeed)
if (fanSpeed == “0”) then
luup.log(“decreaseFanSpeed: Leaving unchanged”)
elseif (fanSpeed == “1”) then
luup.log(“decreaseFanSpeed: Setting to Off”)
luup.call_action(“urn:geektaco-info:serviceId:FanLinc1”, “SetFanSpeed”, {newTargetValue = “0”}, fanDeviceID)
elseif (fanSpeed == “2”) then
luup.log(“decreaseFanSpeed: Setting to Low”)
luup.call_action(“urn:geektaco-info:serviceId:FanLinc1”, “SetFanSpeed”, {newTargetValue = “1”}, fanDeviceID)
elseif (fanSpeed == “3”) then
luup.log(“decreaseFanSpeed: Setting to Med”)
luup.call_action(“urn:geektaco-info:serviceId:FanLinc1”, “SetFanSpeed”, {newTargetValue = “2”}, fanDeviceID)
end
end[/code]
Function placement:
I put all this code in startup LUA (Apps → Develop Apps → Edit Startup LUA)
Examples for setKplLedsFan in scene LUUP:
If the KPL is id 34, the FanLinc is 46, and the buttons are Off=8, Low=7, Med=6, High=5, then use:
setKplLedsFan(34, 46, 8, 7, 6, 5)
If you don’t want to assign a speed to a button, set it to 0 (such as no lights on means the fan is off):
setKplLedsFan(34, 46, 0, 7, 6, 5)
If you want to assign several speeds to a single button, that is ok too.
The following means Off=all buttons off, any speed = button 8 on:
setKplLedsFan(34, 46, 0, 8, 8, 8)
The above setKplLedsFan will only affect the buttons used in the call. Buttons not listed will remain unchanged (so the first example above won’t change buttons 1,2,3, nor 4. Remember, that you can’t set the LED directly for button 1 of an 8 button KPL, or buttons 1/2/7/8 for a 6 button.
I have 1 scene that is triggered any time any fan in the house changes. It runs through each KPL/Fan combination and sets the KP buttons accordingly. It’s a little overkill doing every fan when any one changes, but I didn’t want to have a separate scene for each fan.
Examples for increaseFanSpeed & decreaseFanSpeed in scene LUUP:
In an increase scene, just call
increaseFanSpeed(46)
In an decrease scene, just call
decreaseFanSpeed(46)