UNPKG

ayla

Version:

Ayla at your service.

160 lines (123 loc) 5.83 kB
# SERVER: HOME MANAGER # ----------------------------------------------------------------------------- # Handles automatic messages, trigger events, etc based on API's data. class HomeManager extends (require "./baseManager.coffee") expresser = require "expresser" events = expresser.events logger = expresser.logger mailer = expresser.mailer settings = expresser.settings # PROPERTIES # ------------------------------------------------------------------------- # Computed weather stats. weatherAvgData: => indoor = {} indoor.temperature = getWeatherAverage "indoor", "temperature" indoor.humidity = getWeatherAverage "indoor", "temperature" indoor.co2 = getWeatherAverage "indoor", "temperature" outdoor = {} outdoor.temperature = getWeatherAverage "outdoor", "temperature" outdoor.humidity = getWeatherAverage "outdoor", "humidity" return {indoor: indoor, outdoor: outdoor} # INIT # ------------------------------------------------------------------------- # Init the home manager. init: => @data.bedroom = getRoomObject "Bedroom" @data.livingroom = getRoomObject "Living Room" @data.babyroom = getRoomObject "Noah's room" @data.kitchen = getRoomObject "Kitchen" @data.outdoor = {} @data.forecast = {} @baseInit() # Start the home manager and listen to data updates / events. start: => events.on "netamo.data.indoor", @onNetatmoIndoor events.on "netamo.data.outdoor", @onNetatmoOutdoor events.on "ninja.data.weather", @onNinjaWeather events.on "ubi.data.weather", @onUbiWeather events.on "wunderground.data.current", @onWunderground events.on "hue.data.hub", @onHueHub @baseStart() # Stop the home manager. stop: => @baseStop() # WEATHER AND CLIMATE # ------------------------------------------------------------------------- # Helper to verify if room weather is in good condition. checkRoomWeather: (room) => subject = "#{room.title} weather" if room.temperature > settings.home.temperature.max @notify subject, "#{room.title} too warm", "It's #{room.temperature}C right now, fan will turn on automatically." else if room.temperature < settings.home.temperature.min @notify subject, "#{room.title} too cold", "It's #{room.temperature}C right now, heating will turn on automatically." # Helper to set current conditions for the specified room. setRoomWeather: (room, data) => roomObj = @data[room] roomObj.temperature = data.temperature roomObj.humidity = data.humidity roomObj.co2 = data.co2 logger.info "HomeManager.setRoomWeather", roomObj @checkRoomWeather room # Helper to set current conditions for outdoors. setOutdoorWeather: (data) => @data.outdoor.temperature = data.temperature @data.outdoor.humidity = data.humidity logger.info "HomeManager.setOutdoorWeather", @data.outdoor # Helper to set forecast conditions for outdoors. setWeatherForecast: (data) => @data.forecast.text = data.weather @data.forecast.temperature = data.temperature or data.temp_c @data.forecast.humidity = data.humidity or data.relative_humidity @data.forecast.pressure = data.pressure or data.pressure_mb logger.info "HomeManager.setWeatherForecast", @data.forecast # Check indoor weather conditions using Netatmo. onNetatmoIndoor: (data) => @setRoomWeather "livingroom", data.indoor # Check outdoor weather conditions using Netatmo. onNetatmoOutdoor: (data) => @setOutdoorWeather data.outdoor # Check indoor weather conditions using Ninja Blocks. onNinjaWeather: (data) => weather = {} weather.temperature = data.temperature[0].value if data.temperature.length > 0 weather.humidity = data.humidity[0].value if data.humidity.length > 0 @setRoomWeather "kitchen", weather # Check indoor weather conditions using The Ubi. onUbiWeather: (data) => @setRoomWeather "bedroom", data # Check outdoor weather conditions using Weather Underground. onWunderground: (data) => @setWeatherForecast data # LIGHTS # ------------------------------------------------------------------------- # When Hue hub details are refreshed. onHueHub: (data) => # GENERAL HELPERS # ------------------------------------------------------------------------- # Helper to get weather average readings. getWeatherAverage = (where, prop) => avg = 0 count = 0 # Set properties to be read (indoor rooms or outdoor / forecast). if where is "indoor" arr = ["bedroom", "livingroom", "babyroom", "kitchen"] else arr = ["outdoor", "forecast"] # Iterate readings. for r in arr if @data[r][prop]? avg += @data[r][prop] count += 1 # Return average reading for the specified property. return avg / count # Helper to return room object with weather, title etc. getRoomObject = (title) => weather = {temperature: null, humidity: null, co2: null} return {title: title, weather: weather} # Singleton implementation. # ----------------------------------------------------------------------------- HomeManager.getInstance = -> @instance = new HomeManager() if not @instance? return @instance module.exports = exports = HomeManager.getInstance()