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
JavaScript
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]
}
}