UNPKG

homebridge-enlighten-lux

Version:

This plugin show the power produced by your Envoy solar system as an light sensor.

204 lines (168 loc) 6.55 kB
const { timeStamp, clear } = require('console'); const { exitCode, exit } = require('process'); const PACKAGE_JSON = require('./package.json'); const MANUFACTURER = PACKAGE_JSON.author.name; const SERIAL_NUMBER = '001'; const MODEL = PACKAGE_JSON.name; const FIRMWARE_REVISION = PACKAGE_JSON.version; const MIN_LUX_VALUE = 0.0; const MAX_LUX_VALUE = Math.pow(2, 16) - 1.0; // Default BH1750 max 16bit lux value. var Service, Characteristic module.exports = function (homebridge) { Service = homebridge.hap.Service; Characteristic = homebridge.hap.Characteristic; homebridge.registerAccessory("homebridge-enlighten-lux", "enlighten-lux", Accessory); } class Accessory { constructor(log, config) { // Don't load the plugin if these aren't accessible for any reason if (!log || !config) { return } this.log = log this.log("Initialising...") this.name = config["name"] this.connection = config["connection"] || "bonjour" // local or api if (this.connection == "api") { this.api_key = config["api_key"] this.api_user_id = config["api_user_id"] this.site_id = config["site_id"] this.url = "https://api.enphaseenergy.com/api/v2/systems/" + this.site_id + "/summary?key=" + this.api_key + "&user_id=" + this.api_user_id this.updateInterval = config['update_interval'] || "5" // every 5 min } if (this.connection == "bonjour") { this.url = "http://envoy.local/production.json" this.updateInterval = config['update_interval'] || "1" // every minutes // allow change production type and handling current default to 1 // allow change production type and handling current default to 1 // allow change production type and handling current default to 1 let temp_type = config["type"] || "eim" this.type = (temp_type == "eim") ? 1 : 0 } if (this.connection == "url") { this.url = config["url"] this.updateInterval = config['update_interval'] || "1" // every minutes // allow change production type and handling current default to 1 // allow change production type and handling current default to 1 // allow change production type and handling current default to 1 let temp_type = config["type"] || "eim" this.type = (temp_type == "eim") ? 1 : 0 } this.co2Threshold = config['power_threshold'] || 0 this.lightCurrentLevel = 0 this.co2Detected = 0 this.service = new Service.LightSensor(this.name) this.service .getCharacteristic(Characteristic.CurrentAmbientLightLevel) .on('get', this.getSensorValue.bind(this)) this.informationService = new Service.AccessoryInformation() this.informationService .setCharacteristic(Characteristic.Manufacturer, MANUFACTURER) .setCharacteristic(Characteristic.Model, MODEL) .setCharacteristic(Characteristic.SerialNumber, SERIAL_NUMBER) .setCharacteristic(Characteristic.FirmwareRevision, FIRMWARE_REVISION) this.interval = setInterval(() => { this.getSensorValue(function(error, value) { if (error) { this.log.debug(error) this.log("Refresh disabled") clearInterval(this.interval) } else { this.setLightLevel() } }) // if (this.co2Detected) { // if (this.lightCurrentLevel < this.co2Threshold) { // this.setCo2Detected() // } // } else { // if (this.lightCurrentLevel >= this.co2Threshold) { // this.setCo2Detected() // } // } }, this.updateInterval * 60000) } setLightLevel() { this.service .setCharacteristic(Characteristic.CurrentAmbientLightLevel, this.lightCurrentLevel) } getSensorValue(callback) { let url = new URL(this.url) this.log.debug(url) var protocol = (url.protocol == "http:") ? require('http') : require('https') const options = { hostname: url.hostname, port: url.port, path: url.pathname + url.search, method: 'GET' } var req = protocol.request(options, (resp) => { this.log.debug("GET response received (%s)", resp.statusCode) let data = '' // A chunk of data has been received. resp.on('data', (chunk) => { data += chunk }) // The whole response has been received. Print out the result. resp.on('end', () => { if (resp.statusCode == 200) { try { JSON.parse(data) } catch (e) { this.log("Error: not JSON!") callback(null, 0) return } var json = JSON.parse(data) this.log.debug("JSON: %s", json) if (this.connection == "api") { this.lightCurrentLevel = Math.round(parseFloat(json.current_power)) } else { let power = Math.round(parseFloat(json.production[this.type].wNow)) this.lightCurrentLevel = (power >= 0) ? power : 0 } this.log.debug('Enlighten (%s): Current Power = %s W', this.connection, this.lightCurrentLevel) this.setLightLevel() callback(null, this.lightCurrentLevel) } else { this.error = true this.log("Error getting current power: %s : %s", resp.statusCode, resp.statusMessage) callback(resp, 0) } }) }) req.on("error", (err) => { this.log("Error getting current power: %s - %s : %s", err.code, err.status, err.message) callback(err, 0) }) req.setTimeout(1000) req.on('timeout', () => { // Timeout happend. Server received request, but not handled it // (i.e. doesn't send any response or it took to long). // You don't know what happend. // It will emit 'error' message as well (with ECONNRESET code). this.log('timeout') req.destroy }) req.end() } setCo2Detected() { if (this.lightCurrentLevel >= this.co2Threshold) { this.co2Detected = 1 this.log('Power threshold (%s W) reached (%s W) -> Swith to Detected', this.co2Threshold, this.lightCurrentLevel) } else { this.co2Detected = 0 this.log('Power threshold (%s W) reached (%s W) -> Switch to Not detected', this.co2Threshold, this.lightCurrentLevel) } this.service .setCharacteristic(Characteristic.CarbonDioxideDetected, this.co2Detected) } getCo2Detected(callback) { callback(null, this.co2Detected) } getServices() { return [this.service, this.informationService] } }