Skip to content

Commit

Permalink
First implementation of hue driver for pimatic-led-light. Allows for …
Browse files Browse the repository at this point in the history
…switching individual light bulbs and groups, brighness control and color.

Issue #46 and pimatic/pimatic#28
  • Loading branch information
mwittig committed Jan 15, 2016
1 parent 80b4f01 commit f60cdcb
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 6 deletions.
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Currently supported:
- [MilightRF24] (https://github.com/henryk/openmili)
- [Blinkstick] (https://www.blinkstick.com)
- [Hyperion] (https://github.com/tvdzwan/hyperion/wiki)
- [Hue] (http://wwww.meethue.com)

## Installation

Expand Down Expand Up @@ -103,6 +104,25 @@ Get the sketch from here https://github.com/henryk/openmili and change the CE an
}
```

### For Hue

```
{
"id": "some_id",
"name": "some_name",
"class": "Hue",
"addr": "xxx.xxx.xxx.xxx",
"username": "your username",
"hueId": 1,
"isGroup": false
}
```

You need to create an `username` on your bridge to use this plugin. See the
[hue Developer Program Documentation](http://www.developers.meethue.com/documentation/getting-started)
for details. If you're planning to use the [Hue Emulator](http://steveyo.github.io/Hue-Emulator/)
you can use the username "newdeveloper".

## Features

- switch on/off (UI and rules)
Expand Down
26 changes: 26 additions & 0 deletions device-config-schema.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -84,5 +84,31 @@ module.exports = {
description: "Port of hyperion device"
type: "string",
default: "19444"
},
Hue: {
title: "Hue Light",
type: "object"
properties:
addr:
description: "IP-Address of hue bridge"
type: "string"
username:
description: "Username registered (white-listed) on the bridge for PUT access"
type: "string"
hueId:
description: "The light or group id to be controlled"
type: "number"
isGroup:
description: "If set to true the id property is group id. It is a light id, otherwise."
type: "boolean"
default: false
port:
description: "Port of hue bridge (provided for testing purposes)"
type: "number",
default: 80
timeout:
description: "Timeout in ms for a pending bridge request to complete"
type: "number"
default: 10000
}
}
89 changes: 89 additions & 0 deletions devices/hue.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
module.exports = (env) ->
Promise = env.require 'bluebird'
_ = require 'lodash'
Color = require 'color'
# 'es6-promise' needs to be required at this point to initialize promises for the underlying base library
es6Promise = require 'es6-promise'
hue = require 'node-hue-api'
BaseLedLight = require('./base')(env)


class HueLight extends BaseLedLight

constructor: (@config, lastState) ->
@device = new hue.HueApi(
@config.addr,
@config.username,
@config.timeout,
@config.port,
)

@hueId = @config.hueId
@hueStateCommand = if @config.isGroup then "setGroupLightState" else "setLightState"

initState = _.clone lastState
for key, value of lastState
initState[key] = value.value
super(initState)
if @power then @turnOn() else @turnOff()

_updateState: (attr) =>
state = _.assign @getState(), attr
super null, state

turnOn: ->
hueState = hue.lightState.create().on()
@device[@hueStateCommand](@hueId, hueState).then( =>
@_updateState power: true
).catch( (error) =>
env.logger.error error
).done()

turnOff: ->
hueState = hue.lightState.create().off()
@device[@hueStateCommand](@hueId, hueState).then( =>
@_updateState power: false
).catch( (error) =>
env.logger.error error
).done()

setColor: (newColor) ->
color = Color(newColor).rgb()
hslColor = Color(newColor).hsl()
if color.r == 255 && color.g == 255 && color.b == 255
return @setWhite()
else
hueState = hue.lightState.create().on().hsl(hslColor.h, hslColor.s, hslColor.l)
@device[@hueStateCommand](@hueId, hueState).then(
@_updateState
mode: @COLOR_MODE
color: color
power: true
).catch( (error) =>
env.logger.error error
).done()

setWhite: () ->
hslColor = Color("#FFFFFF").hsl()
hueState = hue.lightState.create().on().hsl(hslColor.h, hslColor.s, hslColor.l)
@device[@hueStateCommand](@hueId, hueState).then(
@_updateState
mode: @WHITE_MODE
power: true
).catch( (error) =>
env.logger.error error
).done()

setBrightness: (newBrightness) ->
# Maximum brightness for hue is 254 rather than 255
# See also http://www.developers.meethue.com/content/maximum-brightness-254-or-255
hueState = hue.lightState.create().on().bri(Math.round(newBrightness * 254 / 100))
@device[@hueStateCommand](@hueId, hueState).then(
@_updateState
brightness: newBrightness
power: true
).catch( (error) =>
env.logger.error error
).done()

return HueLight
14 changes: 8 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,18 @@
"test": "node_modules/.bin/mocha test"
},
"dependencies": {
"blinkstick": "1.1.1",
"bluebird": "^3.1.1",
"cassert": "^0.1.2",
"color": "^0.8.0",
"color": "^0.11.1",
"es6-promise": "^3.0.2",
"event-to-promise": "0.6.0",
"hyperion-client": "1.0.0",
"iwy_master": "0.2.3",
"node-milight-promise": ">=0.0.3",
"node-milight-rf24": ">=0.1.1",
"lodash": "^3.10.1",
"blinkstick": "1.1.1",
"hyperion-client": "1.0.0",
"event-to-promise": "0.6.0"
"node-hue-api": "^2.0.0",
"node-milight-promise": ">=0.0.3",
"node-milight-rf24": ">=0.1.1"
},
"peerDependencies": {
"pimatic": "0.8.*"
Expand Down
5 changes: 5 additions & 0 deletions pimatic-led-light.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module.exports = (env) ->
Blinkstick = require('./devices/blinkstick')(env)
DummyLedLight = require('./devices/dummy')(env)
HyperionLedLight = require('./devices/hyperion')(env)
HueLight = require('./devices/hue')(env)

# import preadicares and actions
ColorActionProvider = require('./predicates_and_actions/color_action')(env)
Expand Down Expand Up @@ -48,6 +49,10 @@ module.exports = (env) ->
configDef: deviceConfigDef.HyperionLedLight
createCallback: (config) -> return new HyperionLedLight(config)

@framework.deviceManager.registerDeviceClass 'Hue',
configDef: deviceConfigDef.Hue
createCallback: (config) -> return new HueLight(config)

@framework.ruleManager.addActionProvider(new ColorActionProvider(@framework))

# wait till all plugins are loaded
Expand Down

0 comments on commit f60cdcb

Please sign in to comment.