Skip to content

Instantly share code, notes, and snippets.

@michaelschade
Created September 7, 2014 22:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save michaelschade/325df0c733bc6a964bd6 to your computer and use it in GitHub Desktop.
Save michaelschade/325df0c733bc6a964bd6 to your computer and use it in GitHub Desktop.
util = require 'util'
lifx = require './lifx'
lx = lifx.init()
log = (text) ->
process.stdout.write("#{text}\n")
typeIsArray = Array.isArray || (value) ->
{}.toString.call(value) is '[object Array]'
randomInt = (min, max) ->
Math.floor(Math.random() * (max - min + 1)) + min
lightState =
hue: 0x2222
dim: 0x02bc
power: 0x0000
kelvin: 0x0dac
brightness: 0xff00
saturation: 0xffff
hex = (char) ->
char.charCodeAt(0)
bulbIndex = undefined
activeBulb = ->
return bulbIndex unless bulbIndex?
lx.bulbs[bulbIndex]
deltaBulbIndex = (delta) ->
bulbIndex = (bulbIndex || 0) + delta
bulbIndex *= -1 if bulbIndex < 0
bulbIndex = bulbIndex % lx.bulbs.length
log("Setting bulb to #{activeBulb()?.name} (index: #{bulbIndex}, delta: #{delta}).")
bulbIndex
resetBulbIndex = ->
log("Setting focus to all #{lx.bulbs.length} bulbs.")
bulbIndex = undefined
# Lifx accepts 0x0000 <= value <= 0xffff
wrapHex = (hex, min=0, max=0xffff) ->
hex += max if hex < 0
min + (Math.abs(hex) % (max - min))
# Change light parameters by a relative amount
updateLightParams = (params) ->
params = [params] unless typeIsArray(params)
for param in params
if param.total?
value = param.total
else
value = lightState[param.key] + param.delta
lightState[param.key] = wrapHex(value, getLightMin(param.key), getLightMax(param.key))
log("Set #{param.key} to #{lightState[param.key]} with params #{util.inspect(param)})")
setLightColor(lx, lightState)
# Update light colors with a parameter object
# Valid keys: hue, saturation, brightness, kelvin, dim
setLightColor = (lx, params) ->
log("Updating light with params: #{util.inspect(params)}")
lx.lightsColour(params.hue, params.saturation, params.brightness, params.kelvin, params.dim, activeBulb())
lightCycleInterval = null
setLightCycleInterval = (interval) ->
lightCycleInterval = interval
log("Set light cycle interval to #{interval}")
lightDelta = 300
setLightDelta = (delta) ->
lightDelta = delta
log("Set light change delta to #{delta}")
clearLightIntervals = (resetInterval = true) ->
log("Stopping all light cycle intervals.")
clearInterval lightIntervals.relaxingCycle
clearInterval lightIntervals.partyCycle
clearInterval lightIntervals.waffleCycle
clearInterval lightIntervals.strobeCycle
clearInterval lightIntervals.customCycle
if resetInterval
setLightCycleInterval(null)
clearLightMax()
lightMax = {}
lightMin = {}
getLightMax = (key) ->
log("Getting light max for #{key}: #{lightMax[key]}")
lightMax[key]
setLightMax = (key, value) ->
lightMax[key] = value % 0xffff
log("Setting light max for #{key}: #{lightMax[key]}")
getLightMin = (key) ->
log("Getting light min for #{key}: #{lightMin[key]}")
lightMin[key]
setLightMin = (key, value) ->
lightMin[key] = value % 0xffff
log("Setting light min for #{key}: #{lightMin[key]}")
clearLightMax = ->
lightMax = {}
log("Clearing light max")
printHelp = ->
log """
Hello, I'm your lifx controller.
O/o : enable or disable the lights
R/r : enable or disable the relaxing light cycle
P/p : enable or disable the party light cycle
F/f : enable or disable the strobe light cycle
H/h : change the hue (ordered)
K/k : increase or decrease kelvins
D/d : increase or decrease dimming time
S/s : increase or decrease saturation
B/b : increase or decrease brightness
>/< : move forward or backward through active bulbs
1 : changes will occur in increments of 100
2 : changes will occur in increments of 300
3 : changes will occur in increments of 500
4 : changes will occur in increments of 700
5 : changes will occur in increments of 1000
6 : changes will occur in increments of 1400
7 : changes will occur in increments of 1700
8 : changes will occur in increments of 2400
9 : changes will occur in increments of 3000
0 : changes will occur in increments of 10000
! : lights will cycle in intervals of 0ms
@ : lights will cycle in intervals of 10ms
# : lights will cycle in intervals of 35ms
$ : lights will cycle in intervals of 70ms
% : lights will cycle in intervals of 140ms
^ : lights will cycle in intervals of 250ms
& : lights will cycle in intervals of 450ms
* : lights will cycle in intervals of 800ms
( : lights will cycle in intervals of 1000ms
) : lights will cycle in intervals of 4200ms
z : reset environment to original settings
q : quit
? : ask me for help
"""
lightIntervals = {}
stdin = process.openStdin()
process.stdin.setRawMode(true)
process.stdin.resume()
printHelp()
stdin.on 'data', (key) ->
switch key[0]
## on/off
when hex('O')
log("Turning on the lights")
lx.lightsOn(activeBulb())
when hex('o')
log("Turning off the lights")
lx.lightsOff(activeBulb())
clearLightIntervals()
## set light delta
when hex('1') then setLightDelta(100)
when hex('2') then setLightDelta(300)
when hex('3') then setLightDelta(500)
when hex('4') then setLightDelta(700)
when hex('5') then setLightDelta(1000)
when hex('6') then setLightDelta(1400)
when hex('7') then setLightDelta(1700)
when hex('8') then setLightDelta(2400)
when hex('9') then setLightDelta(3000)
when hex('0') then setLightDelta(10000)
## try brightness max
when hex('{') # decrease
max = getLightMax('brightness') || 0xffff
setLightMax('brightness', max - lightDelta)
when hex('}') # increase
max = getLightMax('brightness') || 0xffff
setLightMax('brightness', max + lightDelta)
## try brightness min
when hex('[') # decrease
min = getLightMin('brightness') || 0xffff
setLightMin('brightness', min - lightDelta)
when hex(']') # increase
min = getLightMin('brightness') || 0xffff
setLightMin('brightness', min + lightDelta)
## try saturation max
when hex('_') # decrease
max = getLightMax('saturation') || 0xffff
setLightMax('saturation', max - lightDelta)
when hex('+') # increase
max = getLightMax('saturation') || 0xffff
setLightMax('saturation', max + lightDelta)
## try saturation min
when hex('-') # decrease
min = getLightMin('saturation') || 0xffff
setLightMin('saturation', min - lightDelta)
when hex('=') # increase
min = getLightMin('saturation') || 0xffff
setLightMin('saturation', min + lightDelta)
## set light cycle interval
when hex('!') then setLightCycleInterval(0)
when hex('@') then setLightCycleInterval(10)
when hex('#') then setLightCycleInterval(35)
when hex('$') then setLightCycleInterval(70)
when hex('%') then setLightCycleInterval(140)
when hex('^') then setLightCycleInterval(450)
when hex('&') then setLightCycleInterval(850)
when hex('*') then setLightCycleInterval(1800)
when hex('(') then setLightCycleInterval(2800)
when hex(')') then setLightCycleInterval(8480)
## light cycle ##
when hex('g') # disable cycle
clearLightIntervals()
when hex('G') # cycle colors
clearLightIntervals(false)
setLightCycleInterval(2400) unless lightCycleInterval?
lightIntervals.gentleCycle = setInterval ->
updateLightParams [
{ key: 'dim', total: randomInt(2000, 4200) }
{ key: 'hue', total: randomInt(0x0000, 0xffff) }
{ key: 'saturation', total: randomInt(4000, 14200) } #randomInt(17400, 27800) }
{ key: 'brightness', total: randomInt(63000, 0xffff) }
]
, lightCycleInterval
log("Started relaxing light cycle with interval #{lightCycleInterval}")
## relaxing cycle ##
when hex('r') # disable cycle
clearLightIntervals()
when hex('R') # cycle colors
clearLightIntervals(false)
setLightCycleInterval(1900) unless lightCycleInterval?
lightIntervals.relaxingCycle = setInterval ->
updateLightParams [
{ key: 'dim', total: randomInt(3100, 4200) }
{ key: 'hue', total: randomInt(0x0000, 0xffff) }
{ key: 'saturation', total: randomInt(51135, 65535) }
{ key: 'brightness', total: randomInt(7200, 17535) }
]
, lightCycleInterval
log("Started relaxing light cycle with interval #{lightCycleInterval}")
## party cycle ##
when hex('p') # disable party
clearLightIntervals()
when hex('P') # party colors
clearLightIntervals(false)
setLightCycleInterval(70) unless lightCycleInterval?
lightIntervals.partyCycle = setInterval ->
updateLightParams [
{ key: 'dim', total: randomInt(900, 1250) }
{ key: 'hue', total: randomInt(0x0000, 0xffff) }
{ key: 'saturation', total: randomInt(38180, 65535) }
{ key: 'brightness', total: randomInt(0xA410, 0xffff) }
]
, lightCycleInterval
log("Started party light cycle with interval #{lightCycleInterval}")
## waffle cycle ##
when hex('w') # disable waffle
clearLightIntervals()
when hex('W') # waffle colors
clearLightIntervals(false)
setLightCycleInterval(4240) unless lightCycleInterval?
hue = lightState['hue']
saturation = lightState['saturation']
brightness = lightState['brightness']
lightIntervals.waffleCycle = setInterval ->
updateLightParams [
{ key: 'dim', total: randomInt(9400, 12042) }
{ key: 'hue', total: randomInt(hue - 8400, hue + 8400) }
{ key: 'saturation', total: randomInt(saturation - 4800, saturation + 4800) }
{ key: 'brightness', total: randomInt(brightness - 4800, brightness + 4800) }
]
, lightCycleInterval
log("Started waffle light cycle with interval #{lightCycleInterval}")
## strobe cycle ##
when hex('f') # disable strobe
clearLightIntervals()
when hex('F') # strobe colors
clearLightIntervals(false)
setLightCycleInterval(35) unless lightCycleInterval?
brightness = 0
lightIntervals.strobeCycle = setInterval ->
if brightness > 0
brightness = 0
else
brightness = 48728
updateLightParams [
{ key: 'dim', total: 0 }
{ key: 'brightness', total: brightness }
#{ key: 'saturation', total: saturation }
]
, lightCycleInterval
log("Started strobe light cycle with interval #{lightCycleInterval}")
## custom cycle ##
when hex('c') # disable cycle
clearLightIntervals()
when hex('C') # cycle colors
clearLightIntervals(false)
setLightCycleInterval(3200) unless lightCycleInterval?
lightIntervals.customCycle = setInterval ->
updateLightParams [
{ key: 'dim', total: randomInt(3880, 4500) }
{ key: 'hue', total: randomInt(0x0000, 0xffff) }
{ key: 'saturation', total: randomInt(58135, 65535) }
{ key: 'brightness', total: randomInt(3400, 5535) }
]
, lightCycleInterval
log("Started custom light cycle with interval #{lightCycleInterval}")
## kelvin ##
when hex('K') then updateLightParams(key: 'kelvin', delta: lightDelta)
when hex('k') then updateLightParams(key: 'kelvin', delta: lightDelta * -1)
## dim ##
when hex('D') then updateLightParams(key: 'dim', delta: lightDelta)
when hex('d') then updateLightParams(key: 'dim', delta: lightDelta * -1)
## hue ##
when hex('H') then updateLightParams(key: 'hue', delta: lightDelta)
when hex('h') then updateLightParams(key: 'hue', delta: lightDelta * -1)
## saturation ##
when hex('S') then updateLightParams(key: 'saturation', delta: lightDelta)
when hex('s') then updateLightParams(key: 'saturation', delta: lightDelta * -1)
## brightness ##
when hex('B') then updateLightParams(key: 'brightness', delta: lightDelta)
when hex('b') then updateLightParams(key: 'brightness', delta: lightDelta * -1)
## active bulb ##
when hex('>') then deltaBulbIndex(1)
when hex('<') then deltaBulbIndex(-1)
when hex('.') then resetBulbIndex()
## utilities ##
when hex('?') # help
printHelp()
when hex('z') # reset
clearLightIntervals()
when hex('q') # quit
process.exit()
else
char = String.fromCharCode(key)
log("Unknown key `#{char}`: #{util.inspect(key)}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment