UNPKG

ayla

Version:

Ayla at your service.

161 lines (125 loc) 5.75 kB
# PHILIPS HUE API # ----------------------------------------------------------------------------- class Hue extends (require "./baseApi.coffee") expresser = require "expresser" events = expresser.events logger = expresser.logger settings = expresser.settings utils = expresser.utils async = require "async" lodash = require "lodash" networkApi = require "./network.coffee" url = require "url" # PROPERTIES # ------------------------------------------------------------------------- # Holds the current URL in use for the API (local or remote). apiUrl: "" # INIT # ------------------------------------------------------------------------- # Init the Hue module and schedule a job to refresh the hub status every few seconds. init: => @baseInit() # Start the module and refresh the Hue hub data. start: => @baseStart() # Stop the module and cancel the Hue hub refresh jobs. stop: => @baseStop() # API BASE METHODS # ------------------------------------------------------------------------- # Helper to get all lights IDs. getLightIds: => result = [] result.push i for i of @data.hub.lights return result # Make a request to the Hue API. apiRequest: (urlPath, params, callback) => if not settings.hue?.api? logger.warn "Hue.apiRequest", "Hue API settings are not defined. Abort!" return # Set correct parameters. if lodash.isFunction params callback = params params = null # Set full URL and make the HTTP request. baseUrl = (if networkApi.isHome then settings.hue.api.localUrl else settings.hue.api.remoteUrl) reqUrl = baseUrl + settings.hue.api.user + "/" + urlPath @makeRequest reqUrl, params, callback # GET HUB DATA # ------------------------------------------------------------------------- # Refresh information from the Hue hub. refreshHub: (callback) => logger.debug "Hue.refreshHub" @apiRequest "", (err, results) => if err? @logError "Hue.refreshHub", err else @setData "hub", results # Get hub counters. lightCount = 0 groupCount = 0 lightCount = lodash.keys(results.lights).length if results?.lights? groupCount = lodash.keys(results.groups).length if results?.groups? # Log and emit refresh event. logger.info "Hue.refreshHub", "#{lightCount} lights and #{groupCount} groups." callback err, results if callback? # LIGHT CONTROL # ------------------------------------------------------------------------- # Main function to set light state (switch, colour, brightness etc). setLightState: (filter, state, callback) => if not filter? throw new Error "A valid light, array of lights or filter must be specified." else logger.debug "Hue.setLightState", filter, state # Set request parameter to use PUT and pass the full state and create tasks array. params = {method: "PUT", body: state} tasks = [] # Check if id is a single light or an array of lights (if any). if filter.lightId? if lodash.isArray filter.lightId arr = filter.lightId else arr = [filter.lightId] # Make the light state change request for all specified ids. for i of arr do (i) => tasks.push (cb) => @apiRequest "lights/#{i}/state", params, cb # Check if id is a single group or an array of groups (if any). if filter.groupId? if lodash.isArray filter.groupId arr = filter.groupId else arr = [filter.groupId] # Make the light state change request for all specified ids. for i of arr do (i) => tasks.push (cb) => @apiRequest "groups/#{i}/action", params, cb # Execute requests in parallel. async.parallelLimit tasks, settings.general.parallelTasksLimit, (err, results) => if err? @logError "Hue.setLightState", filter, state, err else logger.info "Hue.setLightState", filter, state events.emit "hue.lights.state", filter, state callback err, results if callback? # Turn all lights on (true) or off (false). switchAllLights: (turnOn, callback) => logger.debug "Hue.switchAllLights", turnOn @setLightState {groupId: 0}, {on: turnOn}, callback # Turn group lights on (true) or off (false). switchGroupLights: (id, turnOn, callback) => logger.debug "Hue.switchGroupLights", turnOn @setLightState {groupId: id}, {on: turnOn}, callback # Turn the specified light on (true) or off (false). switchLight: (id, turnOn, callback) => logger.debug "Hue.switchLight", id, turnOn @setLightState {lightId: id}, {on: turnOn}, callback # JOBS # ------------------------------------------------------------------------- # Scheduled job to refresh the hub data. jobRefreshHub: => @refreshHub() # Singleton implementation. # ----------------------------------------------------------------------------- Hue.getInstance = -> @instance = new Hue() if not @instance? return @instance module.exports = exports = Hue.getInstance()