From 825ccadd11ecc42f8b7184a84d987b8691097f9f Mon Sep 17 00:00:00 2001
From: fabianoflnsp <45748723+fabianoflnsp@users.noreply.github.com>
Date: Tue, 21 Apr 2020 01:55:10 -0300
Subject: [PATCH 0001/3183] Update index.js
Added Support for Sonoff Mini
---
index.js | 2 ++
1 file changed, 2 insertions(+)
diff --git a/index.js b/index.js
index a7710bf1..9450617a 100644
--- a/index.js
+++ b/index.js
@@ -142,6 +142,7 @@ function eWeLink(log, config, api) {
if ((deviceInformationFromWebApi !== undefined) && (deviceInformationFromWebApi["productModel"])) {
switch (deviceInformationFromWebApi.productModel) {
case 'B1':
+ case 'MINI':
powerState = deviceInformationFromWebApi.params.state;
break;
case 'iFan02':
@@ -217,6 +218,7 @@ eWeLink.prototype.getStateFromDevice = function(device) {
if ((device !== undefined) && (device["productModel"])) {
switch (device.productModel) {
case 'B1':
+ case "MINI":
powerState = device.params.state;
break;
case 'iFan02':
From 133af6b4040adfbe4a934e3785507021476970d8 Mon Sep 17 00:00:00 2001
From: George <19616587+gbro115@users.noreply.github.com>
Date: Tue, 19 May 2020 11:38:39 -0400
Subject: [PATCH 0002/3183] Update package.json
Modify name post merge
---
package.json | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/package.json b/package.json
index 6c64e424..b66653c9 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
- "name": "homebridge-ewelink-complete",
+ "name": "homebridge-ewelink",
"version": "0.1.76",
- "description": "Fork of homebridge-eWeLink is a Homebrige plugin to control Sonoff relays running OEM firmware",
+ "description": "homebridge-eWeLink is a Homebrige plugin to control Sonoff relays running OEM firmware",
"license": "MIT",
"keywords": [
"homebridge-plugin",
@@ -13,7 +13,7 @@
},
"repository": {
"type": "git",
- "url": "https://github.com/ronnieroberts/homebridge-ewelink.git"
+ "url": "https://github.com/gbro115/homebridge-ewelink.git"
},
"dependencies": {
"ewelink-api": "^2.0.0",
From 87388442fe9025db866e364aa11ef913618239b5 Mon Sep 17 00:00:00 2001
From: George <19616587+gbro115@users.noreply.github.com>
Date: Tue, 19 May 2020 11:40:16 -0400
Subject: [PATCH 0003/3183] Update README.md
---
README.md | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 82d1b8c4..d476dd88 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,9 @@
-## This is a fork of homebridge-ewelink
+# Changes from homebridge-ewelink-complete have been merged into the master
The largest change here is to use evelink-api for all API needs rather than rewrite
-# homebridge-ewelink-complete
+# About
+
Homebridge plugin to control Sonoff relays with OEM firmware. It uses the same API as the iOS app to communicate with your devices.
The platform will dynamically add/remove devices based on what is configured in your eWeLink account.
From b56ea1b9b8521d331042cbb1fde81173b1eaee04 Mon Sep 17 00:00:00 2001
From: George <19616587+gbro115@users.noreply.github.com>
Date: Tue, 19 May 2020 11:40:39 -0400
Subject: [PATCH 0004/3183] Update README.md
Formatting
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index d476dd88..fc4f06d7 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# Changes from homebridge-ewelink-complete have been merged into the master
+### Changes from homebridge-ewelink-complete have been merged into the master
The largest change here is to use evelink-api for all API needs rather than rewrite
From 043705b3dbfc2b7bd3fa298457eeb32eefe37b0f Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 16 Aug 2020 07:53:42 +0100
Subject: [PATCH 0005/3183] jshint format tweaks
---
index.js | 710 +++++++++++++++++++++++++++----------------------------
1 file changed, 343 insertions(+), 367 deletions(-)
diff --git a/index.js b/index.js
index 9450617a..fadb4c55 100644
--- a/index.js
+++ b/index.js
@@ -1,382 +1,358 @@
-var WebSocket = require('ws');
-var http = require('http');
-var url = require('url');
-var request = require('request-json');
+/* jshint esversion: 9, -W030, node: true */
const ewelinkapi = require('ewelink-api');
-var nonce = require('nonce')();
-
-var wsc;
-var isSocketOpen = false;
-var sequence = 0;
-var webClient = '';
-var apiKey = 'UNCONFIGURED';
-var authenticationToken = 'UNCONFIGURED';
-var phoneNumberOrEmail = '';
-var accountPassword = '';
-var connection = 0;
var Accessory, Service, Characteristic, UUIDGen;
-var debug = false;
-
-module.exports = function(homebridge) {
- console.log("homebridge API version: " + homebridge.version);
-
- // Accessory must be created from PlatformAccessory Constructor
- Accessory = homebridge.platformAccessory;
- // Service and Characteristic are from hap-nodejs
- Service = homebridge.hap.Service;
- Characteristic = homebridge.hap.Characteristic;
- UUIDGen = homebridge.hap.uuid;
-
- // For platform plugin to be considered as dynamic platform plugin,
- // registerPlatform(pluginName, platformName, constructor, dynamic), dynamic must be true
- homebridge.registerPlatform("homebridge-eWeLink", "eWeLink", eWeLink, true);
-
-}
+module.exports = function (homebridge) {
+ console.log("homebridge API version: " + homebridge.version);
+
+ // Accessory must be created from PlatformAccessory Constructor
+ Accessory = homebridge.platformAccessory;
+
+ // Service and Characteristic are from hap-nodejs
+ Service = homebridge.hap.Service;
+ Characteristic = homebridge.hap.Characteristic;
+ UUIDGen = homebridge.hap.uuid;
+
+ // For platform plugin to be considered as dynamic platform plugin,
+ // registerPlatform(pluginName, platformName, constructor, dynamic), dynamic must be true
+ homebridge.registerPlatform("homebridge-eWeLink", "eWeLink", eWeLink, true);
+
+};
// Platform constructor
function eWeLink(log, config, api) {
-
- log("Intialising eWeLink");
-
- var platform = this;
-
- this.log = log;
- this.config = config;
- this.accessories = new Map();
- this.authenticationToken = 'UNCONFIGURED';
- this.phoneNumberOrEmail = config['phoneNumberOrEmail'];
- this.accountPassword = config['accountPassword'];
- this.debug = (config['debug'] == 'true') ? true : false;
-
-
- if (api) {
-
- // Save the API object as plugin needs to register new accessory via this object
- this.api = api;
-
- // Listen to event "didFinishLaunching", this means homebridge already finished loading cached accessories.
- // Platform Plugin should only register new accessory that doesn't exist in homebridge after this event.
- // Or start discover new accessories.
-
-
- this.api.on('didFinishLaunching', function() {
-
- platform.log("A total of [%s] accessories were loaded from the local cache", platform.accessories.size);
-
- // Get a list of all devices from the API, and compare it to the list of cached devices.
- // New devices will be added, and devices that exist in the cache but not in the web list
- // will be removed from Homebridge.
-
- (async() => {
-
- const connection = new ewelinkapi({
- email: this.phoneNumberOrEmail,
- password: this.accountPassword
- });
- this.connection = connection;
- this.authenticationToken = await connection.getCredentials();
- if(this.debug) platform.log("authenticationToken %s", JSON.stringify(this.authenticationToken));
-
- /* get all devices */
- platform.log("Requesting a list of devices from eWeLink HTTPS API");
- const devices = await connection.getDevices();
- // console.log(JSON.stringify(devices));
-
- var size = devices.length;
- platform.log("eWeLink HTTPS API reports that there are a total of [%s] devices registered", size);
-
- if (size == 0) {
- platform.log("As there were no devices were found, all devices have been removed from the platorm's cache. Please regiester your devices using the eWeLink app and restart HomeBridge");
- platform.accessories.clear();
- platform.api.unregisterPlatformAccessories("homebridge-eWeLink", "eWeLink", platform.accessories);
- return;
- }
-
- var devicesFromApi = new Map();
- var newDevicesToAdd = new Map();
-
- devices.forEach((device) => {
- platform.apiKey = device.apikey;
- devicesFromApi.set(device.deviceid, device);
- })
-
- // Now we compare the cached devices against the web list
- platform.log("Evaluating if devices need to be removed...");
-
- function checkIfDeviceIsStillRegistered(value, deviceId, map) {
-
- var accessory = platform.accessories.get(deviceId);
-
- if (devicesFromApi.has(deviceId)) {
- platform.log('Device [%s] is regeistered with API. Nothing to do.', accessory.displayName);
- } else {
- platform.log('Device [%s], ID : [%s] was not present in the response from the API. It will be removed.', accessory.displayName, accessory.UUID);
- platform.removeAccessory(accessory);
- };
- }
-
- // If we have devices in our cache, check that they exist in the web response
- if (platform.accessories.size > 0) {
- platform.log("Verifying that all cached devices are still registered with the API. Devices that are no longer registered with the API will be removed.");
- platform.accessories.forEach(checkIfDeviceIsStillRegistered);
- }
-
- platform.log("Evaluating if new devices need to be added...");
-
- // Now we compare the cached devices against the web list
- function checkIfDeviceIsAlreadyConfigured(value, deviceId, map) {
- if (platform.accessories.has(deviceId)) {
-
- platform.log('Device with ID [%s] is already configured. Ensuring that the configuration is current.', deviceId);
-
- var accessory = platform.accessories.get(deviceId);
- var deviceInformationFromWebApi = devicesFromApi.get(deviceId);
-
- accessory.getService(Service.AccessoryInformation).setCharacteristic(Characteristic.Name, deviceInformationFromWebApi.name);
- accessory.getService(Service.AccessoryInformation).setCharacteristic(Characteristic.SerialNumber, deviceInformationFromWebApi.extra.extra.mac);
- accessory.getService(Service.AccessoryInformation).setCharacteristic(Characteristic.Manufacturer, deviceInformationFromWebApi.brandName);
- accessory.getService(Service.AccessoryInformation).setCharacteristic(Characteristic.Model, deviceInformationFromWebApi.productModel);
- accessory.getService(Service.AccessoryInformation).setCharacteristic(Characteristic.FirmwareRevision, deviceInformationFromWebApi.params.fwVersion);
- if ((deviceInformationFromWebApi !== undefined) && (deviceInformationFromWebApi["productModel"])) {
- switch (deviceInformationFromWebApi.productModel) {
- case 'B1':
- case 'MINI':
- powerState = deviceInformationFromWebApi.params.state;
- break;
- case 'iFan02':
- powerState = deviceInformationFromWebApi.params.switches[0].switch;
- break;
- case 'AD500--X':
- powerState = deviceInformationFromWebApi.params.switch;
- };
- }
- if(this.debug) platform.log("::checkIfDeviceIsAlreadyConfigured() " + deviceInformationFromWebApi.name + " is " + powerState);
-
- platform.updatePowerStateCharacteristic(deviceId, powerState);
-
-
- } else {
- var deviceToAdd = devicesFromApi.get(deviceId);
- platform.log('Device [%s], ID : [%s] will be added', deviceToAdd.name, deviceToAdd.deviceid);
- platform.addAccessory(deviceToAdd);
- };
- }
-
- // Go through the web response to make sure that all the devices that are in the response do exist in the accessories map
- if (devicesFromApi.size > 0) {
- devicesFromApi.forEach(checkIfDeviceIsAlreadyConfigured);
- }
-
- if(this.debug) platform.log("API key retrieved from web service is [%s]", platform.apiKey);
-
-
- })().catch(function(error) {
- platform.log("Error in intialization");
- });
- }.bind(this));
- }
+
+ log("Intialising eWeLink");
+
+ var platform = this;
+
+ this.log = log;
+ this.config = config;
+ this.accessories = new Map();
+ this.authenticationToken = 'UNCONFIGURED';
+ this.phoneNumberOrEmail = config.phoneNumberOrEmail;
+ this.accountPassword = config.accountPassword;
+ this.debug = (config.debug === 'true') ? true : false;
+
+ if (api) {
+
+ // Save the API object as plugin needs to register new accessory via this object
+ this.api = api;
+
+ // Listen to event "didFinishLaunching", this means homebridge already finished loading cached accessories.
+ // Platform Plugin should only register new accessory that doesn't exist in homebridge after this event.
+ // Or start discover new accessories.
+
+ this.api.on('didFinishLaunching', function () {
+
+ platform.log("A total of [%s] accessories were loaded from the local cache", platform.accessories.size);
+
+ // Get a list of all devices from the API, and compare it to the list of cached devices.
+ // New devices will be added, and devices that exist in the cache but not in the web list
+ // will be removed from Homebridge.
+
+ (async () => {
+
+ const connection = new ewelinkapi({
+ email: this.phoneNumberOrEmail,
+ password: this.accountPassword
+ });
+ this.connection = connection;
+ this.authenticationToken = await connection.getCredentials();
+ if (this.debug) platform.log("authenticationToken %s", JSON.stringify(this.authenticationToken));
+
+ /* get all devices */
+ platform.log("Requesting a list of devices from eWeLink HTTPS API");
+ const devices = await connection.getDevices();
+ // console.log(JSON.stringify(devices));
+
+ var size = devices.length;
+ platform.log("eWeLink HTTPS API reports that there are a total of [%s] devices registered", size);
+
+ if (size == 0) {
+ platform.log("As there were no devices were found, all devices have been removed from the platorm's cache. Please regiester your devices using the eWeLink app and restart HomeBridge");
+ platform.accessories.clear();
+ platform.api.unregisterPlatformAccessories("homebridge-eWeLink", "eWeLink", platform.accessories);
+ return;
+ }
+
+ var devicesFromApi = new Map();
+
+ devices.forEach((device) => {
+ platform.apiKey = device.apikey;
+ devicesFromApi.set(device.deviceid, device);
+ });
+
+ // Now we compare the cached devices against the web list
+ platform.log("Evaluating if devices need to be removed...");
+
+ function checkIfDeviceIsStillRegistered(value, deviceId, map) {
+
+ var accessory = platform.accessories.get(deviceId);
+
+ if (devicesFromApi.has(deviceId)) {
+ platform.log('Device [%s] is regeistered with API. Nothing to do.', accessory.displayName);
+ } else {
+ platform.log('Device [%s], ID : [%s] was not present in the response from the API. It will be removed.', accessory.displayName, accessory.UUID);
+ platform.removeAccessory(accessory);
+ }
+ }
+
+ // If we have devices in our cache, check that they exist in the web response
+ if (platform.accessories.size > 0) {
+ platform.log("Verifying that all cached devices are still registered with the API. Devices that are no longer registered with the API will be removed.");
+ platform.accessories.forEach(checkIfDeviceIsStillRegistered);
+ }
+
+ platform.log("Evaluating if new devices need to be added...");
+
+ // Now we compare the cached devices against the web list
+ function checkIfDeviceIsAlreadyConfigured(value, deviceId, map) {
+ if (platform.accessories.has(deviceId)) {
+
+ platform.log('Device with ID [%s] is already configured. Ensuring that the configuration is current.', deviceId);
+
+ var accessory = platform.accessories.get(deviceId);
+ var deviceInformationFromWebApi = devicesFromApi.get(deviceId);
+
+ accessory.getService(Service.AccessoryInformation).setCharacteristic(Characteristic.Name, deviceInformationFromWebApi.name);
+ accessory.getService(Service.AccessoryInformation).setCharacteristic(Characteristic.SerialNumber, deviceInformationFromWebApi.extra.extra.mac);
+ accessory.getService(Service.AccessoryInformation).setCharacteristic(Characteristic.Manufacturer, deviceInformationFromWebApi.brandName);
+ accessory.getService(Service.AccessoryInformation).setCharacteristic(Characteristic.Model, deviceInformationFromWebApi.productModel);
+ accessory.getService(Service.AccessoryInformation).setCharacteristic(Characteristic.FirmwareRevision, deviceInformationFromWebApi.params.fwVersion);
+ let powerState;
+ if ((deviceInformationFromWebApi !== undefined) && (deviceInformationFromWebApi.productModel)) {
+ switch (deviceInformationFromWebApi.productModel) {
+ case 'B1':
+ case 'MINI':
+ powerState = deviceInformationFromWebApi.params.state;
+ break;
+ case 'iFan02':
+ powerState = deviceInformationFromWebApi.params.switches[0].switch;
+ break;
+ case 'AD500--X':
+ powerState = deviceInformationFromWebApi.params.switch;
+ }
+ }
+ if (this.debug) platform.log("::checkIfDeviceIsAlreadyConfigured() " + deviceInformationFromWebApi.name + " is " + powerState);
+
+ platform.updatePowerStateCharacteristic(deviceId, powerState);
+
+ } else {
+ var deviceToAdd = devicesFromApi.get(deviceId);
+ platform.log('Device [%s], ID : [%s] will be added', deviceToAdd.name, deviceToAdd.deviceid);
+ platform.addAccessory(deviceToAdd);
+ }
+ }
+
+ // Go through the web response to make sure that all the devices that are in the response do exist in the accessories map
+ if (devicesFromApi.size > 0) {
+ devicesFromApi.forEach(checkIfDeviceIsAlreadyConfigured);
+ }
+
+ if (this.debug) platform.log("API key retrieved from web service is [%s]", platform.apiKey);
+
+ })().catch(function (error) {
+ platform.log("Error in intialization");
+ });
+ }.bind(this));
+ }
}
-
// Function invoked when homebridge tries to restore cached accessory.
// We update the existing devices as part of didFinishLaunching(), as to avoid an additional call to the the HTTPS API.
-eWeLink.prototype.configureAccessory = function(accessory) {
-
- this.log(accessory.displayName, "Configure Accessory");
-
- var platform = this;
- accessory.reachable = true;
-
- accessory.on('identify', function(paired, callback) {
- platform.log(accessory.displayName, "Identify!!!");
- callback();
- });
-
- if (accessory.getService(Service.Switch)) {
-
- accessory.getService(Service.Switch).getCharacteristic(Characteristic.On)
- .on('set', function(value, callback) {
- platform.setPowerState(accessory, value);
- callback();
- })
- .on('get', function(callback) {
- platform.getPowerState(accessory);
- callback();
- });
-
- }
-
- this.accessories.set(accessory.context.deviceId, accessory);
-
-}
-
-eWeLink.prototype.getStateFromDevice = function(device) {
- if(this.debug) this.log("getStateFromDevice:: ENTER");
- var powerState = 'on';
- if ((device !== undefined) && (device["productModel"])) {
- switch (device.productModel) {
- case 'B1':
- case "MINI":
- powerState = device.params.state;
- break;
- case 'iFan02':
- powerState = device.params.switches[0].switch;
- break;
- case 'AD500--X':
- powerState = device.params.switch;
- };
- }
- if(this.debug) this.log("getStateFromDevice:: " + device.name + " is " + powerState);
- if(this.debug) this.log("getStateFromDevice:: EXIT");
- return powerState;
-}
+eWeLink.prototype.configureAccessory = function (accessory) {
+
+ this.log(accessory.displayName, "Configure Accessory");
+
+ var platform = this;
+ accessory.reachable = true;
+
+ accessory.on('identify', function (paired, callback) {
+ platform.log(accessory.displayName, "Identify!!!");
+ callback();
+ });
+
+ if (accessory.getService(Service.Switch)) {
+
+ accessory.getService(Service.Switch).getCharacteristic(Characteristic.On)
+ .on('set', function (value, callback) {
+ platform.setPowerState(accessory, value);
+ callback();
+ })
+ .on('get', function (callback) {
+ platform.getPowerState(accessory);
+ callback();
+ });
+
+ }
+
+ this.accessories.set(accessory.context.deviceId, accessory);
+
+};
+
+eWeLink.prototype.getStateFromDevice = function (device) {
+ if (this.debug) this.log("getStateFromDevice:: ENTER");
+ var powerState = 'on';
+ if ((device !== undefined) && (device.productModel)) {
+ switch (device.productModel) {
+ case 'B1':
+ case "MINI":
+ powerState = device.params.state;
+ break;
+ case 'iFan02':
+ powerState = device.params.switches[0].switch;
+ break;
+ case 'AD500--X':
+ powerState = device.params.switch;
+ }
+ }
+ if (this.debug) this.log("getStateFromDevice:: " + device.name + " is " + powerState);
+ if (this.debug) this.log("getStateFromDevice:: EXIT");
+ return powerState;
+};
// Sample function to show how developer can add accessory dynamically from outside event
-eWeLink.prototype.addAccessory = function(device) {
-
- // Here we need to check if it is currently there
- if (this.accessories.get(device.deviceid)) {
- this.log("Not adding [%s] as it already exists in the cache", device.deviceid);
- return
- }
-
- var platform = this;
-
- if (device.type != 10) {
- this.log("A device with an unknown type was returned. It will be skipped.", device.type);
- return;
- }
-
- this.log("Found Accessory with Name : [%s], Manufacturer : [%s], Status : [%s], Is Online : [%s], API Key: [%s] ", device.name, device.productModel, this.getStateFromDevice(device), device.online, device.apikey);
-
- const accessory = new Accessory(device.name, UUIDGen.generate(device.deviceid.toString()))
-
- accessory.context.deviceId = device.deviceid
- accessory.context.apiKey = device.apikey;
-
- // if (device.online == 'true') {
- accessory.reachable = true;
- // } else {
- // accessory.reachable = false;
- // }
-
- var platform = this;
- accessory.addService(Service.Switch, device.name)
- .getCharacteristic(Characteristic.On)
- .on('set', function(value, callback) {
- platform.setPowerState(accessory, value);
- callback();
- })
- .on('get', function(callback) {
- platform.getPowerState(accessory);
- callback();
- });
-
-
- accessory.on('identify', function(paired, callback) {
- platform.log(accessory.displayName, "Identify not supported");
- callback();
- });
-
- accessory.getService(Service.AccessoryInformation).Characteristic(Characteristic.SerialNumber, device.extra.extra.mac);
- accessory.getService(Service.AccessoryInformation).setCharacteristic(Characteristic.Manufacturer, device.productModel);
- accessory.getService(Service.AccessoryInformation).setCharacteristic(Characteristic.Model, device.extra.extra.model);
- accessory.getService(Service.AccessoryInformation).setCharacteristic(Characteristic.Identify, false);
- accessory.getService(Service.AccessoryInformation).setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion);
-
- this.accessories.set(device.deviceid, accessory);
-
- this.api.registerPlatformAccessories("homebridge-eWeLink",
- "eWeLink", [accessory]);
-
-}
-
-eWeLink.prototype.getSequence = function() {
- var time_stamp = new Date() / 1000;
- this.sequence = Math.floor(time_stamp * 1000);
- return this.sequence;
-}
-
-eWeLink.prototype.updatePowerStateCharacteristic = function(deviceId, state) {
- var platform = this;
- if (platform.debug) platform.log("::updatePowerStateCharacteristic() : ENTER with (deviceId='"+deviceId+"',state='"+state+"')");
-
- // Used when we receive an update from an external source
- var isOn = false;
- var accessory = platform.accessories.get(deviceId);
- if (state == 'on') {
- isOn = true;
- }
- //if (platform.debug) platform.log("::updatePowerStateCharacteristic() : accessory before update: "+JSON.stringify(accessory));
-
- if (platform.debug) platform.log("::updatePowerStateCharacteristic() : Updating recorded Characteristic.On for [%s] to [%s]. No request will be sent to the device.", accessory.context.deviceId, isOn);
- accessory.getService(Service.Switch).setCharacteristic(Characteristic.On, isOn);
- //if (platform.debug) platform.log("::updatePowerStateCharacteristic() : accessory after update: "+JSON.stringify(accessory));
- //platform.updatePowerStateCharacteristic(deviceId, powerState);
- if (platform.debug) platform.log("::updatePowerStateCharacteristic() : EXIT");
-}
-
-
-eWeLink.prototype.getPowerState = function(accessory, callback) {
- var platform = this;
-
- if (this.debug) platform.log("::getPowerState() : ENTER Requesting power state for [%s].", accessory.displayName); //, JSON.stringify(accessory));
-
- (async() => {
- // const device = await platform.connection.getDevice(accessory.context.deviceId);
- var interestedDevice = null;
-/////////////
- const devices = await platform.connection.getDevices();
- //if (platform.debug) platform.log("::getPowerState() : retrieved all devices, found "+devices.length+" devices");
-
- //if (platform.debug) platform.log("::getPowerState() : Looking for interested device");
- devices.forEach((device) => {
-// if (platform.debug) platform.log("::getPowerState() : Found : "+JSON.stringify(device));
- //if (platform.debug) platform.log("::getPowerState() : Looking for " + accessory.context.deviceId + ", but found "+device.deviceid);
- if(accessory.context.deviceId==device.deviceid) {
- //if (platform.debug) platform.log("::getPowerState() : found what I was looking for");
- interestedDevice = device;
- }
- })
-/////////////
- powerState = platform.getStateFromDevice(interestedDevice)
- if (platform.debug) platform.log("::getPowerState() : power state for [%s] is %s", accessory.displayName, powerState);
- this.updatePowerStateCharacteristic(accessory.context.deviceId, powerState);
- if (this.debug) platform.log("::getPowerState() : EXIT");
- })()
- .catch(function(error) {
- platform.log("::getPowerState() : Error in retrieving device\n"+JSON.stringify(error));
- });
-}
-
-eWeLink.prototype.setPowerState = function(accessory, isOn, callback) {
- var platform = this;
- if(platform.debug) platform.log("::setPowerState() : ENTER");
-
- var targetState = 'off';
-
- if (isOn==true || isOn=='on') {
- targetState = 'on';
- }
-
- if (this.debug) platform.log("::setPowerState() : Setting power state to [%s] for device [%s]", targetState, accessory.displayName);
- (async() => {
- const status = await platform.connection.setDevicePowerState(accessory.context.deviceId, targetState);
- if (this.debug) platform.log("::setPowerState() : power state for [%s] is %s", accessory.displayName, JSON.stringify(status));
- //this.updatePowerStateCharacteristic(accessory.context.deviceId, targetState);
- if(platform.debug) platform.log("::setPowerState() : EXIT");
- })().catch(function(error) {
- platform.log("::setPowerState() : Error in retrieving device\n"+JSON.stringify(error));
- });
-}
-
+eWeLink.prototype.addAccessory = function (device) {
+
+ // Here we need to check if it is currently there
+ if (this.accessories.get(device.deviceid)) {
+ this.log("Not adding [%s] as it already exists in the cache", device.deviceid);
+ return;
+ }
+
+ var platform = this;
+
+ if (device.type != 10) {
+ this.log("A device with an unknown type was returned. It will be skipped.", device.type);
+ return;
+ }
+
+ this.log("Found Accessory with Name : [%s], Manufacturer : [%s], Status : [%s], Is Online : [%s], API Key: [%s] ", device.name, device.productModel, this.getStateFromDevice(device), device.online, device.apikey);
+
+ const accessory = new Accessory(device.name, UUIDGen.generate(device.deviceid.toString()));
+
+ accessory.context.deviceId = device.deviceid;
+ accessory.context.apiKey = device.apikey;
+
+ // if (device.online == 'true') {
+ accessory.reachable = true;
+ // } else {
+ // accessory.reachable = false;
+ // }
+
+ accessory.addService(Service.Switch, device.name)
+ .getCharacteristic(Characteristic.On)
+ .on('set', function (value, callback) {
+ platform.setPowerState(accessory, value);
+ callback();
+ })
+ .on('get', function (callback) {
+ platform.getPowerState(accessory);
+ callback();
+ });
+
+ accessory.on('identify', function (paired, callback) {
+ platform.log(accessory.displayName, "Identify not supported");
+ callback();
+ });
+
+ accessory.getService(Service.AccessoryInformation).Characteristic(Characteristic.SerialNumber, device.extra.extra.mac);
+ accessory.getService(Service.AccessoryInformation).setCharacteristic(Characteristic.Manufacturer, device.productModel);
+ accessory.getService(Service.AccessoryInformation).setCharacteristic(Characteristic.Model, device.extra.extra.model);
+ accessory.getService(Service.AccessoryInformation).setCharacteristic(Characteristic.Identify, false);
+ accessory.getService(Service.AccessoryInformation).setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion);
+
+ this.accessories.set(device.deviceid, accessory);
+
+ this.api.registerPlatformAccessories("homebridge-eWeLink",
+ "eWeLink", [accessory]);
+
+};
+
+eWeLink.prototype.getSequence = function () {
+ var time_stamp = new Date() / 1000;
+ this.sequence = Math.floor(time_stamp * 1000);
+ return this.sequence;
+};
+
+eWeLink.prototype.updatePowerStateCharacteristic = function (deviceId, state) {
+ var platform = this;
+ if (platform.debug) platform.log("::updatePowerStateCharacteristic() : ENTER with (deviceId='" + deviceId + "',state='" + state + "')");
+
+ // Used when we receive an update from an external source
+ var isOn = false;
+ var accessory = platform.accessories.get(deviceId);
+ if (state == 'on') {
+ isOn = true;
+ }
+ //if (platform.debug) platform.log("::updatePowerStateCharacteristic() : accessory before update: "+JSON.stringify(accessory));
+
+ if (platform.debug) platform.log("::updatePowerStateCharacteristic() : Updating recorded Characteristic.On for [%s] to [%s]. No request will be sent to the device.", accessory.context.deviceId, isOn);
+ accessory.getService(Service.Switch).setCharacteristic(Characteristic.On, isOn);
+ //if (platform.debug) platform.log("::updatePowerStateCharacteristic() : accessory after update: "+JSON.stringify(accessory));
+ //platform.updatePowerStateCharacteristic(deviceId, powerState);
+ if (platform.debug) platform.log("::updatePowerStateCharacteristic() : EXIT");
+};
+
+eWeLink.prototype.getPowerState = function (accessory, callback) {
+ var platform = this;
+
+ if (this.debug) platform.log("::getPowerState() : ENTER Requesting power state for [%s].", accessory.displayName); //, JSON.stringify(accessory));
+
+ (async () => {
+ // const device = await platform.connection.getDevice(accessory.context.deviceId);
+ var interestedDevice = null;
+ /////////////
+ const devices = await platform.connection.getDevices();
+ //if (platform.debug) platform.log("::getPowerState() : retrieved all devices, found "+devices.length+" devices");
+
+ //if (platform.debug) platform.log("::getPowerState() : Looking for interested device");
+ devices.forEach((device) => {
+ // if (platform.debug) platform.log("::getPowerState() : Found : "+JSON.stringify(device));
+ //if (platform.debug) platform.log("::getPowerState() : Looking for " + accessory.context.deviceId + ", but found "+device.deviceid);
+ if (accessory.context.deviceId == device.deviceid) {
+ //if (platform.debug) platform.log("::getPowerState() : found what I was looking for");
+ interestedDevice = device;
+ }
+ });
+ /////////////
+ let powerState = platform.getStateFromDevice(interestedDevice);
+ if (platform.debug) platform.log("::getPowerState() : power state for [%s] is %s", accessory.displayName, powerState);
+ this.updatePowerStateCharacteristic(accessory.context.deviceId, powerState);
+ if (this.debug) platform.log("::getPowerState() : EXIT");
+ })()
+ .catch(function (error) {
+ platform.log("::getPowerState() : Error in retrieving device\n" + JSON.stringify(error));
+ });
+};
+
+eWeLink.prototype.setPowerState = function (accessory, isOn, callback) {
+ var platform = this;
+ if (platform.debug) platform.log("::setPowerState() : ENTER");
+
+ var targetState = 'off';
+
+ if (isOn == true || isOn == 'on') {
+ targetState = 'on';
+ }
+
+ if (this.debug) platform.log("::setPowerState() : Setting power state to [%s] for device [%s]", targetState, accessory.displayName);
+ (async () => {
+ const status = await platform.connection.setDevicePowerState(accessory.context.deviceId, targetState);
+ if (this.debug) platform.log("::setPowerState() : power state for [%s] is %s", accessory.displayName, JSON.stringify(status));
+ //this.updatePowerStateCharacteristic(accessory.context.deviceId, targetState);
+ if (platform.debug) platform.log("::setPowerState() : EXIT");
+ })().catch(function (error) {
+ platform.log("::setPowerState() : Error in retrieving device\n" + JSON.stringify(error));
+ });
+};
// Sample function to show how developer can remove accessory dynamically from outside event
-eWeLink.prototype.removeAccessory = function(accessory) {
-
- this.log('Removing accessory [%s]', accessory.displayName);
- this.accessories.delete(accessory.context.deviceId);
- this.api.unregisterPlatformAccessories('homebridge-eWeLink', 'eWeLink', [accessory]);
-}
+eWeLink.prototype.removeAccessory = function (accessory) {
+
+ this.log('Removing accessory [%s]', accessory.displayName);
+ this.accessories.delete(accessory.context.deviceId);
+ this.api.unregisterPlatformAccessories('homebridge-eWeLink', 'eWeLink', [accessory]);
+};
\ No newline at end of file
From 9bdc20edf798653f4487f5f298a006f59383720b Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 16 Aug 2020 07:53:58 +0100
Subject: [PATCH 0006/3183] remove unused deps
---
package-lock.json | 382 +---------------------------------------------
package.json | 8 +-
2 files changed, 4 insertions(+), 386 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 6e8d52cf..212a164d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
- "name": "homebridge-ewelink-complete",
- "version": "0.1.11",
+ "name": "homebridge-ewelink",
+ "version": "0.1.76",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -15,16 +15,6 @@
"uri-js": "^4.2.2"
}
},
- "ansi-regex": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
- "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
- },
- "ansi-styles": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
- "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
- },
"arpping": {
"version": "github:skydiver/arpping#ae65410343bdcbddb64b37ac9f674c65af1fe92c",
"from": "github:skydiver/arpping",
@@ -38,39 +28,11 @@
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
"integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y="
},
- "assert-plus": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
- "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ="
- },
- "async": {
- "version": "2.6.0",
- "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz",
- "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==",
- "requires": {
- "lodash": "^4.14.0"
- }
- },
- "async-limiter": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
- "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg=="
- },
"asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
},
- "aws-sign2": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz",
- "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8="
- },
- "aws4": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
- "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4="
- },
"babel-runtime": {
"version": "6.26.0",
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
@@ -89,44 +51,11 @@
"tweetnacl": "^0.14.3"
}
},
- "bl": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/bl/-/bl-1.1.2.tgz",
- "integrity": "sha1-/cqHGplxOqANGeO7ukHER4emU5g=",
- "requires": {
- "readable-stream": "~2.0.5"
- }
- },
"bluebird": {
"version": "3.7.2",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
"integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="
},
- "boom": {
- "version": "2.10.1",
- "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
- "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
- "requires": {
- "hoek": "2.x.x"
- }
- },
- "caseless": {
- "version": "0.11.0",
- "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz",
- "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c="
- },
- "chalk": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
- "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
- "requires": {
- "ansi-styles": "^2.2.1",
- "escape-string-regexp": "^1.0.2",
- "has-ansi": "^2.0.0",
- "strip-ansi": "^3.0.0",
- "supports-color": "^2.0.0"
- }
- },
"child_process": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/child_process/-/child_process-1.0.2.tgz",
@@ -137,19 +66,6 @@
"resolved": "https://registry.npmjs.org/chnl/-/chnl-0.5.0.tgz",
"integrity": "sha512-0dl4ZJfAZdLn9mDnWejs5nasZKVnDTwdXV+dkxodYbb//GJDtXNhPlqCCYUb1xF0NQpIB5zlHRDrU1RCB4BRog=="
},
- "combined-stream": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
- "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=",
- "requires": {
- "delayed-stream": "~1.0.0"
- }
- },
- "commander": {
- "version": "2.12.2",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.12.2.tgz",
- "integrity": "sha512-BFnaq5ZOGcDN7FlrtBT4xxkgIToalIIxwjxLWVJ8bGTpe1LroqMiqQXdA7ygc7CRvaYS+9zfPGFnJqFSayx+AA=="
- },
"core-js": {
"version": "2.6.11",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz",
@@ -160,14 +76,6 @@
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
},
- "cryptiles": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
- "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=",
- "requires": {
- "boom": "2.x.x"
- }
- },
"crypto-js": {
"version": "3.1.9-1",
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.1.9-1.tgz",
@@ -223,11 +131,6 @@
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
},
- "depd": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.0.tgz",
- "integrity": "sha1-4b2Cxqq2ztlluXuIsX7T5SjKGMM="
- },
"ecc-jsbn": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
@@ -294,11 +197,6 @@
"ext": "^1.1.2"
}
},
- "escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
- },
"ewelink-api": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ewelink-api/-/ewelink-api-2.0.0.tgz",
@@ -466,11 +364,6 @@
}
}
},
- "extend": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
- "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ="
- },
"extsprintf": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
@@ -496,34 +389,11 @@
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
"integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
},
- "form-data": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-1.0.1.tgz",
- "integrity": "sha1-rjFduaSQf6BlUCMEpm13M0de43w=",
- "requires": {
- "async": "^2.0.1",
- "combined-stream": "^1.0.5",
- "mime-types": "^2.1.11"
- }
- },
"function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
},
- "generate-function": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz",
- "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ="
- },
- "generate-object-property": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz",
- "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=",
- "requires": {
- "is-property": "^1.0.0"
- }
- },
"getpass": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
@@ -544,17 +414,6 @@
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
"integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
},
- "har-validator": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz",
- "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=",
- "requires": {
- "chalk": "^1.1.1",
- "commander": "^2.9.0",
- "is-my-json-valid": "^2.12.4",
- "pinkie-promise": "^2.0.0"
- }
- },
"has": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
@@ -563,50 +422,11 @@
"function-bind": "^1.1.1"
}
},
- "has-ansi": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
- "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
- "requires": {
- "ansi-regex": "^2.0.0"
- }
- },
"has-symbols": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
"integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg=="
},
- "hawk": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
- "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=",
- "requires": {
- "boom": "2.x.x",
- "cryptiles": "2.x.x",
- "hoek": "2.x.x",
- "sntp": "1.x.x"
- }
- },
- "hoek": {
- "version": "2.16.3",
- "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
- "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0="
- },
- "http-signature": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz",
- "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=",
- "requires": {
- "assert-plus": "^0.2.0",
- "jsprim": "^1.2.2",
- "sshpk": "^1.7.0"
- }
- },
- "inherits": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
- "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
- },
"is-callable": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz",
@@ -617,22 +437,6 @@
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz",
"integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g=="
},
- "is-my-json-valid": {
- "version": "2.16.1",
- "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz",
- "integrity": "sha512-ochPsqWS1WXj8ZnMIV0vnNXooaMhp7cyL4FMSIPKTtnV0Ha/T19G2b9kkhcNsabV9bxYkze7/aLZJb/bYuFduQ==",
- "requires": {
- "generate-function": "^2.0.0",
- "generate-object-property": "^1.1.0",
- "jsonpointer": "^4.0.0",
- "xtend": "^4.0.0"
- }
- },
- "is-property": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
- "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ="
- },
"is-regex": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz",
@@ -654,11 +458,6 @@
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
},
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
- },
"isstream": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
@@ -685,11 +484,6 @@
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
},
- "jsonpointer": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz",
- "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk="
- },
"jsprim": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
@@ -708,24 +502,6 @@
}
}
},
- "lodash": {
- "version": "4.17.4",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
- "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
- },
- "mime-db": {
- "version": "1.30.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz",
- "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE="
- },
- "mime-types": {
- "version": "2.1.17",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz",
- "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=",
- "requires": {
- "mime-db": "~1.30.0"
- }
- },
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
@@ -741,26 +517,11 @@
"resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
"integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw="
},
- "node-uuid": {
- "version": "1.4.8",
- "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz",
- "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc="
- },
"nonce": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/nonce/-/nonce-1.0.4.tgz",
"integrity": "sha1-7nMCrejBvvR28wG4yR9cxRpIdhI="
},
- "npmrc": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/npmrc/-/npmrc-1.1.1.tgz",
- "integrity": "sha1-KBupOt6FxN4rBGEQMfL/LyTmId0="
- },
- "oauth-sign": {
- "version": "0.8.2",
- "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
- "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM="
- },
"object-inspect": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz",
@@ -802,24 +563,6 @@
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
},
- "pinkie": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
- "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA="
- },
- "pinkie-promise": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
- "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
- "requires": {
- "pinkie": "^2.0.0"
- }
- },
- "process-nextick-args": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
- "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M="
- },
"promise-controller": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/promise-controller/-/promise-controller-0.5.2.tgz",
@@ -845,11 +588,6 @@
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
"integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
},
- "qs": {
- "version": "6.2.3",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.3.tgz",
- "integrity": "sha1-HPyyXBCpsrSDBT/zn138kjOQjP4="
- },
"random": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/random/-/random-2.1.1.tgz",
@@ -861,61 +599,11 @@
"seedrandom": "^2.4.4"
}
},
- "readable-stream": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz",
- "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=",
- "requires": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.1",
- "isarray": "~1.0.0",
- "process-nextick-args": "~1.0.6",
- "string_decoder": "~0.10.x",
- "util-deprecate": "~1.0.1"
- }
- },
"regenerator-runtime": {
"version": "0.11.1",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
"integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg=="
},
- "request": {
- "version": "2.74.0",
- "resolved": "https://registry.npmjs.org/request/-/request-2.74.0.tgz",
- "integrity": "sha1-dpPKdou7DqXIzgjAhKRe+gW4kqs=",
- "requires": {
- "aws-sign2": "~0.6.0",
- "aws4": "^1.2.1",
- "bl": "~1.1.2",
- "caseless": "~0.11.0",
- "combined-stream": "~1.0.5",
- "extend": "~3.0.0",
- "forever-agent": "~0.6.1",
- "form-data": "~1.0.0-rc4",
- "har-validator": "~2.0.6",
- "hawk": "~3.1.3",
- "http-signature": "~1.1.0",
- "is-typedarray": "~1.0.0",
- "isstream": "~0.1.2",
- "json-stringify-safe": "~5.0.1",
- "mime-types": "~2.1.7",
- "node-uuid": "~1.4.7",
- "oauth-sign": "~0.8.1",
- "qs": "~6.2.0",
- "stringstream": "~0.0.4",
- "tough-cookie": "~2.3.0",
- "tunnel-agent": "~0.4.1"
- }
- },
- "request-json": {
- "version": "0.6.2",
- "resolved": "https://registry.npmjs.org/request-json/-/request-json-0.6.2.tgz",
- "integrity": "sha1-KMdtBdYMU8nhjUCXywFyO5UGkyI=",
- "requires": {
- "depd": "1.1.0",
- "request": "2.74.0"
- }
- },
"request-promise": {
"version": "4.2.5",
"resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.5.tgz",
@@ -942,24 +630,11 @@
}
}
},
- "safe-buffer": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
- "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
- },
"seedrandom": {
"version": "2.4.4",
"resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-2.4.4.tgz",
"integrity": "sha512-9A+PDmgm+2du77B5i0Ip2cxOqqHjgNxnBgglxLcX78A2D6c2rTo61z4jnVABpF4cKeDMDG+cmXXvdnqse2VqMA=="
},
- "sntp": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
- "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=",
- "requires": {
- "hoek": "2.x.x"
- }
- },
"sshpk": {
"version": "1.13.1",
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz",
@@ -1005,29 +680,6 @@
"function-bind": "^1.1.1"
}
},
- "string_decoder": {
- "version": "0.10.31",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
- "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
- },
- "stringstream": {
- "version": "0.0.5",
- "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
- "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg="
- },
- "strip-ansi": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
- "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
- "requires": {
- "ansi-regex": "^2.0.0"
- }
- },
- "supports-color": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
- "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
- },
"tough-cookie": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz",
@@ -1036,11 +688,6 @@
"punycode": "^1.4.1"
}
},
- "tunnel-agent": {
- "version": "0.4.3",
- "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz",
- "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us="
- },
"tweetnacl": {
"version": "0.14.5",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
@@ -1060,11 +707,6 @@
"is-typedarray": "^1.0.0"
}
},
- "ultron": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz",
- "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og=="
- },
"uri-js": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
@@ -1080,11 +722,6 @@
}
}
},
- "util-deprecate": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
- },
"uuid": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
@@ -1130,21 +767,6 @@
"promise.prototype.finally": "^3.1.0"
}
},
- "ws": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.2.tgz",
- "integrity": "sha512-t+WGpsNxhMR4v6EClXS8r8km5ZljKJzyGhJf7goJz9k5Ye3+b5Bvno5rjqPuIBn5mnn5GBb7o8IrIWHxX1qOLQ==",
- "requires": {
- "async-limiter": "~1.0.0",
- "safe-buffer": "~5.1.0",
- "ultron": "~1.1.0"
- }
- },
- "xtend": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
- "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68="
- },
"yaeti": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz",
diff --git a/package.json b/package.json
index b66653c9..94e0b697 100644
--- a/package.json
+++ b/package.json
@@ -13,13 +13,9 @@
},
"repository": {
"type": "git",
- "url": "https://github.com/gbro115/homebridge-ewelink.git"
+ "url": "https://github.com/bwp91/homebridge-ewelink.git"
},
"dependencies": {
- "ewelink-api": "^2.0.0",
- "nonce": "^1.0.4",
- "npmrc": "^1.1.1",
- "request-json": "^0.6.2",
- "ws": "^3.3.2"
+ "ewelink-api": "^2.0.0"
}
}
From 6fe3d2b23685ba2e6f2178284b39e7a7e032eb9f Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 16 Aug 2020 08:02:00 +0100
Subject: [PATCH 0007/3183] update ewelink-api
---
package-lock.json | 550 ++++++----------------------------------------
package.json | 2 +-
2 files changed, 68 insertions(+), 484 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 212a164d..94d0313e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4,17 +4,6 @@
"lockfileVersion": 1,
"requires": true,
"dependencies": {
- "ajv": {
- "version": "6.11.0",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.11.0.tgz",
- "integrity": "sha512-nCprB/0syFYy9fVYU1ox1l2KN8S9I+tziH8D4zdZuLT3N6RMlGSGt5FSTpAiHB/Whv8Qs1cWHma1aMKZyaHRKA==",
- "requires": {
- "fast-deep-equal": "^3.1.1",
- "fast-json-stable-stringify": "^2.0.0",
- "json-schema-traverse": "^0.4.1",
- "uri-js": "^4.2.2"
- }
- },
"arpping": {
"version": "github:skydiver/arpping#ae65410343bdcbddb64b37ac9f674c65af1fe92c",
"from": "github:skydiver/arpping",
@@ -23,16 +12,6 @@
"os": "^0.1.1"
}
},
- "asn1": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
- "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y="
- },
- "asynckit": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
- "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
- },
"babel-runtime": {
"version": "6.26.0",
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
@@ -42,44 +21,25 @@
"regenerator-runtime": "^0.11.0"
}
},
- "bcrypt-pbkdf": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
- "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
- "optional": true,
- "requires": {
- "tweetnacl": "^0.14.3"
- }
- },
- "bluebird": {
- "version": "3.7.2",
- "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
- "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="
- },
"child_process": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/child_process/-/child_process-1.0.2.tgz",
"integrity": "sha1-sffn/HPSXn/R1FWtyU4UODAYK1o="
},
"chnl": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/chnl/-/chnl-0.5.0.tgz",
- "integrity": "sha512-0dl4ZJfAZdLn9mDnWejs5nasZKVnDTwdXV+dkxodYbb//GJDtXNhPlqCCYUb1xF0NQpIB5zlHRDrU1RCB4BRog=="
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/chnl/-/chnl-1.2.0.tgz",
+ "integrity": "sha512-g5gJb59edwCliFbX2j7G6sBfY4sX9YLy211yctONI2GRaiX0f2zIbKWmBm+sPqFNEpM7Ljzm7IJX/xrjiEbPrw=="
},
"core-js": {
"version": "2.6.11",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz",
"integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg=="
},
- "core-util-is": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
- "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
- },
"crypto-js": {
- "version": "3.1.9-1",
- "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.1.9-1.tgz",
- "integrity": "sha1-/aGedh/Ad+Af+/3G6f38WeiAbNg="
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.0.0.tgz",
+ "integrity": "sha512-bzHZN8Pn+gS7DQA6n+iUmBfl0hO5DJq++QP3U6uTucDtk/0iGpXd/Gg7CGR0p8tJhofJyaKoWBuJI4eAO00BBg=="
},
"d": {
"version": "1.0.1",
@@ -90,21 +50,6 @@
"type": "^1.0.1"
}
},
- "dashdash": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
- "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
- "requires": {
- "assert-plus": "^1.0.0"
- },
- "dependencies": {
- "assert-plus": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
- "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
- }
- }
- },
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@@ -122,40 +67,26 @@
}
},
"delay": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/delay/-/delay-4.3.0.tgz",
- "integrity": "sha512-Lwaf3zVFDMBop1yDuFZ19F9WyGcZcGacsbdlZtWjQmM50tOcMntm1njF/Nb/Vjij3KaSvCF+sEYGKrrjObu2NA=="
- },
- "delayed-stream": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
- "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
- },
- "ecc-jsbn": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
- "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
- "optional": true,
- "requires": {
- "jsbn": "~0.1.0"
- }
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/delay/-/delay-4.4.0.tgz",
+ "integrity": "sha512-txgOrJu3OdtOfTiEOT2e76dJVfG/1dz2NZ4F0Pyt4UGZJryssMRp5vdM5wQoLwSOBNdrJv3F9PAhp/heqd7vrA=="
},
"es-abstract": {
- "version": "1.17.4",
- "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz",
- "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==",
+ "version": "1.17.6",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz",
+ "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==",
"requires": {
"es-to-primitive": "^1.2.1",
"function-bind": "^1.1.1",
"has": "^1.0.3",
"has-symbols": "^1.0.1",
- "is-callable": "^1.1.5",
- "is-regex": "^1.0.5",
+ "is-callable": "^1.2.0",
+ "is-regex": "^1.1.0",
"object-inspect": "^1.7.0",
"object-keys": "^1.1.1",
"object.assign": "^4.1.0",
- "string.prototype.trimleft": "^2.1.1",
- "string.prototype.trimright": "^2.1.1"
+ "string.prototype.trimend": "^1.0.1",
+ "string.prototype.trimstart": "^1.0.1"
}
},
"es-to-primitive": {
@@ -198,155 +129,17 @@
}
},
"ewelink-api": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ewelink-api/-/ewelink-api-2.0.0.tgz",
- "integrity": "sha512-VcIs2PBK2F0RckZAOvZHcPb8ZpLz4eQclFPmHNZFABI/0XGG3UJw+Ev4LGDz9AkAUFHkSc29LM3hRWlfmNdWgQ==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ewelink-api/-/ewelink-api-3.0.0.tgz",
+ "integrity": "sha512-W60dGUIPnV8b/ckCKRAi+0mYyIYil/YrkVrAknlf6CtnivHIVxvcQPUxQPOX6ctWzK10n+ACAh8V7uOok1rjMA==",
"requires": {
"arpping": "github:skydiver/arpping",
- "crypto-js": "^3.1.9-1",
+ "crypto-js": "^4.0.0",
"delay": "^4.3.0",
- "nonce": "^1.0.4",
- "random": "^2.1.1",
- "request": "^2.88.0",
- "request-promise": "^4.2.4",
- "websocket": "^1.0.30",
- "websocket-as-promised": "^0.10.1"
- },
- "dependencies": {
- "assert-plus": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
- "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
- },
- "aws-sign2": {
- "version": "0.7.0",
- "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
- "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
- },
- "aws4": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz",
- "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug=="
- },
- "caseless": {
- "version": "0.12.0",
- "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
- "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
- },
- "combined-stream": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
- "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
- "requires": {
- "delayed-stream": "~1.0.0"
- }
- },
- "extend": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
- "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
- },
- "form-data": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
- "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
- "requires": {
- "asynckit": "^0.4.0",
- "combined-stream": "^1.0.6",
- "mime-types": "^2.1.12"
- }
- },
- "har-validator": {
- "version": "5.1.3",
- "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
- "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
- "requires": {
- "ajv": "^6.5.5",
- "har-schema": "^2.0.0"
- }
- },
- "http-signature": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
- "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
- "requires": {
- "assert-plus": "^1.0.0",
- "jsprim": "^1.2.2",
- "sshpk": "^1.7.0"
- }
- },
- "mime-db": {
- "version": "1.43.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz",
- "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ=="
- },
- "mime-types": {
- "version": "2.1.26",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz",
- "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==",
- "requires": {
- "mime-db": "1.43.0"
- }
- },
- "oauth-sign": {
- "version": "0.9.0",
- "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
- "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
- },
- "qs": {
- "version": "6.5.2",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
- "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
- },
- "request": {
- "version": "2.88.0",
- "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
- "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
- "requires": {
- "aws-sign2": "~0.7.0",
- "aws4": "^1.8.0",
- "caseless": "~0.12.0",
- "combined-stream": "~1.0.6",
- "extend": "~3.0.2",
- "forever-agent": "~0.6.1",
- "form-data": "~2.3.2",
- "har-validator": "~5.1.0",
- "http-signature": "~1.2.0",
- "is-typedarray": "~1.0.0",
- "isstream": "~0.1.2",
- "json-stringify-safe": "~5.0.1",
- "mime-types": "~2.1.19",
- "oauth-sign": "~0.9.0",
- "performance-now": "^2.1.0",
- "qs": "~6.5.2",
- "safe-buffer": "^5.1.2",
- "tough-cookie": "~2.4.3",
- "tunnel-agent": "^0.6.0",
- "uuid": "^3.3.2"
- }
- },
- "safe-buffer": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
- "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg=="
- },
- "tough-cookie": {
- "version": "2.4.3",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
- "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
- "requires": {
- "psl": "^1.1.24",
- "punycode": "^1.4.1"
- }
- },
- "tunnel-agent": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
- "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
- "requires": {
- "safe-buffer": "^5.0.1"
- }
- }
+ "node-fetch": "^2.6.0",
+ "random": "^2.2.0",
+ "websocket": "^1.0.31",
+ "websocket-as-promised": "^1.0.1"
}
},
"ext": {
@@ -364,56 +157,11 @@
}
}
},
- "extsprintf": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
- "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
- },
- "fast-deep-equal": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz",
- "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA=="
- },
- "fast-json-stable-stringify": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
- "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
- },
- "flat-options": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/flat-options/-/flat-options-0.1.3.tgz",
- "integrity": "sha512-z1vH9mb4ly55dWUZZFUeLNqhFWhwSQNngHpK8RQOhFuNw/sWcNDZhkHl3GS1YTHiYxB5qvcbSRbH7X6ThzX9UA=="
- },
- "forever-agent": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
- "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
- },
"function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
},
- "getpass": {
- "version": "0.1.7",
- "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
- "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
- "requires": {
- "assert-plus": "^1.0.0"
- },
- "dependencies": {
- "assert-plus": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
- "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
- }
- }
- },
- "har-schema": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
- "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
- },
"has": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
@@ -428,9 +176,9 @@
"integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg=="
},
"is-callable": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz",
- "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q=="
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz",
+ "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw=="
},
"is-date-object": {
"version": "1.0.2",
@@ -438,11 +186,11 @@
"integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g=="
},
"is-regex": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz",
- "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz",
+ "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==",
"requires": {
- "has": "^1.0.3"
+ "has-symbols": "^1.0.1"
}
},
"is-symbol": {
@@ -458,74 +206,30 @@
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
},
- "isstream": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
- "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
- },
- "jsbn": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
- "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
- "optional": true
- },
- "json-schema": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
- "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
- },
- "json-schema-traverse": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
- "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
- },
- "json-stringify-safe": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
- "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
- },
- "jsprim": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
- "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
- "requires": {
- "assert-plus": "1.0.0",
- "extsprintf": "1.3.0",
- "json-schema": "0.2.3",
- "verror": "1.10.0"
- },
- "dependencies": {
- "assert-plus": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
- "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
- }
- }
- },
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
},
"nan": {
- "version": "2.14.0",
- "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz",
- "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg=="
+ "version": "2.14.1",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz",
+ "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw=="
},
"next-tick": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
"integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw="
},
- "nonce": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/nonce/-/nonce-1.0.4.tgz",
- "integrity": "sha1-7nMCrejBvvR28wG4yR9cxRpIdhI="
+ "node-fetch": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
+ "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA=="
},
"object-inspect": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz",
- "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw=="
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz",
+ "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA=="
},
"object-keys": {
"version": "1.1.1",
@@ -558,15 +262,10 @@
"resolved": "https://registry.npmjs.org/ow-lite/-/ow-lite-0.0.2.tgz",
"integrity": "sha1-359QDmdAtlkKHpqWVzDUmo61l9E="
},
- "performance-now": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
- "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
- },
"promise-controller": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/promise-controller/-/promise-controller-0.5.2.tgz",
- "integrity": "sha512-ymVCGfCxN+A+6TqESLnGZhGfQdQJ08SpIMyft4xQPUDrOgoqzKcQnLIYaqQk7/rPyg4wpKpxBKefeGkvumWgUg=="
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/promise-controller/-/promise-controller-1.0.0.tgz",
+ "integrity": "sha512-goA0zA9L91tuQbUmiMinSYqlyUtEgg4fxJcjYnLYOQnrktb4o4UqciXDNXiRUPiDBPACmsr1k8jDW4r7UDq9Qw=="
},
"promise.prototype.finally": {
"version": "3.1.2",
@@ -578,25 +277,15 @@
"function-bind": "^1.1.1"
}
},
- "psl": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/psl/-/psl-1.7.0.tgz",
- "integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ=="
- },
- "punycode": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
- "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
- },
"random": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/random/-/random-2.1.1.tgz",
- "integrity": "sha512-8HQriGPwjc8R+7hPOI9ZphAEEWmIt/RmuqXZ682ww9kjK5HRGXcN7hgWUxZ9AabgjZm5wIa6EwapTI1sg11XXg==",
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/random/-/random-2.2.0.tgz",
+ "integrity": "sha512-4HBR4Xye4jJ41QBi6RfIaO1yKQpxVUZafQtdE6NvvjzirNlwWgsk3tkGLTbQtWUarF4ofZsUVEmWqB1TDQlkwA==",
"requires": {
"babel-runtime": "^6.26.0",
"ow": "^0.4.0",
"ow-lite": "^0.0.2",
- "seedrandom": "^2.4.4"
+ "seedrandom": "^3.0.5"
}
},
"regenerator-runtime": {
@@ -604,96 +293,29 @@
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
"integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg=="
},
- "request-promise": {
- "version": "4.2.5",
- "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.5.tgz",
- "integrity": "sha512-ZgnepCykFdmpq86fKGwqntyTiUrHycALuGggpyCZwMvGaZWgxW6yagT0FHkgo5LzYvOaCNvxYwWYIjevSH1EDg==",
- "requires": {
- "bluebird": "^3.5.0",
- "request-promise-core": "1.1.3",
- "stealthy-require": "^1.1.1",
- "tough-cookie": "^2.3.3"
- }
- },
- "request-promise-core": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz",
- "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==",
- "requires": {
- "lodash": "^4.17.15"
- },
- "dependencies": {
- "lodash": {
- "version": "4.17.15",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
- "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
- }
- }
- },
"seedrandom": {
- "version": "2.4.4",
- "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-2.4.4.tgz",
- "integrity": "sha512-9A+PDmgm+2du77B5i0Ip2cxOqqHjgNxnBgglxLcX78A2D6c2rTo61z4jnVABpF4cKeDMDG+cmXXvdnqse2VqMA=="
- },
- "sshpk": {
- "version": "1.13.1",
- "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz",
- "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=",
- "requires": {
- "asn1": "~0.2.3",
- "assert-plus": "^1.0.0",
- "bcrypt-pbkdf": "^1.0.0",
- "dashdash": "^1.12.0",
- "ecc-jsbn": "~0.1.1",
- "getpass": "^0.1.1",
- "jsbn": "~0.1.0",
- "tweetnacl": "~0.14.0"
- },
- "dependencies": {
- "assert-plus": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
- "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
- }
- }
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz",
+ "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg=="
},
- "stealthy-require": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
- "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks="
- },
- "string.prototype.trimleft": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz",
- "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==",
+ "string.prototype.trimend": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz",
+ "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==",
"requires": {
"define-properties": "^1.1.3",
- "function-bind": "^1.1.1"
+ "es-abstract": "^1.17.5"
}
},
- "string.prototype.trimright": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz",
- "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==",
+ "string.prototype.trimstart": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz",
+ "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==",
"requires": {
"define-properties": "^1.1.3",
- "function-bind": "^1.1.1"
+ "es-abstract": "^1.17.5"
}
},
- "tough-cookie": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz",
- "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=",
- "requires": {
- "punycode": "^1.4.1"
- }
- },
- "tweetnacl": {
- "version": "0.14.5",
- "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
- "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
- "optional": true
- },
"type": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
@@ -707,43 +329,6 @@
"is-typedarray": "^1.0.0"
}
},
- "uri-js": {
- "version": "4.2.2",
- "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
- "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
- "requires": {
- "punycode": "^2.1.0"
- },
- "dependencies": {
- "punycode": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
- "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
- }
- }
- },
- "uuid": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
- "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
- },
- "verror": {
- "version": "1.10.0",
- "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
- "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
- "requires": {
- "assert-plus": "^1.0.0",
- "core-util-is": "1.0.2",
- "extsprintf": "^1.2.0"
- },
- "dependencies": {
- "assert-plus": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
- "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
- }
- }
- },
"websocket": {
"version": "1.0.31",
"resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.31.tgz",
@@ -757,14 +342,13 @@
}
},
"websocket-as-promised": {
- "version": "0.10.1",
- "resolved": "https://registry.npmjs.org/websocket-as-promised/-/websocket-as-promised-0.10.1.tgz",
- "integrity": "sha512-hKAZPSIGaao4WPoporPkDQpKl9jz0I0Hh9x/Dn05k6u//e44+0rAhMam4/gvBlYZl02wJYELD561bAenyxwJJQ==",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/websocket-as-promised/-/websocket-as-promised-1.0.1.tgz",
+ "integrity": "sha512-+gBevna4yxisb8cigL8NxcS8s241cvfMeyy1fNFcFgBcX/6vknMT84MwMmBNLYmsYH2giVoxOSEiAeeb7txFOw==",
"requires": {
- "chnl": "^0.5.0",
- "flat-options": "^0.1.3",
- "promise-controller": "^0.5.2",
- "promise.prototype.finally": "^3.1.0"
+ "chnl": "^1.0.0",
+ "promise-controller": "^1.0.0",
+ "promise.prototype.finally": "^3.1.1"
}
},
"yaeti": {
diff --git a/package.json b/package.json
index 94e0b697..cb41333c 100644
--- a/package.json
+++ b/package.json
@@ -16,6 +16,6 @@
"url": "https://github.com/bwp91/homebridge-ewelink.git"
},
"dependencies": {
- "ewelink-api": "^2.0.0"
+ "ewelink-api": "^3.0.0"
}
}
From 3d00c1873e3b98f0b7fedd9e65fb29611b2bd24a Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 16 Aug 2020 08:34:24 +0100
Subject: [PATCH 0008/3183] .github
---
.github/FUNDING.yml | 2 ++
.github/ISSUE_TEMPLATE/feature-request.md | 20 ++++++++++++++++++++
.github/ISSUE_TEMPLATE/new-issue.md | 20 ++++++++++++++++++++
3 files changed, 42 insertions(+)
create mode 100644 .github/FUNDING.yml
create mode 100644 .github/ISSUE_TEMPLATE/feature-request.md
create mode 100644 .github/ISSUE_TEMPLATE/new-issue.md
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 00000000..addfcd2d
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,2 @@
+patreon: bwp91
+custom: ["https://www.paypal.me/BenPotter"]
diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md
new file mode 100644
index 00000000..47b2c95b
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature-request.md
@@ -0,0 +1,20 @@
+---
+name: Feature Request
+about: I have an idea for the package!
+title: ''
+labels: ''
+assignees: ''
+
+---
+
+**Please explain your feature request in one sentence.**
+...
+
+**Is your feature request related to a problem? Please describe.**
+...
+
+**Any particular Sonoff devices that this relates to?**
+...
+
+**Anything else?**
+...
diff --git a/.github/ISSUE_TEMPLATE/new-issue.md b/.github/ISSUE_TEMPLATE/new-issue.md
new file mode 100644
index 00000000..44f070df
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/new-issue.md
@@ -0,0 +1,20 @@
+---
+name: New Issue
+about: I have a problem with the package!
+title: ''
+labels: ''
+assignees: ''
+
+---
+
+**What issue do you have? Please be as thorough and explicit as possible.**
+
+...
+
+**Which version of the package are you using?**
+
+...
+
+**Please paste any relevant logs below. It helps if you can turn `debug` and `debugReqRes` in the package settings for more thorough logging.**
+
+...
From 2f47c90df01e87653f0eac31e548a955dd54cfe9 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 16 Aug 2020 08:38:27 +0100
Subject: [PATCH 0009/3183] align with ewelink-sonoff
---
.gitignore | 6 +-
.npmignore | 5 +
LICENSE | 4 +-
config.schema.json | 322 ++++++++
index.js | 359 +--------
lib/constants.js | 119 +++
lib/eWeLink.js | 1825 ++++++++++++++++++++++++++++++++++++++++++++
lib/eWeLinkHTTP.js | 158 ++++
lib/eWeLinkLAN.js | 157 ++++
lib/eWeLinkWS.js | 271 +++++++
package-lock.json | 412 ++--------
package.json | 74 +-
12 files changed, 2979 insertions(+), 733 deletions(-)
create mode 100644 .npmignore
create mode 100644 config.schema.json
create mode 100644 lib/constants.js
create mode 100644 lib/eWeLink.js
create mode 100644 lib/eWeLinkHTTP.js
create mode 100644 lib/eWeLinkLAN.js
create mode 100644 lib/eWeLinkWS.js
diff --git a/.gitignore b/.gitignore
index 3c3629e6..45fb205e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,5 @@
-node_modules
+.DS_Store
+.nova
+.github
+.npm
+node_modules/
\ No newline at end of file
diff --git a/.npmignore b/.npmignore
new file mode 100644
index 00000000..45fb205e
--- /dev/null
+++ b/.npmignore
@@ -0,0 +1,5 @@
+.DS_Store
+.nova
+.github
+.npm
+node_modules/
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
index 85986b7d..23e8aaa0 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2017 George
+Copyright (c) 2020 Ben Potter
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+SOFTWARE.
\ No newline at end of file
diff --git a/config.schema.json b/config.schema.json
new file mode 100644
index 00000000..b8a7a5cf
--- /dev/null
+++ b/config.schema.json
@@ -0,0 +1,322 @@
+{
+ "pluginAlias":"eWeLink",
+ "pluginType":"platform",
+ "singular":true,
+ "headerDisplay":"Homebridge plugin to control Sonoff devices with OEM firmware.",
+ "footerDisplay":"If you have any suggestions, please open an issue on [GitHub](https://github.com/bwp91/homebridge-ewelink/issues).",
+ "schema":{
+ "type":"object",
+ "properties":{
+ "name":{
+ "type":"string",
+ "default":"eWeLink"
+ },
+ "countryCode":{
+ "type":"string",
+ "title":"Country Code",
+ "description":"The telephone country code linked to your eWeLink account (without the +)."
+ },
+ "username":{
+ "type":"string",
+ "title":"Username",
+ "description":"The phone number or email address linked to your eWeLink account. If you use a phone number please enter the country code (with the +), for example +8613185260282."
+ },
+ "password":{
+ "type":"string",
+ "title":"Password",
+ "description":"The password for your eWeLink account."
+ },
+ "debug":{
+ "title":"Debug Logging",
+ "type":"boolean",
+ "required":true,
+ "description":"If enabled, more information will be added to the Homebridge log.",
+ "default":false
+ },
+ "debugReqRes":{
+ "title":"Request & Response Logging",
+ "type":"boolean",
+ "required":true,
+ "description":"If enabled, HTTP, web socket and LAN mode messages will be added to the log. Not recommended for long-term use.",
+ "default":false
+ },
+ "mode":{
+ "type":"string",
+ "title":"Connection Mode",
+ "required":true,
+ "default":"ws",
+ "description":"Preferred method of updating devices. Devices that don't support LAN mode will use web socket.",
+ "oneOf":[
+ {
+ "title":"LAN Mode (Recommended)",
+ "enum":[
+ "lan"
+ ]
+ },
+ {
+ "title":"Web Socket",
+ "enum":[
+ "ws"
+ ]
+ }
+ ]
+ },
+ "hideDevFromHB":{
+ "type":"string",
+ "title":"Hide Devices",
+ "description":"A list of eWeLink devices to hide from Homebridge. For example '10009553c8' or multiple devices separated with a comma '10009553c8,10009553c9'.",
+ "default":""
+ },
+ "hideFromHB":{
+ "type":"string",
+ "title":"Hide Device Channels",
+ "description":"A list of device channels to hide from Homebridge. For example '10009553c8SW1' or multiple channels separated with a comma '10009553c8SW1,10009553c9SW2'. Only channels from switches, lights and irrigation valves can be hidden.",
+ "default":""
+ },
+ "sensorTimeLength":{
+ "type":"integer",
+ "title":"Sensor Length",
+ "description":"The number of seconds which the sensor tile in the Home app will light up for if a sensor detects something.",
+ "default":"2",
+ "maximum":999
+ },
+ "sensorTimeDifference":{
+ "type":"integer",
+ "title":"Sensor Lag",
+ "description":"An offset in seconds to ignore any notifications if they is a delay between a sensor detecting something and Homebridge receiving the notification.",
+ "default":"120",
+ "maximum":999
+ },
+ "valveTimeLength":{
+ "type":"integer",
+ "title":"Valve Duration",
+ "description":"The default number of seconds that irrigation valves will run for.",
+ "default":"20",
+ "maximum":999
+ },
+ "hideZBLDPress":{
+ "title":"Hide Double/Long Press",
+ "type":"boolean",
+ "description":"If enabled, double and long press options will be hidden for the ZigBee button.",
+ "default":false
+ },
+ "groups":{
+ "type":"array",
+ "title":"Custom Groups",
+ "description":"You can group channels of Sonoff devices to simulate another HomeKit accessory instead of having each switch separately. Currently only blinds and garage doors are supported.",
+ "items":{
+ "type":"object",
+ "properties":{
+ "type":{
+ "type":"string",
+ "title":"Type",
+ "default":"null",
+ "description":"A description of this group.",
+ "oneOf":[
+ {
+ "title":"Blind",
+ "enum":[
+ "blind"
+ ]
+ },
+ {
+ "title":"Garage Door",
+ "enum":[
+ "garage"
+ ]
+ }
+ ]
+ },
+ "deviceId":{
+ "type":"string",
+ "title":"Device ID",
+ "description":"Device ID from your eWeLink app (ten digits normally in the format 1000******)."
+ },
+ "setup":{
+ "type":"string",
+ "title":"Device Setup",
+ "default":"null",
+ "description":"The device setup.",
+ "oneOf":[
+ {
+ "title":"One Switch - for up and down",
+ "enum":[
+ "oneSwitch"
+ ]
+ },
+ {
+ "title":"Two Switches - one for up and one for down",
+ "enum":[
+ "twoSwitch"
+ ]
+ }
+ ]
+ },
+ "operationTime":{
+ "type":"number",
+ "title":"Operation Time",
+ "description":"Total time in deciseconds to fully open/close the blind/door. Count the time in seconds and multiply by 10, for example 100 for 10 seconds or 75 for 7.5 seconds.",
+ "default":100
+ },
+ "inched":{
+ "title":"Device Inching",
+ "type":"boolean",
+ "description":"If device inching is already setup in your eWeLink account then set this to true. Otherwise this plugin will send an 'off' command after half a second to mimic the inching behaviour.",
+ "default":true
+ },
+ "sensorId":{
+ "type":"string",
+ "title":"Sensor",
+ "description":"A Sonoff DW2 sensor can be used for a 'one switch' setup. This is to determine the current open/closed state of this device. Please enter the 10 digit device ID. Otherwise leave this blank."
+ }
+ }
+ }
+ },
+ "bridgeSensors":{
+ "type":"array",
+ "title":"Sensors",
+ "description":"You can expose different types of sensors connected to your RF Bridge in HomeKit.",
+ "items":{
+ "type":"object",
+ "properties":{
+ "deviceId":{
+ "type":"string",
+ "title":"RF Bridge Device ID",
+ "description":"Device ID of your RF Bridge from your eWeLink app (10 digits normally in the format 1000******)."
+ },
+ "fullDeviceId":{
+ "type":"string",
+ "title":"Sensor Device ID",
+ "description":"Device ID of the sensor from Homebridge (13 digits normally in the format 1000******SW*)."
+ },
+ "type":{
+ "type":"string",
+ "title":"Sensor Type",
+ "default":"motion",
+ "description":"Select the type of sensor you would like to expose this as in Homebridge.",
+ "oneOf":[
+ {
+ "title":"Button",
+ "enum":[
+ "button"
+ ]
+ },
+ {
+ "title":"Motion",
+ "enum":[
+ "motion"
+ ]
+ },
+ {
+ "title":"Smoke/Fire",
+ "enum":[
+ "smoke"
+ ]
+ },
+ {
+ "title":"Water/Leak",
+ "enum":[
+ "water"
+ ]
+ },
+ {
+ "title":"Carbon Monoxide",
+ "enum":[
+ "co"
+ ]
+ },
+ {
+ "title":"Carbon Dioxide",
+ "enum":[
+ "co2"
+ ]
+ },
+ {
+ "title":"Occupancy",
+ "enum":[
+ "occupancy"
+ ]
+ },
+ {
+ "title":"Contact",
+ "enum":[
+ "contact"
+ ]
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "required":[
+ "countryCode",
+ "username",
+ "password"
+ ]
+ },
+ "layout":[
+ {
+ "type":"fieldset",
+ "items":[
+ "countryCode",
+ "username",
+ "password"
+ ]
+ },
+ {
+ "type":"fieldset",
+ "title":"Optional",
+ "description":"Only adjust these settings if you know what you are doing.",
+ "expandable":true,
+ "items":[
+ "debug",
+ "debugReqRes",
+ "mode",
+ "hideDevFromHB",
+ "hideFromHB",
+ "sensorTimeLength",
+ "sensorTimeDifference",
+ "valveTimeLength",
+ "hideZBLDPress"
+ ]
+ },
+ {
+ "key":"groups",
+ "expandable":true,
+ "title":"Custom Groups",
+ "add":"Add Another Group",
+ "type":"array",
+ "items":[
+ {
+ "type":"fieldset",
+ "items":[
+ "groups[].type",
+ "groups[].deviceId",
+ "groups[].setup",
+ "groups[].operationTime",
+ "groups[].inched",
+ "groups[].sensorId"
+ ]
+ }
+ ]
+ },
+ {
+ "key":"bridgeSensors",
+ "title":"RF Bridge Devices",
+ "expandable":true,
+ "add":"Add Another Device",
+ "type":"array",
+ "items":[
+ {
+ "type":"fieldset",
+ "items":[
+ "bridgeSensors[].deviceId",
+ "bridgeSensors[].fullDeviceId",
+ "bridgeSensors[].type"
+ ]
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/index.js b/index.js
index fadb4c55..3083dd2d 100644
--- a/index.js
+++ b/index.js
@@ -1,358 +1,7 @@
/* jshint esversion: 9, -W030, node: true */
-const ewelinkapi = require('ewelink-api');
-
-var Accessory, Service, Characteristic, UUIDGen;
-
+"use strict";
+const constants = require("./lib/constants");
module.exports = function (homebridge) {
- console.log("homebridge API version: " + homebridge.version);
-
- // Accessory must be created from PlatformAccessory Constructor
- Accessory = homebridge.platformAccessory;
-
- // Service and Characteristic are from hap-nodejs
- Service = homebridge.hap.Service;
- Characteristic = homebridge.hap.Characteristic;
- UUIDGen = homebridge.hap.uuid;
-
- // For platform plugin to be considered as dynamic platform plugin,
- // registerPlatform(pluginName, platformName, constructor, dynamic), dynamic must be true
- homebridge.registerPlatform("homebridge-eWeLink", "eWeLink", eWeLink, true);
-
-};
-
-// Platform constructor
-function eWeLink(log, config, api) {
-
- log("Intialising eWeLink");
-
- var platform = this;
-
- this.log = log;
- this.config = config;
- this.accessories = new Map();
- this.authenticationToken = 'UNCONFIGURED';
- this.phoneNumberOrEmail = config.phoneNumberOrEmail;
- this.accountPassword = config.accountPassword;
- this.debug = (config.debug === 'true') ? true : false;
-
- if (api) {
-
- // Save the API object as plugin needs to register new accessory via this object
- this.api = api;
-
- // Listen to event "didFinishLaunching", this means homebridge already finished loading cached accessories.
- // Platform Plugin should only register new accessory that doesn't exist in homebridge after this event.
- // Or start discover new accessories.
-
- this.api.on('didFinishLaunching', function () {
-
- platform.log("A total of [%s] accessories were loaded from the local cache", platform.accessories.size);
-
- // Get a list of all devices from the API, and compare it to the list of cached devices.
- // New devices will be added, and devices that exist in the cache but not in the web list
- // will be removed from Homebridge.
-
- (async () => {
-
- const connection = new ewelinkapi({
- email: this.phoneNumberOrEmail,
- password: this.accountPassword
- });
- this.connection = connection;
- this.authenticationToken = await connection.getCredentials();
- if (this.debug) platform.log("authenticationToken %s", JSON.stringify(this.authenticationToken));
-
- /* get all devices */
- platform.log("Requesting a list of devices from eWeLink HTTPS API");
- const devices = await connection.getDevices();
- // console.log(JSON.stringify(devices));
-
- var size = devices.length;
- platform.log("eWeLink HTTPS API reports that there are a total of [%s] devices registered", size);
-
- if (size == 0) {
- platform.log("As there were no devices were found, all devices have been removed from the platorm's cache. Please regiester your devices using the eWeLink app and restart HomeBridge");
- platform.accessories.clear();
- platform.api.unregisterPlatformAccessories("homebridge-eWeLink", "eWeLink", platform.accessories);
- return;
- }
-
- var devicesFromApi = new Map();
-
- devices.forEach((device) => {
- platform.apiKey = device.apikey;
- devicesFromApi.set(device.deviceid, device);
- });
-
- // Now we compare the cached devices against the web list
- platform.log("Evaluating if devices need to be removed...");
-
- function checkIfDeviceIsStillRegistered(value, deviceId, map) {
-
- var accessory = platform.accessories.get(deviceId);
-
- if (devicesFromApi.has(deviceId)) {
- platform.log('Device [%s] is regeistered with API. Nothing to do.', accessory.displayName);
- } else {
- platform.log('Device [%s], ID : [%s] was not present in the response from the API. It will be removed.', accessory.displayName, accessory.UUID);
- platform.removeAccessory(accessory);
- }
- }
-
- // If we have devices in our cache, check that they exist in the web response
- if (platform.accessories.size > 0) {
- platform.log("Verifying that all cached devices are still registered with the API. Devices that are no longer registered with the API will be removed.");
- platform.accessories.forEach(checkIfDeviceIsStillRegistered);
- }
-
- platform.log("Evaluating if new devices need to be added...");
-
- // Now we compare the cached devices against the web list
- function checkIfDeviceIsAlreadyConfigured(value, deviceId, map) {
- if (platform.accessories.has(deviceId)) {
-
- platform.log('Device with ID [%s] is already configured. Ensuring that the configuration is current.', deviceId);
-
- var accessory = platform.accessories.get(deviceId);
- var deviceInformationFromWebApi = devicesFromApi.get(deviceId);
-
- accessory.getService(Service.AccessoryInformation).setCharacteristic(Characteristic.Name, deviceInformationFromWebApi.name);
- accessory.getService(Service.AccessoryInformation).setCharacteristic(Characteristic.SerialNumber, deviceInformationFromWebApi.extra.extra.mac);
- accessory.getService(Service.AccessoryInformation).setCharacteristic(Characteristic.Manufacturer, deviceInformationFromWebApi.brandName);
- accessory.getService(Service.AccessoryInformation).setCharacteristic(Characteristic.Model, deviceInformationFromWebApi.productModel);
- accessory.getService(Service.AccessoryInformation).setCharacteristic(Characteristic.FirmwareRevision, deviceInformationFromWebApi.params.fwVersion);
- let powerState;
- if ((deviceInformationFromWebApi !== undefined) && (deviceInformationFromWebApi.productModel)) {
- switch (deviceInformationFromWebApi.productModel) {
- case 'B1':
- case 'MINI':
- powerState = deviceInformationFromWebApi.params.state;
- break;
- case 'iFan02':
- powerState = deviceInformationFromWebApi.params.switches[0].switch;
- break;
- case 'AD500--X':
- powerState = deviceInformationFromWebApi.params.switch;
- }
- }
- if (this.debug) platform.log("::checkIfDeviceIsAlreadyConfigured() " + deviceInformationFromWebApi.name + " is " + powerState);
-
- platform.updatePowerStateCharacteristic(deviceId, powerState);
-
- } else {
- var deviceToAdd = devicesFromApi.get(deviceId);
- platform.log('Device [%s], ID : [%s] will be added', deviceToAdd.name, deviceToAdd.deviceid);
- platform.addAccessory(deviceToAdd);
- }
- }
-
- // Go through the web response to make sure that all the devices that are in the response do exist in the accessories map
- if (devicesFromApi.size > 0) {
- devicesFromApi.forEach(checkIfDeviceIsAlreadyConfigured);
- }
-
- if (this.debug) platform.log("API key retrieved from web service is [%s]", platform.apiKey);
-
- })().catch(function (error) {
- platform.log("Error in intialization");
- });
- }.bind(this));
- }
-}
-
-// Function invoked when homebridge tries to restore cached accessory.
-// We update the existing devices as part of didFinishLaunching(), as to avoid an additional call to the the HTTPS API.
-eWeLink.prototype.configureAccessory = function (accessory) {
-
- this.log(accessory.displayName, "Configure Accessory");
-
- var platform = this;
- accessory.reachable = true;
-
- accessory.on('identify', function (paired, callback) {
- platform.log(accessory.displayName, "Identify!!!");
- callback();
- });
-
- if (accessory.getService(Service.Switch)) {
-
- accessory.getService(Service.Switch).getCharacteristic(Characteristic.On)
- .on('set', function (value, callback) {
- platform.setPowerState(accessory, value);
- callback();
- })
- .on('get', function (callback) {
- platform.getPowerState(accessory);
- callback();
- });
-
- }
-
- this.accessories.set(accessory.context.deviceId, accessory);
-
-};
-
-eWeLink.prototype.getStateFromDevice = function (device) {
- if (this.debug) this.log("getStateFromDevice:: ENTER");
- var powerState = 'on';
- if ((device !== undefined) && (device.productModel)) {
- switch (device.productModel) {
- case 'B1':
- case "MINI":
- powerState = device.params.state;
- break;
- case 'iFan02':
- powerState = device.params.switches[0].switch;
- break;
- case 'AD500--X':
- powerState = device.params.switch;
- }
- }
- if (this.debug) this.log("getStateFromDevice:: " + device.name + " is " + powerState);
- if (this.debug) this.log("getStateFromDevice:: EXIT");
- return powerState;
-};
-
-// Sample function to show how developer can add accessory dynamically from outside event
-eWeLink.prototype.addAccessory = function (device) {
-
- // Here we need to check if it is currently there
- if (this.accessories.get(device.deviceid)) {
- this.log("Not adding [%s] as it already exists in the cache", device.deviceid);
- return;
- }
-
- var platform = this;
-
- if (device.type != 10) {
- this.log("A device with an unknown type was returned. It will be skipped.", device.type);
- return;
- }
-
- this.log("Found Accessory with Name : [%s], Manufacturer : [%s], Status : [%s], Is Online : [%s], API Key: [%s] ", device.name, device.productModel, this.getStateFromDevice(device), device.online, device.apikey);
-
- const accessory = new Accessory(device.name, UUIDGen.generate(device.deviceid.toString()));
-
- accessory.context.deviceId = device.deviceid;
- accessory.context.apiKey = device.apikey;
-
- // if (device.online == 'true') {
- accessory.reachable = true;
- // } else {
- // accessory.reachable = false;
- // }
-
- accessory.addService(Service.Switch, device.name)
- .getCharacteristic(Characteristic.On)
- .on('set', function (value, callback) {
- platform.setPowerState(accessory, value);
- callback();
- })
- .on('get', function (callback) {
- platform.getPowerState(accessory);
- callback();
- });
-
- accessory.on('identify', function (paired, callback) {
- platform.log(accessory.displayName, "Identify not supported");
- callback();
- });
-
- accessory.getService(Service.AccessoryInformation).Characteristic(Characteristic.SerialNumber, device.extra.extra.mac);
- accessory.getService(Service.AccessoryInformation).setCharacteristic(Characteristic.Manufacturer, device.productModel);
- accessory.getService(Service.AccessoryInformation).setCharacteristic(Characteristic.Model, device.extra.extra.model);
- accessory.getService(Service.AccessoryInformation).setCharacteristic(Characteristic.Identify, false);
- accessory.getService(Service.AccessoryInformation).setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion);
-
- this.accessories.set(device.deviceid, accessory);
-
- this.api.registerPlatformAccessories("homebridge-eWeLink",
- "eWeLink", [accessory]);
-
-};
-
-eWeLink.prototype.getSequence = function () {
- var time_stamp = new Date() / 1000;
- this.sequence = Math.floor(time_stamp * 1000);
- return this.sequence;
-};
-
-eWeLink.prototype.updatePowerStateCharacteristic = function (deviceId, state) {
- var platform = this;
- if (platform.debug) platform.log("::updatePowerStateCharacteristic() : ENTER with (deviceId='" + deviceId + "',state='" + state + "')");
-
- // Used when we receive an update from an external source
- var isOn = false;
- var accessory = platform.accessories.get(deviceId);
- if (state == 'on') {
- isOn = true;
- }
- //if (platform.debug) platform.log("::updatePowerStateCharacteristic() : accessory before update: "+JSON.stringify(accessory));
-
- if (platform.debug) platform.log("::updatePowerStateCharacteristic() : Updating recorded Characteristic.On for [%s] to [%s]. No request will be sent to the device.", accessory.context.deviceId, isOn);
- accessory.getService(Service.Switch).setCharacteristic(Characteristic.On, isOn);
- //if (platform.debug) platform.log("::updatePowerStateCharacteristic() : accessory after update: "+JSON.stringify(accessory));
- //platform.updatePowerStateCharacteristic(deviceId, powerState);
- if (platform.debug) platform.log("::updatePowerStateCharacteristic() : EXIT");
-};
-
-eWeLink.prototype.getPowerState = function (accessory, callback) {
- var platform = this;
-
- if (this.debug) platform.log("::getPowerState() : ENTER Requesting power state for [%s].", accessory.displayName); //, JSON.stringify(accessory));
-
- (async () => {
- // const device = await platform.connection.getDevice(accessory.context.deviceId);
- var interestedDevice = null;
- /////////////
- const devices = await platform.connection.getDevices();
- //if (platform.debug) platform.log("::getPowerState() : retrieved all devices, found "+devices.length+" devices");
-
- //if (platform.debug) platform.log("::getPowerState() : Looking for interested device");
- devices.forEach((device) => {
- // if (platform.debug) platform.log("::getPowerState() : Found : "+JSON.stringify(device));
- //if (platform.debug) platform.log("::getPowerState() : Looking for " + accessory.context.deviceId + ", but found "+device.deviceid);
- if (accessory.context.deviceId == device.deviceid) {
- //if (platform.debug) platform.log("::getPowerState() : found what I was looking for");
- interestedDevice = device;
- }
- });
- /////////////
- let powerState = platform.getStateFromDevice(interestedDevice);
- if (platform.debug) platform.log("::getPowerState() : power state for [%s] is %s", accessory.displayName, powerState);
- this.updatePowerStateCharacteristic(accessory.context.deviceId, powerState);
- if (this.debug) platform.log("::getPowerState() : EXIT");
- })()
- .catch(function (error) {
- platform.log("::getPowerState() : Error in retrieving device\n" + JSON.stringify(error));
- });
-};
-
-eWeLink.prototype.setPowerState = function (accessory, isOn, callback) {
- var platform = this;
- if (platform.debug) platform.log("::setPowerState() : ENTER");
-
- var targetState = 'off';
-
- if (isOn == true || isOn == 'on') {
- targetState = 'on';
- }
-
- if (this.debug) platform.log("::setPowerState() : Setting power state to [%s] for device [%s]", targetState, accessory.displayName);
- (async () => {
- const status = await platform.connection.setDevicePowerState(accessory.context.deviceId, targetState);
- if (this.debug) platform.log("::setPowerState() : power state for [%s] is %s", accessory.displayName, JSON.stringify(status));
- //this.updatePowerStateCharacteristic(accessory.context.deviceId, targetState);
- if (platform.debug) platform.log("::setPowerState() : EXIT");
- })().catch(function (error) {
- platform.log("::setPowerState() : Error in retrieving device\n" + JSON.stringify(error));
- });
-};
-
-// Sample function to show how developer can remove accessory dynamically from outside event
-eWeLink.prototype.removeAccessory = function (accessory) {
-
- this.log('Removing accessory [%s]', accessory.displayName);
- this.accessories.delete(accessory.context.deviceId);
- this.api.unregisterPlatformAccessories('homebridge-eWeLink', 'eWeLink', [accessory]);
+ let eWeLink = require("./lib/eWeLink.js")(homebridge);
+ homebridge.registerPlatform(constants.packageName, "eWeLink", eWeLink, true);
};
\ No newline at end of file
diff --git a/lib/constants.js b/lib/constants.js
new file mode 100644
index 00000000..27699ea5
--- /dev/null
+++ b/lib/constants.js
@@ -0,0 +1,119 @@
+/* jshint esversion: 9, -W030, node: true */
+"use strict";
+module.exports = {
+ appId: "oeVkj2lYFGnJu5XUtWisfW4utiN4u9Mq",
+ packageName: "homebridge-ewelink",
+ devicesHideable: ["switch", "light", "valve"],
+ devicesSingleSwitch: [1, 5, 6, 14, 15, 22, 24, 27, 32, 36, 44, 59],
+ devicesSingleSwitchLight: ["T1 1C", "L1", "B1", "B1_R2", "TX1C", "D1", "D1R1", "KING-M4", "Slampher"],
+ devicesMultiSwitch: [2, 3, 4, 7, 8, 9, 29, 30, 31, 34, 41],
+ devicesMultiSwitchLight: ["T1 2C", "T1 3C", "TX2C", "TX3C"],
+ devicesBrightable: [36, 44],
+ devicesColourable: [22, 59],
+ devicesSensor: [102],
+ devicesThermostat: [15],
+ devicesFan: [34],
+ devicesOutlet: [32],
+ devicesUSB: [77],
+ devicesSCM: [78],
+ devicesRFBridge: [28],
+ devicesZBBridge: [66],
+ devicesZB: [1000, 1770, 2026, 3026],
+ paramsToKeep: ["bright", "brightness", "channel", "cmd", "colorB", "colorG", "colorR", "currentHumidity", "currentTemperature", "fan", "humidity", "key", "light", "lock", "mainSwitch", "mode", "online", "rfChl", "rfList", "rfTrig", "sensorType", "speed", "state", "switch", "switches", "temperature", "type", "zyx_mode"],
+ chansFromUiid: {
+ 1: 1, // "SOCKET" \\ 20, MINI, BASIC, S26
+ 2: 2, // "SOCKET_2" \\
+ 3: 3, // "SOCKET_3" \\
+ 4: 4, // "SOCKET_4", \\
+ 5: 1, // "SOCKET_POWER" \\
+ 6: 1, // "SWITCH" \\ T1 1C, TX1C
+ 7: 2, // "SWITCH_2" \\ T1 2C, TX2C
+ 8: 3, // "SWITCH_3" \\ T1 3C, TX3C
+ 9: 4, // "SWITCH_4" \\
+ 10: 0, // "OSPF" \\
+ 11: 0, // "CURTAIN" \\ King Q4 Cover
+ 12: 0, // "EW-RE" \\
+ 13: 0, // "FIREPLACE" \\
+ 14: 1, // "SWITCH_CHANGE" \\
+ 15: 1, // "THERMOSTAT" \\ TH10, TH16
+ 16: 0, // "COLD_WARM_LED" \\
+ 17: 0, // "THREE_GEAR_FAN" \\
+ 18: 0, // "SENSORS_CENTER" \\
+ 19: 0, // "HUMIDIFIER" \\
+ 22: 1, // "RGB_BALL_LIGHT" \\ B1, B1_R2
+ 23: 0, // "NEST_THERMOSTAT" \\
+ 24: 1, // "GSM_SOCKET" \\
+ 25: 0, // "AROMATHERAPY", \\ Diffuser
+ 26: 0, // "RuiMiTeWenKongQi" \\
+ 27: 1, // "GSM_UNLIMIT_SOCKET" \\
+ 28: 1, // "RF_BRIDGE" \\ RFBridge, RF_Bridge
+ 29: 2, // "GSM_SOCKET_2" \\
+ 30: 3, // "GSM_SOCKET_3" \\
+ 31: 4, // "GSM_SOCKET_4" \\
+ 32: 1, // "POWER_DETECTION_SOCKET" \\ Pow_R2 POW
+ 33: 0, // "LIGHT_BELT", \\
+ 34: 4, // "FAN_LIGHT" \\ iFan02, iFan
+ 35: 0, // "EZVIZ_CAMERA", \\
+ 36: 1, // "SINGLE_CHANNEL_DIMMER_SWITCH" \\ KING-M4
+ 38: 0, // "HOME_KIT_BRIDGE", \\
+ 40: 0, // "FUJIN_OPS" \\
+ 41: 4, // "CUN_YOU_DOOR" \\
+ 42: 0, // "SMART_BEDSIDE_AND_NEW_RGB_BALL_LIGHT" \\
+ 43: 0, // "?" \\
+ 44: 1, // "SNOFF_LIGHT" \\ D1
+ 45: 0, // "DOWN_CEILING_LIGHT" \\
+ 46: 0, // "AIR_CLEANER" \\
+ 49: 0, // "MACHINE_BED" \\
+ 51: 0, // "COLD_WARM_DESK_LIGHT" \\
+ 52: 0, // "DOUBLE_COLOR_DEMO_LIGHT" \\
+ 53: 0, // "ELECTRIC_FAN_WITH_LAMP" \\
+ 55: 0, // "SWEEPING_ROBOT" \\
+ 56: 0, // "RGB_BALL_LIGHT_4" \\
+ 57: 0, // "MONOCHROMATIC_BALL_LIGHT" \\
+ 59: 1, // "MUSIC_LIGHT_BELT" \\ L1
+ 60: 0, // "NEW_HUMIDIFIER" \\
+ 61: 0, // "KAI_WEI_ROUTER" \\
+ 62: 0, // "MEARICAMERA" \\
+ 64: 0, // "HeatingTable" \\
+ 65: 0, // "CustomCamera" \\
+ 66: 0, // "ZIGBEE_MAIN_DEVICE" \\
+ 67: 0, // "RollingDoor" \\
+ 68: 0, // "KOOCHUWAH" \\
+ 69: 0, // "ATMOSPHERE_LAMP" \\
+ 76: 0, // "YI_GE_ER_LAMP" \\
+ 77: 4, // "SINGLE_SOCKET_MULTIPLE" \\ (1 socket device using data structure of four :()
+ 78: 4, // "SINGLE_SWITCH_MULTIPLE" \\ (1 switch device using data structure of four :()
+ 79: 0, // "CHRISTMAS_LIGHT" \\
+ 80: 0, // "HANYUAN_AIR_CONDITION" \\
+ 81: 1, // "GSM_SOCKET_NO_FLOW" \\
+ 82: 2, // "GSM_SOCKET_2_NO_FLOW" \\
+ 83: 3, // "GSM_SOCKET_3_NO_FLOW" \\
+ 84: 4, // "GSM_SOCKET_4_NO_FLOW" \\
+ 86: 0, // "CLEAR_BOOT" \\
+ 87: 0, // "EWELINK_IOT_CAMERA" \\ GK-200MP2B
+ 88: 0, // "YK_INFRARED" \\
+ 89: 0, // "SMART_OPEN_MACHINE" \\
+ 90: 0, // "GSM_RFBridge" \\
+ 91: 0, // "ROLLING_DOOR_91" \\
+ 93: 0, // "HTHD_AIR_CLEANER" \\
+ 94: 0, // "YIAN_ELECTRIC_PROTECT" \\
+ 98: 0, // "DOORBELL_RFBRIDGE" \\
+ 102: 1, // "DOOR_MAGNETIC" \\ OPL-DMA, DW2
+ 103: 0, // "WOTEWODE_TEM_LIGHT" \\
+ 104: 0, // "WOTEWODE_RGB_TEM_LIGHT" \\
+ 107: 0, // "GSM_SOCKET_NO_FLOW" \\
+ 109: 0, // "YK_INFRARED_2" \\
+ 1000: 1, // "ZIGBEE_WIRELESS_SWITCH" \\
+ 1001: 0, // "BLADELESS_FAN" \\
+ 1002: 0, // "NEW_HUMIDIFIER" \\
+ 1003: 0, // "WARM_AIR_BLOWER" \\
+ 1256: 1, // "ZIGBEE_SINGLE_SWITCH" \\
+ 1770: 1, // "ZIGBEE_TEMPERATURE_SENSOR" \\
+ 2026: 1, // "ZIGBEE_MOBILE_SENSOR" \\
+ 2256: 2, // "ZIGBEE_SWITCH_2" \\
+ 3026: 1, // "ZIGBEE_DOOR_AND_WINDOW_SENSOR" \\
+ 3256: 3, // "ZIGBEE_SWITCH_3" \\
+ 4026: 1, // "ZIGBEE_WATER_SENSOR" \\
+ 4256: 4, // "ZIGBEE_SWITCH_4" \\
+ }
+};
\ No newline at end of file
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
new file mode 100644
index 00000000..8cfdceec
--- /dev/null
+++ b/lib/eWeLink.js
@@ -0,0 +1,1825 @@
+/* jshint esversion: 9, -W030, node: true */
+"use strict";
+const constants = require("./constants");
+const convert = require("color-convert");
+const eWeLinkHTTP = require("./eWeLinkHTTP");
+const eWeLinkWS = require("./eWeLinkWS");
+const eWeLinkLAN = require("./eWeLinkLAN");
+let Accessory, Service, Characteristic, UUIDGen;
+class eWeLink {
+ constructor(log, config, api) {
+ if (!log || !api) {
+ return;
+ }
+ if (!config || (!config.username || !config.password || !config.countryCode)) {
+ log.error("** Could not load " + constants.packageName + " **");
+ log.warn("Make sure your eWeLink credentials are in the Homebridge configuration.");
+ return;
+ }
+ this.log = log;
+ this.config = config;
+ this.api = api;
+ this.mode = this.config.mode || "lan";
+ this.debug = this.config.debug || false;
+ this.debugReqRes = this.config.debugReqRes || false;
+ this.customHideChanFromHB = this.config.hideFromHB || "";
+ this.customHideDvceFromHB = this.config.hideDevFromHB || "";
+ this.customNameOverride = this.config.nameOverride || {};
+ this.sensorTimeLength = this.config.sensorTimeLength || 2;
+ this.sensorTimeDifference = this.config.sensorTimeDifference || 120;
+ this.valveTimeLength = this.config.valveTimeLength || 120;
+ this.hideZBLDPress = this.config.hideZBLDPress || false;
+ this.devicesInHB = new Map();
+ this.devicesInEwe = new Map();
+ this.cusG = new Map();
+ this.cusS = new Map();
+ this.api.on("didFinishLaunching", () => {
+ this.log("Plugin has finished initialising. Starting synchronisation with eWeLink account.");
+ //*** Set up HTTP client and get the user HTTP host ***\\
+ this.httpClient = new eWeLinkHTTP(this.config, this.log);
+ this.httpClient.getHost()
+ .then(res => { //*** Use the HTTP API host to log into eWeLink ***\\
+ return this.httpClient.login();
+ }).then(res => { //*** Set up the web socket client ***\\
+ this.wsClient = new eWeLinkWS(this.config, this.log, res);
+ return this.wsClient.getHost();
+ }).then(res => { //*** Open web socket connection and get device list via HTTP ***\\
+ this.wsClient.login();
+ return this.httpClient.getDevices();
+ }).then(res => { //*** Get device IP addresses for LAN mode ***\\
+ this.httpDevices = res;
+ this.lanClient = new eWeLinkLAN(this.config, this.log, this.httpDevices);
+ return this.lanClient.getHosts();
+ }).then(res => { //*** Set up the LAN mode listener ***\\
+ this.lanDevices = res;
+ return this.lanClient.startMonitor();
+ }).then(res => { //*** Use the device list to refresh Homebridge accessories ***\\
+ (() => {
+ //*** Remove all Homebridge accessories if none found ***\\
+ if (Object.keys(this.httpDevices).length === 0 && Object.keys(this.lanDevices).length === 0) {
+ this.removeAllAccessories();
+ return;
+ }
+ //*** Make a map of devices from eWeLink ***\\
+ this.httpDevices.forEach(device => {
+ if (this.customHideDvceFromHB.includes(device.deviceid)) {
+ return;
+ }
+ this.devicesInEwe.set(device.deviceid, device);
+ });
+ //*** Make a map of custom groups from Homebridge config ***\\
+ if (this.config.groups && Object.keys(this.config.groups).length > 0) {
+ this.config.groups.forEach(group => {
+ if (typeof group.deviceId !== "undefined" && this.devicesInEwe.has(group.deviceId.toLowerCase())) {
+ this.cusG.set(group.deviceId + "SWX", group);
+ }
+ });
+ }
+ //*** Make a map of RF Bridge custom sensors from Homebridge config ***\\
+ if (this.config.bridgeSensors && Object.keys(this.config.bridgeSensors).length > 0) {
+ this.config.bridgeSensors.forEach(bridgeSensor => {
+ if (typeof bridgeSensor.deviceId !== "undefined" && this.devicesInEwe.has(bridgeSensor.deviceId.toLowerCase())) {
+ this.cusS.set(bridgeSensor.fullDeviceId, bridgeSensor);
+ }
+ });
+ }
+ //*** Logging always helps to see if everything is okay so far ***\\
+ this.log("[%s] eWeLink devices were loaded from the Homebridge cache.", this.devicesInHB.size);
+ this.log("[%s] primary devices were loaded from your eWeLink account.", this.devicesInEwe.size);
+ this.log("[%s] primary devices were discovered on your local network.", Object.keys(this.lanDevices).length);
+ //*** Remove Homebridge accessories that don't appear in eWeLink ***\\
+ if (this.devicesInHB.size > 0) {
+ this.devicesInHB.forEach(accessory => {
+ if (!this.devicesInEwe.has(accessory.context.eweDeviceId)) {
+ this.removeAccessory(accessory);
+ }
+ });
+ }
+ //*** Disable plugin if no eWeLink devices ***\\
+ if (this.devicesInEwe.size === 0) {
+ return;
+ }
+ //*** Synchronise (add/refresh) devices between eWeLink and Homebridge ***\\
+ this.devicesInEwe.forEach(device => {
+ this.initialiseDevice(device);
+ });
+ //*** Set up the ws listener for future external device updates ***\\
+ this.wsClient.receiveUpdate(device => {
+ this.receiveDeviceUpdate(device);
+ });
+ //*** Set up the lan listener for future external device updates ***\\
+ this.lanClient.receiveUpdate(device => {
+ this.receiveDeviceUpdate(device);
+ });
+ this.log("Synchronisation complete. Ready to go!");
+ if (this.debugReqRes) {
+ this.log.warn("You have 'Request & Response Logging' enabled. This setting is not recommended for long-term use.");
+ }
+ })();
+ }).catch(err => {
+ this.log.error("** eWeLink synchronisation error: **");
+ this.log.warn(err);
+ this.log.error("** Plugin will not be loaded. **");
+ });
+ });
+ }
+ initialiseDevice(device) {
+ let accessory;
+ //*** First add the device if it isn't already in Homebridge ***\\
+ if (!this.devicesInHB.has(device.deviceid + "SWX") && !this.devicesInHB.has(device.deviceid + "SW0")) {
+ if (device.extra.uiid === 2 && device.brandName === "coolkit" && device.productModel === "0285") {
+ this.addAccessory(device, device.deviceid + "SWX", "valve");
+ } else if (this.cusG.has(device.deviceid + "SWX") && this.cusG.get(device.deviceid + "SWX").type === "blind") {
+ this.addAccessory(device, device.deviceid + "SWX", "blind");
+ } else if (this.cusG.has(device.deviceid + "SWX") && this.cusG.get(device.deviceid + "SWX").type === "garage") {
+ this.addAccessory(device, device.deviceid + "SWX", "garage");
+ } else if (constants.devicesSensor.includes(device.extra.uiid)) {
+ this.addAccessory(device, device.deviceid + "SWX", "sensor");
+ } else if (constants.devicesFan.includes(device.extra.uiid)) {
+ this.addAccessory(device, device.deviceid + "SWX", "fan");
+ } else if (constants.devicesThermostat.includes(device.extra.uiid)) {
+ this.addAccessory(device, device.deviceid + "SWX", "thermostat");
+ } else if (constants.devicesOutlet.includes(device.extra.uiid)) {
+ this.addAccessory(device, device.deviceid + "SWX", "outlet");
+ } else if (constants.devicesUSB.includes(device.extra.uiid)) {
+ this.addAccessory(device, device.deviceid + "SWX", "usb");
+ } else if (constants.devicesSCM.includes(device.extra.uiid)) {
+ this.addAccessory(device, device.deviceid + "SWX", "scm");
+ } else if (constants.devicesSingleSwitch.includes(device.extra.uiid) && constants.devicesSingleSwitchLight.includes(device.productModel)) {
+ this.addAccessory(device, device.deviceid + "SWX", "light");
+ } else if (constants.devicesMultiSwitch.includes(device.extra.uiid) && constants.devicesMultiSwitchLight.includes(device.productModel)) {
+ for (let i = 0; i <= constants.chansFromUiid[device.extra.uiid]; i++) {
+ this.addAccessory(device, device.deviceid + "SW" + i, "light");
+ }
+ } else if (constants.devicesSingleSwitch.includes(device.extra.uiid)) {
+ this.addAccessory(device, device.deviceid + "SWX", "switch");
+ } else if (constants.devicesMultiSwitch.includes(device.extra.uiid)) {
+ for (let i = 0; i <= constants.chansFromUiid[device.extra.uiid]; i++) {
+ this.addAccessory(device, device.deviceid + "SW" + i, "switch");
+ }
+ } else if (constants.devicesRFBridge.includes(device.extra.uiid)) {
+ this.addAccessory(device, device.deviceid + "SW0", "rf_pri");
+ for (let i = 1; i <= Object.keys(device.params.rfList).length; i++) {
+ this.addAccessory(device, device.deviceid + "SW" + i, "rf_sub");
+ }
+ } else if (constants.devicesZBBridge.includes(device.extra.uiid)) {
+ this.addAccessory(device, device.deviceid + "SWX", "zb_pri");
+ } else if (constants.devicesZB.includes(device.extra.uiid)) {
+ this.addAccessory(device, device.deviceid + "SWX", "zb_sub");
+ } else {
+ this.log.warn("[%s] could not be added as it is not supported by this plugin.", device.name);
+ }
+ }
+ //*** Next refresh the device ***\\
+ if ((accessory = this.devicesInHB.get(device.deviceid + "SWX"))) {
+ accessory.getService(Service.AccessoryInformation).setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion);
+ accessory.context.reachableWAN = accessory.context.eweUIID !== 102 ?
+ device.online :
+ true; //*** DW2 offline sometimes (as battery powered?) ***\\
+ accessory.context.reachableLAN = this.lanDevices[device.deviceid].ip || false;
+ let str = accessory.context.reachableLAN ?
+ "and locally with IP [" + accessory.context.reachableLAN + "]" :
+ (accessory.context.reachableWAN) ?
+ "but LAN mode unavailable as unsupported/shared device" :
+ "but LAN mode unavailable as device offline";
+ this.log("[%s] found in eWeLink %s.", accessory.displayName, str);
+ try {
+ this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
+ this.api.updatePlatformAccessories(constants.packageName, "eWeLink", [accessory]);
+ } catch (e) {
+ this.log.warn("[%s] online/offline status could not be updated - [%s].", accessory.displayName, e);
+ }
+ } else if ((accessory = this.devicesInHB.get(device.deviceid + "SW0"))) {
+ accessory.context.reachableLAN = this.lanDevices[device.deviceid].ip || false;
+ let str = accessory.context.reachableLAN ?
+ "and locally with IP [" + accessory.context.reachableLAN + "]" :
+ (accessory.context.reachableWAN) ?
+ "but LAN mode unavailable as unsupported/shared device" :
+ "but LAN mode unavailable as device offline";
+ this.log("[%s] found in eWeLink %s.", accessory.displayName, str);
+ let isRf = constants.devicesRFBridge.includes(device.extra.uiid);
+ let rfCh = false;
+ for (let i = 0; i <= accessory.context.channelCount; i++) {
+ let oAccessory;
+ try {
+ if (!this.devicesInHB.has(device.deviceid + "SW" + i)) {
+ if (i > 0 && this.customHideChanFromHB.includes(device.deviceid + "SW" + i) && constants.devicesHideable.includes(accessory.context.type)) {
+ continue;
+ } else {
+ this.addAccessory(device, device.deviceid + "SW" + i, "switch");
+ }
+ }
+ oAccessory = this.devicesInHB.get(device.deviceid + "SW" + i);
+ if (i > 0 && this.customHideChanFromHB.includes(device.deviceid + "SW" + i) && constants.devicesHideable.includes(accessory.context.type)) {
+ this.removeAccessory(oAccessory);
+ continue;
+ }
+ if (i > 0 && isRf) {
+ let ct = this.cusS.has(oAccessory.context.hbDeviceId) ? this.cusS.get(oAccessory.context.hbDeviceId).type : "motion";
+ if (ct !== oAccessory.context.sensorType) {
+ rfCh = true;
+ }
+ }
+ oAccessory.getService(Service.AccessoryInformation).setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion);
+ oAccessory.context.reachableWAN = device.online;
+ oAccessory.context.reachableLAN = this.lanDevices[device.deviceid].ip || false;
+ this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory);
+ this.api.updatePlatformAccessories(constants.packageName, "eWeLink", [oAccessory]);
+ } catch (e) {}
+ }
+ if (rfCh) {
+ this.log.warn("RF Bridge configuration changed. Devices will be removed and readded.");
+ try {
+ for (let i = 0; i <= accessory.context.channelCount; i++) {
+ let oAccessory = this.devicesInHB.get(device.deviceid + "SW" + i);
+ this.removeAccessory(oAccessory);
+ }
+ this.initialiseDevice(device);
+ } catch (err) {}
+ return;
+ }
+ } else {
+ this.log.warn("[%s] will not be refreshed as it wasn't found in Homebridge.", device.name);
+ return;
+ }
+ if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
+ this.log.warn("[%s] will not be refreshed as it has been reported offline.", accessory.displayName);
+ return;
+ }
+ device.params.updateSource = "http";
+ if (!this.refreshAccessory(accessory, device.params)) {
+ this.log.warn("[%s] could not be refreshed. Please try removing accessory from the Homebridge cache along with any secondary devices (SW1, SW2, etc.). Debugging: [%s:%s:%s]", accessory.displayName, "initialise", accessory.context.type, accessory.context.channelCount);
+ }
+ }
+ addAccessory(device, hbDeviceId, type) {
+ let channelCount = type === "rf_pri" ? Object.keys(device.params.rfList).length : constants.chansFromUiid[device.extra.uiid],
+ switchNumber = hbDeviceId.substr(-1).toString(),
+ newDeviceName = device.name;
+ if (["1", "2", "3", "4"].includes(switchNumber)) {
+ newDeviceName += " SW" + switchNumber;
+ if (this.customHideChanFromHB.includes(hbDeviceId) && type === "switch") {
+ this.log.warn("[%s] has not been added as per configuration", newDeviceName);
+ return;
+ }
+ }
+ if (this.customNameOverride.hasOwnProperty(hbDeviceId)) {
+ newDeviceName = this.customNameOverride[hbDeviceId];
+ }
+ const accessory = new Accessory(newDeviceName, UUIDGen.generate(hbDeviceId).toString());
+ try {
+ accessory.getService(Service.AccessoryInformation)
+ .setCharacteristic(Characteristic.SerialNumber, hbDeviceId)
+ .setCharacteristic(Characteristic.Manufacturer, device.brandName)
+ .setCharacteristic(Characteristic.Model, device.productModel + " (" + device.extra.model + ")")
+ .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion)
+ .setCharacteristic(Characteristic.Identify, false);
+ accessory.context = {
+ hbDeviceId,
+ eweDeviceId: device.deviceid,
+ eweUIID: device.extra.uiid,
+ eweModel: device.productModel,
+ eweApiKey: device.apikey,
+ switchNumber,
+ channelCount,
+ type
+ };
+ switch (type) {
+ case "valve":
+ ["A", "B"].forEach(v => {
+ accessory.addService(Service.Valve, "Valve " + v, "valve" + v.toLowerCase())
+ .setCharacteristic(Characteristic.Active, 0)
+ .setCharacteristic(Characteristic.InUse, 0)
+ .setCharacteristic(Characteristic.ValveType, 1)
+ .setCharacteristic(Characteristic.SetDuration, this.valveTimeLength)
+ .addCharacteristic(Characteristic.RemainingDuration);
+ });
+ break;
+ case "blind":
+ accessory.addService(Service.WindowCovering)
+ .setCharacteristic(Characteristic.CurrentPosition, 100)
+ .setCharacteristic(Characteristic.TargetPosition, 100)
+ .setCharacteristic(Characteristic.PositionState, 2);
+ break;
+ case "garage":
+ accessory.addService(Service.GarageDoorOpener)
+ .setCharacteristic(Characteristic.CurrentDoorState, 1)
+ .setCharacteristic(Characteristic.TargetDoorState, 1)
+ .setCharacteristic(Characteristic.ObstructionDetected, false);
+ break;
+ case "sensor":
+ accessory.addService(Service.ContactSensor)
+ .setCharacteristic(Characteristic.ContactSensorState, 0);
+ break;
+ case "fan":
+ accessory.addService(Service.Fanv2);
+ accessory.addService(Service.Lightbulb);
+ break;
+ case "thermostat":
+ accessory.addService(Service.Switch);
+ accessory.addService(Service.TemperatureSensor);
+ if (device.params.sensorType !== "DS18B20") {
+ accessory.addService(Service.HumiditySensor);
+ }
+ break;
+ case "outlet":
+ case "usb":
+ accessory.addService(Service.Outlet);
+ break;
+ case "light":
+ accessory.addService(Service.Lightbulb);
+ break;
+ case "switch":
+ case "scm":
+ accessory.addService(Service.Switch);
+ break;
+ case "rf_pri":
+ case "zb_pri":
+ break;
+ case "rf_sub":
+ accessory.context.sensorType = this.cusS.has(hbDeviceId) ? this.cusS.get(hbDeviceId).type : "motion";
+ accessory.context.rfChl = parseInt(switchNumber) - 1;
+ switch (accessory.context.sensorType) {
+ case "button":
+ accessory.addService(Service.Switch);
+ break;
+ case "water":
+ accessory.addService(Service.LeakSensor);
+ break;
+ case "fire":
+ case "smoke":
+ accessory.addService(Service.SmokeSensor);
+ break;
+ case "co":
+ accessory.addService(Service.CarbonMonoxideSensor);
+ break;
+ case "co2":
+ accessory.addService(Service.CarbonDioxideSensor);
+ break;
+ case "contact":
+ accessory.addService(Service.ContactSensor);
+ break;
+ case "occupancy":
+ accessory.addService(Service.OccupancySensor);
+ break;
+ case "motion":
+ default:
+ accessory.addService(Service.MotionSensor);
+ break;
+ }
+ break;
+ case "zb_sub":
+ switch (device.extra.uiid) {
+ case 1000: //*** credit @tasict ***\\
+ accessory.addService(Service.StatelessProgrammableSwitch);
+ if (this.hideZBLDPress) {
+ accessory.getService(Service.StatelessProgrammableSwitch)
+ .getCharacteristic(Characteristic.ProgrammableSwitchEvent)
+ .setProps({
+ validValues: [0]
+ });
+ }
+ break;
+ case 1770:
+ accessory.addService(Service.TemperatureSensor);
+ accessory.addService(Service.HumiditySensor);
+ break;
+ case 2026:
+ accessory.addService(Service.MotionSensor);
+ break;
+ case 3026:
+ accessory.addService(Service.ContactSensor).setCharacteristic(Characteristic.ContactSensorState, 0);
+ break;
+ default:
+ throw "unsupported zigbee device type with uiid [" + device.extra.uiid + "]";
+ }
+ break;
+ default:
+ throw "device is not supported by this plugin";
+ }
+ this.devicesInHB.set(hbDeviceId, accessory);
+ this.api.registerPlatformAccessories(constants.packageName, "eWeLink", [accessory]);
+ this.configureAccessory(accessory);
+ this.log("[%s] has been added to Homebridge.", newDeviceName);
+ } catch (e) {
+ this.log.warn("[%s] could not be added as %s.", accessory.displayName, e);
+ }
+ }
+ configureAccessory(accessory) {
+ if (!this.log) {
+ return;
+ }
+ try {
+ switch (accessory.context.type) {
+ case "valve":
+ ["A", "B"].forEach(v => {
+ accessory.getService("Valve " + v).getCharacteristic(Characteristic.Active)
+ .on("set", (value, callback) => {
+ accessory.getService("Valve " + v).getCharacteristic(Characteristic.Active).value !== value ?
+ this.internalValveUpdate(accessory, "Valve " + v, value, callback) :
+ callback();
+ });
+ accessory.getService("Valve " + v).getCharacteristic(Characteristic.SetDuration)
+ .on("set", (value, callback) => {
+ if (accessory.getService("Valve " + v).getCharacteristic(Characteristic.InUse).value) {
+ accessory.getService("Valve " + v).updateCharacteristic(Characteristic.RemainingDuration, value);
+ clearTimeout(accessory.getService("Valve " + v).timer);
+ accessory.getService("Valve " + v).timer = setTimeout(() => {
+ accessory.getService("Valve " + v).setCharacteristic(Characteristic.Active, 0);
+ }, (value * 1000));
+ }
+ callback();
+ });
+ });
+ break;
+ case "blind":
+ accessory.getService(Service.WindowCovering).getCharacteristic(Characteristic.TargetPosition)
+ .setProps({
+ minStep: 100
+ })
+ .on("set", (value, callback) => {
+ accessory.getService(Service.WindowCovering).getCharacteristic(Characteristic.TargetPosition).value !== value ?
+ this.internalBlindUpdate(accessory, value, callback) :
+ callback();
+ });
+ break;
+ case "garage":
+ accessory.getService(Service.GarageDoorOpener).getCharacteristic(Characteristic.TargetDoorState)
+ .on("set", (value, callback) => {
+ accessory.getService(Service.GarageDoorOpener).getCharacteristic(Characteristic.TargetDoorState).value !== value ?
+ this.internalGarageUpdate(accessory, value, callback) :
+ callback();
+ });
+ break;
+ case "fan":
+ accessory.getService(Service.Fanv2).getCharacteristic(Characteristic.Active)
+ .on("set", (value, callback) => {
+ accessory.getService(Service.Fanv2).getCharacteristic(Characteristic.Active).value !== value ?
+ this.internalFanUpdate(accessory, "power", value, callback) :
+ callback();
+ });
+ accessory.getService(Service.Fanv2).getCharacteristic(Characteristic.RotationSpeed)
+ .setProps({
+ minStep: 33
+ })
+ .on("set", (value, callback) => {
+ accessory.getService(Service.Fanv2).getCharacteristic(Characteristic.RotationSpeed).value !== value ?
+ this.internalFanUpdate(accessory, "speed", value, callback) :
+ callback();
+ });
+ accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On)
+ .on("set", (value, callback) => {
+ accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value !== value ?
+ this.internalFanUpdate(accessory, "light", value, callback) :
+ callback();
+ });
+ break;
+ case "thermostat":
+ accessory.getService(Service.Switch).getCharacteristic(Characteristic.On)
+ .on("set", (value, callback) => {
+ accessory.getService(Service.Switch).getCharacteristic(Characteristic.On).value !== value ?
+ this.internalThermostatUpdate(accessory, value, callback) :
+ callback();
+ });
+ break;
+ case "outlet":
+ accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On)
+ .on("set", (value, callback) => {
+ accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On).value !== value ?
+ this.internalOutletUpdate(accessory, value, callback) :
+ callback();
+ });
+ break;
+ case "usb":
+ accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On)
+ .on("set", (value, callback) => {
+ accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On).value !== value ?
+ this.internalUSBUpdate(accessory, value, callback) :
+ callback();
+ });
+ break;
+ case "scm":
+ accessory.getService(Service.Switch).getCharacteristic(Characteristic.On)
+ .on("set", (value, callback) => {
+ accessory.getService(Service.Switch).getCharacteristic(Characteristic.On).value !== value ?
+ this.internalSCMUpdate(accessory, value, callback) :
+ callback();
+ });
+ break;
+ case "light":
+ accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On)
+ .on("set", (value, callback) => {
+ accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value !== value ?
+ this.internalLightbulbUpdate(accessory, value, callback) :
+ callback();
+ });
+ if (constants.devicesBrightable.includes(accessory.context.eweUIID)) {
+ accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Brightness)
+ .on("set", (value, callback) => {
+ if (value > 0) {
+ if (!accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value) {
+ this.internalLightbulbUpdate(accessory, true, callback);
+ }
+ accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Brightness).value !== value ?
+ this.internalBrightnessUpdate(accessory, value, callback) :
+ callback();
+ } else {
+ accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value ?
+ this.internalLightbulbUpdate(accessory, false, callback) :
+ callback();
+ }
+ });
+ } else if (constants.devicesColourable.includes(accessory.context.eweUIID)) {
+ accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Brightness)
+ .on("set", (value, callback) => {
+ if (value > 0) {
+ if (!accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value) {
+ this.internalLightbulbUpdate(accessory, true, callback);
+ }
+ accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Brightness).value !== value ?
+ this.internalHSBUpdate(accessory, "bri", value, callback) :
+ callback();
+ } else {
+ accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value ?
+ this.internalLightbulbUpdate(accessory, false, callback) :
+ callback();
+ }
+ });
+ accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Hue)
+ .on("set", (value, callback) => {
+ accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Hue).value !== value ?
+ this.internalHSBUpdate(accessory, "hue", value, callback) :
+ callback();
+ });
+ accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Saturation)
+ .on("set", (value, callback) => {
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Saturation, value);
+ callback();
+ });
+ }
+ break;
+ case "switch":
+ accessory.getService(Service.Switch).getCharacteristic(Characteristic.On)
+ .on("set", (value, callback) => {
+ accessory.getService(Service.Switch).getCharacteristic(Characteristic.On).value !== value ?
+ this.internalSwitchUpdate(accessory, value, callback) :
+ callback();
+ });
+ break;
+ case "rf_sub":
+ if (accessory.context.sensorType === "button") {
+ accessory.getService(Service.Switch).getCharacteristic(Characteristic.On)
+ .on("set", (value, callback) => {
+ this.internalRFDeviceUpdate(accessory, true, callback);
+ });
+ }
+ break;
+ }
+ accessory.context.reachableWAN = true;
+ accessory.context.reachableLAN = true;
+ this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
+ this.api.updatePlatformAccessories(constants.packageName, "eWeLink", [accessory]);
+ } catch (e) {
+ this.log.warn("[%s] could not be refreshed - [%s].", accessory.displayName, e);
+ }
+ }
+ refreshAccessory(accessory, newParams) {
+ switch (accessory.context.type) {
+ case "valve":
+ if (Array.isArray(newParams.switches)) {
+ this.externalValveUpdate(accessory, newParams);
+ }
+ return true;
+ case "blind":
+ if (Array.isArray(newParams.switches)) {
+ this.externalBlindUpdate(accessory, newParams);
+ }
+ return true;
+ case "garage":
+ if (newParams.hasOwnProperty("switch") || Array.isArray(newParams.switches)) {
+ this.externalGarageUpdate(accessory, newParams);
+ }
+ return true;
+ case "sensor":
+ if (newParams.hasOwnProperty("switch")) {
+ this.externalSensorUpdate(accessory, newParams);
+ }
+ return true;
+ case "fan":
+ if (Array.isArray(newParams.switches) || (newParams.hasOwnProperty("light") && newParams.hasOwnProperty("fan") && newParams.hasOwnProperty("speed"))) {
+ this.externalFanUpdate(accessory, newParams);
+ }
+ return true;
+ case "thermostat":
+ if (newParams.hasOwnProperty("currentTemperature") || newParams.hasOwnProperty("currentHumidity") || newParams.hasOwnProperty("switch") || newParams.hasOwnProperty("masterSwitch")) {
+ this.externalThermostatUpdate(accessory, newParams);
+ }
+ return true;
+ case "outlet":
+ if (newParams.hasOwnProperty("switch")) {
+ this.externalOutletUpdate(accessory, newParams);
+ }
+ return true;
+ case "usb":
+ if (Array.isArray(newParams.switches)) {
+ this.externalUSBUpdate(accessory, newParams);
+ }
+ return true;
+ case "scm":
+ if (Array.isArray(newParams.switches)) {
+ this.externalSCMUpdate(accessory, newParams);
+ }
+ return true;
+ case "light":
+ if (constants.devicesSingleSwitch.includes(accessory.context.eweUIID) && constants.devicesSingleSwitchLight.includes(accessory.context.eweModel)) {
+ if (newParams.hasOwnProperty("switch") || newParams.hasOwnProperty("state") || newParams.hasOwnProperty("bright") || newParams.hasOwnProperty("colorR") || newParams.hasOwnProperty("brightness") || newParams.hasOwnProperty("channel0") || newParams.hasOwnProperty("channel2") || newParams.hasOwnProperty("zyx_mode")) {
+ this.externalSingleLightUpdate(accessory, newParams);
+ }
+ } else if (constants.devicesMultiSwitch.includes(accessory.context.eweUIID) && constants.devicesMultiSwitchLight.includes(accessory.context.eweModel)) {
+ if (Array.isArray(newParams.switches)) {
+ this.externalMultiLightUpdate(accessory, newParams);
+ }
+ }
+ return true;
+ case "switch":
+ if (constants.devicesSingleSwitch.includes(accessory.context.eweUIID)) {
+ if (newParams.hasOwnProperty("switch")) {
+ this.externalSingleSwitchUpdate(accessory, newParams);
+ }
+ } else if (constants.devicesMultiSwitch.includes(accessory.context.eweUIID)) {
+ if (Array.isArray(newParams.switches)) {
+ this.externalMultiSwitchUpdate(accessory, newParams);
+ }
+ }
+ return true;
+ case "rf_pri":
+ this.externalRFDeviceUpdate(accessory, newParams);
+ return true;
+ case "rf_sub":
+ return true;
+ case "zb_pri":
+ return true;
+ case "zb_sub":
+ this.externalZBDeviceUpdate(accessory, newParams);
+ return true;
+ default:
+ return false;
+ }
+ }
+ removeAccessory(accessory) {
+ try {
+ this.devicesInHB.delete(accessory.context.hbDeviceId);
+ this.api.unregisterPlatformAccessories(constants.packageName, "eWeLink", [accessory]);
+ this.log("[%s] will be removed from Homebridge.", accessory.displayName);
+ } catch (e) {
+ this.log.warn("[%s] needed to be removed but couldn't - [%s].", accessory.displayName, e);
+ }
+ }
+ removeAllAccessories() {
+ try {
+ this.log.warn("[0] primary devices were loaded from your eWeLink account so any eWeLink devices in the Homebridge cache will be removed. This plugin will not load as there is no reason to continue.");
+ this.api.unregisterPlatformAccessories(constants.packageName, "eWeLink", Array.from(this.devicesInHB.values()));
+ this.devicesInHB.clear();
+ } catch (e) {
+ this.log.warn("Accessories could not be removed from the Homebridge cache - [%s].", e);
+ }
+ }
+ sendDeviceUpdate(accessory, params, callback) {
+ let payload = {
+ apikey: accessory.context.eweApiKey,
+ deviceid: accessory.context.eweDeviceId,
+ params
+ };
+ switch (this.mode) {
+ case "lan":
+ default:
+ this.lanClient.sendUpdate(payload)
+ .then(res => {
+ callback();
+ })
+ .catch(err => {
+ if (accessory.context.reachableWAN) {
+ if (this.debug) {
+ this.log.warn("[%s] LAN update failed as %s. Trying web socket update.", accessory.displayName, err);
+ }
+ this.wsClient.sendUpdate(payload, callback);
+ setTimeout(() => {
+ this.wsClient.requestUpdate(accessory);
+ }, 2500);
+ } else {
+ this.log.error("[%s] could not be updated as it appears to be offline.", accessory.displayName);
+ callback("Device has failed to update");
+ }
+ });
+ break;
+ case "ws":
+ this.wsClient.sendUpdate(payload, callback);
+ setTimeout(() => {
+ this.wsClient.requestUpdate(accessory);
+ }, 2500);
+ break;
+ }
+ }
+ receiveDeviceUpdate(device) {
+ let accessory;
+ switch (device.action) {
+ case "sysmsg":
+ if (this.devicesInHB.has(device.deviceid + "SWX") || this.devicesInHB.has(device.deviceid + "SW0")) {
+ accessory = this.devicesInHB.get(device.deviceid + "SWX") || this.devicesInHB.get(device.deviceid + "SW0");
+ try {
+ if (accessory.context.reachableWAN !== device.params.online) {
+ accessory.context.reachableWAN = device.params.online;
+ this.log("[%s] has been reported [%s].", accessory.displayName, accessory.context.reachableWAN ? "online" : "offline");
+ this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
+ this.api.updatePlatformAccessories(constants.packageName, "eWeLink", [accessory]);
+ if (accessory.context.reachableWAN) {
+ this.wsClient.requestUpdate(accessory);
+ }
+ }
+ } catch (e) {
+ this.log.warn("[%s] online/offline status could not be updated - [%s].", accessory.displayName, e);
+ }
+ if (this.devicesInHB.has(device.deviceid + "SW0")) {
+ let oAccessory;
+ for (let i = 1; i <= accessory.context.channelCount; i++) {
+ try {
+ if (this.devicesInHB.has(device.deviceid + "SW" + i)) {
+ oAccessory = this.devicesInHB.get(device.deviceid + "SW" + i);
+ oAccessory.context.reachableWAN = device.params.online;
+ this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory);
+ this.api.updatePlatformAccessories(constants.packageName, "eWeLink", [oAccessory]);
+ }
+ } catch (e) {
+ this.log.warn("[%s] online/offline status could not be updated - [%s].", oAccessory.displayName, e);
+ }
+ }
+ }
+ }
+ break;
+ case "update":
+ let source = device.params.updateSource === "ws" ? "WS" : "LAN";
+ if (this.devicesInHB.has(device.deviceid + "SWX") || this.devicesInHB.has(device.deviceid + "SW0")) {
+ accessory = this.devicesInHB.get(device.deviceid + "SWX") || this.devicesInHB.get(device.deviceid + "SW0");
+ if (source === "ws" && !accessory.context.reachableWAN) {
+ accessory.context.reachableWAN = true;
+ }
+ if (source === "lan" && !accessory.context.reachableLAN) {
+ accessory.context.reachableLAN = true;
+ }
+ if (this.debug) {
+ this.log("[%s] externally updated from above %s message and will be refreshed.", accessory.displayName, source);
+ }
+ if (this.refreshAccessory(accessory, device.params)) {
+ return;
+ }
+ this.log.warn("[%s] cannot be refreshed. Please try removing accessory from the Homebridge cache along with any secondary devices (SW1, SW2, etc.). Debugging: [%s:%s:%s]", accessory.displayName, "refresh", accessory.context.type, accessory.context.channelCount);
+ } else if (this.customHideDvceFromHB.includes(device.deviceid)) {
+ this.log.warn("[%s] %s update is for hidden accessory.", device.deviceid, source);
+ } else {
+ this.log.warn("[%s] Accessory received via %s update does not exist in Homebridge. If it's a new accessory please restart Homebridge so it is added.", device.deviceid, source);
+ }
+ break;
+ }
+ }
+ internalValveUpdate(accessory, valve, value, callback) {
+ try {
+ if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
+ throw "it is currently offline";
+ }
+ let params = {};
+ accessory.getService(valve)
+ .updateCharacteristic(Characteristic.Active, value)
+ .updateCharacteristic(Characteristic.InUse, value);
+ switch (value) {
+ case 0:
+ accessory.getService(valve).updateCharacteristic(Characteristic.RemainingDuration, 0);
+ clearTimeout(accessory.getService(valve).timer);
+ break;
+ case 1:
+ let timer = accessory.getService(valve).getCharacteristic(Characteristic.SetDuration).value;
+ accessory.getService(valve).updateCharacteristic(Characteristic.RemainingDuration, timer);
+ accessory.getService(valve).timer = setTimeout(() => {
+ accessory.getService(valve).setCharacteristic(Characteristic.Active, 0);
+ }, (timer * 1000));
+ break;
+ }
+ params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
+ switch (valve) {
+ case "Valve A":
+ params.switches[0].switch = value ? "on" : "off";
+ params.switches[1].switch = accessory.getService("Valve B").getCharacteristic(Characteristic.Active).value ? "on" : "off";
+ break;
+ case "Valve B":
+ params.switches[0].switch = accessory.getService("Valve A").getCharacteristic(Characteristic.Active).value ? "on" : "off";
+ params.switches[1].switch = value ? "on" : "off";
+ break;
+ default:
+ throw "unknown valve [" + valve + "]";
+ }
+ params.switches[2].switch = "off";
+ params.switches[3].switch = "off";
+ this.sendDeviceUpdate(accessory, params, callback);
+ } catch (err) {
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ this.log.error(str);
+ callback(str);
+ }
+ }
+ internalBlindUpdate(accessory, value, callback) {
+ try {
+ if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
+ throw "it is currently offline";
+ }
+ let blindConfig;
+ if (!(blindConfig = this.cusG.get(accessory.context.hbDeviceId))) {
+ throw "group config missing";
+ }
+ if (blindConfig.type !== "blind" || !["oneSwitch", "twoSwitch"].includes(blindConfig.setup)) {
+ throw "improper configuration";
+ }
+ let pSte, params = {};
+ value = value >= 50 ? 100 : 0;
+ pSte = accessory.getService(Service.WindowCovering).getCharacteristic(Characteristic.PositionState).value;
+ if (value === pSte * 100) {
+ accessory.getService(Service.WindowCovering)
+ .updateCharacteristic(Characteristic.TargetPosition, value)
+ .updateCharacteristic(Characteristic.PositionState, pSte);
+ callback();
+ return;
+ }
+ switch (blindConfig.setup) {
+ case "oneSwitch":
+ params.switch = "on";
+ break;
+ case "twoSwitch":
+ params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
+ params.switches[0].switch = value === 100 ? "on" : "off";
+ params.switches[1].switch = value === 0 ? "on" : "off";
+ break;
+ }
+ this.sendDeviceUpdate(accessory, params, function () {
+ return;
+ });
+ accessory.getService(Service.WindowCovering)
+ .updateCharacteristic(Characteristic.TargetPosition, value)
+ .updateCharacteristic(Characteristic.PositionState, (value / 100));
+ if (!blindConfig.inched || blindConfig.inched === "false") {
+ setTimeout(() => {
+ switch (blindConfig.setup) {
+ case "oneSwitch":
+ params.switch = "off";
+ break;
+ case "twoSwitch":
+ params.switches[0].switch = "off";
+ params.switches[1].switch = "off";
+ break;
+ }
+ this.sendDeviceUpdate(accessory, params, function () {
+ return;
+ });
+ }, 500);
+ }
+ setTimeout(() => {
+ accessory.getService(Service.WindowCovering)
+ .updateCharacteristic(Characteristic.CurrentPosition, value)
+ .updateCharacteristic(Characteristic.PositionState, 2);
+ callback();
+ }, parseInt(blindConfig.operationTime) * 100);
+ } catch (err) {
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ this.log.error(str);
+ callback(str);
+ }
+ }
+ internalGarageUpdate(accessory, value, callback) {
+ try {
+ if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
+ throw "it is currently offline";
+ }
+ let garageConfig;
+ if (!(garageConfig = this.cusG.get(accessory.context.hbDeviceId))) {
+ throw "group config missing";
+ }
+ if (garageConfig.type !== "garage" || !["oneSwitch", "twoSwitch"].includes(garageConfig.setup)) {
+ throw "improper configuration";
+ }
+ let sensorDefinition = garageConfig.sensorId || false,
+ sAccessory = false,
+ pSte,
+ params = {};
+ if (sensorDefinition && !(sAccessory = this.devicesInHB.get(garageConfig.sensorId + "SWX"))) {
+ throw "defined sensor doesn't exist";
+ }
+ this.log("[%s] has received request to [%s].", accessory.displayName, value === 0 ? "open" : "close");
+ pSte = sAccessory ?
+ sAccessory.getService(Service.ContactSensor).getCharacteristic(Characteristic.ContactSensorState).value === 0 ? 1 : 0 : [0, 2].includes(accessory.getService(Service.GarageDoorOpener).getCharacteristic(Characteristic.CurrentDoorState).value) ? 0 : 1;
+ if (value === pSte) {
+ accessory.getService(Service.GarageDoorOpener)
+ .updateCharacteristic(Characteristic.TargetDoorState, value)
+ .updateCharacteristic(Characteristic.CurrentDoorState, value);
+ callback();
+ return;
+ }
+ switch (garageConfig.setup) {
+ case "oneSwitch":
+ params.switch = "on";
+ break;
+ case "twoSwitch":
+ params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
+ params.switches[0].switch = value === 0 ? "on" : "off";
+ params.switches[1].switch = value === 1 ? "on" : "off";
+ break;
+ }
+ this.sendDeviceUpdate(accessory, params, function () {
+ return;
+ });
+ accessory.getService(Service.GarageDoorOpener)
+ .updateCharacteristic(Characteristic.TargetDoorState, value)
+ .updateCharacteristic(Characteristic.CurrentDoorState, value === 0 ? 2 : 3);
+ if (!garageConfig.inched || garageConfig.inched === "false") {
+ setTimeout(() => {
+ switch (garageConfig.setup) {
+ case "oneSwitch":
+ params.switch = "off";
+ break;
+ case "twoSwitch":
+ params.switches[0].switch = "off";
+ params.switches[1].switch = "off";
+ break;
+ }
+ this.sendDeviceUpdate(accessory, params, function () {
+ return;
+ });
+ }, 500);
+ }
+ if (!sAccessory) {
+ setTimeout(() => {
+ accessory.getService(Service.GarageDoorOpener)
+ .updateCharacteristic(Characteristic.CurrentDoorState, value === 0 ? 0 : 1);
+ callback();
+ }, parseInt(garageConfig.operationTime) * 100);
+ } else {
+ callback();
+ }
+ } catch (err) {
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ this.log.error(str);
+ callback(str);
+ }
+ }
+ internalFanUpdate(accessory, type, value, callback) {
+ try {
+ if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
+ throw "it is currently offline";
+ }
+ let newPower, newSpeed, newLight;
+ switch (type) {
+ case "power":
+ newPower = value;
+ newSpeed = value ? 33 : 0;
+ newLight = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value;
+ break;
+ case "speed":
+ newPower = value >= 33 ? 1 : 0;
+ newSpeed = value;
+ newLight = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value;
+ break;
+ case "light":
+ newPower = accessory.getService(Service.Fanv2).getCharacteristic(Characteristic.Active).value;
+ newSpeed = accessory.getService(Service.Fanv2).getCharacteristic(Characteristic.RotationSpeed).value;
+ newLight = value;
+ break;
+ }
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, newLight);
+ accessory.getService(Service.Fanv2)
+ .updateCharacteristic(Characteristic.Active, newPower)
+ .updateCharacteristic(Characteristic.RotationSpeed, newSpeed);
+ let params = {
+ switches: this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches
+ };
+ params.switches[0].switch = newLight ? "on" : "off";
+ params.switches[1].switch = (newPower === 1 && newSpeed >= 33) ? "on" : "off";
+ params.switches[2].switch = (newPower === 1 && newSpeed >= 66 && newSpeed < 99) ? "on" : "off";
+ params.switches[3].switch = (newPower === 1 && newSpeed >= 99) ? "on" : "off";
+ if (this.debug) {
+ this.log.warn("Fan Update - setting " + type + " to " + value);
+ this.log("[%s] new stats: power [%s], speed [%s%], light [%s].", accessory.displayName, newPower, newSpeed, newLight);
+ }
+ this.sendDeviceUpdate(accessory, params, callback);
+ } catch (err) {
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ this.log.error(str);
+ callback(str);
+ }
+ }
+ internalThermostatUpdate(accessory, value, callback) {
+ try {
+ if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
+ throw "it is currently offline";
+ }
+ let params = {
+ switch: value ? "on" : "off",
+ mainSwitch: value ? "on" : "off"
+ };
+ if (this.debug) {
+ this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
+ }
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
+ this.sendDeviceUpdate(accessory, params, callback);
+ } catch (err) {
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ this.log.error(str);
+ callback(str);
+ }
+ }
+ internalOutletUpdate(accessory, value, callback) {
+ try {
+ if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
+ throw "it is currently offline";
+ }
+ let params = {
+ switch: value ? "on" : "off"
+ };
+ if (this.debug) {
+ this.log("[%s] requesting to turn [%s].", accessory.displayName, value ? "on" : "off");
+ }
+ accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, value);
+ this.sendDeviceUpdate(accessory, params, callback);
+ } catch (err) {
+ callback("[" + accessory.displayName + "] " + err + ".");
+ }
+ }
+ internalUSBUpdate(accessory, value, callback) {
+ try {
+ if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
+ throw "it is currently offline";
+ }
+ let params = {
+ switches: this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches
+ };
+ params.switches[0].switch = value ? "on" : "off";
+ if (this.debug) {
+ this.log("[%s] requesting to turn [%s].", accessory.displayName, value ? "on" : "off");
+ }
+ accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, value);
+ this.sendDeviceUpdate(accessory, params, callback);
+ } catch (err) {
+ callback("[" + accessory.displayName + "] " + err + ".");
+ }
+ }
+ internalSCMUpdate(accessory, value, callback) {
+ try {
+ if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
+ throw "it is currently offline";
+ }
+ let params = {
+ switches: this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches
+ };
+ params.switches[0].switch = value ? "on" : "off";
+ if (this.debug) {
+ this.log("[%s] requesting to turn [%s].", accessory.displayName, value ? "on" : "off");
+ }
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
+ this.sendDeviceUpdate(accessory, params, callback);
+ } catch (err) {
+ callback("[" + accessory.displayName + "] " + err + ".");
+ }
+ }
+ internalLightbulbUpdate(accessory, value, callback) {
+ try {
+ if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
+ throw "it is currently offline";
+ }
+ let oAccessory, params = {};
+ switch (accessory.context.switchNumber) {
+ case "X":
+ if (accessory.context.eweUIID === 22) { //*** B1 ***\\
+ params.state = value ? "on" : "off";
+ } else {
+ params.switch = value ? "on" : "off";
+ }
+ if (this.debug) {
+ this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
+ }
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
+ break;
+ case "0":
+ params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
+ params.switches[0].switch = value ? "on" : "off";
+ params.switches[1].switch = value ? "on" : "off";
+ params.switches[2].switch = value ? "on" : "off";
+ params.switches[3].switch = value ? "on" : "off";
+ if (this.debug) {
+ this.log("[%s] updating to turn group [%s].", accessory.displayName, value ? "on" : "off");
+ }
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
+ for (let i = 1; i <= 4; i++) {
+ if (this.devicesInHB.has(accessory.context.eweDeviceId + "SW" + i)) {
+ oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i);
+ oAccessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
+ }
+ }
+ break;
+ case "1":
+ case "2":
+ case "3":
+ case "4":
+ if (this.debug) {
+ this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
+ }
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
+ let tAccessory,
+ masterState = "off";
+ params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
+ for (let i = 1; i <= 4; i++) {
+ if ((tAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
+ i === parseInt(accessory.context.switchNumber) ?
+ params.switches[i - 1].switch = value ? "on" : "off" :
+ params.switches[i - 1].switch = tAccessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value ? "on" : "off";
+ if (tAccessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value) {
+ masterState = "on";
+ }
+ } else {
+ params.switches[i - 1].switch = "off";
+ }
+ }
+ oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
+ oAccessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, masterState === "on");
+ break;
+ default:
+ throw "unknown switch number [" + accessory.context.switchNumber + "]";
+ }
+ this.sendDeviceUpdate(accessory, params, callback);
+ } catch (err) {
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ this.log.error(str);
+ callback(str);
+ }
+ }
+ internalBrightnessUpdate(accessory, value, callback) {
+ try {
+ if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
+ throw "it is currently offline";
+ }
+ let params = {};
+ if (value === 0) {
+ params.switch = "off";
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, false);
+ } else {
+ if (!accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value) {
+ params.switch = "on";
+ }
+ switch (accessory.context.eweUIID) {
+ case 36: //*** KING-M4 ***\\
+ params.bright = Math.round(value * 9 / 10 + 10);
+ break;
+ case 44: //*** D1 ***\\
+ params.brightness = value;
+ params.mode = 0;
+ break;
+ default:
+ throw "unknown device UIID";
+ }
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Brightness, value);
+ }
+ if (this.debug) {
+ this.log("[%s] updating brightness to [%s%].", accessory.displayName, value);
+ }
+ setTimeout(() => {
+ this.sendDeviceUpdate(accessory, params, callback);
+ }, 250);
+ } catch (err) {
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ this.log.error(str);
+ callback(str);
+ }
+ }
+ internalHSBUpdate(accessory, type, value, callback) {
+ try {
+ if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
+ throw "it is currently offline";
+ }
+ let newRGB,
+ params = {},
+ curHue = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Hue).value,
+ curSat = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Saturation).value;
+ switch (type) {
+ case "hue":
+ newRGB = convert.hsv.rgb(value, curSat, 100);
+ switch (accessory.context.eweUIID) {
+ case 22: //*** B1 ***\\
+ params = {
+ zyx_mode: 2,
+ type: "middle",
+ channel0: "0",
+ channel1: "0",
+ channel2: newRGB[0].toString(),
+ channel3: newRGB[1].toString(),
+ channel4: newRGB[2].toString()
+ };
+ break;
+ case 59: //*** L1 ***\\
+ params = {
+ mode: 1,
+ colorR: newRGB[0],
+ colorG: newRGB[1],
+ colorB: newRGB[2]
+ };
+ break;
+ default:
+ throw "unknown device UIID";
+ }
+ if (this.debug) {
+ this.log("[%s] updating hue to [%s°].", accessory.displayName, value);
+ }
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Hue, value);
+ break;
+ case "bri":
+ switch (accessory.context.eweUIID) {
+ case 22: //*** B1 ***\\
+ newRGB = convert.hsv.rgb(curHue, curSat, value);
+ params = {
+ zyx_mode: 2,
+ type: "middle",
+ channel0: "0",
+ channel1: "0",
+ channel2: newRGB[0].toString(),
+ channel3: newRGB[1].toString(),
+ channel4: newRGB[2].toString()
+ };
+ break;
+ case 59: //*** L1 ***\\
+ params = {
+ mode: 1,
+ bright: value
+ };
+ break;
+ }
+ if (this.debug) {
+ this.log("[%s] updating brightness to [%s%].", accessory.displayName, value);
+ }
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Brightness, value);
+ break;
+ default:
+ throw "unknown device UIID";
+ }
+ setTimeout(() => {
+ this.sendDeviceUpdate(accessory, params, callback);
+ }, 250);
+ } catch (err) {
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ this.log.error(str);
+ callback(str);
+ }
+ }
+ internalSwitchUpdate(accessory, value, callback) {
+ try {
+ if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
+ throw "it is currently offline";
+ }
+ let oAccessory, params = {};
+ switch (accessory.context.switchNumber) {
+ case "X":
+ params.switch = value ? "on" : "off";
+ if (this.debug) {
+ this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
+ }
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
+ break;
+ case "0":
+ params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
+ params.switches[0].switch = value ? "on" : "off";
+ params.switches[1].switch = value ? "on" : "off";
+ params.switches[2].switch = value ? "on" : "off";
+ params.switches[3].switch = value ? "on" : "off";
+ if (this.debug) {
+ this.log("[%s] updating to turn group [%s].", accessory.displayName, value ? "on" : "off");
+ }
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
+ for (let i = 1; i <= 4; i++) {
+ if (this.devicesInHB.has(accessory.context.eweDeviceId + "SW" + i)) {
+ oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i);
+ oAccessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
+ }
+ }
+ break;
+ case "1":
+ case "2":
+ case "3":
+ case "4":
+ if (this.debug) {
+ this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
+ }
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
+ let tAccessory,
+ masterState = "off";
+ params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
+ for (let i = 1; i <= 4; i++) {
+ if ((tAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
+ i === parseInt(accessory.context.switchNumber) ?
+ params.switches[i - 1].switch = value ? "on" : "off" :
+ params.switches[i - 1].switch = tAccessory.getService(Service.Switch).getCharacteristic(Characteristic.On).value ? "on" : "off";
+ if (tAccessory.getService(Service.Switch).getCharacteristic(Characteristic.On).value) {
+ masterState = "on";
+ }
+ } else {
+ params.switches[i - 1].switch = "off";
+ }
+ }
+ oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
+ oAccessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, masterState === "on");
+ break;
+ default:
+ throw "unknown switch number [" + accessory.context.switchNumber + "]";
+ }
+ this.sendDeviceUpdate(accessory, params, callback);
+ } catch (err) {
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ this.log.error(str);
+ callback(str);
+ }
+ }
+ externalValveUpdate(accessory, params) {
+ try {
+ ["A", "B"].forEach((v, k) => {
+ accessory.getService("Valve " + v)
+ .updateCharacteristic(Characteristic.Active, params.switches[k].switch === "on")
+ .updateCharacteristic(Characteristic.InUse, params.switches[k].switch === "on");
+ if (params.switches[k].switch === "on") {
+ let timer = accessory.getService("Valve " + v).getCharacteristic(Characteristic.SetDuration).value;
+ accessory.getService("Valve " + v).updateCharacteristic(Characteristic.RemainingDuration, timer);
+ accessory.getService("Valve " + v).timer = setTimeout(() => {
+ accessory.getService("Valve " + v).setCharacteristic(Characteristic.Active, 0);
+ }, (timer * 1000));
+ } else {
+ accessory.getService("Valve " + v).updateCharacteristic(Characteristic.RemainingDuration, 0);
+ clearTimeout(accessory.getService("Valve " + v).timer);
+ }
+ });
+ } catch (err) {
+ this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
+ }
+ }
+ internalRFDeviceUpdate(accessory, value, callback) {
+ try {
+ if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
+ throw "it is currently offline";
+ }
+ let params = {
+ cmd: "transmit",
+ rfChl: accessory.context.rfChl
+ };
+ if (this.debug) {
+ this.log("[%s] mimicking RF button press.", accessory.displayName);
+ }
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, true);
+ this.sendDeviceUpdate(accessory, params, callback);
+ setTimeout(() => {
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, false);
+ }, 500);
+ } catch (err) {
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ this.log.error(str);
+ callback(str);
+ }
+ }
+ externalBlindUpdate(accessory, params) {
+ try {
+ let blindConfig, nSte;
+ if (!(blindConfig = this.cusG.get(accessory.context.hbDeviceId))) {
+ throw "group config missing";
+ }
+ if (blindConfig.type !== "blind" || ["oneSwitch", "twoSwitch"].includes(blindConfig.setup)) {
+ throw "improper configuration";
+ }
+ switch (blindConfig.setup) {
+ case "oneSwitch":
+ if (params.switch === "off") {
+ return;
+ }
+ nSte = accessory.getService(Service.WindowCovering).getCharacteristic(Characteristic.PositionState).value === 0 ? 1 : 0;
+ break;
+ case "twoSwitch":
+ if (params.switches[0].switch === "off" && params.switches[1].switch === "off") {
+ return;
+ }
+ let switchUp = params.switches[0].switch === "on" ? -1 : 0, // matrix of numbers to get
+ switchDown = params.switches[1].switch === "on" ? 0 : 2; // ... the correct HomeKit value
+ nSte = switchUp + switchDown;
+ break;
+ }
+ accessory.getService(Service.WindowCovering)
+ .updateCharacteristic(Characteristic.PositionState, nSte)
+ .updateCharacteristic(Characteristic.TargetPosition, nSte * 100);
+ setTimeout(() => {
+ accessory.getService(Service.WindowCovering)
+ .updateCharacteristic(Characteristic.PositionState, 2)
+ .updateCharacteristic(Characteristic.CurrentPosition, nSte * 100);
+ }, parseInt(blindConfig.operationTime) * 100);
+ } catch (err) {
+ this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
+ }
+ }
+ externalGarageUpdate(accessory, params) {
+ try {
+ let garageConfig, nSte;
+ if (!(garageConfig = this.cusG.get(accessory.context.hbDeviceId))) {
+ throw "group config missing";
+ }
+ if (garageConfig.type !== "garage" || !["oneSwitch", "twoSwitch"].includes(garageConfig.setup)) {
+ throw "improper configuration";
+ }
+ switch (garageConfig.setup) {
+ case "oneSwitch":
+ if (params.switch === "off" || garageConfig.sensorId) {
+ return;
+ }
+ nSte = [0, 2].includes(accessory.getService(Service.GarageDoorOpener).getCharacteristic(Characteristic.CurrentDoorState).value) ? 3 : 2;
+ break;
+ case "twoSwitch":
+ if (params.switches[0].switch === "off" && params.switches[1].switch === "off") {
+ return;
+ }
+ // @TODO twoSwitch garage external update
+ return;
+ }
+ if (garageConfig.setup !== "oneSwitch" || !garageConfig.sensorId) {
+ accessory.getService(Service.GarageDoorOpener)
+ .updateCharacteristic(Characteristic.CurrentDoorState, nSte)
+ .updateCharacteristic(Characteristic.TargetDoorState, nSte - 2);
+ setTimeout(() => {
+ accessory.getService(Service.GarageDoorOpener)
+ .updateCharacteristic(Characteristic.CurrentDoorState, nSte - 2);
+ }, parseInt(garageConfig.operationTime) * 100);
+ }
+ } catch (err) {
+ this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
+ }
+ }
+ externalSensorUpdate(accessory, params) {
+ try {
+ let oldState = accessory.getService(Service.ContactSensor).getCharacteristic(Characteristic.ContactSensorState).value,
+ newState = params.switch === "on" ? 1 : 0,
+ oAccessory = false;
+ accessory.getService(Service.ContactSensor).updateCharacteristic(Characteristic.ContactSensorState, newState);
+ this.log("[%s] sent update that it was [%s] and is now [%s].", accessory.displayName, oldState ? "apart" : "joined", newState ? "apart" : "joined");
+ this.cusG.forEach(group => {
+ if (group.sensorId === accessory.context.eweDeviceId && group.type === "garage") {
+ if ((oAccessory = this.devicesInHB.get(group.deviceId + "SWX"))) {
+ switch (newState) {
+ case 0:
+ oAccessory.getService(Service.GarageDoorOpener)
+ .updateCharacteristic(Characteristic.TargetDoorState, 1)
+ .updateCharacteristic(Characteristic.CurrentDoorState, 1);
+ this.log("[%s] updating to [closed] based on sensor.", oAccessory.displayName);
+ break;
+ case 1:
+ setTimeout(() => {
+ oAccessory.getService(Service.GarageDoorOpener)
+ .updateCharacteristic(Characteristic.TargetDoorState, 0)
+ .updateCharacteristic(Characteristic.CurrentDoorState, 0);
+ this.log("[%s] updating to [open] based on sensor.", oAccessory.displayName);
+ }, group.operationTime * 100);
+ break;
+ default:
+ throw "unknown sensor status received";
+ }
+ }
+ }
+ });
+ } catch (err) {
+ this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
+ }
+ }
+ externalFanUpdate(accessory, params) {
+ try {
+ let light, status, speed;
+ if (Array.isArray(params.switches)) {
+ light = params.switches[0].switch === "on";
+ switch (params.switches[1].switch+params.switches[2].switch+params.switches[3].switch) {
+ default:
+ status = 0;
+ speed = 0;
+ break;
+ case "onoffoff":
+ status = 1;
+ speed = 33;
+ break;
+ case "ononoff":
+ status = 1;
+ speed = 66;
+ break;
+ case "onoffon":
+ status = 1;
+ speed = 99;
+ }
+ } else if (params.hasOwnProperty("light") && params.hasOwnProperty("fan") && params.hasOwnProperty("speed")) {
+ light = params.light === "on";
+ status = params.fan === "on" ? 1 : 0;
+ speed = params.speed * 33 * status;
+ } else {
+ throw "unknown parameters received";
+ }
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, light);
+ accessory.getService(Service.Fanv2)
+ .updateCharacteristic(Characteristic.Active, status)
+ .updateCharacteristic(Characteristic.RotationSpeed, speed);
+ } catch (err) {
+ this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
+ }
+ }
+ externalThermostatUpdate(accessory, params) {
+ try {
+ if (params.hasOwnProperty("switch") || params.hasOwnProperty("mainSwitch")) {
+ let newState = params.hasOwnProperty("switch") ? params.switch === "on" : params.mainSwitch === "on";
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, newState);
+ }
+ if (params.hasOwnProperty("currentTemperature") && accessory.getService(Service.TemperatureSensor)) {
+ let currentTemp = params.currentTemperature !== "unavailable" ? params.currentTemperature : 0;
+ accessory.getService(Service.TemperatureSensor).updateCharacteristic(Characteristic.CurrentTemperature, currentTemp);
+ }
+ if (params.hasOwnProperty("currentHumidity") && accessory.getService(Service.HumiditySensor)) {
+ let currentHumi = params.currentHumidity !== "unavailable" ? params.currentHumidity : 0;
+ accessory.getService(Service.HumiditySensor).updateCharacteristic(Characteristic.CurrentRelativeHumidity, currentHumi);
+ }
+ } catch (err) {
+ this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
+ }
+ }
+ externalOutletUpdate(accessory, params) {
+ try {
+ accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, params.switch === "on");
+ } catch (err) {
+ this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
+ }
+ }
+ externalUSBUpdate(accessory, params) {
+ try {
+ accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, params.switches[0].switch === "on");
+ } catch (err) {
+ this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
+ }
+ }
+ externalSCMUpdate(accessory, params) {
+ try {
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, params.switches[0].switch === "on");
+ } catch (err) {
+ this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
+ }
+ }
+ externalSingleLightUpdate(accessory, params) {
+ try {
+ let newColour, mode, isOn = false;
+ if (accessory.context.eweUIID === 22 && params.hasOwnProperty("state")) {
+ isOn = params.state === "on";
+ } else if (accessory.context.eweUIID !== 22 && params.hasOwnProperty("switch")) {
+ isOn = params.switch === "on";
+ } else {
+ isOn = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value;
+ }
+ if (isOn) {
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, true);
+ switch (accessory.context.eweUIID) {
+ case 36: // KING-M4
+ if (params.hasOwnProperty("bright")) {
+ let nb = Math.round((params.bright - 10) * 10 / 9); // eWeLink scale is 10-100 and HomeKit scale is 0-100.
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Brightness, nb);
+ }
+ break;
+ case 44: // D1
+ if (params.hasOwnProperty("brightness")) {
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Brightness, params.brightness);
+ }
+ break;
+ case 22: // B1
+ if (params.hasOwnProperty("zyx_mode")) {
+ mode = parseInt(params.zyx_mode);
+ } else if (params.hasOwnProperty("channel0") && (parseInt(params.channel0) + parseInt(params.channel1) > 0)) {
+ mode = 1;
+ } else {
+ mode = 2;
+ }
+ if (mode === 2) {
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, true);
+ newColour = convert.rgb.hsv(parseInt(params.channel2), parseInt(params.channel3), parseInt(params.channel4));
+ accessory.getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.Hue, newColour[0])
+ .updateCharacteristic(Characteristic.Saturation, 100)
+ .updateCharacteristic(Characteristic.Brightness, 100);
+ } else if (mode === 1) {
+ throw "has been set to white mode which is not supported";
+ }
+ break;
+ case 59: // L1
+ if (params.hasOwnProperty("bright")) {
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Brightness, params.bright);
+ }
+ if (params.hasOwnProperty("colorR")) {
+ newColour = convert.rgb.hsv(params.colorR, params.colorG, params.colorB);
+ accessory.getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.Hue, newColour[0])
+ .updateCharacteristic(Characteristic.Saturation, newColour[1]);
+ }
+ break;
+ default:
+ return;
+ }
+ } else {
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, false);
+ }
+ } catch (err) {
+ this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
+ }
+ }
+ externalMultiLightUpdate(accessory, params) {
+ try {
+ let idToCheck = accessory.context.hbDeviceId.slice(0, -1),
+ primaryState = false;
+ for (let i = 1; i <= accessory.context.channelCount; i++) {
+ if (this.devicesInHB.has(idToCheck + i)) {
+ let oAccessory = this.devicesInHB.get(idToCheck + i);
+ oAccessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, params.switches[i - 1].switch === "on");
+ if (params.switches[i - 1].switch === "on") {
+ primaryState = true;
+ }
+ }
+ }
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, primaryState);
+ } catch (err) {
+ this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
+ }
+ }
+ externalSingleSwitchUpdate(accessory, params) {
+ try {
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, params.switch === "on");
+ } catch (err) {
+ this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
+ }
+ }
+ externalMultiSwitchUpdate(accessory, params) {
+ try {
+ let idToCheck = accessory.context.hbDeviceId.slice(0, -1),
+ primaryState = false;
+ for (let i = 1; i <= accessory.context.channelCount; i++) {
+ if (this.devicesInHB.has(idToCheck + i)) {
+ let oAccessory = this.devicesInHB.get(idToCheck + i);
+ oAccessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, params.switches[i - 1].switch === "on");
+ if (params.switches[i - 1].switch === "on") {
+ primaryState = true;
+ }
+ }
+ }
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, primaryState);
+ } catch (err) {
+ this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
+ }
+ }
+ externalRFDeviceUpdate(accessory, params) {
+ try {
+ let idToCheck = accessory.context.hbDeviceId.slice(0, -1),
+ timeNow = new Date();
+ if (params.hasOwnProperty("cmd") && params.cmd === "transmit" && params.hasOwnProperty("rfChl")) { // RF Button
+ let bAccessory;
+ if ((bAccessory = this.devicesInHB.get(idToCheck + (params.rfChl + 1)))) {
+ bAccessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, 1);
+ setTimeout(() => {
+ bAccessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, 0);
+ }, 500);
+ } else {
+ throw "rf button not found in Homebridge";
+ }
+ return;
+ } // else RF Sensor
+ for (let i = 1; i <= accessory.context.channelCount; i++) {
+ if (this.devicesInHB.has(idToCheck + i)) {
+ let oAccessory = this.devicesInHB.get(idToCheck + i);
+ if (params.hasOwnProperty("rfTrig" + (i - 1))) {
+ let timeOfMotion = new Date(params["rfTrig" + (i - 1)]),
+ timeDifference = (timeNow.getTime() - timeOfMotion.getTime()) / 1000;
+ if (timeDifference < this.sensorTimeDifference) {
+ switch (oAccessory.context.sensorType) {
+ case "button":
+ break;
+ case "water":
+ oAccessory.getService(Service.LeakSensor).updateCharacteristic(Characteristic.LeakDetected, 1);
+ break;
+ case "fire":
+ case "smoke":
+ oAccessory.getService(Service.SmokeSensor).updateCharacteristic(Characteristic.SmokeDetected, 1);
+ break;
+ case "co":
+ oAccessory.getService(Service.CarbonMonoxideSensor).updateCharacteristic(Characteristic.CarbonMonoxideDetected, 1);
+ break;
+ case "co2":
+ oAccessory.getService(Service.CarbonDioxideSensor).updateCharacteristic(Characteristic.CarbonDioxideDetected, 1);
+ break;
+ case "contact":
+ oAccessory.getService(Service.ContactSensor).updateCharacteristic(Characteristic.ContactSensorState, 1);
+ break;
+ case "occupancy":
+ oAccessory.getService(Service.OccupancySensor).updateCharacteristic(Characteristic.OccupancyDetected, 1);
+ break;
+ case "motion":
+ default:
+ oAccessory.getService(Service.MotionSensor).updateCharacteristic(Characteristic.MotionDetected, true);
+ break;
+ }
+ if (this.debug) {
+ this.log("[%s] has detected [%s].", oAccessory.displayName, oAccessory.context.sensorType);
+ }
+ }
+ }
+ }
+ }
+ setTimeout(() => {
+ for (let i = 1; i <= accessory.context.channelCount; i++) {
+ if (this.devicesInHB.has(idToCheck + i)) {
+ let oAccessory = this.devicesInHB.get(idToCheck + i);
+ switch (oAccessory.context.sensorType) {
+ case "button":
+ break;
+ case "water":
+ oAccessory.getService(Service.LeakSensor).updateCharacteristic(Characteristic.LeakDetected, 0);
+ break;
+ case "fire":
+ case "smoke":
+ oAccessory.getService(Service.SmokeSensor).updateCharacteristic(Characteristic.SmokeDetected, 0);
+ break;
+ case "co":
+ oAccessory.getService(Service.CarbonMonoxideSensor).updateCharacteristic(Characteristic.CarbonMonoxideDetected, 0);
+ break;
+ case "co2":
+ oAccessory.getService(Service.CarbonDioxideSensor).updateCharacteristic(Characteristic.CarbonDioxideDetected, 0);
+ break;
+ case "contact":
+ oAccessory.getService(Service.ContactSensor).updateCharacteristic(Characteristic.ContactSensorState, 0);
+ break;
+ case "occupancy":
+ oAccessory.getService(Service.OccupancySensor).updateCharacteristic(Characteristic.OccupancyDetected, 0);
+ break;
+ case "motion":
+ default:
+ oAccessory.getService(Service.MotionSensor).updateCharacteristic(Characteristic.MotionDetected, false);
+ break;
+ }
+ }
+ }
+ }, this.sensorTimeLength * 1000);
+ } catch (err) {
+ this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
+ }
+ }
+ externalZBDeviceUpdate(accessory, params) {
+ try {
+ switch (accessory.context.eweUIID) {
+ case 1000:
+ if (params.hasOwnProperty("key")) {
+ if ([0, 1, 2].includes(params.key)) {
+ accessory.getService(Service.StatelessProgrammableSwitch).updateCharacteristic(Characteristic.ProgrammableSwitchEvent, params.key); //*** credit @tasict ***\\
+ } else {
+ throw "unknown 'key' parameter received [" + params.key + "]";
+ }
+ }
+ break;
+ case 1770:
+ if (params.hasOwnProperty("temperature")) {
+ let currentTemp = parseInt(params.temperature) / 100;
+ accessory.getService(Service.TemperatureSensor).updateCharacteristic(Characteristic.CurrentTemperature, currentTemp);
+ }
+ if (params.hasOwnProperty("humidity")) {
+ let currentHumi = parseInt(params.humidity) / 100;
+ accessory.getService(Service.HumiditySensor).updateCharacteristic(Characteristic.CurrentRelativeHumidity, currentHumi);
+ }
+ break;
+ case 2026:
+ if (params.hasOwnProperty("motion")) {
+ if ([0, 1].includes(params.lock)) {
+ accessory.getService(Service.MotionSensor).updateCharacteristic(Characteristic.MotionDetected, params.motion);
+ } else {
+ throw "unknown 'motion' parameter received [" + params.motion + "]";
+ }
+ }
+ break;
+ case 3026:
+ if (params.hasOwnProperty("lock")) {
+ if ([0, 1].includes(params.lock)) {
+ accessory.getService(Service.ContactSensor).updateCharacteristic(Characteristic.ContactSensorState, params.lock);
+ } else {
+ throw "unknown 'lock' parameter received [" + params.lock + "]";
+ }
+ }
+ break;
+ default:
+ throw "unsupported zigbee device type";
+ }
+ } catch (err) {
+ this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
+ }
+ }
+}
+module.exports = function (homebridge) {
+ Accessory = homebridge.platformAccessory;
+ Service = homebridge.hap.Service;
+ Characteristic = homebridge.hap.Characteristic;
+ UUIDGen = homebridge.hap.uuid;
+ return eWeLink;
+};
\ No newline at end of file
diff --git a/lib/eWeLinkHTTP.js b/lib/eWeLinkHTTP.js
new file mode 100644
index 00000000..f6c0c71d
--- /dev/null
+++ b/lib/eWeLinkHTTP.js
@@ -0,0 +1,158 @@
+/* jshint esversion: 9, -W030, node: true */
+"use strict";
+const axios = require("axios");
+const constants = require("./constants");
+const crypto = require("crypto");
+module.exports = class eWeLinkHTTP {
+ constructor(config, log) {
+ this.config = config;
+ this.log = log;
+ this.debug = this.config.debug || false;
+ this.debugReqRes = this.config.debugReqRes || false;
+ }
+ login() {
+ let data = {
+ countryCode: "+" + this.config.countryCode.toString().replace("+", "").replace(" ", ""),
+ password: this.config.password
+ };
+ this.config.username.includes("@") ?
+ data.email = this.config.username :
+ data.phoneNumber = this.config.username;
+ if (this.debugReqRes) {
+ let msg = JSON.stringify(data, null, 2).replace(this.config.password, "**hidden**").replace(this.config.username, "**hidden**");
+ this.log.warn("Sending HTTP login request. This text is yellow for clarity.\n%s", msg);
+ } else if (this.debug) {
+ this.log("Sending HTTP login request.");
+ }
+ let dataToSign = crypto.createHmac("sha256", "6Nz4n0xA8s8qdxQf2GqurZj2Fs55FUvM").update(JSON.stringify(data)).digest("base64");
+ return new Promise((resolve, reject) => {
+ axios({
+ url: "https://" + this.httpHost + "/v2/user/login",
+ method: "post",
+ headers: {
+ Authorization: "Sign " + dataToSign,
+ "Content-Type": "application/json",
+ Host: this.httpHost,
+ "X-CK-Appid": constants.appId,
+ "X-CK-Nonce": Math.random().toString(36).substr(2, 8)
+ },
+ data
+ }).then(res => {
+ let body = res.data;
+ if (body.hasOwnProperty("error") && body.error === 10004 && body.hasOwnProperty("data") && body.data.hasOwnProperty("region")) {
+ switch (body.data.region) {
+ case "eu":
+ case "us":
+ case "as":
+ this.httpHost = body.data.region + "-apia.coolkit.cc";
+ break;
+ case "cn":
+ this.httpHost = "cn-apia.coolkit.cn";
+ break;
+ default:
+ throw "No valid region received - [" + body.data.region + "].";
+ }
+ if (this.debug) {
+ this.log("New HTTP API host received [%s].", this.httpHost);
+ }
+ resolve(this.login());
+ return;
+ }
+ if (!body.data.at) {
+ throw "Server did not respond with an authentication token. Please double check your eWeLink username and password in the Homebridge configuration.\n" + JSON.stringify(body, null, 2);
+ }
+ this.aToken = body.data.at;
+ this.apiKey = body.data.user.apikey;
+ resolve({
+ aToken: body.data.at,
+ apiKey: body.data.user.apikey,
+ httpHost: this.httpHost
+ });
+ }).catch(err => {
+ reject(err);
+ });
+ });
+ }
+ getHost() {
+ let data = {
+ appid: constants.appId,
+ country_code: this.config.countryCode.toString().replace("+", "").replace(" ", ""),
+ nonce: Math.random().toString(36).substr(2, 8),
+ ts: Math.floor(new Date().getTime() / 1000),
+ version: 8
+ },
+ dataToSign = [];
+ Object.keys(data).forEach(function (key) {
+ dataToSign.push({
+ key: key,
+ value: data[key]
+ });
+ });
+ dataToSign.sort(function (a, b) {
+ return a.key < b.key ? -1 : 1;
+ });
+ dataToSign = dataToSign.map(function (kv) {
+ return kv.key + "=" + kv.value;
+ }).join("&");
+ dataToSign = crypto.createHmac("sha256", "6Nz4n0xA8s8qdxQf2GqurZj2Fs55FUvM").update(dataToSign).digest("base64");
+ return new Promise((resolve, reject) => {
+ axios.get("https://api.coolkit.cc:8080/api/user/region", {
+ headers: {
+ Authorization: "Sign " + dataToSign,
+ "Content-Type": "application/json"
+ },
+ params: data
+ }).then(res => {
+ let body = res.data;
+ if (!body.region) {
+ throw "Server did not respond with a region.\n" + JSON.stringify(body, null, 2);
+ }
+ switch (body.region) {
+ case "eu":
+ case "us":
+ case "as":
+ this.httpHost = body.region + "-apia.coolkit.cc";
+ break;
+ case "cn":
+ this.httpHost = "cn-apia.coolkit.cn";
+ break;
+ default:
+ throw "No valid region received - [" + body.region + "].";
+ }
+ if (this.debug) {
+ this.log("HTTP API host received [%s].", this.httpHost);
+ }
+ resolve(this.httpHost);
+ }).catch(err => {
+ reject(err);
+ });
+ });
+ }
+ getDevices() {
+ return new Promise((resolve, reject) => {
+ axios.get("https://" + this.httpHost + "/v2/device/thing", {
+ headers: {
+ Authorization: "Bearer " + this.aToken,
+ "Content-Type": "application/json",
+ Host: this.httpHost,
+ "X-CK-Appid": constants.appId,
+ "X-CK-Nonce": Math.random().toString(36).substr(2, 8)
+ }
+ }).then(res => {
+ let body = res.data;
+ if (!body.hasOwnProperty("error") || (body.hasOwnProperty("error") && body.error !== 0)) {
+ throw JSON.stringify(body, null, 2);
+ }
+ let deviceList = [];
+ if (body.data.thingList && body.data.thingList.length > 0) {
+ body.data.thingList.forEach(device => {
+ deviceList.push(device.itemData);
+ });
+ }
+ resolve(deviceList);
+ }).catch(err => {
+ reject(err);
+ });
+ });
+ }
+};
\ No newline at end of file
diff --git a/lib/eWeLinkLAN.js b/lib/eWeLinkLAN.js
new file mode 100644
index 00000000..9146dbe7
--- /dev/null
+++ b/lib/eWeLinkLAN.js
@@ -0,0 +1,157 @@
+/* jshint esversion: 9, -W030, node: true */
+"use strict";
+const axios = require("axios");
+const constants = require("./constants");
+const crypto = require("crypto");
+const dns = require("node-dns-sd");
+const eventemitter = require("events");
+module.exports = class eWeLinkLAN {
+ constructor(config, log, devices) {
+ this.config = config;
+ this.log = log;
+ this.devices = devices;
+ let deviceMap = {};
+ devices.forEach(device => {
+ deviceMap[device.deviceid] = {
+ apiKey: device.devicekey,
+ ip: false
+ };
+ });
+ this.deviceMap = deviceMap;
+ this.debug = this.config.debug || false;
+ this.debugReqRes = this.config.debugReqRes || false;
+ this.emitter = new eventemitter();
+ }
+ getHosts() {
+ return new Promise((resolve, reject) => {
+ dns.discover({
+ name: "_ewelink._tcp.local"
+ }).then(res => {
+ res.forEach(device => {
+ let a = device.fqdn.replace("._ewelink._tcp.local", "").replace("eWeLink_", "");
+ if (this.deviceMap.hasOwnProperty(a)) {
+ this.deviceMap[a].ip = device.address;
+ }
+ });
+ resolve(this.deviceMap);
+ }).catch(err => {
+ reject(err);
+ });
+ });
+ }
+ startMonitor() {
+ dns.ondata = packet => {
+ if (packet.answers) {
+ packet.answers
+ .filter(value => value.name.includes("_ewelink._tcp.local"))
+ .forEach(value => {
+ if (value.type === "TXT") {
+ let rdata = value.rdata;
+ if (this.deviceMap.hasOwnProperty(rdata.id)) {
+ let deviceKey = this.deviceMap[rdata.id].apiKey,
+ data = rdata.data1 +
+ (rdata.hasOwnProperty("data2") ? rdata.data2 : "") +
+ (rdata.hasOwnProperty("data3") ? rdata.data3 : "") +
+ (rdata.hasOwnProperty("data4") ? rdata.data4 : ""),
+ key = crypto.createHash("md5").update(Buffer.from(deviceKey, "utf8")).digest(),
+ dText = crypto.createDecipheriv("aes-128-cbc", key, Buffer.from(rdata.iv, "base64")),
+ pText = Buffer.concat([dText.update(Buffer.from(data, "base64")), dText.final()]).toString("utf8"),
+ params;
+ try {
+ params = JSON.parse(pText);
+ } catch (e) {
+ this.log.warn("[%s] An error occured reading the LAN message [%s]", rdata.id, e);
+ return;
+ }
+ for (let param in params) {
+ if (params.hasOwnProperty(param)) {
+ if (!constants.paramsToKeep.includes(param.replace(/[0-9]/g, ""))) {
+ delete params[param];
+ }
+ }
+ }
+ params.updateSource = "lan";
+ if (Object.keys(params).length > 0) {
+ let returnTemplate = {
+ deviceid: rdata.id,
+ action: "update",
+ params
+ };
+ if (this.debugReqRes) {
+ let msg = JSON.stringify(returnTemplate, null, 2).replace(rdata.id, "**hidden**");
+ this.log("LAN message received.\n%s", msg);
+ } else if (this.debug) {
+ this.log("LAN message received.");
+ }
+ this.emitter.emit("update", returnTemplate);
+ }
+ }
+ }
+ });
+ }
+ };
+ return new Promise((resolve, reject) => {
+ dns.startMonitoring().then(() => {
+ resolve();
+ }).catch(err => {
+ reject(err);
+ });
+ });
+ }
+ sendUpdate(json) {
+ return new Promise((resolve, reject) => {
+ if (!this.deviceMap[json.deviceid].ip) {
+ throw "device does not support LAN mode";
+ }
+ let apiKey, suffix, params = {};
+ if (json.params.hasOwnProperty("switches")) {
+ params.switches = json.params.switches;
+ suffix = "switches";
+ } else if (json.params.hasOwnProperty("switch")) {
+ params.switch = json.params.switch;
+ suffix = "switch";
+ } else {
+ throw "plugin does not support lan mode for this device yet - feel free to create a github issue";
+ }
+ if ((apiKey = this.deviceMap[json.deviceid].apiKey)) {
+ let key = crypto.createHash('md5').update(Buffer.from(apiKey, 'utf8')).digest(),
+ iv = crypto.randomBytes(16),
+ enc = crypto.createCipheriv('aes-128-cbc', key, iv),
+ data = {
+ data: Buffer.concat([enc.update(JSON.stringify(params)), enc.final()]).toString('base64'),
+ deviceid: json.deviceid,
+ encrypt: true,
+ iv: iv.toString('base64'),
+ selfApikey: "123",
+ sequence: Date.now().toString()
+ };
+ if (this.debugReqRes) {
+ let msg = JSON.stringify(json, null, 2).replace(json.apikey, "**hidden**").replace(json.apikey, "**hidden**").replace(json.deviceid, "**hidden**");
+ this.log.warn("LAN mode message sent. This text is yellow for clarity.\n%s", msg);
+ } else if (this.debug) {
+ this.log("LAN mode message sent.");
+ }
+ axios({
+ method: "post",
+ url: "http://" + this.deviceMap[json.deviceid].ip + ":8081/zeroconf/" + suffix,
+ headers: {
+ Accept: "application/json",
+ "Content-Type": "application/json;charset=UTF-8"
+ },
+ data
+ }).then(res => {
+ let body = res.data;
+ if (body.hasOwnProperty("error") && body.error === 0) {
+ resolve();
+ }
+ throw body;
+ }).catch(err => {
+ reject(err);
+ });
+ }
+ });
+ }
+ receiveUpdate(f) {
+ this.emitter.addListener("update", f);
+ }
+};
\ No newline at end of file
diff --git a/lib/eWeLinkWS.js b/lib/eWeLinkWS.js
new file mode 100644
index 00000000..23f690d7
--- /dev/null
+++ b/lib/eWeLinkWS.js
@@ -0,0 +1,271 @@
+/* jshint esversion: 9, -W030, node: true */
+"use strict";
+const axios = require("axios");
+const constants = require("./constants");
+const eventemitter = require("events");
+const ws = require("ws");
+module.exports = class eWeLinkWS {
+ constructor(config, log, res) {
+ this.config = config;
+ this.log = log;
+ this.debug = this.config.debug || false;
+ this.debugReqRes = this.config.debugReqRes || false;
+ this.httpHost = res.httpHost;
+ this.aToken = res.aToken;
+ this.apiKey = res.apiKey;
+ this.wsIsOpen = false;
+ this.emitter = new eventemitter();
+ this.delaySend = 0;
+ }
+ getHost() {
+ return new Promise((resolve, reject) => {
+ axios({
+ method: "post",
+ url: "https://" + this.httpHost.replace("-api", "-disp") + "/dispatch/app",
+ headers: {
+ Authorization: "Bearer " + this.aToken,
+ "Content-Type": "application/json"
+ },
+ data: {
+ appid: constants.appId,
+ nonce: Math.random().toString(36).substr(2, 8),
+ ts: Math.floor(new Date().getTime() / 1000),
+ version: 8
+ }
+ }).then(res => {
+ let body = res.data;
+ if (!body.domain) {
+ throw "Server did not respond with a web socket host.";
+ }
+ if (this.debug) {
+ this.log("Web socket host received [%s].", body.domain);
+ }
+ this.wsHost = body.domain;
+ resolve(body.domain);
+ }).catch(err => {
+ reject(err);
+ });
+ });
+ }
+ login() {
+ this.ws = new ws("wss://" + this.wsHost + ":8080/api/ws");
+ this.ws.on("open", () => {
+ this.wsIsOpen = true;
+ let payload = {
+ action: "userOnline",
+ apikey: this.apiKey,
+ appid: constants.appId,
+ at: this.aToken,
+ nonce: Math.random().toString(36).substr(2, 8),
+ sequence: Math.floor(new Date()),
+ ts: Math.floor(new Date() / 1000),
+ userAgent: "app",
+ version: 8
+ };
+ this.ws.send(JSON.stringify(payload));
+ if (this.debugReqRes) {
+ let msg = JSON.stringify(payload, null, 2).replace(this.aToken, "**hidden**").replace(this.apiKey, "**hidden**");
+ this.log.warn("Sending WS login request. This text is yellow for clarity.\n%s", msg);
+ } else if (this.debug) {
+ this.log("Sending WS login request.");
+ }
+ });
+ this.ws.on("message", m => {
+ if (m === "pong") {
+ return;
+ }
+ let device;
+ try {
+ device = JSON.parse(m);
+ } catch (e) {
+ this.log.warn("An error occured reading the web socket message [%s]", e);
+ return;
+ }
+ // for requestUpdate response
+ if (device.hasOwnProperty("deviceid") && device.hasOwnProperty("params") && device.hasOwnProperty("error") && device.error === 0) {
+ device.action = "update";
+ } else if (device.hasOwnProperty("deviceid") && device.hasOwnProperty("error") && device.error === 504) {
+ device.action = "sysmsg";
+ device.params = {
+ online: false
+ };
+ }
+ // for external updates
+ if (device.hasOwnProperty("config") && device.config.hb && device.config.hbInterval && !this.hbInterval) {
+ this.hbInterval = setInterval(() => {
+ this.ws.send("ping");
+ }, (device.config.hbInterval + 7) * 1000);
+ } else if (device.hasOwnProperty("action")) {
+ switch (device.action) {
+ case "sysmsg":
+ device.params.updateSource = "ws";
+ let returnTemplate = {
+ deviceid: device.deviceid,
+ action: "sysmsg",
+ params: device.params
+ };
+ if (this.debugReqRes) {
+ let msg = JSON.stringify(returnTemplate, null, 2).replace(device.deviceid, "**hidden**");
+ this.log("WS message received.\n%s", msg);
+ } else if (this.debug) {
+ this.log("WS message received.");
+ }
+ this.emitter.emit("update", returnTemplate);
+ break;
+ case "update":
+ let params = device.params;
+ for (let param in params) {
+ if (params.hasOwnProperty(param)) {
+ if (!constants.paramsToKeep.includes(param.replace(/[0-9]/g, ""))) {
+ delete params[param];
+ }
+ }
+ }
+ if (Object.keys(params).length > 0) {
+ params.updateSource = "ws";
+ let returnTemplate = {
+ deviceid: device.deviceid,
+ action: "update",
+ params
+ };
+ if (this.debugReqRes) {
+ let msg = JSON.stringify(returnTemplate, null, 2).replace(device.deviceid, "**hidden**");
+ this.log("WS message received.\n%s", msg);
+ } else if (this.debug) {
+ this.log("WS message received.");
+ }
+ this.emitter.emit("update", returnTemplate);
+ }
+ break;
+ default:
+ this.log.warn("[%s] WS message has unknown action.\n" + JSON.stringify(device, null, 2), device.deviceid);
+ return;
+ }
+ } else if (device.hasOwnProperty("error") && device.error === 0) {
+ // *** Safe to ignore these messages *** \\
+ } else {
+ if (this.debug) {
+ this.log.warn("WS unknown command received.\n" + JSON.stringify(device, null, 2));
+ }
+ }
+ });
+ this.ws.on("close", (e) => {
+ this.log.warn("Web socket closed - [%s].", e);
+ if (e.code !== 1000) {
+ this.log.warn("Web socket will try to reconnect in five seconds then try the command again.");
+ this.ws.removeAllListeners();
+ setTimeout(() => {
+ this.login();
+ }, 5000);
+ } else {
+ this.log.error("Please try restarting Homebridge so that this plugin can work again.");
+ }
+ this.wsIsOpen = false;
+ if (this.hbInterval) {
+ clearInterval(this.hbInterval);
+ this.hbInterval = null;
+ }
+ });
+ this.ws.on("error", (e) => {
+ this.log.error("Web socket error - [%s].", e);
+ if (e.code === "ECONNREFUSED") {
+ this.log.warn("Web socket will try to reconnect in five seconds then try the command again.");
+ this.ws.removeAllListeners();
+ setTimeout(() => {
+ this.login();
+ }, 5000);
+ } else {
+ this.log.warn("If this was unexpected then please try restarting Homebridge.");
+ }
+ });
+ }
+ sendUpdate(json, callback) {
+ json = {
+ ...json,
+ ...{
+ action: "update",
+ sequence: Math.floor(new Date()),
+ userAgent: "app"
+ }
+ };
+ let sendOperation = req => {
+ if (!this.wsIsOpen) {
+ setTimeout(() => {
+ sendOperation(req);
+ }, 280);
+ return;
+ }
+ if (this.ws) {
+ callback();
+ this.ws.send(req);
+ if (this.debugReqRes) {
+ let msg = JSON.stringify(json, null, 2).replace(json.apikey, "**hidden**").replace(json.apiKey, "**hidden**").replace(json.deviceid, "**hidden**");
+ this.log.warn("Web socket message sent. This text is yellow for clarity.\n%s", msg);
+ }
+ return;
+ }
+ this.delaySend = this.delaySend <= 0 ? 0 : this.delaySend -= 280;
+ };
+ let string = JSON.stringify(json);
+ if (this.wsIsOpen) {
+ setTimeout(sendOperation, this.delaySend, string);
+ this.delaySend += 280;
+ } else {
+ this.log.warn("Web socket is currently reconnecting. Command will be resent.");
+ let interval,
+ waitToSend = req => {
+ if (this.wsIsOpen) {
+ clearInterval(interval);
+ sendOperation(req);
+ }
+ };
+ interval = setInterval(waitToSend, 2500, string);
+ }
+ }
+ requestUpdate(accessory) {
+ let json = {
+ action: "query",
+ apikey: accessory.context.eweApiKey,
+ deviceid: accessory.context.eweDeviceId,
+ params: [],
+ sequence: Math.floor(new Date()),
+ ts: 0,
+ userAgent: "app"
+ },
+ sendOperation = req => {
+ if (!this.wsIsOpen) {
+ setTimeout(() => {
+ sendOperation(req);
+ }, 280);
+ return;
+ }
+ if (this.ws) {
+ this.ws.send(req);
+ if (this.debugReqRes) {
+ let msg = JSON.stringify(json, null, 2).replace(json.apikey, "**hidden**").replace(json.apiKey, "**hidden**").replace(json.deviceid, "**hidden**");
+ this.log.warn("Web socket message sent. This text is yellow for clarity.\n%s", msg);
+ }
+ return;
+ }
+ this.delaySend = this.delaySend <= 0 ? 0 : this.delaySend -= 280;
+ },
+ string = JSON.stringify(json);
+ if (this.wsIsOpen) {
+ setTimeout(sendOperation, this.delaySend, string);
+ this.delaySend += 280;
+ } else {
+ this.log.warn("Web socket is currently reconnecting. Command will be resent.");
+ let interval,
+ waitToSend = req => {
+ if (this.wsIsOpen) {
+ clearInterval(interval);
+ sendOperation(req);
+ }
+ };
+ interval = setInterval(waitToSend, 2500, string);
+ }
+ }
+ receiveUpdate(f) {
+ this.emitter.addListener("update", f);
+ }
+};
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 94d0313e..9420b343 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,360 +1,60 @@
{
- "name": "homebridge-ewelink",
- "version": "0.1.76",
- "lockfileVersion": 1,
- "requires": true,
- "dependencies": {
- "arpping": {
- "version": "github:skydiver/arpping#ae65410343bdcbddb64b37ac9f674c65af1fe92c",
- "from": "github:skydiver/arpping",
- "requires": {
- "child_process": "^1.0.2",
- "os": "^0.1.1"
- }
- },
- "babel-runtime": {
- "version": "6.26.0",
- "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
- "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
- "requires": {
- "core-js": "^2.4.0",
- "regenerator-runtime": "^0.11.0"
- }
- },
- "child_process": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/child_process/-/child_process-1.0.2.tgz",
- "integrity": "sha1-sffn/HPSXn/R1FWtyU4UODAYK1o="
- },
- "chnl": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/chnl/-/chnl-1.2.0.tgz",
- "integrity": "sha512-g5gJb59edwCliFbX2j7G6sBfY4sX9YLy211yctONI2GRaiX0f2zIbKWmBm+sPqFNEpM7Ljzm7IJX/xrjiEbPrw=="
- },
- "core-js": {
- "version": "2.6.11",
- "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz",
- "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg=="
- },
- "crypto-js": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.0.0.tgz",
- "integrity": "sha512-bzHZN8Pn+gS7DQA6n+iUmBfl0hO5DJq++QP3U6uTucDtk/0iGpXd/Gg7CGR0p8tJhofJyaKoWBuJI4eAO00BBg=="
- },
- "d": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
- "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
- "requires": {
- "es5-ext": "^0.10.50",
- "type": "^1.0.1"
- }
- },
- "debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "requires": {
- "ms": "2.0.0"
- }
- },
- "define-properties": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
- "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
- "requires": {
- "object-keys": "^1.0.12"
- }
- },
- "delay": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/delay/-/delay-4.4.0.tgz",
- "integrity": "sha512-txgOrJu3OdtOfTiEOT2e76dJVfG/1dz2NZ4F0Pyt4UGZJryssMRp5vdM5wQoLwSOBNdrJv3F9PAhp/heqd7vrA=="
- },
- "es-abstract": {
- "version": "1.17.6",
- "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz",
- "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==",
- "requires": {
- "es-to-primitive": "^1.2.1",
- "function-bind": "^1.1.1",
- "has": "^1.0.3",
- "has-symbols": "^1.0.1",
- "is-callable": "^1.2.0",
- "is-regex": "^1.1.0",
- "object-inspect": "^1.7.0",
- "object-keys": "^1.1.1",
- "object.assign": "^4.1.0",
- "string.prototype.trimend": "^1.0.1",
- "string.prototype.trimstart": "^1.0.1"
- }
- },
- "es-to-primitive": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
- "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
- "requires": {
- "is-callable": "^1.1.4",
- "is-date-object": "^1.0.1",
- "is-symbol": "^1.0.2"
- }
- },
- "es5-ext": {
- "version": "0.10.53",
- "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz",
- "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==",
- "requires": {
- "es6-iterator": "~2.0.3",
- "es6-symbol": "~3.1.3",
- "next-tick": "~1.0.0"
- }
- },
- "es6-iterator": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
- "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
- "requires": {
- "d": "1",
- "es5-ext": "^0.10.35",
- "es6-symbol": "^3.1.1"
- }
- },
- "es6-symbol": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
- "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
- "requires": {
- "d": "^1.0.1",
- "ext": "^1.1.2"
- }
- },
- "ewelink-api": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/ewelink-api/-/ewelink-api-3.0.0.tgz",
- "integrity": "sha512-W60dGUIPnV8b/ckCKRAi+0mYyIYil/YrkVrAknlf6CtnivHIVxvcQPUxQPOX6ctWzK10n+ACAh8V7uOok1rjMA==",
- "requires": {
- "arpping": "github:skydiver/arpping",
- "crypto-js": "^4.0.0",
- "delay": "^4.3.0",
- "node-fetch": "^2.6.0",
- "random": "^2.2.0",
- "websocket": "^1.0.31",
- "websocket-as-promised": "^1.0.1"
- }
- },
- "ext": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz",
- "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==",
- "requires": {
- "type": "^2.0.0"
+ "name": "homebridge-ewelink",
+ "version": "2.19.1",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "axios": {
+ "version": "0.19.2",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz",
+ "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==",
+ "requires": {
+ "follow-redirects": "1.5.10"
+ }
},
- "dependencies": {
- "type": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/type/-/type-2.0.0.tgz",
- "integrity": "sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow=="
- }
- }
- },
- "function-bind": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
- "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
- },
- "has": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
- "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
- "requires": {
- "function-bind": "^1.1.1"
- }
- },
- "has-symbols": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
- "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg=="
- },
- "is-callable": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz",
- "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw=="
- },
- "is-date-object": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz",
- "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g=="
- },
- "is-regex": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz",
- "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==",
- "requires": {
- "has-symbols": "^1.0.1"
- }
- },
- "is-symbol": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz",
- "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==",
- "requires": {
- "has-symbols": "^1.0.1"
- }
- },
- "is-typedarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
- "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
- },
- "ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
- },
- "nan": {
- "version": "2.14.1",
- "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz",
- "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw=="
- },
- "next-tick": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
- "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw="
- },
- "node-fetch": {
- "version": "2.6.0",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
- "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA=="
- },
- "object-inspect": {
- "version": "1.8.0",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz",
- "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA=="
- },
- "object-keys": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
- "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="
- },
- "object.assign": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
- "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
- "requires": {
- "define-properties": "^1.1.2",
- "function-bind": "^1.1.1",
- "has-symbols": "^1.0.0",
- "object-keys": "^1.0.11"
- }
- },
- "os": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/os/-/os-0.1.1.tgz",
- "integrity": "sha1-IIhF6J4ZOtTZcUdLk5R3NqVtE/M="
- },
- "ow": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/ow/-/ow-0.4.0.tgz",
- "integrity": "sha512-kJNzxUgVd6EF5LoGs+s2/etJPwjfRDLXPTCfEgV8At77sRrV+PSFA8lcoW2HF15Qd455mIR2Stee/2MzDiFBDA=="
- },
- "ow-lite": {
- "version": "0.0.2",
- "resolved": "https://registry.npmjs.org/ow-lite/-/ow-lite-0.0.2.tgz",
- "integrity": "sha1-359QDmdAtlkKHpqWVzDUmo61l9E="
- },
- "promise-controller": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/promise-controller/-/promise-controller-1.0.0.tgz",
- "integrity": "sha512-goA0zA9L91tuQbUmiMinSYqlyUtEgg4fxJcjYnLYOQnrktb4o4UqciXDNXiRUPiDBPACmsr1k8jDW4r7UDq9Qw=="
- },
- "promise.prototype.finally": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/promise.prototype.finally/-/promise.prototype.finally-3.1.2.tgz",
- "integrity": "sha512-A2HuJWl2opDH0EafgdjwEw7HysI8ff/n4lW4QEVBCUXFk9QeGecBWv0Deph0UmLe3tTNYegz8MOjsVuE6SMoJA==",
- "requires": {
- "define-properties": "^1.1.3",
- "es-abstract": "^1.17.0-next.0",
- "function-bind": "^1.1.1"
- }
- },
- "random": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/random/-/random-2.2.0.tgz",
- "integrity": "sha512-4HBR4Xye4jJ41QBi6RfIaO1yKQpxVUZafQtdE6NvvjzirNlwWgsk3tkGLTbQtWUarF4ofZsUVEmWqB1TDQlkwA==",
- "requires": {
- "babel-runtime": "^6.26.0",
- "ow": "^0.4.0",
- "ow-lite": "^0.0.2",
- "seedrandom": "^3.0.5"
- }
- },
- "regenerator-runtime": {
- "version": "0.11.1",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
- "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg=="
- },
- "seedrandom": {
- "version": "3.0.5",
- "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz",
- "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg=="
- },
- "string.prototype.trimend": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz",
- "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==",
- "requires": {
- "define-properties": "^1.1.3",
- "es-abstract": "^1.17.5"
- }
- },
- "string.prototype.trimstart": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz",
- "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==",
- "requires": {
- "define-properties": "^1.1.3",
- "es-abstract": "^1.17.5"
- }
- },
- "type": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
- "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg=="
- },
- "typedarray-to-buffer": {
- "version": "3.1.5",
- "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
- "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
- "requires": {
- "is-typedarray": "^1.0.0"
- }
- },
- "websocket": {
- "version": "1.0.31",
- "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.31.tgz",
- "integrity": "sha512-VAouplvGKPiKFDTeCCO65vYHsyay8DqoBSlzIO3fayrfOgU94lQN5a1uWVnFrMLceTJw/+fQXR5PGbUVRaHshQ==",
- "requires": {
- "debug": "^2.2.0",
- "es5-ext": "^0.10.50",
- "nan": "^2.14.0",
- "typedarray-to-buffer": "^3.1.5",
- "yaeti": "^0.0.6"
- }
- },
- "websocket-as-promised": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/websocket-as-promised/-/websocket-as-promised-1.0.1.tgz",
- "integrity": "sha512-+gBevna4yxisb8cigL8NxcS8s241cvfMeyy1fNFcFgBcX/6vknMT84MwMmBNLYmsYH2giVoxOSEiAeeb7txFOw==",
- "requires": {
- "chnl": "^1.0.0",
- "promise-controller": "^1.0.0",
- "promise.prototype.finally": "^3.1.1"
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+ },
+ "debug": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "follow-redirects": {
+ "version": "1.5.10",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
+ "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
+ "requires": {
+ "debug": "=3.1.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ },
+ "node-dns-sd": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/node-dns-sd/-/node-dns-sd-0.4.1.tgz",
+ "integrity": "sha512-x+WSuMgvDBQv24OCq75YHcZj1SOzvP5fU4Tz+PBUiVvVBsfc+9XAHAuIftaCpf2nPLl+ys71uZoGr/v9fVDa6A=="
+ },
+ "ws": {
+ "version": "7.3.1",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz",
+ "integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA=="
}
- },
- "yaeti": {
- "version": "0.0.6",
- "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz",
- "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc="
- }
- }
+ }
}
diff --git a/package.json b/package.json
index cb41333c..8a64e5a3 100644
--- a/package.json
+++ b/package.json
@@ -1,21 +1,57 @@
{
- "name": "homebridge-ewelink",
- "version": "0.1.76",
- "description": "homebridge-eWeLink is a Homebrige plugin to control Sonoff relays running OEM firmware",
- "license": "MIT",
- "keywords": [
- "homebridge-plugin",
- "sonoff"
- ],
- "engines": {
- "node": ">=0.12.0",
- "homebridge": ">=0.2.0"
- },
- "repository": {
- "type": "git",
- "url": "https://github.com/bwp91/homebridge-ewelink.git"
- },
- "dependencies": {
- "ewelink-api": "^3.0.0"
- }
+ "name": "homebridge-ewelink",
+ "version": "2.19.1",
+ "author": "bwp91",
+ "contributors": [
+ "gbro115",
+ "MrTomAsh",
+ "howanghk",
+ "LeJeko",
+ "aremishevsky-chegg",
+ "samkni",
+ "robsonfj",
+ "ramsesz",
+ "metarutaiga",
+ "janbuecker",
+ "jacopofranza",
+ "donavanbecker",
+ "dhutchison",
+ "danielk117",
+ "bassrock",
+ "VictorKrasnov",
+ "JuniorGenius",
+ "BobbySlope"
+ ],
+ "description": "homebridge-ewelink-sonoff is a Homebrige plugin to control Sonoff devices running OEM firmware.",
+ "license": "MIT",
+ "keywords": [
+ "homebridge",
+ "homebridge-plugin",
+ "sonoff",
+ "ewelink"
+ ],
+ "engines": {
+ "node": ">=6.0.0",
+ "homebridge": ">=0.2.0"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/bwp91/homebridge-ewelink"
+ },
+ "dependencies": {
+ "axios": "0.19.2",
+ "color-convert": "2.0.1",
+ "node-dns-sd": "0.4.1",
+ "ws": "7.3.1"
+ },
+ "funding": [
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/bwp91"
+ },
+ {
+ "type": "paypal",
+ "url": "https://www.paypal.me/BenPotter"
+ }
+ ]
}
From 227f2f29d54bfbb4c888cf723cb99b3576648bab Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Sun, 16 Aug 2020 11:36:01 +0100
Subject: [PATCH 0010/3183] Update README.md
---
README.md | 117 +-----------------------------------------------------
1 file changed, 1 insertion(+), 116 deletions(-)
diff --git a/README.md b/README.md
index fc4f06d7..1a70beb2 100644
--- a/README.md
+++ b/README.md
@@ -1,116 +1 @@
-### Changes from homebridge-ewelink-complete have been merged into the master
-
-The largest change here is to use evelink-api for all API needs rather than rewrite
-
-# About
-
-Homebridge plugin to control Sonoff relays with OEM firmware. It uses the same API as the iOS app to communicate with your devices.
-
-The platform will dynamically add/remove devices based on what is configured in your eWeLink account.
-
-It has been tested with the [Sonoff basic](http://sonoff.itead.cc/en/products/sonoff/sonoff-basic) relays. I have performed testing with up to two relays associated to my account.
-
-The plugin will only support one eWeLink account.
-
-It is possible to continute to use the OEM functionality (eWeLink app, Google Home integration); this plugin requires no modification to the relay's firmware.
-
-## Shortcomings
-
-The plugin uses the same credentials as the eWeLink app. In order to obtain the authenticationToken, you'll need to use Charles to inspect the traffic and grab the value from the Authorization header. See below for information on how to obtain this value.
-
-Also, the code is of suboptimal quality. It was a quick-and-dirty plugin; feel free to contribute & improve.
-
-## Steps to install / configure
-
-*Assuming that you've already downloaded the eWeLink app on your iOS device & have configured it:*
-
-1) Install the plugin
-```
-sudo npm -g install homebridge-ewelink-complete
-```
-
-2) Add to the platforms[] section of config.json. Steps for obtaining the values for authenticationToken, apiHost, and webSocketApi can be found below.
-
-3) Restart Homebridge
-
-### Sample config.json
-
-```
-{
- "bridge": {
- "name": "Homebridge",
- "username": "XX:XX:XX:XX:XX:XX",
- "port": 51826,
- "pin": "123-45-678"
- },
-
- "description": "Your description here",
-
- "accessories": [
- ],
-
- "platforms": [
- {
- "platform": "eWeLink",
- "name": "eWeLink",
- "phoneNumberOrEmail": "YOUR_ACCOUNT_EMAIL_OR_PHONE",
- "accountPassword": "YOUR_ACCOUNT_PASSWORD",
- "apiHost": "us-api.coolkit.cc:8080",
- "webSocketApi": "us-long.coolkit.cc",
- "debug": "true"
- } ]
-}
-```
-
-### A note on the authenticationToken
-
-The authentication token is generated every time your device's app logs in to the eWeLink service. Based on my limited testing, the session seems to persist for quite some time.
-
-You can only have one authentication token per user account.
-
-If you logout and login to the app again, you'll need to perform the above steps to get things working again.
-
-## Troubleshooting
-
-I've attempted to make the logging as useful as possible. If you have any suggestions, please open an issue on GitHub. I've also hidden most logging behind the debug parameter, please set to true or false accordingly
-
-## Sample logging
-
-```
-[12/13/2017, 9:39:05 PM] [eWeLink] A total of [1] accessories were loaded from the local cache
-[12/13/2017, 9:39:05 PM] [eWeLink] Requesting a list of devices from eWeLink HTTPS API at [https://us-api.coolkit.cc:8080]
-[12/13/2017, 9:39:06 PM] [eWeLink] eWeLink HTTPS API reports that there are a total of [1] devices registered
-[12/13/2017, 9:39:06 PM] [eWeLink] Evaluating if devices need to be removed...
-[12/13/2017, 9:39:06 PM] [eWeLink] Verifying that all cached devices are still registered with the API. Devices that are no longer registered with the API will be removed.
-[12/13/2017, 9:39:06 PM] [eWeLink] Device [Fan] is regeistered with API. Nothing to do.
-[12/13/2017, 9:39:06 PM] [eWeLink] Evaluating if new devices need to be added...
-[12/13/2017, 9:39:06 PM] [eWeLink] Device with ID [XXXXXXX] is already configured. Ensuring that the configuration is current.
-[12/13/2017, 9:39:06 PM] [eWeLink] Updating recorded Characteristic.On for [Fan] to [false]. No request will be sent to the device.
-[12/13/2017, 9:39:06 PM] [eWeLink] Setting power state to [off] for device [Fan]
-[12/13/2017, 9:39:06 PM] [eWeLink] API key retrieved from web service is [XXXXXXX]
-[12/13/2017, 9:39:06 PM] [eWeLink] Connecting to the WebSocket API at [wss://us-long.coolkit.cc:8080/api/ws]
-[12/13/2017, 9:39:06 PM] [eWeLink] Sending login request [{"action":"userOnline","userAgent":"app","version":6,"nonce":"151321914688000","apkVesrion":"1.8","os":"ios","at":"XXXXXXX","apikey":"xxxxxxx","ts":"1513219146","model":"iPhone10,6","romVersion":"11.1.2","sequence":1513219146880}]
-[12/13/2017, 9:39:06 PM] [eWeLink] WebSocket messge received: {"error":0,"apikey":"xxxxxxx","config":{"hb":1,"hbInterval":145},"sequence":"1513219146880"}
-```
-
-*Hey Siri, turn on the fan*
-```
-[12/13/2017, 9:39:09 PM] [eWeLink] Setting power state to [on] for device [Fan]
-[12/13/2017, 9:39:09 PM] [eWeLink] WebSocket messge received: {"error":0,"deviceid":"XXXXXXX","apikey":"XXXXXXX","sequence":"1513219149620"}
-[12/13/2017, 9:39:11 PM] [eWeLink] Setting power state to [off] for device [Fan]
-[12/13/2017, 9:39:12 PM] [eWeLink] WebSocket messge received: {"error":0,"deviceid":"XXXXXXX","apikey":"XXXXXXX","sequence":"1513219151735"}
-```
-
-The plugin will also listen for announcements via a persistent web socket. This allows you to control the device from the likes of Google Home & have Homebridge be kept up-to-date
-
-*Hey Google, turn on the fan*
-```
-[12/13/2017, 9:41:50 PM] [eWeLink] Update message received for device [XXXXXXX]
-[12/13/2017, 9:41:50 PM] [eWeLink] Updating recorded Characteristic.On for [Fan] to [true]. No request will be sent to the device.
-[12/13/2017, 9:41:50 PM] [eWeLink] Setting power state to [on] for device [Fan]
-[12/13/2017, 9:41:50 PM] [eWeLink] WebSocket messge received: {"error":0,"deviceid":"XXXXXXX","apikey":"XXXXXXX","sequence":"1513219310003"}
-```
-## Credits
-
-So many... needs updated. This is a fork of homebridge-ewelink
-
+Plugin update coming soon.
From 8aa5141fb5fba65492c98265b949aeb1203f467d Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Mon, 17 Aug 2020 06:58:47 +0100
Subject: [PATCH 0011/3183] Update README.md
---
README.md | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/README.md b/README.md
index 1a70beb2..cf449835 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,10 @@
+
+
+
+
+
+# homebridge-ewelink-sonoff
+
+
+
Plugin update coming soon.
From 9a235aec17bf57a7575f1a74ca63fc4d892742bf Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Mon, 17 Aug 2020 08:55:17 +0100
Subject: [PATCH 0012/3183] Update README.md
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index cf449835..b4af0fec 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
-
+
From e5010696d51a3c6ad6b4c9b62c02cd189d420881 Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Mon, 17 Aug 2020 08:55:53 +0100
Subject: [PATCH 0013/3183] Update README.md
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index b4af0fec..a5b69dcb 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
-# homebridge-ewelink-sonoff
+# homebridge-ewelink
From 307b049208a804d18f7d229ad2ae44e01cafb7ec Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Mon, 17 Aug 2020 13:19:41 +0100
Subject: [PATCH 0014/3183] Update new-issue.md
---
.github/ISSUE_TEMPLATE/new-issue.md | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/.github/ISSUE_TEMPLATE/new-issue.md b/.github/ISSUE_TEMPLATE/new-issue.md
index 44f070df..8f5f5df0 100644
--- a/.github/ISSUE_TEMPLATE/new-issue.md
+++ b/.github/ISSUE_TEMPLATE/new-issue.md
@@ -11,10 +11,20 @@ assignees: ''
...
-**Which version of the package are you using?**
+**Details of your setup.**
+Do you use Homebridge or HOOBS?
+
+...
+
+Which version of Homebridge/HOOBS do you have?
+
+...
+
+Which version of this plugin (homebridge-ewelink-sonoff) do you have?
...
**Please paste any relevant logs below. It helps if you can turn `debug` and `debugReqRes` in the package settings for more thorough logging.**
+> If you are posting an error then it is helpful for me to also see the previous few lines as this can show the cause of the error.
...
From dd9903f5220f1eeea524c6182c40419406fb8fc6 Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Mon, 17 Aug 2020 13:19:56 +0100
Subject: [PATCH 0015/3183] Update new-issue.md
---
.github/ISSUE_TEMPLATE/new-issue.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/ISSUE_TEMPLATE/new-issue.md b/.github/ISSUE_TEMPLATE/new-issue.md
index 8f5f5df0..32cfb7df 100644
--- a/.github/ISSUE_TEMPLATE/new-issue.md
+++ b/.github/ISSUE_TEMPLATE/new-issue.md
@@ -20,7 +20,7 @@ Which version of Homebridge/HOOBS do you have?
...
-Which version of this plugin (homebridge-ewelink-sonoff) do you have?
+Which version of this plugin (homebridge-ewelink) do you have?
...
From 44eec9875bb2bc9131a8c01d37c81a36fee478ae Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Mon, 17 Aug 2020 13:27:39 +0100
Subject: [PATCH 0016/3183] Update README.md
---
README.md | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index a5b69dcb..e17ee9a1 100644
--- a/README.md
+++ b/README.md
@@ -7,4 +7,7 @@
-Plugin update coming soon.
+This package will soon become the new home of [homebridge-ewelink-sonoff](https://github.com/bwp91/homebridge-ewelink-sonoff)!
+
+### Credit
+To the original owner of this package @gbro115 for letting me take over. I will look after it as best as I can!
From a99c3c3e65e5f371285bd554add10f405c6997d4 Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Mon, 17 Aug 2020 16:19:46 +0100
Subject: [PATCH 0017/3183] Update FUNDING.yml
---
.github/FUNDING.yml | 1 +
1 file changed, 1 insertion(+)
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
index addfcd2d..9444c69e 100644
--- a/.github/FUNDING.yml
+++ b/.github/FUNDING.yml
@@ -1,2 +1,3 @@
patreon: bwp91
+ko_fi: bwp91
custom: ["https://www.paypal.me/BenPotter"]
From ca47926ac14e6fdbb13e01ac5b64feb00f414186 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Mon, 17 Aug 2020 16:23:26 +0100
Subject: [PATCH 0018/3183] v rollback
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 9420b343..7b3138f9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.19.1",
+ "version": "2.19.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 8a64e5a3..c516fe57 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.19.1",
+ "version": "2.19.0",
"author": "bwp91",
"contributors": [
"gbro115",
From cfd348deee2ee899ae9ab2d032fa6f34e7b7d91f Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Mon, 17 Aug 2020 16:32:46 +0100
Subject: [PATCH 0019/3183] 2.19.1
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 7b3138f9..9420b343 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.19.0",
+ "version": "2.19.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index c516fe57..8a64e5a3 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.19.0",
+ "version": "2.19.1",
"author": "bwp91",
"contributors": [
"gbro115",
From c536c2507203c7db3a089438f13ee1ff0815324f Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Mon, 17 Aug 2020 16:40:23 +0100
Subject: [PATCH 0020/3183] Update README.md
---
README.md | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/README.md b/README.md
index e17ee9a1..deb01fd4 100644
--- a/README.md
+++ b/README.md
@@ -3,11 +3,18 @@
-# homebridge-ewelink
+# homebridge-ewelink
+ [![verified-by-homebridge](https://badgen.net/badge/homebridge/verified/purple)](https://github.com/homebridge/homebridge/wiki/Verified-Plugins)
+ [![Discord](https://img.shields.io/discord/432663330281226270?color=728ED5&logo=discord&label=discord)](https://discord.com/channels/432663330281226270/742733745743855627)
+ [![npm](https://img.shields.io/npm/dt/homebridge-ewelink-sonoff)](https://www.npmjs.com/package/homebridge-ewelink)
+ [![npm](https://img.shields.io/npm/v/homebridge-ewelink-sonoff?label=release)](https://www.npmjs.com/package/homebridge-ewelink)
+ [![npm](https://img.shields.io/npm/v/homebridge-ewelink-beta?label=beta)](https://www.npmjs.com/package/homebridge-ewelink-beta)
+
-This package will soon become the new home of [homebridge-ewelink-sonoff](https://github.com/bwp91/homebridge-ewelink-sonoff)!
+## Documentation
+Please refer to the [wiki](https://github.com/bwp91/homebridge-ewelink-sonoff/wiki) for documentation.
-### Credit
-To the original owner of this package @gbro115 for letting me take over. I will look after it as best as I can!
+## Credit
+To the original owner of this package @gbro115 for letting me take over. I will look after it as best as I can :)
From e27c2d228975ec87034dd9aec418a450957ccb59 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Mon, 17 Aug 2020 16:55:25 +0100
Subject: [PATCH 0021/3183] Update package.json
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index 8a64e5a3..e33b50b4 100644
--- a/package.json
+++ b/package.json
@@ -22,7 +22,7 @@
"JuniorGenius",
"BobbySlope"
],
- "description": "homebridge-ewelink-sonoff is a Homebrige plugin to control Sonoff devices running OEM firmware.",
+ "description": "Homebridge plugin to control eWeLink devices with original firmware.",
"license": "MIT",
"keywords": [
"homebridge",
From 72000421e0e12dc4068236f001f6c4638c2aa6c2 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Mon, 17 Aug 2020 17:25:03 +0100
Subject: [PATCH 0022/3183] Update config.schema.json
---
config.schema.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/config.schema.json b/config.schema.json
index b8a7a5cf..90c72ece 100644
--- a/config.schema.json
+++ b/config.schema.json
@@ -2,7 +2,7 @@
"pluginAlias":"eWeLink",
"pluginType":"platform",
"singular":true,
- "headerDisplay":"Homebridge plugin to control Sonoff devices with OEM firmware.",
+ "headerDisplay":"Homebridge plugin to control eWeLink devices with original firmware.",
"footerDisplay":"If you have any suggestions, please open an issue on [GitHub](https://github.com/bwp91/homebridge-ewelink/issues).",
"schema":{
"type":"object",
From b75ec7243364d82eb519ebac7ca4190d4bc5069c Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Mon, 17 Aug 2020 17:37:26 +0100
Subject: [PATCH 0023/3183] Update README.md
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index deb01fd4..6f976a7a 100644
--- a/README.md
+++ b/README.md
@@ -14,7 +14,7 @@
## Documentation
-Please refer to the [wiki](https://github.com/bwp91/homebridge-ewelink-sonoff/wiki) for documentation.
+Please refer to the [wiki](https://github.com/bwp91/homebridge-ewelink/wiki) for documentation.
## Credit
To the original owner of this package @gbro115 for letting me take over. I will look after it as best as I can :)
From 82b6fdf9151eccba656e9028d51364fdf47c8f93 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Mon, 17 Aug 2020 19:34:14 +0100
Subject: [PATCH 0024/3183] camera log entries
---
lib/eWeLink.js | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 8cfdceec..eba46a71 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -166,6 +166,8 @@ class eWeLink {
this.addAccessory(device, device.deviceid + "SWX", "zb_pri");
} else if (constants.devicesZB.includes(device.extra.uiid)) {
this.addAccessory(device, device.deviceid + "SWX", "zb_sub");
+ } else if (device.extra.uiid === 87) {
+ this.log.warn("[%s] please consider using homebridge-camera-ffmpeg to use this camera.", device.name);
} else {
this.log.warn("[%s] could not be added as it is not supported by this plugin.", device.name);
}
@@ -239,7 +241,9 @@ class eWeLink {
return;
}
} else {
- this.log.warn("[%s] will not be refreshed as it wasn't found in Homebridge.", device.name);
+ if (device.extra.uiid !== 87) {
+ this.log.warn("[%s] will not be refreshed as it wasn't found in Homebridge.", device.name);
+ }
return;
}
if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
@@ -655,7 +659,6 @@ class eWeLink {
this.externalRFDeviceUpdate(accessory, newParams);
return true;
case "rf_sub":
- return true;
case "zb_pri":
return true;
case "zb_sub":
@@ -1460,7 +1463,7 @@ class eWeLink {
let oldState = accessory.getService(Service.ContactSensor).getCharacteristic(Characteristic.ContactSensorState).value,
newState = params.switch === "on" ? 1 : 0,
oAccessory = false;
- accessory.getService(Service.ContactSensor).updateCharacteristic(Characteristic.ContactSensorState, newState);
+ accessory.getService(Service.ContactSensor).updateCharacteristic(Characteristic.ContactSensorState, newState);
this.log("[%s] sent update that it was [%s] and is now [%s].", accessory.displayName, oldState ? "apart" : "joined", newState ? "apart" : "joined");
this.cusG.forEach(group => {
if (group.sensorId === accessory.context.eweDeviceId && group.type === "garage") {
From c2db874675578f4d768c31a5d8591837c235df7d Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Mon, 17 Aug 2020 20:29:00 +0100
Subject: [PATCH 0025/3183] 2.19.2
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 9420b343..386790ae 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.19.1",
+ "version": "2.19.2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index e33b50b4..607d3323 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.19.1",
+ "version": "2.19.2",
"author": "bwp91",
"contributors": [
"gbro115",
From 8d7ba03d6ef201e48136e5021ab71b1c586cd98b Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Mon, 17 Aug 2020 20:41:35 +0100
Subject: [PATCH 0026/3183] Update README.md
---
README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 6f976a7a..c8124630 100644
--- a/README.md
+++ b/README.md
@@ -7,8 +7,8 @@
[![verified-by-homebridge](https://badgen.net/badge/homebridge/verified/purple)](https://github.com/homebridge/homebridge/wiki/Verified-Plugins)
[![Discord](https://img.shields.io/discord/432663330281226270?color=728ED5&logo=discord&label=discord)](https://discord.com/channels/432663330281226270/742733745743855627)
- [![npm](https://img.shields.io/npm/dt/homebridge-ewelink-sonoff)](https://www.npmjs.com/package/homebridge-ewelink)
- [![npm](https://img.shields.io/npm/v/homebridge-ewelink-sonoff?label=release)](https://www.npmjs.com/package/homebridge-ewelink)
+ [![npm](https://img.shields.io/npm/dt/homebridge-ewelink)](https://www.npmjs.com/package/homebridge-ewelink)
+ [![npm](https://img.shields.io/npm/v/homebridge-ewelink?label=release)](https://www.npmjs.com/package/homebridge-ewelink)
[![npm](https://img.shields.io/npm/v/homebridge-ewelink-beta?label=beta)](https://www.npmjs.com/package/homebridge-ewelink-beta)
From 76f7b8bbfa0d6c58e713e4bcb0d255fda78c45e9 Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Mon, 17 Aug 2020 21:12:45 +0100
Subject: [PATCH 0027/3183] Update README.md
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index c8124630..633cb902 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
-
+
From e8db9d9846438abf2fa6e975a6d51b23e96f8d5a Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Mon, 17 Aug 2020 21:29:14 +0100
Subject: [PATCH 0028/3183] Set theme jekyll-theme-slate
---
_config.yml | 1 +
1 file changed, 1 insertion(+)
create mode 100644 _config.yml
diff --git a/_config.yml b/_config.yml
new file mode 100644
index 00000000..c7418817
--- /dev/null
+++ b/_config.yml
@@ -0,0 +1 @@
+theme: jekyll-theme-slate
\ No newline at end of file
From 36ca2782e763647cd50b58ec3c13f4c5e8c037ba Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Wed, 19 Aug 2020 14:32:18 +0100
Subject: [PATCH 0029/3183] remove button as now auto
---
config.schema.json | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/config.schema.json b/config.schema.json
index 90c72ece..95772b9f 100644
--- a/config.schema.json
+++ b/config.schema.json
@@ -195,12 +195,6 @@
"default":"motion",
"description":"Select the type of sensor you would like to expose this as in Homebridge.",
"oneOf":[
- {
- "title":"Button",
- "enum":[
- "button"
- ]
- },
{
"title":"Motion",
"enum":[
@@ -303,9 +297,9 @@
},
{
"key":"bridgeSensors",
- "title":"RF Bridge Devices",
+ "title":"RF Bridge Sensors",
"expandable":true,
- "add":"Add Another Device",
+ "add":"Add Another Sensor",
"type":"array",
"items":[
{
From 098d2b90d58d2bb150a6d48a076483896a67b199 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Wed, 19 Aug 2020 21:24:43 +0100
Subject: [PATCH 0030/3183] issue #72 helper
---
lib/eWeLink.js | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index eba46a71..9516058e 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -101,7 +101,12 @@ class eWeLink {
}
//*** Synchronise (add/refresh) devices between eWeLink and Homebridge ***\\
this.devicesInEwe.forEach(device => {
- this.initialiseDevice(device);
+ if (device.hasOwnProperty("extra") && device.extra.hasOwnProperty("uiid")) {
+ this.initialiseDevice(device);
+ } else {
+ let deviceName = device.hasOwnProperty("name") ? device.name : "Unknown Device";
+ this.log.warn("[%s] could not be synchronised due to missing uiid parameter.", deviceName);
+ }
});
//*** Set up the ws listener for future external device updates ***\\
this.wsClient.receiveUpdate(device => {
From 1f423035ad05fc4bef92e74b1bf9e421a9fe4fae Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Wed, 19 Aug 2020 21:25:19 +0100
Subject: [PATCH 0031/3183] 2.19.3
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 386790ae..0077fce1 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.19.2",
+ "version": "2.19.3",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 607d3323..83a1c664 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.19.2",
+ "version": "2.19.3",
"author": "bwp91",
"contributors": [
"gbro115",
From 6a2b380605ab338b11c267f3e9f543735f7d4a74 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Wed, 19 Aug 2020 22:21:56 +0100
Subject: [PATCH 0032/3183] lan default
---
config.schema.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/config.schema.json b/config.schema.json
index 95772b9f..a265ff91 100644
--- a/config.schema.json
+++ b/config.schema.json
@@ -44,7 +44,7 @@
"type":"string",
"title":"Connection Mode",
"required":true,
- "default":"ws",
+ "default":"lan",
"description":"Preferred method of updating devices. Devices that don't support LAN mode will use web socket.",
"oneOf":[
{
From 29cd09f93f8ad01d4ab92e319e22c2140eef0fba Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Thu, 20 Aug 2020 17:06:19 +0100
Subject: [PATCH 0033/3183] remove mode option
---
config.schema.json | 22 ----------------------
1 file changed, 22 deletions(-)
diff --git a/config.schema.json b/config.schema.json
index a265ff91..8a6237d9 100644
--- a/config.schema.json
+++ b/config.schema.json
@@ -40,27 +40,6 @@
"description":"If enabled, HTTP, web socket and LAN mode messages will be added to the log. Not recommended for long-term use.",
"default":false
},
- "mode":{
- "type":"string",
- "title":"Connection Mode",
- "required":true,
- "default":"lan",
- "description":"Preferred method of updating devices. Devices that don't support LAN mode will use web socket.",
- "oneOf":[
- {
- "title":"LAN Mode (Recommended)",
- "enum":[
- "lan"
- ]
- },
- {
- "title":"Web Socket",
- "enum":[
- "ws"
- ]
- }
- ]
- },
"hideDevFromHB":{
"type":"string",
"title":"Hide Devices",
@@ -266,7 +245,6 @@
"items":[
"debug",
"debugReqRes",
- "mode",
"hideDevFromHB",
"hideFromHB",
"sensorTimeLength",
From fa9c3f422e4dae90309ea914ca52e326364f6c6a Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Thu, 20 Aug 2020 17:06:28 +0100
Subject: [PATCH 0034/3183] add camera uiid
---
lib/constants.js | 1 +
1 file changed, 1 insertion(+)
diff --git a/lib/constants.js b/lib/constants.js
index 27699ea5..3c557fca 100644
--- a/lib/constants.js
+++ b/lib/constants.js
@@ -14,6 +14,7 @@ module.exports = {
devicesThermostat: [15],
devicesFan: [34],
devicesOutlet: [32],
+ devicesCamera: [87],
devicesUSB: [77],
devicesSCM: [78],
devicesRFBridge: [28],
From 387e98bcae9ceda49b9057f22f1c84d863ead5d8 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Thu, 20 Aug 2020 17:06:39 +0100
Subject: [PATCH 0035/3183] refactors
---
lib/eWeLink.js | 1974 +++++++++++++++++++++-----------------------
lib/eWeLinkHTTP.js | 46 +-
lib/eWeLinkLAN.js | 43 +-
lib/eWeLinkWS.js | 91 +-
4 files changed, 1056 insertions(+), 1098 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 9516058e..89352a12 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -1,6 +1,6 @@
/* jshint esversion: 9, -W030, node: true */
"use strict";
-const constants = require("./constants");
+const cns = require("./constants");
const convert = require("color-convert");
const eWeLinkHTTP = require("./eWeLinkHTTP");
const eWeLinkWS = require("./eWeLinkWS");
@@ -12,23 +12,12 @@ class eWeLink {
return;
}
if (!config || (!config.username || !config.password || !config.countryCode)) {
- log.error("** Could not load " + constants.packageName + " **");
- log.warn("Make sure your eWeLink credentials are in the Homebridge configuration.");
+ log.error("đ´ Cannot load %s - please check your eWeLink credentials in the plugin settings.", cns.packageName);
return;
}
this.log = log;
this.config = config;
this.api = api;
- this.mode = this.config.mode || "lan";
- this.debug = this.config.debug || false;
- this.debugReqRes = this.config.debugReqRes || false;
- this.customHideChanFromHB = this.config.hideFromHB || "";
- this.customHideDvceFromHB = this.config.hideDevFromHB || "";
- this.customNameOverride = this.config.nameOverride || {};
- this.sensorTimeLength = this.config.sensorTimeLength || 2;
- this.sensorTimeDifference = this.config.sensorTimeDifference || 120;
- this.valveTimeLength = this.config.valveTimeLength || 120;
- this.hideZBLDPress = this.config.hideZBLDPress || false;
this.devicesInHB = new Map();
this.devicesInEwe = new Map();
this.cusG = new Map();
@@ -43,94 +32,78 @@ class eWeLink {
}).then(res => { //*** Set up the web socket client ***\\
this.wsClient = new eWeLinkWS(this.config, this.log, res);
return this.wsClient.getHost();
- }).then(res => { //*** Open web socket connection and get device list via HTTP ***\\
+ }).then(() => { //*** Open web socket connection and get device list via HTTP ***\\
this.wsClient.login();
return this.httpClient.getDevices();
}).then(res => { //*** Get device IP addresses for LAN mode ***\\
+ this.httpDevices = res
+ .filter(device => !(this.config.hideDevFromHB || "").includes(device.deviceid))
+ .forEach(device => this.devicesInEwe.set(device.deviceid, device));
this.httpDevices = res;
this.lanClient = new eWeLinkLAN(this.config, this.log, this.httpDevices);
return this.lanClient.getHosts();
}).then(res => { //*** Set up the LAN mode listener ***\\
- this.lanDevices = res;
+ this.lanDevices = res.map;
+ this.lanDeviceOnline = res.count;
return this.lanClient.startMonitor();
- }).then(res => { //*** Use the device list to refresh Homebridge accessories ***\\
+ }).then(() => { //*** Use the device list to refresh Homebridge accessories ***\\
(() => {
//*** Remove all Homebridge accessories if none found ***\\
if (Object.keys(this.httpDevices).length === 0 && Object.keys(this.lanDevices).length === 0) {
- this.removeAllAccessories();
+ Array.from(this.devicesInHB.values()).forEach(a => this.removeAccessory(a));
+ this.devicesInHB.clear();
+ this.log.warn("đ No devices were found registered to your eWeLink account so disabling plugin.");
return;
}
- //*** Make a map of devices from eWeLink ***\\
- this.httpDevices.forEach(device => {
- if (this.customHideDvceFromHB.includes(device.deviceid)) {
- return;
- }
- this.devicesInEwe.set(device.deviceid, device);
- });
//*** Make a map of custom groups from Homebridge config ***\\
- if (this.config.groups && Object.keys(this.config.groups).length > 0) {
- this.config.groups.forEach(group => {
- if (typeof group.deviceId !== "undefined" && this.devicesInEwe.has(group.deviceId.toLowerCase())) {
- this.cusG.set(group.deviceId + "SWX", group);
- }
- });
+ if (Object.keys(this.config.groups || []).length > 0) {
+ this.config.groups
+ .filter(g => g.hasOwnProperty("deviceId") && this.devicesInEwe.has(g.deviceId.toLowerCase()))
+ .forEach(g => this.cusG.set(g.deviceId + "SWX", g));
}
//*** Make a map of RF Bridge custom sensors from Homebridge config ***\\
- if (this.config.bridgeSensors && Object.keys(this.config.bridgeSensors).length > 0) {
- this.config.bridgeSensors.forEach(bridgeSensor => {
- if (typeof bridgeSensor.deviceId !== "undefined" && this.devicesInEwe.has(bridgeSensor.deviceId.toLowerCase())) {
- this.cusS.set(bridgeSensor.fullDeviceId, bridgeSensor);
- }
- });
+ if (Object.keys(this.config.bridgeSensors || []).length > 0) {
+ this.config.bridgeSensors
+ .filter(s => s.hasOwnProperty("deviceId") && this.devicesInEwe.has(s.deviceId.toLowerCase()))
+ .forEach(s => this.cusS.set(s.fullDeviceId, s));
}
//*** Logging always helps to see if everything is okay so far ***\\
this.log("[%s] eWeLink devices were loaded from the Homebridge cache.", this.devicesInHB.size);
this.log("[%s] primary devices were loaded from your eWeLink account.", this.devicesInEwe.size);
- this.log("[%s] primary devices were discovered on your local network.", Object.keys(this.lanDevices).length);
+ this.log("[%s] primary devices were discovered on your local network.", this.lanDeviceOnline);
//*** Remove Homebridge accessories that don't appear in eWeLink ***\\
- if (this.devicesInHB.size > 0) {
- this.devicesInHB.forEach(accessory => {
- if (!this.devicesInEwe.has(accessory.context.eweDeviceId)) {
- this.removeAccessory(accessory);
- }
- });
- }
- //*** Disable plugin if no eWeLink devices ***\\
- if (this.devicesInEwe.size === 0) {
- return;
- }
- //*** Synchronise (add/refresh) devices between eWeLink and Homebridge ***\\
- this.devicesInEwe.forEach(device => {
- if (device.hasOwnProperty("extra") && device.extra.hasOwnProperty("uiid")) {
- this.initialiseDevice(device);
- } else {
- let deviceName = device.hasOwnProperty("name") ? device.name : "Unknown Device";
- this.log.warn("[%s] could not be synchronised due to missing uiid parameter.", deviceName);
+ this.devicesInHB.forEach(accessory => {
+ if (!this.devicesInEwe.has(accessory.context.eweDeviceId)) {
+ this.removeAccessory(accessory);
}
});
- //*** Set up the ws listener for future external device updates ***\\
- this.wsClient.receiveUpdate(device => {
- this.receiveDeviceUpdate(device);
- });
- //*** Set up the lan listener for future external device updates ***\\
- this.lanClient.receiveUpdate(device => {
- this.receiveDeviceUpdate(device);
- });
- this.log("Synchronisation complete. Ready to go!");
- if (this.debugReqRes) {
+ //*** Synchronise devices between eWeLink and Homebridge and set up ws/lan listeners ***\\
+ this.devicesInEwe.forEach(device => this.initialiseDevice(device));
+ this.wsClient.receiveUpdate(device => this.receiveDeviceUpdate(device));
+ this.lanClient.receiveUpdate(device => this.receiveDeviceUpdate(device));
+ this.log("đĸ eWeLink setup complete. If you're enjoying this package please consider a âī¸ on GitHub!");
+ if (this.config.debugReqRes) {
this.log.warn("You have 'Request & Response Logging' enabled. This setting is not recommended for long-term use.");
}
})();
- }).catch(err => {
- this.log.error("** eWeLink synchronisation error: **");
- this.log.warn(err);
- this.log.error("** Plugin will not be loaded. **");
- });
+ }).catch(err => this.log.error("đ´ Cannot load %s - %s", cns.packageName, err));
+ });
+ this.api.on('shutdown', () => {
+ this.lanClient.closeConnection();
+ this.wsClient.closeConnection();
});
}
initialiseDevice(device) {
+ if (!device.hasOwnProperty("extra") || !device.extra.hasOwnProperty("uiid")) {
+ let deviceName = device.hasOwnProperty("name") ?
+ device.name :
+ device.hasOwnProperty("deviceid") ? device.deviceid : "Unknown Device";
+ this.log.warn("[%s] could not be synchronised due to missing uiid parameter.", deviceName);
+ return;
+ }
let accessory;
- //*** First add the device if it isn't already in Homebridge ***\\
+ device.params.updateSource = "http";
+ //*** First add the device if it isn't already in Homebridge. Yeah this code looks a mess :| ***\\
if (!this.devicesInHB.has(device.deviceid + "SWX") && !this.devicesInHB.has(device.deviceid + "SW0")) {
if (device.extra.uiid === 2 && device.brandName === "coolkit" && device.productModel === "0285") {
this.addAccessory(device, device.deviceid + "SWX", "valve");
@@ -138,141 +111,117 @@ class eWeLink {
this.addAccessory(device, device.deviceid + "SWX", "blind");
} else if (this.cusG.has(device.deviceid + "SWX") && this.cusG.get(device.deviceid + "SWX").type === "garage") {
this.addAccessory(device, device.deviceid + "SWX", "garage");
- } else if (constants.devicesSensor.includes(device.extra.uiid)) {
+ } else if (cns.devicesSensor.includes(device.extra.uiid)) {
this.addAccessory(device, device.deviceid + "SWX", "sensor");
- } else if (constants.devicesFan.includes(device.extra.uiid)) {
+ } else if (cns.devicesFan.includes(device.extra.uiid)) {
this.addAccessory(device, device.deviceid + "SWX", "fan");
- } else if (constants.devicesThermostat.includes(device.extra.uiid)) {
+ } else if (cns.devicesThermostat.includes(device.extra.uiid)) {
this.addAccessory(device, device.deviceid + "SWX", "thermostat");
- } else if (constants.devicesOutlet.includes(device.extra.uiid)) {
+ } else if (cns.devicesOutlet.includes(device.extra.uiid)) {
this.addAccessory(device, device.deviceid + "SWX", "outlet");
- } else if (constants.devicesUSB.includes(device.extra.uiid)) {
+ } else if (cns.devicesUSB.includes(device.extra.uiid)) {
this.addAccessory(device, device.deviceid + "SWX", "usb");
- } else if (constants.devicesSCM.includes(device.extra.uiid)) {
+ } else if (cns.devicesSCM.includes(device.extra.uiid)) {
this.addAccessory(device, device.deviceid + "SWX", "scm");
- } else if (constants.devicesSingleSwitch.includes(device.extra.uiid) && constants.devicesSingleSwitchLight.includes(device.productModel)) {
+ } else if (cns.devicesSingleSwitch.includes(device.extra.uiid) && cns.devicesSingleSwitchLight.includes(device.productModel)) {
this.addAccessory(device, device.deviceid + "SWX", "light");
- } else if (constants.devicesMultiSwitch.includes(device.extra.uiid) && constants.devicesMultiSwitchLight.includes(device.productModel)) {
- for (let i = 0; i <= constants.chansFromUiid[device.extra.uiid]; i++) {
+ } else if (cns.devicesMultiSwitch.includes(device.extra.uiid) && cns.devicesMultiSwitchLight.includes(device.productModel)) {
+ for (let i = 0; i <= cns.chansFromUiid[device.extra.uiid]; i++) {
this.addAccessory(device, device.deviceid + "SW" + i, "light");
}
- } else if (constants.devicesSingleSwitch.includes(device.extra.uiid)) {
+ } else if (cns.devicesSingleSwitch.includes(device.extra.uiid)) {
this.addAccessory(device, device.deviceid + "SWX", "switch");
- } else if (constants.devicesMultiSwitch.includes(device.extra.uiid)) {
- for (let i = 0; i <= constants.chansFromUiid[device.extra.uiid]; i++) {
+ } else if (cns.devicesMultiSwitch.includes(device.extra.uiid)) {
+ for (let i = 0; i <= cns.chansFromUiid[device.extra.uiid]; i++) {
this.addAccessory(device, device.deviceid + "SW" + i, "switch");
}
- } else if (constants.devicesRFBridge.includes(device.extra.uiid)) {
+ } else if (cns.devicesRFBridge.includes(device.extra.uiid)) {
this.addAccessory(device, device.deviceid + "SW0", "rf_pri");
- for (let i = 1; i <= Object.keys(device.params.rfList).length; i++) {
+ for (let i = 1; i <= Object.keys(device.tags.zyx_info).length; i++) {
this.addAccessory(device, device.deviceid + "SW" + i, "rf_sub");
}
- } else if (constants.devicesZBBridge.includes(device.extra.uiid)) {
+ } else if (cns.devicesZBBridge.includes(device.extra.uiid)) {
this.addAccessory(device, device.deviceid + "SWX", "zb_pri");
- } else if (constants.devicesZB.includes(device.extra.uiid)) {
+ } else if (cns.devicesZB.includes(device.extra.uiid)) {
this.addAccessory(device, device.deviceid + "SWX", "zb_sub");
- } else if (device.extra.uiid === 87) {
+ } else if (cns.devicesCamera.includes(device.extra.uiid)) {
this.log.warn("[%s] please consider using homebridge-camera-ffmpeg to use this camera.", device.name);
+ return;
} else {
- this.log.warn("[%s] could not be added as it is not supported by this plugin.", device.name);
+ this.log.warn("[%s] cannot be added as it is not supported by this plugin. Please make a GitHub issue request.", device.name);
+ return;
}
}
//*** Next refresh the device ***\\
- if ((accessory = this.devicesInHB.get(device.deviceid + "SWX"))) {
+ if ((accessory = this.devicesInHB.get(device.deviceid + "SWX") || this.devicesInHB.get(device.deviceid + "SW0"))) {
+ let isX = accessory.context.hbDeviceId.substr(-1) === "X",
+ isRfBridge = cns.devicesRFBridge.includes(accessory.context.eweUIID),
+ rfBridgeChange = false;
accessory.getService(Service.AccessoryInformation).setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion);
- accessory.context.reachableWAN = accessory.context.eweUIID !== 102 ?
- device.online :
- true; //*** DW2 offline sometimes (as battery powered?) ***\\
- accessory.context.reachableLAN = this.lanDevices[device.deviceid].ip || false;
+ accessory.context.reachableWAN = accessory.context.eweUIID !== 102 ? device.online : true; //*** DW2 ***\\
+ accessory.context.reachableLAN = this.lanDevices.get(device.deviceid).online || false;
let str = accessory.context.reachableLAN ?
- "and locally with IP [" + accessory.context.reachableLAN + "]" :
- (accessory.context.reachableWAN) ?
- "but LAN mode unavailable as unsupported/shared device" :
- "but LAN mode unavailable as device offline";
+ "and locally with IP [" + this.lanDevices.get(device.deviceid).ip + "]" :
+ "but LAN mode unavailable as unsupported/shared device";
this.log("[%s] found in eWeLink %s.", accessory.displayName, str);
- try {
- this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
- this.api.updatePlatformAccessories(constants.packageName, "eWeLink", [accessory]);
- } catch (e) {
- this.log.warn("[%s] online/offline status could not be updated - [%s].", accessory.displayName, e);
- }
- } else if ((accessory = this.devicesInHB.get(device.deviceid + "SW0"))) {
- accessory.context.reachableLAN = this.lanDevices[device.deviceid].ip || false;
- let str = accessory.context.reachableLAN ?
- "and locally with IP [" + accessory.context.reachableLAN + "]" :
- (accessory.context.reachableWAN) ?
- "but LAN mode unavailable as unsupported/shared device" :
- "but LAN mode unavailable as device offline";
- this.log("[%s] found in eWeLink %s.", accessory.displayName, str);
- let isRf = constants.devicesRFBridge.includes(device.extra.uiid);
- let rfCh = false;
- for (let i = 0; i <= accessory.context.channelCount; i++) {
- let oAccessory;
- try {
+ this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
+ if (!isX) {
+ for (let i = 1; i <= accessory.context.channelCount; i++) {
if (!this.devicesInHB.has(device.deviceid + "SW" + i)) {
- if (i > 0 && this.customHideChanFromHB.includes(device.deviceid + "SW" + i) && constants.devicesHideable.includes(accessory.context.type)) {
- continue;
- } else {
- this.addAccessory(device, device.deviceid + "SW" + i, "switch");
+ if (cns.devicesHideable.includes(accessory.context.type)) {
+ if ((this.config.hideFromHB || "").includes(device.deviceid + "SW" + i)) {
+ continue;
+ } else {
+ this.addAccessory(device, device.deviceid + "SW" + i, "switch");
+ }
}
}
- oAccessory = this.devicesInHB.get(device.deviceid + "SW" + i);
- if (i > 0 && this.customHideChanFromHB.includes(device.deviceid + "SW" + i) && constants.devicesHideable.includes(accessory.context.type)) {
+ let oAccessory = this.devicesInHB.get(device.deviceid + "SW" + i);
+ if ((this.config.hideFromHB || "").includes(device.deviceid + "SW" + i) && cns.devicesHideable.includes(accessory.context.type)) {
this.removeAccessory(oAccessory);
continue;
}
- if (i > 0 && isRf) {
+ if (isRfBridge && oAccessory.context.sensorType !== "button") {
let ct = this.cusS.has(oAccessory.context.hbDeviceId) ? this.cusS.get(oAccessory.context.hbDeviceId).type : "motion";
- if (ct !== oAccessory.context.sensorType) {
- rfCh = true;
+ if (ct !== oAccessory.context.sensorType || typeof accessory.context.updated === "undefined") {
+ rfBridgeChange = true;
}
}
oAccessory.getService(Service.AccessoryInformation).setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion);
oAccessory.context.reachableWAN = device.online;
- oAccessory.context.reachableLAN = this.lanDevices[device.deviceid].ip || false;
+ oAccessory.context.reachableLAN = this.lanDevices.get(device.deviceid).online || false;
this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory);
- this.api.updatePlatformAccessories(constants.packageName, "eWeLink", [oAccessory]);
- } catch (e) {}
- }
- if (rfCh) {
- this.log.warn("RF Bridge configuration changed. Devices will be removed and readded.");
- try {
- for (let i = 0; i <= accessory.context.channelCount; i++) {
- let oAccessory = this.devicesInHB.get(device.deviceid + "SW" + i);
- this.removeAccessory(oAccessory);
- }
- this.initialiseDevice(device);
- } catch (err) {}
+ }
+ }
+ if (rfBridgeChange) {
+ this.log.warn("[%s] bridge configuration changed - devices will be removed and readded.", accessory.displayName);
+ for (let i = 0; i <= accessory.context.channelCount; i++) {
+ let oAccessory = this.devicesInHB.get(device.deviceid + "SW" + i);
+ this.removeAccessory(oAccessory);
+ }
+ this.initialiseDevice(device);
return;
}
- } else {
- if (device.extra.uiid !== 87) {
- this.log.warn("[%s] will not be refreshed as it wasn't found in Homebridge.", device.name);
+ if (!this.refreshAccessory(accessory, device.params)) {
+ this.log.warn("[%s] could not be initialised. Please try removing accessory from the Homebridge cache along with any secondary devices (SW1, SW2, etc.) [debug:%s:%s].", accessory.displayName, accessory.context.type, accessory.context.channelCount);
}
- return;
- }
- if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
- this.log.warn("[%s] will not be refreshed as it has been reported offline.", accessory.displayName);
- return;
- }
- device.params.updateSource = "http";
- if (!this.refreshAccessory(accessory, device.params)) {
- this.log.warn("[%s] could not be refreshed. Please try removing accessory from the Homebridge cache along with any secondary devices (SW1, SW2, etc.). Debugging: [%s:%s:%s]", accessory.displayName, "initialise", accessory.context.type, accessory.context.channelCount);
+ } else {
+ this.log.warn("[%s] cannot be initialised as it wasn't found in Homebridge.", device.name);
}
}
addAccessory(device, hbDeviceId, type) {
- let channelCount = type === "rf_pri" ? Object.keys(device.params.rfList).length : constants.chansFromUiid[device.extra.uiid],
+ let channelCount = type === "rf_pri" ? Object.keys(device.tags.zyx_info).length : cns.chansFromUiid[device.extra.uiid],
switchNumber = hbDeviceId.substr(-1).toString(),
- newDeviceName = device.name;
- if (["1", "2", "3", "4"].includes(switchNumber)) {
+ newDeviceName = type === "rf_sub" ? device.tags.zyx_info[switchNumber - 1].name : device.name;
+ if (["1", "2", "3", "4"].includes(switchNumber) && type !== "rf_sub") {
newDeviceName += " SW" + switchNumber;
- if (this.customHideChanFromHB.includes(hbDeviceId) && type === "switch") {
+ if ((this.config.hideFromHB || "").includes(hbDeviceId) && cns.devicesHideable.includes(type)) {
this.log.warn("[%s] has not been added as per configuration", newDeviceName);
return;
}
}
- if (this.customNameOverride.hasOwnProperty(hbDeviceId)) {
- newDeviceName = this.customNameOverride[hbDeviceId];
+ if ((this.config.nameOverride || {}).hasOwnProperty(hbDeviceId)) {
+ newDeviceName = this.config.nameOverride[hbDeviceId];
}
const accessory = new Accessory(newDeviceName, UUIDGen.generate(hbDeviceId).toString());
try {
@@ -293,124 +242,150 @@ class eWeLink {
type
};
switch (type) {
- case "valve":
- ["A", "B"].forEach(v => {
- accessory.addService(Service.Valve, "Valve " + v, "valve" + v.toLowerCase())
- .setCharacteristic(Characteristic.Active, 0)
- .setCharacteristic(Characteristic.InUse, 0)
- .setCharacteristic(Characteristic.ValveType, 1)
- .setCharacteristic(Characteristic.SetDuration, this.valveTimeLength)
- .addCharacteristic(Characteristic.RemainingDuration);
- });
- break;
- case "blind":
- accessory.addService(Service.WindowCovering)
- .setCharacteristic(Characteristic.CurrentPosition, 100)
- .setCharacteristic(Characteristic.TargetPosition, 100)
- .setCharacteristic(Characteristic.PositionState, 2);
- break;
- case "garage":
- accessory.addService(Service.GarageDoorOpener)
- .setCharacteristic(Characteristic.CurrentDoorState, 1)
- .setCharacteristic(Characteristic.TargetDoorState, 1)
- .setCharacteristic(Characteristic.ObstructionDetected, false);
- break;
- case "sensor":
- accessory.addService(Service.ContactSensor)
- .setCharacteristic(Characteristic.ContactSensorState, 0);
- break;
- case "fan":
- accessory.addService(Service.Fanv2);
- accessory.addService(Service.Lightbulb);
- break;
- case "thermostat":
- accessory.addService(Service.Switch);
- accessory.addService(Service.TemperatureSensor);
- if (device.params.sensorType !== "DS18B20") {
- accessory.addService(Service.HumiditySensor);
- }
- break;
- case "outlet":
- case "usb":
- accessory.addService(Service.Outlet);
- break;
- case "light":
- accessory.addService(Service.Lightbulb);
- break;
- case "switch":
- case "scm":
- accessory.addService(Service.Switch);
- break;
- case "rf_pri":
- case "zb_pri":
- break;
- case "rf_sub":
- accessory.context.sensorType = this.cusS.has(hbDeviceId) ? this.cusS.get(hbDeviceId).type : "motion";
- accessory.context.rfChl = parseInt(switchNumber) - 1;
- switch (accessory.context.sensorType) {
- case "button":
- accessory.addService(Service.Switch);
+ case "valve":
+ ["A", "B"].forEach(v => {
+ accessory.addService(Service.Valve, "Valve " + v, "valve" + v.toLowerCase())
+ .setCharacteristic(Characteristic.Active, 0)
+ .setCharacteristic(Characteristic.InUse, 0)
+ .setCharacteristic(Characteristic.ValveType, 1)
+ .setCharacteristic(Characteristic.SetDuration, (this.config.valveTimeLength || 120))
+ .addCharacteristic(Characteristic.RemainingDuration);
+ });
break;
- case "water":
- accessory.addService(Service.LeakSensor);
+ case "blind":
+ accessory.addService(Service.WindowCovering)
+ .setCharacteristic(Characteristic.CurrentPosition, 100)
+ .setCharacteristic(Characteristic.TargetPosition, 100)
+ .setCharacteristic(Characteristic.PositionState, 2);
break;
- case "fire":
- case "smoke":
- accessory.addService(Service.SmokeSensor);
+ case "garage":
+ accessory.addService(Service.GarageDoorOpener)
+ .setCharacteristic(Characteristic.CurrentDoorState, 1)
+ .setCharacteristic(Characteristic.TargetDoorState, 1)
+ .setCharacteristic(Characteristic.ObstructionDetected, false);
break;
- case "co":
- accessory.addService(Service.CarbonMonoxideSensor);
+ case "sensor":
+ accessory.addService(Service.ContactSensor);
break;
- case "co2":
- accessory.addService(Service.CarbonDioxideSensor);
+ case "fan":
+ accessory.addService(Service.Fanv2);
+ accessory.addService(Service.Lightbulb);
break;
- case "contact":
- accessory.addService(Service.ContactSensor);
+ case "thermostat":
+ accessory.addService(Service.Switch);
+ accessory.addService(Service.TemperatureSensor);
+ if (device.params.sensorType !== "DS18B20") {
+ accessory.addService(Service.HumiditySensor);
+ }
break;
- case "occupancy":
- accessory.addService(Service.OccupancySensor);
+ case "outlet":
+ case "usb":
+ accessory.addService(Service.Outlet);
break;
- case "motion":
- default:
- accessory.addService(Service.MotionSensor);
+ case "light":
+ accessory.addService(Service.Lightbulb);
break;
- }
- break;
- case "zb_sub":
- switch (device.extra.uiid) {
- case 1000: //*** credit @tasict ***\\
- accessory.addService(Service.StatelessProgrammableSwitch);
- if (this.hideZBLDPress) {
- accessory.getService(Service.StatelessProgrammableSwitch)
- .getCharacteristic(Characteristic.ProgrammableSwitchEvent)
- .setProps({
- validValues: [0]
- });
- }
+ case "switch":
+ case "scm":
+ accessory.addService(Service.Switch);
break;
- case 1770:
- accessory.addService(Service.TemperatureSensor);
- accessory.addService(Service.HumiditySensor);
+ case "rf_pri":
+ accessory.context.rfChlMap = {};
+ accessory.context.updated = true;
break;
- case 2026:
- accessory.addService(Service.MotionSensor);
+ case "zb_pri":
break;
- case 3026:
- accessory.addService(Service.ContactSensor).setCharacteristic(Characteristic.ContactSensorState, 0);
+ case "rf_sub":
+ accessory.context.rfChls = {};
+ switch (device.tags.zyx_info[parseInt(switchNumber) - 1].remote_type) {
+ case "1":
+ case "2":
+ case "3":
+ case "4":
+ accessory.context.sensorType = "button";
+ break;
+ case "6":
+ accessory.context.sensorType = this.cusS.has(hbDeviceId) ? this.cusS.get(hbDeviceId).type : "motion";
+ break;
+ case "5":
+ default:
+ throw "RF device type is not supported";
+ }
+ let mAccessory = this.devicesInHB.get(device.deviceid + "SW0");
+ device.tags.zyx_info[parseInt(switchNumber) - 1].buttonName.forEach(button => {
+ let rfChan, name;
+ Object.entries(button).forEach(([k, v]) => {
+ rfChan = k;
+ name = v;
+ });
+ accessory.context.rfChls[rfChan] = name;
+ mAccessory.context.rfChlMap[rfChan] = switchNumber;
+ switch (accessory.context.sensorType) {
+ case "button":
+ accessory.addService(Service.Switch, name, "switch" + rfChan);
+ break;
+ case "water":
+ accessory.addService(Service.LeakSensor);
+ break;
+ case "fire":
+ case "smoke":
+ accessory.addService(Service.SmokeSensor);
+ break;
+ case "co":
+ accessory.addService(Service.CarbonMonoxideSensor);
+ break;
+ case "co2":
+ accessory.addService(Service.CarbonDioxideSensor);
+ break;
+ case "contact":
+ accessory.addService(Service.ContactSensor);
+ break;
+ case "occupancy":
+ accessory.addService(Service.OccupancySensor);
+ break;
+ case "motion":
+ default:
+ accessory.addService(Service.MotionSensor);
+ break;
+ }
+ this.devicesInHB.set(mAccessory.context.hbDeviceId, mAccessory);
+ });
+ break;
+ case "zb_sub": //*** credit @tasict ***\\
+ switch (device.extra.uiid) {
+ case 1000:
+ accessory.addService(Service.StatelessProgrammableSwitch);
+ if (this.config.hideZBLDPress) {
+ accessory.getService(Service.StatelessProgrammableSwitch)
+ .getCharacteristic(Characteristic.ProgrammableSwitchEvent)
+ .setProps({
+ validValues: [0]
+ });
+ }
+ break;
+ case 1770:
+ accessory.addService(Service.TemperatureSensor);
+ accessory.addService(Service.HumiditySensor);
+ break;
+ case 2026:
+ accessory.addService(Service.MotionSensor);
+ break;
+ case 3026:
+ accessory.addService(Service.ContactSensor);
+ break;
+ default:
+ throw "unsupported zigbee device type with uiid [" + device.extra.uiid + "]";
+ }
break;
default:
- throw "unsupported zigbee device type with uiid [" + device.extra.uiid + "]";
- }
- break;
- default:
- throw "device is not supported by this plugin";
+ throw "device is not supported by this plugin";
}
this.devicesInHB.set(hbDeviceId, accessory);
- this.api.registerPlatformAccessories(constants.packageName, "eWeLink", [accessory]);
+ this.api.registerPlatformAccessories(cns.packageName, "eWeLink", [accessory]);
this.configureAccessory(accessory);
this.log("[%s] has been added to Homebridge.", newDeviceName);
- } catch (e) {
- this.log.warn("[%s] could not be added as %s.", accessory.displayName, e);
+ } catch (err) {
+ this.log.warn("[%s] could not be added - %s.", newDeviceName, err);
}
}
configureAccessory(accessory) {
@@ -419,276 +394,272 @@ class eWeLink {
}
try {
switch (accessory.context.type) {
- case "valve":
- ["A", "B"].forEach(v => {
- accessory.getService("Valve " + v).getCharacteristic(Characteristic.Active)
+ case "valve":
+ ["A", "B"].forEach(v => {
+ accessory.getService("Valve " + v).getCharacteristic(Characteristic.Active)
+ .on("set", (value, callback) => {
+ accessory.getService("Valve " + v).getCharacteristic(Characteristic.Active).value !== value ?
+ this.internalValveUpdate(accessory, "Valve " + v, value, callback) :
+ callback();
+ });
+ accessory.getService("Valve " + v).getCharacteristic(Characteristic.SetDuration)
+ .on("set", (value, callback) => {
+ if (accessory.getService("Valve " + v).getCharacteristic(Characteristic.InUse).value) {
+ accessory.getService("Valve " + v).updateCharacteristic(Characteristic.RemainingDuration, value);
+ clearTimeout(accessory.getService("Valve " + v).timer);
+ accessory.getService("Valve " + v).timer = setTimeout(() => {
+ accessory.getService("Valve " + v).setCharacteristic(Characteristic.Active, 0);
+ }, (value * 1000));
+ }
+ callback();
+ });
+ });
+ break;
+ case "blind":
+ accessory.getService(Service.WindowCovering).getCharacteristic(Characteristic.TargetPosition)
+ .setProps({
+ minStep: 100
+ })
.on("set", (value, callback) => {
- accessory.getService("Valve " + v).getCharacteristic(Characteristic.Active).value !== value ?
- this.internalValveUpdate(accessory, "Valve " + v, value, callback) :
+ accessory.getService(Service.WindowCovering).getCharacteristic(Characteristic.TargetPosition).value !== value ?
+ this.internalBlindUpdate(accessory, value, callback) :
callback();
});
- accessory.getService("Valve " + v).getCharacteristic(Characteristic.SetDuration)
+ break;
+ case "garage":
+ accessory.getService(Service.GarageDoorOpener).getCharacteristic(Characteristic.TargetDoorState)
.on("set", (value, callback) => {
- if (accessory.getService("Valve " + v).getCharacteristic(Characteristic.InUse).value) {
- accessory.getService("Valve " + v).updateCharacteristic(Characteristic.RemainingDuration, value);
- clearTimeout(accessory.getService("Valve " + v).timer);
- accessory.getService("Valve " + v).timer = setTimeout(() => {
- accessory.getService("Valve " + v).setCharacteristic(Characteristic.Active, 0);
- }, (value * 1000));
- }
- callback();
+ accessory.getService(Service.GarageDoorOpener).getCharacteristic(Characteristic.TargetDoorState).value !== value ?
+ this.internalGarageUpdate(accessory, value, callback) :
+ callback();
});
- });
- break;
- case "blind":
- accessory.getService(Service.WindowCovering).getCharacteristic(Characteristic.TargetPosition)
- .setProps({
- minStep: 100
- })
- .on("set", (value, callback) => {
- accessory.getService(Service.WindowCovering).getCharacteristic(Characteristic.TargetPosition).value !== value ?
- this.internalBlindUpdate(accessory, value, callback) :
- callback();
- });
- break;
- case "garage":
- accessory.getService(Service.GarageDoorOpener).getCharacteristic(Characteristic.TargetDoorState)
- .on("set", (value, callback) => {
- accessory.getService(Service.GarageDoorOpener).getCharacteristic(Characteristic.TargetDoorState).value !== value ?
- this.internalGarageUpdate(accessory, value, callback) :
- callback();
- });
- break;
- case "fan":
- accessory.getService(Service.Fanv2).getCharacteristic(Characteristic.Active)
- .on("set", (value, callback) => {
- accessory.getService(Service.Fanv2).getCharacteristic(Characteristic.Active).value !== value ?
- this.internalFanUpdate(accessory, "power", value, callback) :
- callback();
- });
- accessory.getService(Service.Fanv2).getCharacteristic(Characteristic.RotationSpeed)
- .setProps({
- minStep: 33
- })
- .on("set", (value, callback) => {
- accessory.getService(Service.Fanv2).getCharacteristic(Characteristic.RotationSpeed).value !== value ?
- this.internalFanUpdate(accessory, "speed", value, callback) :
- callback();
- });
- accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => {
- accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value !== value ?
- this.internalFanUpdate(accessory, "light", value, callback) :
- callback();
- });
- break;
- case "thermostat":
- accessory.getService(Service.Switch).getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => {
- accessory.getService(Service.Switch).getCharacteristic(Characteristic.On).value !== value ?
- this.internalThermostatUpdate(accessory, value, callback) :
- callback();
- });
- break;
- case "outlet":
- accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => {
- accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On).value !== value ?
- this.internalOutletUpdate(accessory, value, callback) :
- callback();
- });
- break;
- case "usb":
- accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => {
- accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On).value !== value ?
- this.internalUSBUpdate(accessory, value, callback) :
- callback();
- });
- break;
- case "scm":
- accessory.getService(Service.Switch).getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => {
- accessory.getService(Service.Switch).getCharacteristic(Characteristic.On).value !== value ?
- this.internalSCMUpdate(accessory, value, callback) :
- callback();
- });
- break;
- case "light":
- accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => {
- accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value !== value ?
- this.internalLightbulbUpdate(accessory, value, callback) :
- callback();
- });
- if (constants.devicesBrightable.includes(accessory.context.eweUIID)) {
- accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Brightness)
+ break;
+ case "fan":
+ accessory.getService(Service.Fanv2).getCharacteristic(Characteristic.Active)
.on("set", (value, callback) => {
- if (value > 0) {
- if (!accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value) {
- this.internalLightbulbUpdate(accessory, true, callback);
- }
- accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Brightness).value !== value ?
- this.internalBrightnessUpdate(accessory, value, callback) :
- callback();
- } else {
- accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value ?
- this.internalLightbulbUpdate(accessory, false, callback) :
- callback();
- }
+ accessory.getService(Service.Fanv2).getCharacteristic(Characteristic.Active).value !== value ?
+ this.internalFanUpdate(accessory, "power", value, callback) :
+ callback();
});
- } else if (constants.devicesColourable.includes(accessory.context.eweUIID)) {
- accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Brightness)
+ accessory.getService(Service.Fanv2).getCharacteristic(Characteristic.RotationSpeed)
+ .setProps({
+ minStep: 33
+ })
.on("set", (value, callback) => {
- if (value > 0) {
- if (!accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value) {
- this.internalLightbulbUpdate(accessory, true, callback);
- }
- accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Brightness).value !== value ?
- this.internalHSBUpdate(accessory, "bri", value, callback) :
- callback();
- } else {
- accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value ?
- this.internalLightbulbUpdate(accessory, false, callback) :
- callback();
- }
+ accessory.getService(Service.Fanv2).getCharacteristic(Characteristic.RotationSpeed).value !== value ?
+ this.internalFanUpdate(accessory, "speed", value, callback) :
+ callback();
});
- accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Hue)
+ accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On)
.on("set", (value, callback) => {
- accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Hue).value !== value ?
- this.internalHSBUpdate(accessory, "hue", value, callback) :
+ accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value !== value ?
+ this.internalFanUpdate(accessory, "light", value, callback) :
callback();
});
- accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Saturation)
+ break;
+ case "thermostat":
+ accessory.getService(Service.Switch).getCharacteristic(Characteristic.On)
.on("set", (value, callback) => {
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Saturation, value);
- callback();
+ accessory.getService(Service.Switch).getCharacteristic(Characteristic.On).value !== value ?
+ this.internalThermostatUpdate(accessory, value, callback) :
+ callback();
});
- }
- break;
- case "switch":
- accessory.getService(Service.Switch).getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => {
- accessory.getService(Service.Switch).getCharacteristic(Characteristic.On).value !== value ?
- this.internalSwitchUpdate(accessory, value, callback) :
- callback();
- });
- break;
- case "rf_sub":
- if (accessory.context.sensorType === "button") {
+ break;
+ case "outlet":
+ accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On)
+ .on("set", (value, callback) => {
+ accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On).value !== value ?
+ this.internalOutletUpdate(accessory, value, callback) :
+ callback();
+ });
+ break;
+ case "usb":
+ accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On)
+ .on("set", (value, callback) => {
+ accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On).value !== value ?
+ this.internalUSBUpdate(accessory, value, callback) :
+ callback();
+ });
+ break;
+ case "scm":
accessory.getService(Service.Switch).getCharacteristic(Characteristic.On)
.on("set", (value, callback) => {
- this.internalRFDeviceUpdate(accessory, true, callback);
+ accessory.getService(Service.Switch).getCharacteristic(Characteristic.On).value !== value ?
+ this.internalSCMUpdate(accessory, value, callback) :
+ callback();
});
- }
- break;
+ break;
+ case "light":
+ accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On)
+ .on("set", (value, callback) => {
+ accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value !== value ?
+ this.internalLightbulbUpdate(accessory, value, callback) :
+ callback();
+ });
+ if (cns.devicesBrightable.includes(accessory.context.eweUIID)) {
+ accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Brightness)
+ .on("set", (value, callback) => {
+ if (value > 0) {
+ if (!accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value) {
+ this.internalLightbulbUpdate(accessory, true, callback);
+ }
+ accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Brightness).value !== value ?
+ this.internalBrightnessUpdate(accessory, value, callback) :
+ callback();
+ } else {
+ accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value ?
+ this.internalLightbulbUpdate(accessory, false, callback) :
+ callback();
+ }
+ });
+ } else if (cns.devicesColourable.includes(accessory.context.eweUIID)) {
+ accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Brightness)
+ .on("set", (value, callback) => {
+ if (value > 0) {
+ if (!accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value) {
+ this.internalLightbulbUpdate(accessory, true, callback);
+ }
+ accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Brightness).value !== value ?
+ this.internalHSBUpdate(accessory, "bri", value, callback) :
+ callback();
+ } else {
+ accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value ?
+ this.internalLightbulbUpdate(accessory, false, callback) :
+ callback();
+ }
+ });
+ accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Hue)
+ .on("set", (value, callback) => {
+ accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Hue).value !== value ?
+ this.internalHSBUpdate(accessory, "hue", value, callback) :
+ callback();
+ });
+ accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Saturation)
+ .on("set", (value, callback) => {
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Saturation, value);
+ callback();
+ });
+ }
+ break;
+ case "switch":
+ accessory.getService(Service.Switch).getCharacteristic(Characteristic.On)
+ .on("set", (value, callback) => {
+ accessory.getService(Service.Switch).getCharacteristic(Characteristic.On).value !== value ?
+ this.internalSwitchUpdate(accessory, value, callback) :
+ callback();
+ });
+ break;
+ case "rf_sub":
+ accessory.context.rfChls = accessory.context.rfChls || {};
+ if (accessory.context.sensorType === "button") {
+ Object.entries(accessory.context.rfChls).forEach(([k, v]) => {
+ accessory.getService(v).updateCharacteristic(Characteristic.On, false);
+ accessory.getService(v).getCharacteristic(Characteristic.On)
+ .on("set", (value, callback) => {
+ value ?
+ this.internalRFDeviceUpdate(accessory, k, callback) :
+ callback();
+ });
+ });
+ }
+ break;
}
accessory.context.reachableWAN = true;
accessory.context.reachableLAN = true;
this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
- this.api.updatePlatformAccessories(constants.packageName, "eWeLink", [accessory]);
- } catch (e) {
- this.log.warn("[%s] could not be refreshed - [%s].", accessory.displayName, e);
+ } catch (err) {
+ this.log.warn("[%s] could not be refreshed - [%s].", accessory.displayName, err);
}
}
refreshAccessory(accessory, newParams) {
switch (accessory.context.type) {
- case "valve":
- if (Array.isArray(newParams.switches)) {
- this.externalValveUpdate(accessory, newParams);
- }
- return true;
- case "blind":
- if (Array.isArray(newParams.switches)) {
- this.externalBlindUpdate(accessory, newParams);
- }
- return true;
- case "garage":
- if (newParams.hasOwnProperty("switch") || Array.isArray(newParams.switches)) {
- this.externalGarageUpdate(accessory, newParams);
- }
- return true;
- case "sensor":
- if (newParams.hasOwnProperty("switch")) {
- this.externalSensorUpdate(accessory, newParams);
- }
- return true;
- case "fan":
- if (Array.isArray(newParams.switches) || (newParams.hasOwnProperty("light") && newParams.hasOwnProperty("fan") && newParams.hasOwnProperty("speed"))) {
- this.externalFanUpdate(accessory, newParams);
- }
- return true;
- case "thermostat":
- if (newParams.hasOwnProperty("currentTemperature") || newParams.hasOwnProperty("currentHumidity") || newParams.hasOwnProperty("switch") || newParams.hasOwnProperty("masterSwitch")) {
- this.externalThermostatUpdate(accessory, newParams);
- }
- return true;
- case "outlet":
- if (newParams.hasOwnProperty("switch")) {
- this.externalOutletUpdate(accessory, newParams);
- }
- return true;
- case "usb":
- if (Array.isArray(newParams.switches)) {
- this.externalUSBUpdate(accessory, newParams);
- }
- return true;
- case "scm":
- if (Array.isArray(newParams.switches)) {
- this.externalSCMUpdate(accessory, newParams);
- }
- return true;
- case "light":
- if (constants.devicesSingleSwitch.includes(accessory.context.eweUIID) && constants.devicesSingleSwitchLight.includes(accessory.context.eweModel)) {
- if (newParams.hasOwnProperty("switch") || newParams.hasOwnProperty("state") || newParams.hasOwnProperty("bright") || newParams.hasOwnProperty("colorR") || newParams.hasOwnProperty("brightness") || newParams.hasOwnProperty("channel0") || newParams.hasOwnProperty("channel2") || newParams.hasOwnProperty("zyx_mode")) {
- this.externalSingleLightUpdate(accessory, newParams);
+ case "valve":
+ if (Array.isArray(newParams.switches)) {
+ this.externalValveUpdate(accessory, newParams);
}
- } else if (constants.devicesMultiSwitch.includes(accessory.context.eweUIID) && constants.devicesMultiSwitchLight.includes(accessory.context.eweModel)) {
+ return true;
+ case "blind":
if (Array.isArray(newParams.switches)) {
- this.externalMultiLightUpdate(accessory, newParams);
+ this.externalBlindUpdate(accessory, newParams);
}
- }
- return true;
- case "switch":
- if (constants.devicesSingleSwitch.includes(accessory.context.eweUIID)) {
+ return true;
+ case "garage":
+ if (newParams.hasOwnProperty("switch") || Array.isArray(newParams.switches)) {
+ this.externalGarageUpdate(accessory, newParams);
+ }
+ return true;
+ case "sensor":
if (newParams.hasOwnProperty("switch")) {
- this.externalSingleSwitchUpdate(accessory, newParams);
+ this.externalSensorUpdate(accessory, newParams);
+ }
+ return true;
+ case "fan":
+ if (Array.isArray(newParams.switches) || (newParams.hasOwnProperty("light") && newParams.hasOwnProperty("fan") && newParams.hasOwnProperty("speed"))) {
+ this.externalFanUpdate(accessory, newParams);
+ }
+ return true;
+ case "thermostat":
+ if (newParams.hasOwnProperty("currentTemperature") || newParams.hasOwnProperty("currentHumidity") || newParams.hasOwnProperty("switch") || newParams.hasOwnProperty("masterSwitch")) {
+ this.externalThermostatUpdate(accessory, newParams);
+ }
+ return true;
+ case "outlet":
+ if (newParams.hasOwnProperty("switch")) {
+ this.externalOutletUpdate(accessory, newParams);
+ }
+ return true;
+ case "usb":
+ if (Array.isArray(newParams.switches)) {
+ this.externalUSBUpdate(accessory, newParams);
}
- } else if (constants.devicesMultiSwitch.includes(accessory.context.eweUIID)) {
+ return true;
+ case "scm":
if (Array.isArray(newParams.switches)) {
- this.externalMultiSwitchUpdate(accessory, newParams);
+ this.externalSCMUpdate(accessory, newParams);
}
- }
- return true;
- case "rf_pri":
- this.externalRFDeviceUpdate(accessory, newParams);
- return true;
- case "rf_sub":
- case "zb_pri":
- return true;
- case "zb_sub":
- this.externalZBDeviceUpdate(accessory, newParams);
- return true;
- default:
- return false;
+ return true;
+ case "light":
+ if (cns.devicesSingleSwitch.includes(accessory.context.eweUIID) && cns.devicesSingleSwitchLight.includes(accessory.context.eweModel)) {
+ if (newParams.hasOwnProperty("switch") || newParams.hasOwnProperty("state") || newParams.hasOwnProperty("bright") || newParams.hasOwnProperty("colorR") || newParams.hasOwnProperty("brightness") || newParams.hasOwnProperty("channel0") || newParams.hasOwnProperty("channel2") || newParams.hasOwnProperty("zyx_mode")) {
+ this.externalSingleLightUpdate(accessory, newParams);
+ }
+ } else if (cns.devicesMultiSwitch.includes(accessory.context.eweUIID) && cns.devicesMultiSwitchLight.includes(accessory.context.eweModel)) {
+ if (Array.isArray(newParams.switches)) {
+ this.externalMultiLightUpdate(accessory, newParams);
+ }
+ }
+ return true;
+ case "switch":
+ if (cns.devicesSingleSwitch.includes(accessory.context.eweUIID)) {
+ if (newParams.hasOwnProperty("switch")) {
+ this.externalSingleSwitchUpdate(accessory, newParams);
+ }
+ } else if (cns.devicesMultiSwitch.includes(accessory.context.eweUIID)) {
+ if (Array.isArray(newParams.switches)) {
+ this.externalMultiSwitchUpdate(accessory, newParams);
+ }
+ }
+ return true;
+ case "rf_pri":
+ this.externalRFDeviceUpdate(accessory, newParams);
+ return true;
+ case "rf_sub":
+ case "zb_pri":
+ return true;
+ case "zb_sub":
+ this.externalZBDeviceUpdate(accessory, newParams);
+ return true;
+ default:
+ return false;
}
}
removeAccessory(accessory) {
try {
this.devicesInHB.delete(accessory.context.hbDeviceId);
- this.api.unregisterPlatformAccessories(constants.packageName, "eWeLink", [accessory]);
- this.log("[%s] will be removed from Homebridge.", accessory.displayName);
- } catch (e) {
- this.log.warn("[%s] needed to be removed but couldn't - [%s].", accessory.displayName, e);
- }
- }
- removeAllAccessories() {
- try {
- this.log.warn("[0] primary devices were loaded from your eWeLink account so any eWeLink devices in the Homebridge cache will be removed. This plugin will not load as there is no reason to continue.");
- this.api.unregisterPlatformAccessories(constants.packageName, "eWeLink", Array.from(this.devicesInHB.values()));
- this.devicesInHB.clear();
- } catch (e) {
- this.log.warn("Accessories could not be removed from the Homebridge cache - [%s].", e);
+ this.api.unregisterPlatformAccessories(cns.packageName, "eWeLink", [accessory]);
+ this.log("[%s] has been removed from Homebridge.", accessory.displayName);
+ } catch (err) {
+ this.log.warn("[%s] needed to be removed but couldn't - [%s].", accessory.displayName, err);
}
}
sendDeviceUpdate(accessory, params, callback) {
@@ -697,95 +668,70 @@ class eWeLink {
deviceid: accessory.context.eweDeviceId,
params
};
- switch (this.mode) {
- case "lan":
- default:
- this.lanClient.sendUpdate(payload)
- .then(res => {
- callback();
- })
- .catch(err => {
- if (accessory.context.reachableWAN) {
- if (this.debug) {
- this.log.warn("[%s] LAN update failed as %s. Trying web socket update.", accessory.displayName, err);
- }
- this.wsClient.sendUpdate(payload, callback);
- setTimeout(() => {
- this.wsClient.requestUpdate(accessory);
- }, 2500);
- } else {
- this.log.error("[%s] could not be updated as it appears to be offline.", accessory.displayName);
- callback("Device has failed to update");
+ this.lanClient.sendUpdate(payload)
+ .then(res => {
+ callback();
+ })
+ .catch(err => {
+ if (accessory.context.reachableWAN) {
+ if (this.config.debug) {
+ this.log.warn("[%s] Reverting to web socket as %s.", accessory.displayName, err);
}
- });
- break;
- case "ws":
- this.wsClient.sendUpdate(payload, callback);
- setTimeout(() => {
- this.wsClient.requestUpdate(accessory);
- }, 2500);
- break;
- }
+ this.wsClient.sendUpdate(payload, callback);
+ setTimeout(() => {
+ this.wsClient.requestUpdate(accessory);
+ }, 3000);
+ } else {
+ this.log.error("[%s] could not be updated as it appears to be offline.", accessory.displayName);
+ callback("Device has failed to update");
+ }
+ });
}
receiveDeviceUpdate(device) {
- let accessory;
+ let accessory, source = device.params.updateSource === "ws" ? "WS" : "LAN";
switch (device.action) {
- case "sysmsg":
- if (this.devicesInHB.has(device.deviceid + "SWX") || this.devicesInHB.has(device.deviceid + "SW0")) {
- accessory = this.devicesInHB.get(device.deviceid + "SWX") || this.devicesInHB.get(device.deviceid + "SW0");
- try {
- if (accessory.context.reachableWAN !== device.params.online) {
+ case "sysmsg":
+ if ((accessory = this.devicesInHB.get(device.deviceid + "SWX") || this.devicesInHB.get(device.deviceid + "SW0"))) {
+ let isX = accessory.context.hbDeviceId.substr(-1) === "X";
+ if (source === "ws" && accessory.context.reachableWAN !== device.params.online) {
accessory.context.reachableWAN = device.params.online;
this.log("[%s] has been reported [%s].", accessory.displayName, accessory.context.reachableWAN ? "online" : "offline");
this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
- this.api.updatePlatformAccessories(constants.packageName, "eWeLink", [accessory]);
if (accessory.context.reachableWAN) {
this.wsClient.requestUpdate(accessory);
}
}
- } catch (e) {
- this.log.warn("[%s] online/offline status could not be updated - [%s].", accessory.displayName, e);
- }
- if (this.devicesInHB.has(device.deviceid + "SW0")) {
- let oAccessory;
- for (let i = 1; i <= accessory.context.channelCount; i++) {
- try {
+ if (!isX) {
+ for (let i = 1; i <= accessory.context.channelCount; i++) {
if (this.devicesInHB.has(device.deviceid + "SW" + i)) {
- oAccessory = this.devicesInHB.get(device.deviceid + "SW" + i);
+ let oAccessory = this.devicesInHB.get(device.deviceid + "SW" + i);
oAccessory.context.reachableWAN = device.params.online;
this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory);
- this.api.updatePlatformAccessories(constants.packageName, "eWeLink", [oAccessory]);
}
- } catch (e) {
- this.log.warn("[%s] online/offline status could not be updated - [%s].", oAccessory.displayName, e);
}
}
}
- }
- break;
- case "update":
- let source = device.params.updateSource === "ws" ? "WS" : "LAN";
- if (this.devicesInHB.has(device.deviceid + "SWX") || this.devicesInHB.has(device.deviceid + "SW0")) {
- accessory = this.devicesInHB.get(device.deviceid + "SWX") || this.devicesInHB.get(device.deviceid + "SW0");
- if (source === "ws" && !accessory.context.reachableWAN) {
- accessory.context.reachableWAN = true;
- }
- if (source === "lan" && !accessory.context.reachableLAN) {
- accessory.context.reachableLAN = true;
- }
- if (this.debug) {
- this.log("[%s] externally updated from above %s message and will be refreshed.", accessory.displayName, source);
- }
- if (this.refreshAccessory(accessory, device.params)) {
- return;
+ break;
+ case "update":
+ if ((accessory = this.devicesInHB.get(device.deviceid + "SWX") || this.devicesInHB.get(device.deviceid + "SW0"))) {
+ if (source === "ws" && !accessory.context.reachableWAN) {
+ accessory.context.reachableWAN = true;
+ }
+ if (source === "lan" && !accessory.context.reachableLAN) {
+ accessory.context.reachableLAN = true;
+ }
+ if (this.config.debug) {
+ this.log("[%s] externally updated from above %s message and will be refreshed.", accessory.displayName, source);
+ }
+ if (!this.refreshAccessory(accessory, device.params)) {
+ this.log.warn("[%s] cannot be refreshed. Please try removing accessory from the Homebridge cache along with any secondary devices (SW1, SW2, etc.). [debug:%s:%s]", accessory.displayName, accessory.context.type, accessory.context.channelCount);
+ }
+ } else {
+ if (!(this.config.hideDevFromHB || "").includes(device.deviceid)) {
+ this.log.warn("[%s] Accessory received via %s update does not exist in Homebridge. If it's a new accessory please restart Homebridge so it is added.", device.deviceid, source);
+ }
}
- this.log.warn("[%s] cannot be refreshed. Please try removing accessory from the Homebridge cache along with any secondary devices (SW1, SW2, etc.). Debugging: [%s:%s:%s]", accessory.displayName, "refresh", accessory.context.type, accessory.context.channelCount);
- } else if (this.customHideDvceFromHB.includes(device.deviceid)) {
- this.log.warn("[%s] %s update is for hidden accessory.", device.deviceid, source);
- } else {
- this.log.warn("[%s] Accessory received via %s update does not exist in Homebridge. If it's a new accessory please restart Homebridge so it is added.", device.deviceid, source);
- }
- break;
+ break;
}
}
internalValveUpdate(accessory, valve, value, callback) {
@@ -798,30 +744,30 @@ class eWeLink {
.updateCharacteristic(Characteristic.Active, value)
.updateCharacteristic(Characteristic.InUse, value);
switch (value) {
- case 0:
- accessory.getService(valve).updateCharacteristic(Characteristic.RemainingDuration, 0);
- clearTimeout(accessory.getService(valve).timer);
- break;
- case 1:
- let timer = accessory.getService(valve).getCharacteristic(Characteristic.SetDuration).value;
- accessory.getService(valve).updateCharacteristic(Characteristic.RemainingDuration, timer);
- accessory.getService(valve).timer = setTimeout(() => {
- accessory.getService(valve).setCharacteristic(Characteristic.Active, 0);
- }, (timer * 1000));
- break;
+ case 0:
+ accessory.getService(valve).updateCharacteristic(Characteristic.RemainingDuration, 0);
+ clearTimeout(accessory.getService(valve).timer);
+ break;
+ case 1:
+ let timer = accessory.getService(valve).getCharacteristic(Characteristic.SetDuration).value;
+ accessory.getService(valve).updateCharacteristic(Characteristic.RemainingDuration, timer);
+ accessory.getService(valve).timer = setTimeout(() => {
+ accessory.getService(valve).setCharacteristic(Characteristic.Active, 0);
+ }, (timer * 1000));
+ break;
}
params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
switch (valve) {
- case "Valve A":
- params.switches[0].switch = value ? "on" : "off";
- params.switches[1].switch = accessory.getService("Valve B").getCharacteristic(Characteristic.Active).value ? "on" : "off";
- break;
- case "Valve B":
- params.switches[0].switch = accessory.getService("Valve A").getCharacteristic(Characteristic.Active).value ? "on" : "off";
- params.switches[1].switch = value ? "on" : "off";
- break;
- default:
- throw "unknown valve [" + valve + "]";
+ case "Valve A":
+ params.switches[0].switch = value ? "on" : "off";
+ params.switches[1].switch = accessory.getService("Valve B").getCharacteristic(Characteristic.Active).value ? "on" : "off";
+ break;
+ case "Valve B":
+ params.switches[0].switch = accessory.getService("Valve A").getCharacteristic(Characteristic.Active).value ? "on" : "off";
+ params.switches[1].switch = value ? "on" : "off";
+ break;
+ default:
+ throw "unknown valve [" + valve + "]";
}
params.switches[2].switch = "off";
params.switches[3].switch = "off";
@@ -855,16 +801,16 @@ class eWeLink {
return;
}
switch (blindConfig.setup) {
- case "oneSwitch":
- params.switch = "on";
- break;
- case "twoSwitch":
- params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
- params.switches[0].switch = value === 100 ? "on" : "off";
- params.switches[1].switch = value === 0 ? "on" : "off";
- break;
+ case "oneSwitch":
+ params.switch = "on";
+ break;
+ case "twoSwitch":
+ params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
+ params.switches[0].switch = value === 100 ? "on" : "off";
+ params.switches[1].switch = value === 0 ? "on" : "off";
+ break;
}
- this.sendDeviceUpdate(accessory, params, function () {
+ this.sendDeviceUpdate(accessory, params, function() {
return;
});
accessory.getService(Service.WindowCovering)
@@ -873,15 +819,15 @@ class eWeLink {
if (!blindConfig.inched || blindConfig.inched === "false") {
setTimeout(() => {
switch (blindConfig.setup) {
- case "oneSwitch":
- params.switch = "off";
- break;
- case "twoSwitch":
- params.switches[0].switch = "off";
- params.switches[1].switch = "off";
- break;
+ case "oneSwitch":
+ params.switch = "off";
+ break;
+ case "twoSwitch":
+ params.switches[0].switch = "off";
+ params.switches[1].switch = "off";
+ break;
}
- this.sendDeviceUpdate(accessory, params, function () {
+ this.sendDeviceUpdate(accessory, params, function() {
return;
});
}, 500);
@@ -928,16 +874,16 @@ class eWeLink {
return;
}
switch (garageConfig.setup) {
- case "oneSwitch":
- params.switch = "on";
- break;
- case "twoSwitch":
- params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
- params.switches[0].switch = value === 0 ? "on" : "off";
- params.switches[1].switch = value === 1 ? "on" : "off";
- break;
+ case "oneSwitch":
+ params.switch = "on";
+ break;
+ case "twoSwitch":
+ params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
+ params.switches[0].switch = value === 0 ? "on" : "off";
+ params.switches[1].switch = value === 1 ? "on" : "off";
+ break;
}
- this.sendDeviceUpdate(accessory, params, function () {
+ this.sendDeviceUpdate(accessory, params, function() {
return;
});
accessory.getService(Service.GarageDoorOpener)
@@ -946,15 +892,15 @@ class eWeLink {
if (!garageConfig.inched || garageConfig.inched === "false") {
setTimeout(() => {
switch (garageConfig.setup) {
- case "oneSwitch":
- params.switch = "off";
- break;
- case "twoSwitch":
- params.switches[0].switch = "off";
- params.switches[1].switch = "off";
- break;
+ case "oneSwitch":
+ params.switch = "off";
+ break;
+ case "twoSwitch":
+ params.switches[0].switch = "off";
+ params.switches[1].switch = "off";
+ break;
}
- this.sendDeviceUpdate(accessory, params, function () {
+ this.sendDeviceUpdate(accessory, params, function() {
return;
});
}, 500);
@@ -981,21 +927,21 @@ class eWeLink {
}
let newPower, newSpeed, newLight;
switch (type) {
- case "power":
- newPower = value;
- newSpeed = value ? 33 : 0;
- newLight = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value;
- break;
- case "speed":
- newPower = value >= 33 ? 1 : 0;
- newSpeed = value;
- newLight = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value;
- break;
- case "light":
- newPower = accessory.getService(Service.Fanv2).getCharacteristic(Characteristic.Active).value;
- newSpeed = accessory.getService(Service.Fanv2).getCharacteristic(Characteristic.RotationSpeed).value;
- newLight = value;
- break;
+ case "power":
+ newPower = value;
+ newSpeed = value ? 33 : 0;
+ newLight = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value;
+ break;
+ case "speed":
+ newPower = value >= 33 ? 1 : 0;
+ newSpeed = value;
+ newLight = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value;
+ break;
+ case "light":
+ newPower = accessory.getService(Service.Fanv2).getCharacteristic(Characteristic.Active).value;
+ newSpeed = accessory.getService(Service.Fanv2).getCharacteristic(Characteristic.RotationSpeed).value;
+ newLight = value;
+ break;
}
accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, newLight);
accessory.getService(Service.Fanv2)
@@ -1008,7 +954,7 @@ class eWeLink {
params.switches[1].switch = (newPower === 1 && newSpeed >= 33) ? "on" : "off";
params.switches[2].switch = (newPower === 1 && newSpeed >= 66 && newSpeed < 99) ? "on" : "off";
params.switches[3].switch = (newPower === 1 && newSpeed >= 99) ? "on" : "off";
- if (this.debug) {
+ if (this.config.debug) {
this.log.warn("Fan Update - setting " + type + " to " + value);
this.log("[%s] new stats: power [%s], speed [%s%], light [%s].", accessory.displayName, newPower, newSpeed, newLight);
}
@@ -1028,7 +974,7 @@ class eWeLink {
switch: value ? "on" : "off",
mainSwitch: value ? "on" : "off"
};
- if (this.debug) {
+ if (this.config.debug) {
this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
}
accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
@@ -1047,7 +993,7 @@ class eWeLink {
let params = {
switch: value ? "on" : "off"
};
- if (this.debug) {
+ if (this.config.debug) {
this.log("[%s] requesting to turn [%s].", accessory.displayName, value ? "on" : "off");
}
accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, value);
@@ -1065,7 +1011,7 @@ class eWeLink {
switches: this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches
};
params.switches[0].switch = value ? "on" : "off";
- if (this.debug) {
+ if (this.config.debug) {
this.log("[%s] requesting to turn [%s].", accessory.displayName, value ? "on" : "off");
}
accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, value);
@@ -1083,7 +1029,7 @@ class eWeLink {
switches: this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches
};
params.switches[0].switch = value ? "on" : "off";
- if (this.debug) {
+ if (this.config.debug) {
this.log("[%s] requesting to turn [%s].", accessory.displayName, value ? "on" : "off");
}
accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
@@ -1099,62 +1045,62 @@ class eWeLink {
}
let oAccessory, params = {};
switch (accessory.context.switchNumber) {
- case "X":
- if (accessory.context.eweUIID === 22) { //*** B1 ***\\
- params.state = value ? "on" : "off";
- } else {
- params.switch = value ? "on" : "off";
- }
- if (this.debug) {
- this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
- }
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
- break;
- case "0":
- params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
- params.switches[0].switch = value ? "on" : "off";
- params.switches[1].switch = value ? "on" : "off";
- params.switches[2].switch = value ? "on" : "off";
- params.switches[3].switch = value ? "on" : "off";
- if (this.debug) {
- this.log("[%s] updating to turn group [%s].", accessory.displayName, value ? "on" : "off");
- }
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
- for (let i = 1; i <= 4; i++) {
- if (this.devicesInHB.has(accessory.context.eweDeviceId + "SW" + i)) {
- oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i);
- oAccessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
+ case "X":
+ if (accessory.context.eweUIID === 22) { //*** B1 ***\\
+ params.state = value ? "on" : "off";
+ } else {
+ params.switch = value ? "on" : "off";
}
- }
- break;
- case "1":
- case "2":
- case "3":
- case "4":
- if (this.debug) {
- this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
- }
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
- let tAccessory,
- masterState = "off";
- params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
- for (let i = 1; i <= 4; i++) {
- if ((tAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
- i === parseInt(accessory.context.switchNumber) ?
- params.switches[i - 1].switch = value ? "on" : "off" :
- params.switches[i - 1].switch = tAccessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value ? "on" : "off";
- if (tAccessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value) {
- masterState = "on";
+ if (this.config.debug) {
+ this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
+ }
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
+ break;
+ case "0":
+ params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
+ params.switches[0].switch = value ? "on" : "off";
+ params.switches[1].switch = value ? "on" : "off";
+ params.switches[2].switch = value ? "on" : "off";
+ params.switches[3].switch = value ? "on" : "off";
+ if (this.config.debug) {
+ this.log("[%s] updating to turn group [%s].", accessory.displayName, value ? "on" : "off");
+ }
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
+ for (let i = 1; i <= 4; i++) {
+ if (this.devicesInHB.has(accessory.context.eweDeviceId + "SW" + i)) {
+ oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i);
+ oAccessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
}
- } else {
- params.switches[i - 1].switch = "off";
}
- }
- oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
- oAccessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, masterState === "on");
- break;
- default:
- throw "unknown switch number [" + accessory.context.switchNumber + "]";
+ break;
+ case "1":
+ case "2":
+ case "3":
+ case "4":
+ if (this.config.debug) {
+ this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
+ }
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
+ let tAccessory,
+ masterState = "off";
+ params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
+ for (let i = 1; i <= 4; i++) {
+ if ((tAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
+ i === parseInt(accessory.context.switchNumber) ?
+ params.switches[i - 1].switch = value ? "on" : "off" :
+ params.switches[i - 1].switch = tAccessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value ? "on" : "off";
+ if (tAccessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value) {
+ masterState = "on";
+ }
+ } else {
+ params.switches[i - 1].switch = "off";
+ }
+ }
+ oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
+ oAccessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, masterState === "on");
+ break;
+ default:
+ throw "unknown switch number [" + accessory.context.switchNumber + "]";
}
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
@@ -1177,19 +1123,19 @@ class eWeLink {
params.switch = "on";
}
switch (accessory.context.eweUIID) {
- case 36: //*** KING-M4 ***\\
- params.bright = Math.round(value * 9 / 10 + 10);
- break;
- case 44: //*** D1 ***\\
- params.brightness = value;
- params.mode = 0;
- break;
- default:
- throw "unknown device UIID";
+ case 36: //*** KING-M4 ***\\
+ params.bright = Math.round(value * 9 / 10 + 10);
+ break;
+ case 44: //*** D1 ***\\
+ params.brightness = value;
+ params.mode = 0;
+ break;
+ default:
+ throw "unknown device UIID";
}
accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Brightness, value);
}
- if (this.debug) {
+ if (this.config.debug) {
this.log("[%s] updating brightness to [%s%].", accessory.displayName, value);
}
setTimeout(() => {
@@ -1211,64 +1157,64 @@ class eWeLink {
curHue = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Hue).value,
curSat = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Saturation).value;
switch (type) {
- case "hue":
- newRGB = convert.hsv.rgb(value, curSat, 100);
- switch (accessory.context.eweUIID) {
- case 22: //*** B1 ***\\
- params = {
- zyx_mode: 2,
- type: "middle",
- channel0: "0",
- channel1: "0",
- channel2: newRGB[0].toString(),
- channel3: newRGB[1].toString(),
- channel4: newRGB[2].toString()
- };
+ case "hue":
+ newRGB = convert.hsv.rgb(value, curSat, 100);
+ switch (accessory.context.eweUIID) {
+ case 22: //*** B1 ***\\
+ params = {
+ zyx_mode: 2,
+ type: "middle",
+ channel0: "0",
+ channel1: "0",
+ channel2: newRGB[0].toString(),
+ channel3: newRGB[1].toString(),
+ channel4: newRGB[2].toString()
+ };
+ break;
+ case 59: //*** L1 ***\\
+ params = {
+ mode: 1,
+ colorR: newRGB[0],
+ colorG: newRGB[1],
+ colorB: newRGB[2]
+ };
+ break;
+ default:
+ throw "unknown device UIID";
+ }
+ if (this.config.debug) {
+ this.log("[%s] updating hue to [%s°].", accessory.displayName, value);
+ }
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Hue, value);
break;
- case 59: //*** L1 ***\\
- params = {
- mode: 1,
- colorR: newRGB[0],
- colorG: newRGB[1],
- colorB: newRGB[2]
- };
+ case "bri":
+ switch (accessory.context.eweUIID) {
+ case 22: //*** B1 ***\\
+ newRGB = convert.hsv.rgb(curHue, curSat, value);
+ params = {
+ zyx_mode: 2,
+ type: "middle",
+ channel0: "0",
+ channel1: "0",
+ channel2: newRGB[0].toString(),
+ channel3: newRGB[1].toString(),
+ channel4: newRGB[2].toString()
+ };
+ break;
+ case 59: //*** L1 ***\\
+ params = {
+ mode: 1,
+ bright: value
+ };
+ break;
+ }
+ if (this.config.debug) {
+ this.log("[%s] updating brightness to [%s%].", accessory.displayName, value);
+ }
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Brightness, value);
break;
default:
throw "unknown device UIID";
- }
- if (this.debug) {
- this.log("[%s] updating hue to [%s°].", accessory.displayName, value);
- }
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Hue, value);
- break;
- case "bri":
- switch (accessory.context.eweUIID) {
- case 22: //*** B1 ***\\
- newRGB = convert.hsv.rgb(curHue, curSat, value);
- params = {
- zyx_mode: 2,
- type: "middle",
- channel0: "0",
- channel1: "0",
- channel2: newRGB[0].toString(),
- channel3: newRGB[1].toString(),
- channel4: newRGB[2].toString()
- };
- break;
- case 59: //*** L1 ***\\
- params = {
- mode: 1,
- bright: value
- };
- break;
- }
- if (this.debug) {
- this.log("[%s] updating brightness to [%s%].", accessory.displayName, value);
- }
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Brightness, value);
- break;
- default:
- throw "unknown device UIID";
}
setTimeout(() => {
this.sendDeviceUpdate(accessory, params, callback);
@@ -1286,58 +1232,58 @@ class eWeLink {
}
let oAccessory, params = {};
switch (accessory.context.switchNumber) {
- case "X":
- params.switch = value ? "on" : "off";
- if (this.debug) {
- this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
- }
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
- break;
- case "0":
- params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
- params.switches[0].switch = value ? "on" : "off";
- params.switches[1].switch = value ? "on" : "off";
- params.switches[2].switch = value ? "on" : "off";
- params.switches[3].switch = value ? "on" : "off";
- if (this.debug) {
- this.log("[%s] updating to turn group [%s].", accessory.displayName, value ? "on" : "off");
- }
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
- for (let i = 1; i <= 4; i++) {
- if (this.devicesInHB.has(accessory.context.eweDeviceId + "SW" + i)) {
- oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i);
- oAccessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
+ case "X":
+ params.switch = value ? "on" : "off";
+ if (this.config.debug) {
+ this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
}
- }
- break;
- case "1":
- case "2":
- case "3":
- case "4":
- if (this.debug) {
- this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
- }
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
- let tAccessory,
- masterState = "off";
- params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
- for (let i = 1; i <= 4; i++) {
- if ((tAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
- i === parseInt(accessory.context.switchNumber) ?
- params.switches[i - 1].switch = value ? "on" : "off" :
- params.switches[i - 1].switch = tAccessory.getService(Service.Switch).getCharacteristic(Characteristic.On).value ? "on" : "off";
- if (tAccessory.getService(Service.Switch).getCharacteristic(Characteristic.On).value) {
- masterState = "on";
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
+ break;
+ case "0":
+ params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
+ params.switches[0].switch = value ? "on" : "off";
+ params.switches[1].switch = value ? "on" : "off";
+ params.switches[2].switch = value ? "on" : "off";
+ params.switches[3].switch = value ? "on" : "off";
+ if (this.config.debug) {
+ this.log("[%s] updating to turn group [%s].", accessory.displayName, value ? "on" : "off");
+ }
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
+ for (let i = 1; i <= 4; i++) {
+ if (this.devicesInHB.has(accessory.context.eweDeviceId + "SW" + i)) {
+ oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i);
+ oAccessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
}
- } else {
- params.switches[i - 1].switch = "off";
}
- }
- oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
- oAccessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, masterState === "on");
- break;
- default:
- throw "unknown switch number [" + accessory.context.switchNumber + "]";
+ break;
+ case "1":
+ case "2":
+ case "3":
+ case "4":
+ if (this.config.debug) {
+ this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
+ }
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
+ let tAccessory,
+ masterState = "off";
+ params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
+ for (let i = 1; i <= 4; i++) {
+ if ((tAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
+ i === parseInt(accessory.context.switchNumber) ?
+ params.switches[i - 1].switch = value ? "on" : "off" :
+ params.switches[i - 1].switch = tAccessory.getService(Service.Switch).getCharacteristic(Characteristic.On).value ? "on" : "off";
+ if (tAccessory.getService(Service.Switch).getCharacteristic(Characteristic.On).value) {
+ masterState = "on";
+ }
+ } else {
+ params.switches[i - 1].switch = "off";
+ }
+ }
+ oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
+ oAccessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, masterState === "on");
+ break;
+ default:
+ throw "unknown switch number [" + accessory.context.switchNumber + "]";
}
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
@@ -1367,25 +1313,26 @@ class eWeLink {
this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
}
}
- internalRFDeviceUpdate(accessory, value, callback) {
+ internalRFDeviceUpdate(accessory, rfChl, callback) {
try {
if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
throw "it is currently offline";
}
+ rfChl = parseInt(rfChl);
let params = {
cmd: "transmit",
- rfChl: accessory.context.rfChl
+ rfChl
};
- if (this.debug) {
- this.log("[%s] mimicking RF button press.", accessory.displayName);
+ if (this.config.debug) {
+ this.log("[%s %s] mimicking RF button press.", accessory.displayName, accessory.context.rfChls[rfChl]);
}
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, true);
+ accessory.getService(accessory.context.rfChls[rfChl]).updateCharacteristic(Characteristic.On, true);
this.sendDeviceUpdate(accessory, params, callback);
setTimeout(() => {
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, false);
- }, 500);
+ accessory.getService(accessory.context.rfChls[rfChl]).updateCharacteristic(Characteristic.On, false);
+ }, 3000);
} catch (err) {
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str = "[" + accessory.displayName + " " + name + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -1400,20 +1347,20 @@ class eWeLink {
throw "improper configuration";
}
switch (blindConfig.setup) {
- case "oneSwitch":
- if (params.switch === "off") {
- return;
- }
- nSte = accessory.getService(Service.WindowCovering).getCharacteristic(Characteristic.PositionState).value === 0 ? 1 : 0;
- break;
- case "twoSwitch":
- if (params.switches[0].switch === "off" && params.switches[1].switch === "off") {
- return;
- }
- let switchUp = params.switches[0].switch === "on" ? -1 : 0, // matrix of numbers to get
- switchDown = params.switches[1].switch === "on" ? 0 : 2; // ... the correct HomeKit value
- nSte = switchUp + switchDown;
- break;
+ case "oneSwitch":
+ if (params.switch === "off") {
+ return;
+ }
+ nSte = accessory.getService(Service.WindowCovering).getCharacteristic(Characteristic.PositionState).value === 0 ? 1 : 0;
+ break;
+ case "twoSwitch":
+ if (params.switches[0].switch === "off" && params.switches[1].switch === "off") {
+ return;
+ }
+ let switchUp = params.switches[0].switch === "on" ? -1 : 0, // matrix of numbers to get
+ switchDown = params.switches[1].switch === "on" ? 0 : 2; // ... the correct HomeKit value
+ nSte = switchUp + switchDown;
+ break;
}
accessory.getService(Service.WindowCovering)
.updateCharacteristic(Characteristic.PositionState, nSte)
@@ -1437,18 +1384,18 @@ class eWeLink {
throw "improper configuration";
}
switch (garageConfig.setup) {
- case "oneSwitch":
- if (params.switch === "off" || garageConfig.sensorId) {
- return;
- }
- nSte = [0, 2].includes(accessory.getService(Service.GarageDoorOpener).getCharacteristic(Characteristic.CurrentDoorState).value) ? 3 : 2;
- break;
- case "twoSwitch":
- if (params.switches[0].switch === "off" && params.switches[1].switch === "off") {
+ case "oneSwitch":
+ if (params.switch === "off" || garageConfig.sensorId) {
+ return;
+ }
+ nSte = [0, 2].includes(accessory.getService(Service.GarageDoorOpener).getCharacteristic(Characteristic.CurrentDoorState).value) ? 3 : 2;
+ break;
+ case "twoSwitch":
+ if (params.switches[0].switch === "off" && params.switches[1].switch === "off") {
+ return;
+ }
+ // @TODO twoSwitch garage external update
return;
- }
- // @TODO twoSwitch garage external update
- return;
}
if (garageConfig.setup !== "oneSwitch" || !garageConfig.sensorId) {
accessory.getService(Service.GarageDoorOpener)
@@ -1474,22 +1421,22 @@ class eWeLink {
if (group.sensorId === accessory.context.eweDeviceId && group.type === "garage") {
if ((oAccessory = this.devicesInHB.get(group.deviceId + "SWX"))) {
switch (newState) {
- case 0:
- oAccessory.getService(Service.GarageDoorOpener)
- .updateCharacteristic(Characteristic.TargetDoorState, 1)
- .updateCharacteristic(Characteristic.CurrentDoorState, 1);
- this.log("[%s] updating to [closed] based on sensor.", oAccessory.displayName);
- break;
- case 1:
- setTimeout(() => {
+ case 0:
oAccessory.getService(Service.GarageDoorOpener)
- .updateCharacteristic(Characteristic.TargetDoorState, 0)
- .updateCharacteristic(Characteristic.CurrentDoorState, 0);
- this.log("[%s] updating to [open] based on sensor.", oAccessory.displayName);
- }, group.operationTime * 100);
- break;
- default:
- throw "unknown sensor status received";
+ .updateCharacteristic(Characteristic.TargetDoorState, 1)
+ .updateCharacteristic(Characteristic.CurrentDoorState, 1);
+ this.log("[%s] updating to [closed] based on sensor.", oAccessory.displayName);
+ break;
+ case 1:
+ setTimeout(() => {
+ oAccessory.getService(Service.GarageDoorOpener)
+ .updateCharacteristic(Characteristic.TargetDoorState, 0)
+ .updateCharacteristic(Characteristic.CurrentDoorState, 0);
+ this.log("[%s] updating to [open] based on sensor.", oAccessory.displayName);
+ }, group.operationTime * 100);
+ break;
+ default:
+ throw "unknown sensor status received";
}
}
}
@@ -1504,21 +1451,21 @@ class eWeLink {
if (Array.isArray(params.switches)) {
light = params.switches[0].switch === "on";
switch (params.switches[1].switch+params.switches[2].switch+params.switches[3].switch) {
- default:
- status = 0;
- speed = 0;
- break;
- case "onoffoff":
- status = 1;
- speed = 33;
- break;
- case "ononoff":
- status = 1;
- speed = 66;
- break;
- case "onoffon":
- status = 1;
- speed = 99;
+ default:
+ status = 0;
+ speed = 0;
+ break;
+ case "onoffoff":
+ status = 1;
+ speed = 33;
+ break;
+ case "ononoff":
+ status = 1;
+ speed = 66;
+ break;
+ case "onoffon":
+ status = 1;
+ speed = 99;
}
} else if (params.hasOwnProperty("light") && params.hasOwnProperty("fan") && params.hasOwnProperty("speed")) {
light = params.light === "on";
@@ -1587,49 +1534,49 @@ class eWeLink {
if (isOn) {
accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, true);
switch (accessory.context.eweUIID) {
- case 36: // KING-M4
- if (params.hasOwnProperty("bright")) {
- let nb = Math.round((params.bright - 10) * 10 / 9); // eWeLink scale is 10-100 and HomeKit scale is 0-100.
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Brightness, nb);
- }
- break;
- case 44: // D1
- if (params.hasOwnProperty("brightness")) {
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Brightness, params.brightness);
- }
- break;
- case 22: // B1
- if (params.hasOwnProperty("zyx_mode")) {
- mode = parseInt(params.zyx_mode);
- } else if (params.hasOwnProperty("channel0") && (parseInt(params.channel0) + parseInt(params.channel1) > 0)) {
- mode = 1;
- } else {
- mode = 2;
- }
- if (mode === 2) {
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, true);
- newColour = convert.rgb.hsv(parseInt(params.channel2), parseInt(params.channel3), parseInt(params.channel4));
- accessory.getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.Hue, newColour[0])
- .updateCharacteristic(Characteristic.Saturation, 100)
- .updateCharacteristic(Characteristic.Brightness, 100);
- } else if (mode === 1) {
- throw "has been set to white mode which is not supported";
- }
- break;
- case 59: // L1
- if (params.hasOwnProperty("bright")) {
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Brightness, params.bright);
- }
- if (params.hasOwnProperty("colorR")) {
- newColour = convert.rgb.hsv(params.colorR, params.colorG, params.colorB);
- accessory.getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.Hue, newColour[0])
- .updateCharacteristic(Characteristic.Saturation, newColour[1]);
- }
- break;
- default:
- return;
+ case 36: // KING-M4
+ if (params.hasOwnProperty("bright")) {
+ let nb = Math.round((params.bright - 10) * 10 / 9); // eWeLink scale is 10-100 and HomeKit scale is 0-100.
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Brightness, nb);
+ }
+ break;
+ case 44: // D1
+ if (params.hasOwnProperty("brightness")) {
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Brightness, params.brightness);
+ }
+ break;
+ case 22: // B1
+ if (params.hasOwnProperty("zyx_mode")) {
+ mode = parseInt(params.zyx_mode);
+ } else if (params.hasOwnProperty("channel0") && (parseInt(params.channel0) + parseInt(params.channel1) > 0)) {
+ mode = 1;
+ } else {
+ mode = 2;
+ }
+ if (mode === 2) {
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, true);
+ newColour = convert.rgb.hsv(parseInt(params.channel2), parseInt(params.channel3), parseInt(params.channel4));
+ accessory.getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.Hue, newColour[0])
+ .updateCharacteristic(Characteristic.Saturation, 100)
+ .updateCharacteristic(Characteristic.Brightness, 100);
+ } else if (mode === 1) {
+ throw "has been set to white mode which is not supported";
+ }
+ break;
+ case 59: // L1
+ if (params.hasOwnProperty("bright")) {
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Brightness, params.bright);
+ }
+ if (params.hasOwnProperty("colorR")) {
+ newColour = convert.rgb.hsv(params.colorR, params.colorG, params.colorB);
+ accessory.getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.Hue, newColour[0])
+ .updateCharacteristic(Characteristic.Saturation, newColour[1]);
+ }
+ break;
+ default:
+ return;
}
} else {
accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, false);
@@ -1683,95 +1630,86 @@ class eWeLink {
}
externalRFDeviceUpdate(accessory, params) {
try {
+ if (params.updateSource === "http") {
+ return;
+ }
let idToCheck = accessory.context.hbDeviceId.slice(0, -1),
timeNow = new Date();
if (params.hasOwnProperty("cmd") && params.cmd === "transmit" && params.hasOwnProperty("rfChl")) { // RF Button
let bAccessory;
- if ((bAccessory = this.devicesInHB.get(idToCheck + (params.rfChl + 1)))) {
- bAccessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, 1);
+ if ((bAccessory = this.devicesInHB.get(idToCheck + accessory.context.rfChlMap[params.rfChl]))) {
+ bAccessory.getService(bAccessory.context.rfChls[params.rfChl]).updateCharacteristic(Characteristic.On, 1);
setTimeout(() => {
- bAccessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, 0);
- }, 500);
+ bAccessory.getService(bAccessory.context.rfChls[params.rfChl]).updateCharacteristic(Characteristic.On, 0);
+ }, 3000);
} else {
throw "rf button not found in Homebridge";
}
- return;
- } // else RF Sensor
- for (let i = 1; i <= accessory.context.channelCount; i++) {
- if (this.devicesInHB.has(idToCheck + i)) {
- let oAccessory = this.devicesInHB.get(idToCheck + i);
- if (params.hasOwnProperty("rfTrig" + (i - 1))) {
- let timeOfMotion = new Date(params["rfTrig" + (i - 1)]),
+ } else if (params.hasOwnProperty("cmd") && params.cmd === "trigger") { // RF Sensor
+ let rfChan = Object.keys(params).filter(name => /rfTrig/.test(name));
+ rfChan.forEach(chan => {
+ let chanNum = chan.substr(-1).toString(),
+ accessoryNum = accessory.context.rfChlMap[chanNum],
+ oAccessory;
+ if ((oAccessory = this.devicesInHB.get(idToCheck + accessoryNum))) {
+ let timeOfMotion = new Date(params[chan]),
timeDifference = (timeNow.getTime() - timeOfMotion.getTime()) / 1000;
- if (timeDifference < this.sensorTimeDifference) {
+ if (timeDifference < (this.config.sensorTimeDifference || 120)) {
switch (oAccessory.context.sensorType) {
- case "button":
- break;
- case "water":
- oAccessory.getService(Service.LeakSensor).updateCharacteristic(Characteristic.LeakDetected, 1);
- break;
- case "fire":
- case "smoke":
- oAccessory.getService(Service.SmokeSensor).updateCharacteristic(Characteristic.SmokeDetected, 1);
- break;
- case "co":
- oAccessory.getService(Service.CarbonMonoxideSensor).updateCharacteristic(Characteristic.CarbonMonoxideDetected, 1);
- break;
- case "co2":
- oAccessory.getService(Service.CarbonDioxideSensor).updateCharacteristic(Characteristic.CarbonDioxideDetected, 1);
- break;
- case "contact":
- oAccessory.getService(Service.ContactSensor).updateCharacteristic(Characteristic.ContactSensorState, 1);
- break;
- case "occupancy":
- oAccessory.getService(Service.OccupancySensor).updateCharacteristic(Characteristic.OccupancyDetected, 1);
- break;
- case "motion":
- default:
- oAccessory.getService(Service.MotionSensor).updateCharacteristic(Characteristic.MotionDetected, true);
- break;
+ case "button":
+ break;
+ case "water":
+ oAccessory.getService(Service.LeakSensor).updateCharacteristic(Characteristic.LeakDetected, 1);
+ setTimeout(() => {
+ oAccessory.getService(Service.LeakSensor).updateCharacteristic(Characteristic.LeakDetected, 0);
+ }, (this.config.sensorTimeLength || 2) * 1000);
+ break;
+ case "fire":
+ case "smoke":
+ oAccessory.getService(Service.SmokeSensor).updateCharacteristic(Characteristic.SmokeDetected, 1);
+ setTimeout(() => {
+ oAccessory.getService(Service.SmokeSensor).updateCharacteristic(Characteristic.SmokeDetected, 0);
+ }, (this.config.sensorTimeLength || 2) * 1000);
+ break;
+ case "co":
+ oAccessory.getService(Service.CarbonMonoxideSensor).updateCharacteristic(Characteristic.CarbonMonoxideDetected, 1);
+ setTimeout(() => {
+ oAccessory.getService(Service.CarbonMonoxideSensor).updateCharacteristic(Characteristic.CarbonMonoxideDetected, 0);
+ }, (this.config.sensorTimeLength || 2) * 1000);
+ break;
+ case "co2":
+ oAccessory.getService(Service.CarbonDioxideSensor).updateCharacteristic(Characteristic.CarbonDioxideDetected, 1);
+ setTimeout(() => {
+ oAccessory.getService(Service.CarbonDioxideSensor).updateCharacteristic(Characteristic.CarbonDioxideDetected, 0);
+ }, (this.config.sensorTimeLength || 2) * 1000);
+ break;
+ case "contact":
+ oAccessory.getService(Service.ContactSensor).updateCharacteristic(Characteristic.ContactSensorState, 1);
+ setTimeout(() => {
+ oAccessory.getService(Service.ContactSensor).updateCharacteristic(Characteristic.ContactSensorState, 0);
+ }, (this.config.sensorTimeLength || 2) * 1000);
+ break;
+ case "occupancy":
+ oAccessory.getService(Service.OccupancySensor).updateCharacteristic(Characteristic.OccupancyDetected, 1);
+ setTimeout(() => {
+ oAccessory.getService(Service.OccupancySensor).updateCharacteristic(Characteristic.OccupancyDetected, 0);
+ }, (this.config.sensorTimeLength || 2) * 1000);
+ break;
+ case "motion":
+ default:
+ oAccessory.getService(Service.MotionSensor).updateCharacteristic(Characteristic.MotionDetected, true);
+ setTimeout(() => {
+ oAccessory.getService(Service.MotionSensor).updateCharacteristic(Characteristic.MotionDetected, false);
+ }, (this.config.sensorTimeLength || 2) * 1000);
+ break;
}
- if (this.debug) {
+ if (this.config.debug) {
this.log("[%s] has detected [%s].", oAccessory.displayName, oAccessory.context.sensorType);
}
}
}
- }
+ });
}
- setTimeout(() => {
- for (let i = 1; i <= accessory.context.channelCount; i++) {
- if (this.devicesInHB.has(idToCheck + i)) {
- let oAccessory = this.devicesInHB.get(idToCheck + i);
- switch (oAccessory.context.sensorType) {
- case "button":
- break;
- case "water":
- oAccessory.getService(Service.LeakSensor).updateCharacteristic(Characteristic.LeakDetected, 0);
- break;
- case "fire":
- case "smoke":
- oAccessory.getService(Service.SmokeSensor).updateCharacteristic(Characteristic.SmokeDetected, 0);
- break;
- case "co":
- oAccessory.getService(Service.CarbonMonoxideSensor).updateCharacteristic(Characteristic.CarbonMonoxideDetected, 0);
- break;
- case "co2":
- oAccessory.getService(Service.CarbonDioxideSensor).updateCharacteristic(Characteristic.CarbonDioxideDetected, 0);
- break;
- case "contact":
- oAccessory.getService(Service.ContactSensor).updateCharacteristic(Characteristic.ContactSensorState, 0);
- break;
- case "occupancy":
- oAccessory.getService(Service.OccupancySensor).updateCharacteristic(Characteristic.OccupancyDetected, 0);
- break;
- case "motion":
- default:
- oAccessory.getService(Service.MotionSensor).updateCharacteristic(Characteristic.MotionDetected, false);
- break;
- }
- }
- }
- }, this.sensorTimeLength * 1000);
} catch (err) {
this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
}
@@ -1779,52 +1717,52 @@ class eWeLink {
externalZBDeviceUpdate(accessory, params) {
try {
switch (accessory.context.eweUIID) {
- case 1000:
- if (params.hasOwnProperty("key")) {
- if ([0, 1, 2].includes(params.key)) {
- accessory.getService(Service.StatelessProgrammableSwitch).updateCharacteristic(Characteristic.ProgrammableSwitchEvent, params.key); //*** credit @tasict ***\\
- } else {
- throw "unknown 'key' parameter received [" + params.key + "]";
+ case 1000:
+ if (params.hasOwnProperty("key")) {
+ if ([0, 1, 2].includes(params.key)) {
+ accessory.getService(Service.StatelessProgrammableSwitch).updateCharacteristic(Characteristic.ProgrammableSwitchEvent, params.key); //*** credit @tasict ***\\
+ } else {
+ throw "unknown 'key' parameter received [" + params.key + "]";
+ }
}
- }
- break;
- case 1770:
- if (params.hasOwnProperty("temperature")) {
- let currentTemp = parseInt(params.temperature) / 100;
- accessory.getService(Service.TemperatureSensor).updateCharacteristic(Characteristic.CurrentTemperature, currentTemp);
- }
- if (params.hasOwnProperty("humidity")) {
- let currentHumi = parseInt(params.humidity) / 100;
- accessory.getService(Service.HumiditySensor).updateCharacteristic(Characteristic.CurrentRelativeHumidity, currentHumi);
- }
- break;
- case 2026:
- if (params.hasOwnProperty("motion")) {
- if ([0, 1].includes(params.lock)) {
- accessory.getService(Service.MotionSensor).updateCharacteristic(Characteristic.MotionDetected, params.motion);
- } else {
- throw "unknown 'motion' parameter received [" + params.motion + "]";
+ break;
+ case 1770:
+ if (params.hasOwnProperty("temperature")) {
+ let currentTemp = parseInt(params.temperature) / 100;
+ accessory.getService(Service.TemperatureSensor).updateCharacteristic(Characteristic.CurrentTemperature, currentTemp);
}
- }
- break;
- case 3026:
- if (params.hasOwnProperty("lock")) {
- if ([0, 1].includes(params.lock)) {
- accessory.getService(Service.ContactSensor).updateCharacteristic(Characteristic.ContactSensorState, params.lock);
- } else {
- throw "unknown 'lock' parameter received [" + params.lock + "]";
+ if (params.hasOwnProperty("humidity")) {
+ let currentHumi = parseInt(params.humidity) / 100;
+ accessory.getService(Service.HumiditySensor).updateCharacteristic(Characteristic.CurrentRelativeHumidity, currentHumi);
}
- }
- break;
- default:
- throw "unsupported zigbee device type";
+ break;
+ case 2026:
+ if (params.hasOwnProperty("motion")) {
+ if ([0, 1].includes(params.lock)) {
+ accessory.getService(Service.MotionSensor).updateCharacteristic(Characteristic.MotionDetected, params.motion);
+ } else {
+ throw "unknown 'motion' parameter received [" + params.motion + "]";
+ }
+ }
+ break;
+ case 3026:
+ if (params.hasOwnProperty("lock")) {
+ if ([0, 1].includes(params.lock)) {
+ accessory.getService(Service.ContactSensor).updateCharacteristic(Characteristic.ContactSensorState, params.lock);
+ } else {
+ throw "unknown 'lock' parameter received [" + params.lock + "]";
+ }
+ }
+ break;
+ default:
+ throw "unsupported zigbee device type";
}
} catch (err) {
this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
}
}
}
-module.exports = function (homebridge) {
+module.exports = function(homebridge) {
Accessory = homebridge.platformAccessory;
Service = homebridge.hap.Service;
Characteristic = homebridge.hap.Characteristic;
diff --git a/lib/eWeLinkHTTP.js b/lib/eWeLinkHTTP.js
index f6c0c71d..f7701ed7 100644
--- a/lib/eWeLinkHTTP.js
+++ b/lib/eWeLinkHTTP.js
@@ -41,16 +41,16 @@ module.exports = class eWeLinkHTTP {
let body = res.data;
if (body.hasOwnProperty("error") && body.error === 10004 && body.hasOwnProperty("data") && body.data.hasOwnProperty("region")) {
switch (body.data.region) {
- case "eu":
- case "us":
- case "as":
- this.httpHost = body.data.region + "-apia.coolkit.cc";
- break;
- case "cn":
- this.httpHost = "cn-apia.coolkit.cn";
- break;
- default:
- throw "No valid region received - [" + body.data.region + "].";
+ case "eu":
+ case "us":
+ case "as":
+ this.httpHost = body.data.region + "-apia.coolkit.cc";
+ break;
+ case "cn":
+ this.httpHost = "cn-apia.coolkit.cn";
+ break;
+ default:
+ throw "No valid region received - [" + body.data.region + "].";
}
if (this.debug) {
this.log("New HTTP API host received [%s].", this.httpHost);
@@ -82,16 +82,16 @@ module.exports = class eWeLinkHTTP {
version: 8
},
dataToSign = [];
- Object.keys(data).forEach(function (key) {
+ Object.keys(data).forEach(function(key) {
dataToSign.push({
key: key,
value: data[key]
});
});
- dataToSign.sort(function (a, b) {
+ dataToSign.sort(function(a, b) {
return a.key < b.key ? -1 : 1;
});
- dataToSign = dataToSign.map(function (kv) {
+ dataToSign = dataToSign.map(function(kv) {
return kv.key + "=" + kv.value;
}).join("&");
dataToSign = crypto.createHmac("sha256", "6Nz4n0xA8s8qdxQf2GqurZj2Fs55FUvM").update(dataToSign).digest("base64");
@@ -108,16 +108,16 @@ module.exports = class eWeLinkHTTP {
throw "Server did not respond with a region.\n" + JSON.stringify(body, null, 2);
}
switch (body.region) {
- case "eu":
- case "us":
- case "as":
- this.httpHost = body.region + "-apia.coolkit.cc";
- break;
- case "cn":
- this.httpHost = "cn-apia.coolkit.cn";
- break;
- default:
- throw "No valid region received - [" + body.region + "].";
+ case "eu":
+ case "us":
+ case "as":
+ this.httpHost = body.region + "-apia.coolkit.cc";
+ break;
+ case "cn":
+ this.httpHost = "cn-apia.coolkit.cn";
+ break;
+ default:
+ throw "No valid region received - [" + body.region + "].";
}
if (this.debug) {
this.log("HTTP API host received [%s].", this.httpHost);
diff --git a/lib/eWeLinkLAN.js b/lib/eWeLinkLAN.js
index 9146dbe7..1032afa0 100644
--- a/lib/eWeLinkLAN.js
+++ b/lib/eWeLinkLAN.js
@@ -10,12 +10,13 @@ module.exports = class eWeLinkLAN {
this.config = config;
this.log = log;
this.devices = devices;
- let deviceMap = {};
+ let deviceMap = new Map();
devices.forEach(device => {
- deviceMap[device.deviceid] = {
+ deviceMap.set(device.deviceid, {
apiKey: device.devicekey,
- ip: false
- };
+ online: false,
+ ip: null
+ });
});
this.deviceMap = deviceMap;
this.debug = this.config.debug || false;
@@ -27,13 +28,22 @@ module.exports = class eWeLinkLAN {
dns.discover({
name: "_ewelink._tcp.local"
}).then(res => {
+ let onlineCount = 0;
res.forEach(device => {
- let a = device.fqdn.replace("._ewelink._tcp.local", "").replace("eWeLink_", "");
- if (this.deviceMap.hasOwnProperty(a)) {
- this.deviceMap[a].ip = device.address;
+ let d, deviceId = device.fqdn.replace("._ewelink._tcp.local", "").replace("eWeLink_", "");
+ if ((d = this.deviceMap.get(deviceId))) {
+ this.deviceMap.set(deviceId, {
+ apiKey: d.apiKey,
+ online: true,
+ ip: device.address
+ });
+ onlineCount++;
}
});
- resolve(this.deviceMap);
+ resolve({
+ map: this.deviceMap,
+ count: onlineCount
+ });
}).catch(err => {
reject(err);
});
@@ -100,7 +110,7 @@ module.exports = class eWeLinkLAN {
}
sendUpdate(json) {
return new Promise((resolve, reject) => {
- if (!this.deviceMap[json.deviceid].ip) {
+ if (!this.deviceMap.get(json.deviceid).online) {
throw "device does not support LAN mode";
}
let apiKey, suffix, params = {};
@@ -113,7 +123,7 @@ module.exports = class eWeLinkLAN {
} else {
throw "plugin does not support lan mode for this device yet - feel free to create a github issue";
}
- if ((apiKey = this.deviceMap[json.deviceid].apiKey)) {
+ if ((apiKey = this.deviceMap.get(json.deviceid).apiKey)) {
let key = crypto.createHash('md5').update(Buffer.from(apiKey, 'utf8')).digest(),
iv = crypto.randomBytes(16),
enc = crypto.createCipheriv('aes-128-cbc', key, iv),
@@ -133,18 +143,17 @@ module.exports = class eWeLinkLAN {
}
axios({
method: "post",
- url: "http://" + this.deviceMap[json.deviceid].ip + ":8081/zeroconf/" + suffix,
+ url: "http://" + this.deviceMap.get(json.deviceid).ip + ":8081/zeroconf/" + suffix,
headers: {
Accept: "application/json",
- "Content-Type": "application/json;charset=UTF-8"
+ "Content-Type": "application/json"
},
data
}).then(res => {
- let body = res.data;
- if (body.hasOwnProperty("error") && body.error === 0) {
+ if (res.data.hasOwnProperty("error") && res.data.error === 0) {
resolve();
}
- throw body;
+ throw res.data;
}).catch(err => {
reject(err);
});
@@ -154,4 +163,8 @@ module.exports = class eWeLinkLAN {
receiveUpdate(f) {
this.emitter.addListener("update", f);
}
+ closeConnection() {
+ dns.stopMonitoring();
+ this.log("LAN monitoring stopped as part of Homebridge shutdown.");
+ }
};
\ No newline at end of file
diff --git a/lib/eWeLinkWS.js b/lib/eWeLinkWS.js
index 23f690d7..95aea46d 100644
--- a/lib/eWeLinkWS.js
+++ b/lib/eWeLinkWS.js
@@ -97,36 +97,12 @@ module.exports = class eWeLinkWS {
}, (device.config.hbInterval + 7) * 1000);
} else if (device.hasOwnProperty("action")) {
switch (device.action) {
- case "sysmsg":
- device.params.updateSource = "ws";
- let returnTemplate = {
- deviceid: device.deviceid,
- action: "sysmsg",
- params: device.params
- };
- if (this.debugReqRes) {
- let msg = JSON.stringify(returnTemplate, null, 2).replace(device.deviceid, "**hidden**");
- this.log("WS message received.\n%s", msg);
- } else if (this.debug) {
- this.log("WS message received.");
- }
- this.emitter.emit("update", returnTemplate);
- break;
- case "update":
- let params = device.params;
- for (let param in params) {
- if (params.hasOwnProperty(param)) {
- if (!constants.paramsToKeep.includes(param.replace(/[0-9]/g, ""))) {
- delete params[param];
- }
- }
- }
- if (Object.keys(params).length > 0) {
- params.updateSource = "ws";
+ case "sysmsg":
+ device.params.updateSource = "ws";
let returnTemplate = {
deviceid: device.deviceid,
- action: "update",
- params
+ action: "sysmsg",
+ params: device.params
};
if (this.debugReqRes) {
let msg = JSON.stringify(returnTemplate, null, 2).replace(device.deviceid, "**hidden**");
@@ -135,11 +111,35 @@ module.exports = class eWeLinkWS {
this.log("WS message received.");
}
this.emitter.emit("update", returnTemplate);
- }
- break;
- default:
- this.log.warn("[%s] WS message has unknown action.\n" + JSON.stringify(device, null, 2), device.deviceid);
- return;
+ break;
+ case "update":
+ let params = device.params;
+ for (let param in params) {
+ if (params.hasOwnProperty(param)) {
+ if (!constants.paramsToKeep.includes(param.replace(/[0-9]/g, ""))) {
+ delete params[param];
+ }
+ }
+ }
+ if (Object.keys(params).length > 0) {
+ params.updateSource = "ws";
+ let returnTemplate = {
+ deviceid: device.deviceid,
+ action: "update",
+ params
+ };
+ if (this.debugReqRes) {
+ let msg = JSON.stringify(returnTemplate, null, 2).replace(device.deviceid, "**hidden**");
+ this.log("WS message received.\n%s", msg);
+ } else if (this.debug) {
+ this.log("WS message received.");
+ }
+ this.emitter.emit("update", returnTemplate);
+ }
+ break;
+ default:
+ this.log.warn("[%s] WS message has unknown action.\n" + JSON.stringify(device, null, 2), device.deviceid);
+ return;
}
} else if (device.hasOwnProperty("error") && device.error === 0) {
// *** Safe to ignore these messages *** \\
@@ -149,22 +149,26 @@ module.exports = class eWeLinkWS {
}
}
});
- this.ws.on("close", (e) => {
- this.log.warn("Web socket closed - [%s].", e);
- if (e.code !== 1000) {
- this.log.warn("Web socket will try to reconnect in five seconds then try the command again.");
- this.ws.removeAllListeners();
- setTimeout(() => {
- this.login();
- }, 5000);
+ this.ws.on("close", (e, m) => {
+ if (m === "Stopping Homebridge") {
+ this.log("Web socket closed as part of Homebridge shutdown.");
} else {
- this.log.error("Please try restarting Homebridge so that this plugin can work again.");
+ this.log.warn("Web socket closed - [%s - %s].", e, m);
+ if (e !== 1000) {
+ this.log("Web socket will try to reconnect in five seconds.");
+ setTimeout(() => {
+ this.login();
+ }, 5000);
+ } else {
+ this.log("Please try restarting Homebridge so that this plugin can work again.");
+ }
}
this.wsIsOpen = false;
if (this.hbInterval) {
clearInterval(this.hbInterval);
this.hbInterval = null;
}
+ this.ws.removeAllListeners();
});
this.ws.on("error", (e) => {
this.log.error("Web socket error - [%s].", e);
@@ -268,4 +272,7 @@ module.exports = class eWeLinkWS {
receiveUpdate(f) {
this.emitter.addListener("update", f);
}
+ closeConnection() {
+ this.ws.close(1000, "Stopping Homebridge");
+ }
};
\ No newline at end of file
From 65fc7549cc9aa1150e937b3cf4d59cd36a4cfe37 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Thu, 20 Aug 2020 17:08:50 +0100
Subject: [PATCH 0036/3183] 2.23.0-0
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 0077fce1..8254df29 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.19.3",
+ "version": "2.23.0-0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 83a1c664..eb102db4 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.19.3",
+ "version": "2.23.0-0",
"author": "bwp91",
"contributors": [
"gbro115",
From acfa27e6c86b7d4666d06b6b382b2f38a1dba9c5 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Thu, 20 Aug 2020 20:39:32 +0100
Subject: [PATCH 0037/3183] 2.23.0
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 8254df29..9f311274 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.23.0-0",
+ "version": "2.23.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index eb102db4..1f11ab88 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.23.0-0",
+ "version": "2.23.0",
"author": "bwp91",
"contributors": [
"gbro115",
From db010c5d0b872afdef3d7b7c729028954ce3777d Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Thu, 20 Aug 2020 23:04:59 +0100
Subject: [PATCH 0038/3183] Delete _config.yml
---
_config.yml | 1 -
1 file changed, 1 deletion(-)
delete mode 100644 _config.yml
diff --git a/_config.yml b/_config.yml
deleted file mode 100644
index c7418817..00000000
--- a/_config.yml
+++ /dev/null
@@ -1 +0,0 @@
-theme: jekyll-theme-slate
\ No newline at end of file
From 5edc9ef42a58d4d46530deba8af0bb71c1d6bb39 Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Thu, 20 Aug 2020 23:08:52 +0100
Subject: [PATCH 0039/3183] Update README.md
---
README.md | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 633cb902..f2df355c 100644
--- a/README.md
+++ b/README.md
@@ -8,8 +8,9 @@
[![verified-by-homebridge](https://badgen.net/badge/homebridge/verified/purple)](https://github.com/homebridge/homebridge/wiki/Verified-Plugins)
[![Discord](https://img.shields.io/discord/432663330281226270?color=728ED5&logo=discord&label=discord)](https://discord.com/channels/432663330281226270/742733745743855627)
[![npm](https://img.shields.io/npm/dt/homebridge-ewelink)](https://www.npmjs.com/package/homebridge-ewelink)
- [![npm](https://img.shields.io/npm/v/homebridge-ewelink?label=release)](https://www.npmjs.com/package/homebridge-ewelink)
- [![npm](https://img.shields.io/npm/v/homebridge-ewelink-beta?label=beta)](https://www.npmjs.com/package/homebridge-ewelink-beta)
+ [![npm](https://img.shields.io/npm/v/homebridge-ewelink/release?label=release)](https://www.npmjs.com/package/homebridge-ewelink)
+ [![npm](https://img.shields.io/npm/v/homebridge-ewelink/beta?label=beta)](https://www.npmjs.com/package/homebridge-ewelink)
+
From f0d386db08af9d56ef380793213e4c2cce86f9db Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Thu, 20 Aug 2020 23:09:12 +0100
Subject: [PATCH 0040/3183] Update README.md
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index f2df355c..bbcd2fef 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,7 @@
[![verified-by-homebridge](https://badgen.net/badge/homebridge/verified/purple)](https://github.com/homebridge/homebridge/wiki/Verified-Plugins)
[![Discord](https://img.shields.io/discord/432663330281226270?color=728ED5&logo=discord&label=discord)](https://discord.com/channels/432663330281226270/742733745743855627)
[![npm](https://img.shields.io/npm/dt/homebridge-ewelink)](https://www.npmjs.com/package/homebridge-ewelink)
- [![npm](https://img.shields.io/npm/v/homebridge-ewelink/release?label=release)](https://www.npmjs.com/package/homebridge-ewelink)
+ [![npm](https://img.shields.io/npm/v/homebridge-ewelink/latest?label=release)](https://www.npmjs.com/package/homebridge-ewelink)
[![npm](https://img.shields.io/npm/v/homebridge-ewelink/beta?label=beta)](https://www.npmjs.com/package/homebridge-ewelink)
From f6b0531a6d7a85c647ad640ed2d0d29890b3edc1 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Fri, 21 Aug 2020 08:52:03 +0100
Subject: [PATCH 0041/3183] default ws for unsupported lan
---
lib/constants.js | 1 +
lib/eWeLink.js | 43 +++++++++++++++++++++++--------------------
2 files changed, 24 insertions(+), 20 deletions(-)
diff --git a/lib/constants.js b/lib/constants.js
index 3c557fca..077cc40f 100644
--- a/lib/constants.js
+++ b/lib/constants.js
@@ -4,6 +4,7 @@ module.exports = {
appId: "oeVkj2lYFGnJu5XUtWisfW4utiN4u9Mq",
packageName: "homebridge-ewelink",
devicesHideable: ["switch", "light", "valve"],
+ devicesNonLAN: [22, 59, 102],
devicesSingleSwitch: [1, 5, 6, 14, 15, 22, 24, 27, 32, 36, 44, 59],
devicesSingleSwitchLight: ["T1 1C", "L1", "B1", "B1_R2", "TX1C", "D1", "D1R1", "KING-M4", "Slampher"],
devicesMultiSwitch: [2, 3, 4, 7, 8, 9, 29, 30, 31, 34, 41],
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 89352a12..c5f9bb29 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -307,7 +307,6 @@ class eWeLink {
case "6":
accessory.context.sensorType = this.cusS.has(hbDeviceId) ? this.cusS.get(hbDeviceId).type : "motion";
break;
- case "5":
default:
throw "RF device type is not supported";
}
@@ -343,7 +342,6 @@ class eWeLink {
case "occupancy":
accessory.addService(Service.OccupancySensor);
break;
- case "motion":
default:
accessory.addService(Service.MotionSensor);
break;
@@ -668,24 +666,30 @@ class eWeLink {
deviceid: accessory.context.eweDeviceId,
params
};
- this.lanClient.sendUpdate(payload)
- .then(res => {
- callback();
- })
- .catch(err => {
- if (accessory.context.reachableWAN) {
- if (this.config.debug) {
- this.log.warn("[%s] Reverting to web socket as %s.", accessory.displayName, err);
+ if (cns.devicesNonLAN.includes(accessory.context.eweUIID)) {
+ if (accessory.context.reachableWAN) {
+ this.wsClient.sendUpdate(payload, callback);
+ } else {
+ this.log.error("[%s] could not be updated as it appears to be offline.", accessory.displayName);
+ callback("Device has failed to update");
+ }
+ } else {
+ this.lanClient.sendUpdate(payload)
+ .then(res => {
+ callback();
+ })
+ .catch(err => {
+ if (accessory.context.reachableWAN) {
+ if (this.config.debug) {
+ this.log.warn("[%s] Reverting to web socket as %s.", accessory.displayName, err);
+ }
+ this.wsClient.sendUpdate(payload, callback);
+ } else {
+ this.log.error("[%s] could not be updated as it appears to be offline.", accessory.displayName);
+ callback("Device has failed to update");
}
- this.wsClient.sendUpdate(payload, callback);
- setTimeout(() => {
- this.wsClient.requestUpdate(accessory);
- }, 3000);
- } else {
- this.log.error("[%s] could not be updated as it appears to be offline.", accessory.displayName);
- callback("Device has failed to update");
- }
- });
+ });
+ }
}
receiveDeviceUpdate(device) {
let accessory, source = device.params.updateSource === "ws" ? "WS" : "LAN";
@@ -1695,7 +1699,6 @@ class eWeLink {
oAccessory.getService(Service.OccupancySensor).updateCharacteristic(Characteristic.OccupancyDetected, 0);
}, (this.config.sensorTimeLength || 2) * 1000);
break;
- case "motion":
default:
oAccessory.getService(Service.MotionSensor).updateCharacteristic(Characteristic.MotionDetected, true);
setTimeout(() => {
From 514708fbaef362f0f846793d1ca90bd9a25e43e7 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Fri, 21 Aug 2020 08:53:27 +0100
Subject: [PATCH 0042/3183] 2.23.1
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 9f311274..7481fabd 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.23.0",
+ "version": "2.23.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 1f11ab88..c1aa9dee 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.23.0",
+ "version": "2.23.1",
"author": "bwp91",
"contributors": [
"gbro115",
From 1d6f1a4c59f39577dc0de7f87ee664ae4de4f330 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Fri, 21 Aug 2020 13:51:52 +0100
Subject: [PATCH 0043/3183] ws/lan refactor
---
lib/eWeLink.js | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index c5f9bb29..87b1838a 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -666,28 +666,26 @@ class eWeLink {
deviceid: accessory.context.eweDeviceId,
params
};
- if (cns.devicesNonLAN.includes(accessory.context.eweUIID)) {
+ let sendViaWS = () => {
if (accessory.context.reachableWAN) {
this.wsClient.sendUpdate(payload, callback);
} else {
this.log.error("[%s] could not be updated as it appears to be offline.", accessory.displayName);
callback("Device has failed to update");
}
+ };
+ if (cns.devicesNonLAN.includes(accessory.context.eweUIID) || !this.lanDevices.get(accessory.context.eweDeviceId).online) {
+ sendViaWS();
} else {
this.lanClient.sendUpdate(payload)
.then(res => {
callback();
})
.catch(err => {
- if (accessory.context.reachableWAN) {
- if (this.config.debug) {
- this.log.warn("[%s] Reverting to web socket as %s.", accessory.displayName, err);
- }
- this.wsClient.sendUpdate(payload, callback);
- } else {
- this.log.error("[%s] could not be updated as it appears to be offline.", accessory.displayName);
- callback("Device has failed to update");
+ if (this.config.debug) {
+ this.log.warn("[%s] Reverting to web socket as %s.", accessory.displayName, err);
}
+ sendViaWS();
});
}
}
From dd78ff39f4a267d3da7d0d78e1bc47f3d9f7561c Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Fri, 21 Aug 2020 13:52:23 +0100
Subject: [PATCH 0044/3183] 2.23.2
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 7481fabd..39fb9235 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.23.1",
+ "version": "2.23.2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index c1aa9dee..dea62940 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.23.1",
+ "version": "2.23.2",
"author": "bwp91",
"contributors": [
"gbro115",
From 23884cc9575bc90315e85fe107febff969eaaca4 Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Fri, 21 Aug 2020 23:36:49 +0100
Subject: [PATCH 0045/3183] config hide TH switch
---
config.schema.json | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/config.schema.json b/config.schema.json
index 8a6237d9..1ef46d3e 100644
--- a/config.schema.json
+++ b/config.schema.json
@@ -73,6 +73,12 @@
"default":"20",
"maximum":999
},
+ "hideTHSwitch":{
+ "title":"Hide TH10/TH16 Switch",
+ "type":"boolean",
+ "description":"If enabled, the switch for the TH10/TH16 devices will be hidden from Homebridge.",
+ "default":false
+ },
"hideZBLDPress":{
"title":"Hide Double/Long Press",
"type":"boolean",
@@ -291,4 +297,4 @@
]
}
]
-}
\ No newline at end of file
+}
From 54c68c19b381e5620e288b805153bb92a352bdcb Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Fri, 21 Aug 2020 23:41:37 +0100
Subject: [PATCH 0046/3183] ability to hide th10/16 switch
---
lib/eWeLink.js | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 87b1838a..89a16d67 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -272,7 +272,9 @@ class eWeLink {
accessory.addService(Service.Lightbulb);
break;
case "thermostat":
- accessory.addService(Service.Switch);
+ if (!this.config.hideTHSwitch) {
+ accessory.addService(Service.Switch);
+ }
accessory.addService(Service.TemperatureSensor);
if (device.params.sensorType !== "DS18B20") {
accessory.addService(Service.HumiditySensor);
@@ -1486,7 +1488,7 @@ class eWeLink {
}
externalThermostatUpdate(accessory, params) {
try {
- if (params.hasOwnProperty("switch") || params.hasOwnProperty("mainSwitch")) {
+ if (!this.config.hideTHSwitch && (params.hasOwnProperty("switch") || params.hasOwnProperty("mainSwitch"))) {
let newState = params.hasOwnProperty("switch") ? params.switch === "on" : params.mainSwitch === "on";
accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, newState);
}
@@ -1769,4 +1771,4 @@ module.exports = function(homebridge) {
Characteristic = homebridge.hap.Characteristic;
UUIDGen = homebridge.hap.uuid;
return eWeLink;
-};
\ No newline at end of file
+};
From 8743d0e81d7b976da86218d7a880f4af1788ab01 Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Fri, 21 Aug 2020 23:44:02 +0100
Subject: [PATCH 0047/3183] hideTHSwitch visability
---
config.schema.json | 1 +
1 file changed, 1 insertion(+)
diff --git a/config.schema.json b/config.schema.json
index 1ef46d3e..c41d0656 100644
--- a/config.schema.json
+++ b/config.schema.json
@@ -256,6 +256,7 @@
"sensorTimeLength",
"sensorTimeDifference",
"valveTimeLength",
+ "hideTHSwitch",
"hideZBLDPress"
]
},
From 344b03b5647668c187660e15ddb8fc4c317b5724 Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Sat, 22 Aug 2020 00:01:00 +0100
Subject: [PATCH 0048/3183] Update README.md
---
README.md | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index bbcd2fef..31a356b8 100644
--- a/README.md
+++ b/README.md
@@ -17,5 +17,6 @@
## Documentation
Please refer to the [wiki](https://github.com/bwp91/homebridge-ewelink/wiki) for documentation.
-## Credit
-To the original owner of this package @gbro115 for letting me take over. I will look after it as best as I can :)
+## Credits
+- To the original owner of this package @gbro115 for letting me take over. I will look after it as best as I can :)
+- More credits in the [wiki](https://github.com/bwp91/homebridge-ewelink/wiki/Credits).
From d6d8f4fe1997044d7e72124c97651a75a4dd1689 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sat, 22 Aug 2020 00:04:25 +0100
Subject: [PATCH 0049/3183] 2.24.0-0
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 39fb9235..16318a79 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.23.2",
+ "version": "2.24.0-0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index dea62940..f27e3e2e 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.23.2",
+ "version": "2.24.0-0",
"author": "bwp91",
"contributors": [
"gbro115",
From e87441134623fac2d644ee78df757ddf5e9e5491 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 23 Aug 2020 13:05:25 +0100
Subject: [PATCH 0050/3183] hide th switch option
---
lib/eWeLink.js | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 89a16d67..cb9464c2 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -458,12 +458,14 @@ class eWeLink {
});
break;
case "thermostat":
- accessory.getService(Service.Switch).getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => {
- accessory.getService(Service.Switch).getCharacteristic(Characteristic.On).value !== value ?
- this.internalThermostatUpdate(accessory, value, callback) :
- callback();
- });
+ if (!this.config.hideTHSwitch) {
+ accessory.getService(Service.Switch).getCharacteristic(Characteristic.On)
+ .on("set", (value, callback) => {
+ accessory.getService(Service.Switch).getCharacteristic(Characteristic.On).value !== value ?
+ this.internalThermostatUpdate(accessory, value, callback) :
+ callback();
+ });
+ }
break;
case "outlet":
accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On)
@@ -1771,4 +1773,4 @@ module.exports = function(homebridge) {
Characteristic = homebridge.hap.Characteristic;
UUIDGen = homebridge.hap.uuid;
return eWeLink;
-};
+};
\ No newline at end of file
From b352daf404d0c732871964dc4f974f5bce9cd4fc Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 23 Aug 2020 13:06:05 +0100
Subject: [PATCH 0051/3183] 2.24.0
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 16318a79..07fbec86 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.24.0-0",
+ "version": "2.24.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index f27e3e2e..e03ce3b9 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.24.0-0",
+ "version": "2.24.0",
"author": "bwp91",
"contributors": [
"gbro115",
From 9cf948cac5c57880204ce6788430683bfcef4ee8 Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Mon, 24 Aug 2020 19:46:44 +0200
Subject: [PATCH 0052/3183] Create codeql-analysis.yml
---
.github/workflows/codeql-analysis.yml | 54 +++++++++++++++++++++++++++
1 file changed, 54 insertions(+)
create mode 100644 .github/workflows/codeql-analysis.yml
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
new file mode 100644
index 00000000..7158717c
--- /dev/null
+++ b/.github/workflows/codeql-analysis.yml
@@ -0,0 +1,54 @@
+name: "CodeQL"
+
+on:
+ push:
+ branches: [master, ]
+ pull_request:
+ # The branches below must be a subset of the branches above
+ branches: [master]
+ schedule:
+ - cron: '0 1 * * 5'
+
+jobs:
+ analyze:
+ name: Analyze
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v2
+ with:
+ # We must fetch at least the immediate parents so that if this is
+ # a pull request then we can checkout the head.
+ fetch-depth: 2
+
+ # If this run was triggered by a pull request event, then checkout
+ # the head of the pull request instead of the merge commit.
+ - run: git checkout HEAD^2
+ if: ${{ github.event_name == 'pull_request' }}
+
+ # Initializes the CodeQL tools for scanning.
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@v1
+ # Override language selection by uncommenting this and choosing your languages
+ # with:
+ # languages: go, javascript, csharp, python, cpp, java
+
+ # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
+ # If this step fails, then you should remove it and run the build manually (see below)
+ - name: Autobuild
+ uses: github/codeql-action/autobuild@v1
+
+ # âšī¸ Command-line programs to run using the OS shell.
+ # đ https://git.io/JvXDl
+
+ # âī¸ If the Autobuild fails above, remove it and uncomment the following three lines
+ # and modify them (or add more) to build your code if your project
+ # uses a compiled language
+
+ #- run: |
+ # make bootstrap
+ # make release
+
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@v1
From 4e50f266f526d1af85c29b9e58f16fa3f8c9b04a Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 25 Aug 2020 16:29:53 +0100
Subject: [PATCH 0053/3183] improve lag
---
lib/eWeLinkWS.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/eWeLinkWS.js b/lib/eWeLinkWS.js
index 95aea46d..cf35ae34 100644
--- a/lib/eWeLinkWS.js
+++ b/lib/eWeLinkWS.js
@@ -200,8 +200,8 @@ module.exports = class eWeLinkWS {
return;
}
if (this.ws) {
- callback();
this.ws.send(req);
+ callback();
if (this.debugReqRes) {
let msg = JSON.stringify(json, null, 2).replace(json.apikey, "**hidden**").replace(json.apiKey, "**hidden**").replace(json.deviceid, "**hidden**");
this.log.warn("Web socket message sent. This text is yellow for clarity.\n%s", msg);
From 50a6921cedd6bbc05be6ef3de223dc961c020228 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 25 Aug 2020 16:30:00 +0100
Subject: [PATCH 0054/3183] support for led device
---
lib/constants.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/constants.js b/lib/constants.js
index 077cc40f..653f547c 100644
--- a/lib/constants.js
+++ b/lib/constants.js
@@ -6,7 +6,7 @@ module.exports = {
devicesHideable: ["switch", "light", "valve"],
devicesNonLAN: [22, 59, 102],
devicesSingleSwitch: [1, 5, 6, 14, 15, 22, 24, 27, 32, 36, 44, 59],
- devicesSingleSwitchLight: ["T1 1C", "L1", "B1", "B1_R2", "TX1C", "D1", "D1R1", "KING-M4", "Slampher"],
+ devicesSingleSwitchLight: ["T1 1C", "L1", "B1", "B1_R2", "TX1C", "D1", "D1R1", "KING-M4", "Slampher", "GTTA59"],
devicesMultiSwitch: [2, 3, 4, 7, 8, 9, 29, 30, 31, 34, 41],
devicesMultiSwitchLight: ["T1 2C", "T1 3C", "TX2C", "TX3C"],
devicesBrightable: [36, 44],
From e0d3f3812a361e4f0c77d598e14a98a4a47b9256 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 25 Aug 2020 16:33:58 +0100
Subject: [PATCH 0055/3183] 2.24.1
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 07fbec86..2732cb07 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.24.0",
+ "version": "2.24.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index e03ce3b9..9e42cfff 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.24.0",
+ "version": "2.24.1",
"author": "bwp91",
"contributors": [
"gbro115",
From 0eaa483317fbbcd38169a942506009f87eed8ba0 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Fri, 28 Aug 2020 13:11:28 +0100
Subject: [PATCH 0056/3183] callback position
---
lib/eWeLink.js | 3 ++-
lib/eWeLinkWS.js | 3 +--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index cb9464c2..4d69b335 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -672,7 +672,8 @@ class eWeLink {
};
let sendViaWS = () => {
if (accessory.context.reachableWAN) {
- this.wsClient.sendUpdate(payload, callback);
+ this.wsClient.sendUpdate(payload);
+ callback();
} else {
this.log.error("[%s] could not be updated as it appears to be offline.", accessory.displayName);
callback("Device has failed to update");
diff --git a/lib/eWeLinkWS.js b/lib/eWeLinkWS.js
index cf35ae34..fb5ba293 100644
--- a/lib/eWeLinkWS.js
+++ b/lib/eWeLinkWS.js
@@ -183,7 +183,7 @@ module.exports = class eWeLinkWS {
}
});
}
- sendUpdate(json, callback) {
+ sendUpdate(json) {
json = {
...json,
...{
@@ -201,7 +201,6 @@ module.exports = class eWeLinkWS {
}
if (this.ws) {
this.ws.send(req);
- callback();
if (this.debugReqRes) {
let msg = JSON.stringify(json, null, 2).replace(json.apikey, "**hidden**").replace(json.apiKey, "**hidden**").replace(json.deviceid, "**hidden**");
this.log.warn("Web socket message sent. This text is yellow for clarity.\n%s", msg);
From 8859987af89637345ea864b12ef83c115962f341 Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Sun, 30 Aug 2020 14:56:47 +0100
Subject: [PATCH 0057/3183] Update README.md
---
README.md | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/README.md b/README.md
index 31a356b8..003d8a37 100644
--- a/README.md
+++ b/README.md
@@ -14,9 +14,8 @@
-## Documentation
+### Documentation
Please refer to the [wiki](https://github.com/bwp91/homebridge-ewelink/wiki) for documentation.
-## Credits
-- To the original owner of this package @gbro115 for letting me take over. I will look after it as best as I can :)
-- More credits in the [wiki](https://github.com/bwp91/homebridge-ewelink/wiki/Credits).
+### Credit
+Thank you to the original owner of this package @gbro115 for letting me take over. I will look after it as best as I can :)
From f4cdc7c23a1ec771a5c61dd81cefc81a3d4a1e3b Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Sun, 30 Aug 2020 15:02:37 +0100
Subject: [PATCH 0058/3183] Update README.md
---
README.md | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 003d8a37..3aa9e0e0 100644
--- a/README.md
+++ b/README.md
@@ -5,17 +5,18 @@
# homebridge-ewelink
+ Homebridge plugin to control eWeLink devices with original firmware.
+
[![verified-by-homebridge](https://badgen.net/badge/homebridge/verified/purple)](https://github.com/homebridge/homebridge/wiki/Verified-Plugins)
[![Discord](https://img.shields.io/discord/432663330281226270?color=728ED5&logo=discord&label=discord)](https://discord.com/channels/432663330281226270/742733745743855627)
[![npm](https://img.shields.io/npm/dt/homebridge-ewelink)](https://www.npmjs.com/package/homebridge-ewelink)
[![npm](https://img.shields.io/npm/v/homebridge-ewelink/latest?label=release)](https://www.npmjs.com/package/homebridge-ewelink)
[![npm](https://img.shields.io/npm/v/homebridge-ewelink/beta?label=beta)](https://www.npmjs.com/package/homebridge-ewelink)
-
### Documentation
Please refer to the [wiki](https://github.com/bwp91/homebridge-ewelink/wiki) for documentation.
### Credit
-Thank you to the original owner of this package @gbro115 for letting me take over. I will look after it as best as I can :)
+To the original owner of this package @gbro115 for letting me take over. I will look after it as best as I can :)
From ee8674c0528219f447f33aae280ec712328903cd Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Sun, 30 Aug 2020 15:23:00 +0100
Subject: [PATCH 0059/3183] Update README.md
---
README.md | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/README.md b/README.md
index 3aa9e0e0..f0c86501 100644
--- a/README.md
+++ b/README.md
@@ -15,8 +15,18 @@
-### Documentation
-Please refer to the [wiki](https://github.com/bwp91/homebridge-ewelink/wiki) for documentation.
-
-### Credit
-To the original owner of this package @gbro115 for letting me take over. I will look after it as best as I can :)
+### Setup
+* [Installation](https://github.com/bwp91/homebridge-ewelink/wiki/Installation)
+* [Configuration](https://github.com/bwp91/homebridge-ewelink/wiki/Configuration)
+* [Beta Version](https://github.com/bwp91/homebridge-ewelink/wiki/Beta-Version)
+### Features
+* [Supported Devices](https://github.com/bwp91/homebridge-ewelink/wiki/Supported-Devices)
+* [Connection Methods](https://github.com/bwp91/homebridge-ewelink/wiki/Connection-Methods)
+### How-to Guides
+* [How to copy Homebridge logs](https://github.com/bwp91/homebridge-ewelink/wiki/How-to-copy-Homebridge-logs)
+* [How to enable/disable plugin extended logging](https://github.com/bwp91/homebridge-ewelink/wiki/How-to-enable-disable-plugin-extended-logging)
+* [How to set up RF Bridge sensors](https://github.com/bwp91/homebridge-ewelink/wiki/How-to-set-up-RF-Bridge-sensors)
+### About
+* [Support Request](https://github.com/bwp91/homebridge-ewelink/issues)
+* [Roadmap](https://github.com/bwp91/homebridge-ewelink/wiki/Roadmap)
+* [Credits](https://github.com/bwp91/homebridge-ewelink/wiki/Credits)
From 6b2518d4749ea98f879720bd58d97e0d4a7da63a Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sat, 5 Sep 2020 11:06:31 +0100
Subject: [PATCH 0060/3183] closeConnection checks
---
lib/eWeLink.js | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 4d69b335..6940cc0a 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -89,8 +89,12 @@ class eWeLink {
}).catch(err => this.log.error("đ´ Cannot load %s - %s", cns.packageName, err));
});
this.api.on('shutdown', () => {
- this.lanClient.closeConnection();
- this.wsClient.closeConnection();
+ if (this.lanClient) {
+ this.lanClient.closeConnection();
+ }
+ if (this.wsClient) {
+ this.wsClient.closeConnection();
+ }
});
}
initialiseDevice(device) {
From 870a4304c862e937c5f9c663f1019a7b0c51bef0 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sat, 5 Sep 2020 15:22:06 +0100
Subject: [PATCH 0061/3183] link to wiki
---
config.schema.json | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/config.schema.json b/config.schema.json
index c41d0656..9362768b 100644
--- a/config.schema.json
+++ b/config.schema.json
@@ -3,7 +3,7 @@
"pluginType":"platform",
"singular":true,
"headerDisplay":"Homebridge plugin to control eWeLink devices with original firmware.",
- "footerDisplay":"If you have any suggestions, please open an issue on [GitHub](https://github.com/bwp91/homebridge-ewelink/issues).",
+ "footerDisplay":"For help and support please visit our [GitHub Wiki](https://github.com/bwp91/homebridge-ewelink/wiki).",
"schema":{
"type":"object",
"properties":{
@@ -298,4 +298,4 @@
]
}
]
-}
+}
\ No newline at end of file
From d077ba4a6c0d0a0ed8136268e9517f84198c63af Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sat, 5 Sep 2020 15:22:16 +0100
Subject: [PATCH 0062/3183] remove package name
---
lib/constants.js | 1 -
1 file changed, 1 deletion(-)
diff --git a/lib/constants.js b/lib/constants.js
index 653f547c..1a11a419 100644
--- a/lib/constants.js
+++ b/lib/constants.js
@@ -2,7 +2,6 @@
"use strict";
module.exports = {
appId: "oeVkj2lYFGnJu5XUtWisfW4utiN4u9Mq",
- packageName: "homebridge-ewelink",
devicesHideable: ["switch", "light", "valve"],
devicesNonLAN: [22, 59, 102],
devicesSingleSwitch: [1, 5, 6, 14, 15, 22, 24, 27, 32, 36, 44, 59],
From db052e3541fd04936b175627373aa7b318d375d9 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sat, 5 Sep 2020 15:22:19 +0100
Subject: [PATCH 0063/3183] remove package name
---
index.js | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/index.js b/index.js
index 3083dd2d..624be64e 100644
--- a/index.js
+++ b/index.js
@@ -1,7 +1,6 @@
/* jshint esversion: 9, -W030, node: true */
"use strict";
-const constants = require("./lib/constants");
module.exports = function (homebridge) {
let eWeLink = require("./lib/eWeLink.js")(homebridge);
- homebridge.registerPlatform(constants.packageName, "eWeLink", eWeLink, true);
+ homebridge.registerPlatform("homebridge-ewelink", "eWeLink", eWeLink, true);
};
\ No newline at end of file
From 2d90bbe787c1dc6fbb680d9e7b6a4b15c31eacc9 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sat, 5 Sep 2020 15:22:33 +0100
Subject: [PATCH 0064/3183] remove package name
---
lib/eWeLink.js | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 6940cc0a..c780b194 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -12,7 +12,7 @@ class eWeLink {
return;
}
if (!config || (!config.username || !config.password || !config.countryCode)) {
- log.error("đ´ Cannot load %s - please check your eWeLink credentials in the plugin settings.", cns.packageName);
+ log.error("đ´ Cannot load homebridge-ewelink - please check your eWeLink credentials in the plugin settings.");
return;
}
this.log = log;
@@ -86,7 +86,7 @@ class eWeLink {
this.log.warn("You have 'Request & Response Logging' enabled. This setting is not recommended for long-term use.");
}
})();
- }).catch(err => this.log.error("đ´ Cannot load %s - %s", cns.packageName, err));
+ }).catch(err => this.log.error("đ´ Cannot load homebridge-ewelink - %s", err));
});
this.api.on('shutdown', () => {
if (this.lanClient) {
@@ -385,7 +385,7 @@ class eWeLink {
throw "device is not supported by this plugin";
}
this.devicesInHB.set(hbDeviceId, accessory);
- this.api.registerPlatformAccessories(cns.packageName, "eWeLink", [accessory]);
+ this.api.registerPlatformAccessories("homebridge-ewelink", "eWeLink", [accessory]);
this.configureAccessory(accessory);
this.log("[%s] has been added to Homebridge.", newDeviceName);
} catch (err) {
@@ -662,7 +662,7 @@ class eWeLink {
removeAccessory(accessory) {
try {
this.devicesInHB.delete(accessory.context.hbDeviceId);
- this.api.unregisterPlatformAccessories(cns.packageName, "eWeLink", [accessory]);
+ this.api.unregisterPlatformAccessories("homebridge-ewelink", "eWeLink", [accessory]);
this.log("[%s] has been removed from Homebridge.", accessory.displayName);
} catch (err) {
this.log.warn("[%s] needed to be removed but couldn't - [%s].", accessory.displayName, err);
From a78de6c08a9da858be283445877e923698f6fd0e Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sat, 5 Sep 2020 15:25:25 +0100
Subject: [PATCH 0065/3183] 2.24.2
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 2732cb07..c761890a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.24.1",
+ "version": "2.24.2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 9e42cfff..0fc56a42 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.24.1",
+ "version": "2.24.2",
"author": "bwp91",
"contributors": [
"gbro115",
From 0e1e9c57373221c44f8bb7fc6cb6ec95d7e570dc Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sat, 5 Sep 2020 15:42:19 +0100
Subject: [PATCH 0066/3183] update axios dep
---
package-lock.json | 30 +++++++-----------------------
package.json | 2 +-
2 files changed, 8 insertions(+), 24 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index c761890a..6aaae582 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5,11 +5,11 @@
"requires": true,
"dependencies": {
"axios": {
- "version": "0.19.2",
- "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz",
- "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==",
+ "version": "0.20.0",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-0.20.0.tgz",
+ "integrity": "sha512-ANA4rr2BDcmmAQLOKft2fufrtuvlqR+cXNNinUmvfeSNCOF98PZL+7M/v1zIdGo7OLjEA9J2gXJL+j4zGsl0bA==",
"requires": {
- "follow-redirects": "1.5.10"
+ "follow-redirects": "^1.10.0"
}
},
"color-convert": {
@@ -25,26 +25,10 @@
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
- "debug": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
- "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
- "requires": {
- "ms": "2.0.0"
- }
- },
"follow-redirects": {
- "version": "1.5.10",
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
- "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
- "requires": {
- "debug": "=3.1.0"
- }
- },
- "ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ "version": "1.13.0",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz",
+ "integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA=="
},
"node-dns-sd": {
"version": "0.4.1",
diff --git a/package.json b/package.json
index 0fc56a42..a8d8bcaf 100644
--- a/package.json
+++ b/package.json
@@ -39,7 +39,7 @@
"url": "https://github.com/bwp91/homebridge-ewelink"
},
"dependencies": {
- "axios": "0.19.2",
+ "axios": "0.20.0",
"color-convert": "2.0.1",
"node-dns-sd": "0.4.1",
"ws": "7.3.1"
From 7163dd6f63b9a4f57870d22fc6dd56ece20da8fd Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 6 Sep 2020 01:10:17 +0100
Subject: [PATCH 0067/3183] lan receive msg bug
---
lib/eWeLinkLAN.js | 294 +++++++++++++++++++++++-----------------------
1 file changed, 146 insertions(+), 148 deletions(-)
diff --git a/lib/eWeLinkLAN.js b/lib/eWeLinkLAN.js
index 1032afa0..b50b901f 100644
--- a/lib/eWeLinkLAN.js
+++ b/lib/eWeLinkLAN.js
@@ -6,165 +6,163 @@ const crypto = require("crypto");
const dns = require("node-dns-sd");
const eventemitter = require("events");
module.exports = class eWeLinkLAN {
- constructor(config, log, devices) {
- this.config = config;
- this.log = log;
- this.devices = devices;
- let deviceMap = new Map();
- devices.forEach(device => {
- deviceMap.set(device.deviceid, {
- apiKey: device.devicekey,
- online: false,
- ip: null
- });
- });
- this.deviceMap = deviceMap;
- this.debug = this.config.debug || false;
- this.debugReqRes = this.config.debugReqRes || false;
- this.emitter = new eventemitter();
- }
- getHosts() {
- return new Promise((resolve, reject) => {
- dns.discover({
- name: "_ewelink._tcp.local"
- }).then(res => {
- let onlineCount = 0;
- res.forEach(device => {
- let d, deviceId = device.fqdn.replace("._ewelink._tcp.local", "").replace("eWeLink_", "");
- if ((d = this.deviceMap.get(deviceId))) {
- this.deviceMap.set(deviceId, {
- apiKey: d.apiKey,
- online: true,
- ip: device.address
- });
- onlineCount++;
- }
+ constructor(config, log, devices) {
+ this.config = config;
+ this.log = log;
+ this.devices = devices;
+ let deviceMap = new Map();
+ devices.forEach(device => {
+ deviceMap.set(device.deviceid, {
+ apiKey: device.devicekey,
+ online: false,
+ ip: null
});
- resolve({
- map: this.deviceMap,
- count: onlineCount
+ });
+ this.deviceMap = deviceMap;
+ this.debug = this.config.debug || false;
+ this.debugReqRes = this.config.debugReqRes || false;
+ this.emitter = new eventemitter();
+ }
+ getHosts() {
+ return new Promise((resolve, reject) => {
+ dns.discover({
+ name: "_ewelink._tcp.local"
+ }).then(res => {
+ let onlineCount = 0;
+ res.forEach(device => {
+ let d, deviceId = device.fqdn.replace("._ewelink._tcp.local", "").replace("eWeLink_", "");
+ if ((d = this.deviceMap.get(deviceId))) {
+ this.deviceMap.set(deviceId, {
+ apiKey: d.apiKey,
+ online: true,
+ ip: device.address
+ });
+ onlineCount++;
+ }
+ });
+ resolve({
+ map: this.deviceMap,
+ count: onlineCount
+ });
+ }).catch(err => {
+ reject(err);
});
- }).catch(err => {
- reject(err);
- });
- });
- }
- startMonitor() {
- dns.ondata = packet => {
- if (packet.answers) {
- packet.answers
- .filter(value => value.name.includes("_ewelink._tcp.local"))
- .forEach(value => {
- if (value.type === "TXT") {
- let rdata = value.rdata;
- if (this.deviceMap.hasOwnProperty(rdata.id)) {
- let deviceKey = this.deviceMap[rdata.id].apiKey,
- data = rdata.data1 +
- (rdata.hasOwnProperty("data2") ? rdata.data2 : "") +
- (rdata.hasOwnProperty("data3") ? rdata.data3 : "") +
- (rdata.hasOwnProperty("data4") ? rdata.data4 : ""),
- key = crypto.createHash("md5").update(Buffer.from(deviceKey, "utf8")).digest(),
- dText = crypto.createDecipheriv("aes-128-cbc", key, Buffer.from(rdata.iv, "base64")),
- pText = Buffer.concat([dText.update(Buffer.from(data, "base64")), dText.final()]).toString("utf8"),
- params;
+ });
+ }
+ startMonitor() {
+ dns.ondata = packet => {
+ if (packet.answers) {
+ packet.answers
+ .filter(value => value.name.includes("_ewelink._tcp.local"))
+ .filter(value => value.type === "TXT")
+ .filter(value => this.deviceMap.has(value.rdata.id))
+ .forEach(value => {
+ let rdata = value.rdata,
+ deviceKey = this.deviceMap.get(rdata.id).apiKey,
+ data = rdata.data1 +
+ (rdata.hasOwnProperty("data2") ? rdata.data2 : "") +
+ (rdata.hasOwnProperty("data3") ? rdata.data3 : "") +
+ (rdata.hasOwnProperty("data4") ? rdata.data4 : ""),
+ key = crypto.createHash("md5").update(Buffer.from(deviceKey, "utf8")).digest(),
+ dText = crypto.createDecipheriv("aes-128-cbc", key, Buffer.from(rdata.iv, "base64")),
+ pText = Buffer.concat([dText.update(Buffer.from(data, "base64")), dText.final()]).toString("utf8"),
+ params;
try {
- params = JSON.parse(pText);
+ params = JSON.parse(pText);
} catch (e) {
- this.log.warn("[%s] An error occured reading the LAN message [%s]", rdata.id, e);
- return;
+ this.log.warn("[%s] An error occured reading the LAN message [%s]", rdata.id, e);
+ return;
}
for (let param in params) {
- if (params.hasOwnProperty(param)) {
- if (!constants.paramsToKeep.includes(param.replace(/[0-9]/g, ""))) {
- delete params[param];
- }
- }
+ if (params.hasOwnProperty(param)) {
+ if (!constants.paramsToKeep.includes(param.replace(/[0-9]/g, ""))) {
+ delete params[param];
+ }
+ }
}
params.updateSource = "lan";
if (Object.keys(params).length > 0) {
- let returnTemplate = {
- deviceid: rdata.id,
- action: "update",
- params
- };
- if (this.debugReqRes) {
- let msg = JSON.stringify(returnTemplate, null, 2).replace(rdata.id, "**hidden**");
- this.log("LAN message received.\n%s", msg);
- } else if (this.debug) {
- this.log("LAN message received.");
- }
- this.emitter.emit("update", returnTemplate);
+ let returnTemplate = {
+ deviceid: rdata.id,
+ action: "update",
+ params
+ };
+ if (this.debugReqRes) {
+ let msg = JSON.stringify(returnTemplate, null, 2).replace(rdata.id, "**hidden**");
+ this.log("LAN message received.\n%s", msg);
+ } else if (this.debug) {
+ this.log("LAN message received.");
+ }
+ this.emitter.emit("update", returnTemplate);
}
- }
- }
- });
- }
- };
- return new Promise((resolve, reject) => {
- dns.startMonitoring().then(() => {
- resolve();
- }).catch(err => {
- reject(err);
- });
- });
- }
- sendUpdate(json) {
- return new Promise((resolve, reject) => {
- if (!this.deviceMap.get(json.deviceid).online) {
- throw "device does not support LAN mode";
- }
- let apiKey, suffix, params = {};
- if (json.params.hasOwnProperty("switches")) {
- params.switches = json.params.switches;
- suffix = "switches";
- } else if (json.params.hasOwnProperty("switch")) {
- params.switch = json.params.switch;
- suffix = "switch";
- } else {
- throw "plugin does not support lan mode for this device yet - feel free to create a github issue";
- }
- if ((apiKey = this.deviceMap.get(json.deviceid).apiKey)) {
- let key = crypto.createHash('md5').update(Buffer.from(apiKey, 'utf8')).digest(),
- iv = crypto.randomBytes(16),
- enc = crypto.createCipheriv('aes-128-cbc', key, iv),
- data = {
- data: Buffer.concat([enc.update(JSON.stringify(params)), enc.final()]).toString('base64'),
- deviceid: json.deviceid,
- encrypt: true,
- iv: iv.toString('base64'),
- selfApikey: "123",
- sequence: Date.now().toString()
- };
- if (this.debugReqRes) {
- let msg = JSON.stringify(json, null, 2).replace(json.apikey, "**hidden**").replace(json.apikey, "**hidden**").replace(json.deviceid, "**hidden**");
- this.log.warn("LAN mode message sent. This text is yellow for clarity.\n%s", msg);
- } else if (this.debug) {
- this.log("LAN mode message sent.");
+ });
}
- axios({
- method: "post",
- url: "http://" + this.deviceMap.get(json.deviceid).ip + ":8081/zeroconf/" + suffix,
- headers: {
- Accept: "application/json",
- "Content-Type": "application/json"
- },
- data
- }).then(res => {
- if (res.data.hasOwnProperty("error") && res.data.error === 0) {
- resolve();
- }
- throw res.data;
+ };
+ return new Promise((resolve, reject) => {
+ dns.startMonitoring().then(() => {
+ resolve();
}).catch(err => {
- reject(err);
+ reject(err);
});
- }
- });
- }
- receiveUpdate(f) {
- this.emitter.addListener("update", f);
- }
- closeConnection() {
- dns.stopMonitoring();
- this.log("LAN monitoring stopped as part of Homebridge shutdown.");
- }
+ });
+ }
+ sendUpdate(json) {
+ return new Promise((resolve, reject) => {
+ if (!this.deviceMap.get(json.deviceid).online) {
+ throw "device does not support LAN mode";
+ }
+ let apiKey, suffix, params = {};
+ if (json.params.hasOwnProperty("switches")) {
+ params.switches = json.params.switches;
+ suffix = "switches";
+ } else if (json.params.hasOwnProperty("switch")) {
+ params.switch = json.params.switch;
+ suffix = "switch";
+ } else {
+ throw "plugin does not support lan mode for this device yet - feel free to create a github issue";
+ }
+ if ((apiKey = this.deviceMap.get(json.deviceid).apiKey)) {
+ let key = crypto.createHash('md5').update(Buffer.from(apiKey, 'utf8')).digest(),
+ iv = crypto.randomBytes(16),
+ enc = crypto.createCipheriv('aes-128-cbc', key, iv),
+ data = {
+ data: Buffer.concat([enc.update(JSON.stringify(params)), enc.final()]).toString('base64'),
+ deviceid: json.deviceid,
+ encrypt: true,
+ iv: iv.toString('base64'),
+ selfApikey: "123",
+ sequence: Date.now().toString()
+ };
+ if (this.debugReqRes) {
+ let msg = JSON.stringify(json, null, 2).replace(json.apikey, "**hidden**").replace(json.apikey, "**hidden**").replace(json.deviceid, "**hidden**");
+ this.log.warn("LAN mode message sent. This text is yellow for clarity.\n%s", msg);
+ } else if (this.debug) {
+ this.log("LAN mode message sent.");
+ }
+ axios({
+ method: "post",
+ url: "http://" + this.deviceMap.get(json.deviceid).ip + ":8081/zeroconf/" + suffix,
+ headers: {
+ Accept: "application/json",
+ "Content-Type": "application/json"
+ },
+ data
+ }).then(res => {
+ if (res.data.hasOwnProperty("error") && res.data.error === 0) {
+ resolve();
+ }
+ throw res.data;
+ }).catch(err => {
+ reject(err);
+ });
+ }
+ });
+ }
+ receiveUpdate(f) {
+ this.emitter.addListener("update", f);
+ }
+ closeConnection() {
+ dns.stopMonitoring();
+ this.log("LAN monitoring stopped as part of Homebridge shutdown.");
+ }
};
\ No newline at end of file
From 722a754d29c521cf1d8f74f0bbe3afdc13b98295 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 6 Sep 2020 01:13:47 +0100
Subject: [PATCH 0068/3183] formatting
---
lib/eWeLinkLAN.js | 306 +++++++++++++++++++++++-----------------------
1 file changed, 153 insertions(+), 153 deletions(-)
diff --git a/lib/eWeLinkLAN.js b/lib/eWeLinkLAN.js
index b50b901f..098be312 100644
--- a/lib/eWeLinkLAN.js
+++ b/lib/eWeLinkLAN.js
@@ -6,163 +6,163 @@ const crypto = require("crypto");
const dns = require("node-dns-sd");
const eventemitter = require("events");
module.exports = class eWeLinkLAN {
- constructor(config, log, devices) {
- this.config = config;
- this.log = log;
- this.devices = devices;
- let deviceMap = new Map();
- devices.forEach(device => {
- deviceMap.set(device.deviceid, {
- apiKey: device.devicekey,
- online: false,
- ip: null
+ constructor(config, log, devices) {
+ this.config = config;
+ this.log = log;
+ this.devices = devices;
+ let deviceMap = new Map();
+ devices.forEach(device => {
+ deviceMap.set(device.deviceid, {
+ apiKey: device.devicekey,
+ online: false,
+ ip: null
+ });
+ });
+ this.deviceMap = deviceMap;
+ this.debug = this.config.debug || false;
+ this.debugReqRes = this.config.debugReqRes || false;
+ this.emitter = new eventemitter();
+ }
+ getHosts() {
+ return new Promise((resolve, reject) => {
+ dns.discover({
+ name: "_ewelink._tcp.local"
+ }).then(res => {
+ let onlineCount = 0;
+ res.forEach(device => {
+ let d, deviceId = device.fqdn.replace("._ewelink._tcp.local", "").replace("eWeLink_", "");
+ if ((d = this.deviceMap.get(deviceId))) {
+ this.deviceMap.set(deviceId, {
+ apiKey: d.apiKey,
+ online: true,
+ ip: device.address
+ });
+ onlineCount++;
+ }
});
- });
- this.deviceMap = deviceMap;
- this.debug = this.config.debug || false;
- this.debugReqRes = this.config.debugReqRes || false;
- this.emitter = new eventemitter();
- }
- getHosts() {
- return new Promise((resolve, reject) => {
- dns.discover({
- name: "_ewelink._tcp.local"
- }).then(res => {
- let onlineCount = 0;
- res.forEach(device => {
- let d, deviceId = device.fqdn.replace("._ewelink._tcp.local", "").replace("eWeLink_", "");
- if ((d = this.deviceMap.get(deviceId))) {
- this.deviceMap.set(deviceId, {
- apiKey: d.apiKey,
- online: true,
- ip: device.address
- });
- onlineCount++;
- }
- });
- resolve({
- map: this.deviceMap,
- count: onlineCount
- });
- }).catch(err => {
- reject(err);
+ resolve({
+ map: this.deviceMap,
+ count: onlineCount
});
- });
- }
- startMonitor() {
- dns.ondata = packet => {
- if (packet.answers) {
- packet.answers
- .filter(value => value.name.includes("_ewelink._tcp.local"))
- .filter(value => value.type === "TXT")
- .filter(value => this.deviceMap.has(value.rdata.id))
- .forEach(value => {
- let rdata = value.rdata,
- deviceKey = this.deviceMap.get(rdata.id).apiKey,
- data = rdata.data1 +
- (rdata.hasOwnProperty("data2") ? rdata.data2 : "") +
- (rdata.hasOwnProperty("data3") ? rdata.data3 : "") +
- (rdata.hasOwnProperty("data4") ? rdata.data4 : ""),
- key = crypto.createHash("md5").update(Buffer.from(deviceKey, "utf8")).digest(),
- dText = crypto.createDecipheriv("aes-128-cbc", key, Buffer.from(rdata.iv, "base64")),
- pText = Buffer.concat([dText.update(Buffer.from(data, "base64")), dText.final()]).toString("utf8"),
- params;
- try {
- params = JSON.parse(pText);
- } catch (e) {
- this.log.warn("[%s] An error occured reading the LAN message [%s]", rdata.id, e);
- return;
- }
- for (let param in params) {
- if (params.hasOwnProperty(param)) {
- if (!constants.paramsToKeep.includes(param.replace(/[0-9]/g, ""))) {
- delete params[param];
- }
- }
- }
- params.updateSource = "lan";
- if (Object.keys(params).length > 0) {
- let returnTemplate = {
- deviceid: rdata.id,
- action: "update",
- params
- };
- if (this.debugReqRes) {
- let msg = JSON.stringify(returnTemplate, null, 2).replace(rdata.id, "**hidden**");
- this.log("LAN message received.\n%s", msg);
- } else if (this.debug) {
- this.log("LAN message received.");
- }
- this.emitter.emit("update", returnTemplate);
+ }).catch(err => {
+ reject(err);
+ });
+ });
+ }
+ startMonitor() {
+ dns.ondata = packet => {
+ if (packet.answers) {
+ packet.answers
+ .filter(value => value.name.includes("_ewelink._tcp.local"))
+ .filter(value => value.type === "TXT")
+ .filter(value => this.deviceMap.has(value.rdata.id))
+ .forEach(value => {
+ let rdata = value.rdata,
+ deviceKey = this.deviceMap.get(rdata.id).apiKey,
+ data = rdata.data1 +
+ (rdata.hasOwnProperty("data2") ? rdata.data2 : "") +
+ (rdata.hasOwnProperty("data3") ? rdata.data3 : "") +
+ (rdata.hasOwnProperty("data4") ? rdata.data4 : ""),
+ key = crypto.createHash("md5").update(Buffer.from(deviceKey, "utf8")).digest(),
+ dText = crypto.createDecipheriv("aes-128-cbc", key, Buffer.from(rdata.iv, "base64")),
+ pText = Buffer.concat([dText.update(Buffer.from(data, "base64")), dText.final()]).toString("utf8"),
+ params;
+ try {
+ params = JSON.parse(pText);
+ } catch (e) {
+ this.log.warn("[%s] An error occured reading the LAN message [%s]", rdata.id, e);
+ return;
+ }
+ for (let param in params) {
+ if (params.hasOwnProperty(param)) {
+ if (!constants.paramsToKeep.includes(param.replace(/[0-9]/g, ""))) {
+ delete params[param];
}
- });
+ }
+ }
+ params.updateSource = "lan";
+ if (Object.keys(params).length > 0) {
+ let returnTemplate = {
+ deviceid: rdata.id,
+ action: "update",
+ params
+ };
+ if (this.debugReqRes) {
+ let msg = JSON.stringify(returnTemplate, null, 2).replace(rdata.id, "**hidden**");
+ this.log("LAN message received.\n%s", msg);
+ } else if (this.debug) {
+ this.log("LAN message received.");
+ }
+ this.emitter.emit("update", returnTemplate);
+ }
+ });
+ }
+ };
+ return new Promise((resolve, reject) => {
+ dns.startMonitoring().then(() => {
+ resolve();
+ }).catch(err => {
+ reject(err);
+ });
+ });
+ }
+ sendUpdate(json) {
+ return new Promise((resolve, reject) => {
+ if (!this.deviceMap.get(json.deviceid).online) {
+ throw "device does not support LAN mode";
+ }
+ let apiKey, suffix, params = {};
+ if (json.params.hasOwnProperty("switches")) {
+ params.switches = json.params.switches;
+ suffix = "switches";
+ } else if (json.params.hasOwnProperty("switch")) {
+ params.switch = json.params.switch;
+ suffix = "switch";
+ } else {
+ throw "plugin does not support lan mode for this device yet - feel free to create a github issue";
+ }
+ if ((apiKey = this.deviceMap.get(json.deviceid).apiKey)) {
+ let key = crypto.createHash('md5').update(Buffer.from(apiKey, 'utf8')).digest(),
+ iv = crypto.randomBytes(16),
+ enc = crypto.createCipheriv('aes-128-cbc', key, iv),
+ data = {
+ data: Buffer.concat([enc.update(JSON.stringify(params)), enc.final()]).toString('base64'),
+ deviceid: json.deviceid,
+ encrypt: true,
+ iv: iv.toString('base64'),
+ selfApikey: "123",
+ sequence: Date.now().toString()
+ };
+ if (this.debugReqRes) {
+ let msg = JSON.stringify(json, null, 2).replace(json.apikey, "**hidden**").replace(json.apikey, "**hidden**").replace(json.deviceid, "**hidden**");
+ this.log.warn("LAN mode message sent. This text is yellow for clarity.\n%s", msg);
+ } else if (this.debug) {
+ this.log("LAN mode message sent.");
}
- };
- return new Promise((resolve, reject) => {
- dns.startMonitoring().then(() => {
- resolve();
+ axios({
+ method: "post",
+ url: "http://" + this.deviceMap.get(json.deviceid).ip + ":8081/zeroconf/" + suffix,
+ headers: {
+ Accept: "application/json",
+ "Content-Type": "application/json"
+ },
+ data
+ }).then(res => {
+ if (res.data.hasOwnProperty("error") && res.data.error === 0) {
+ resolve();
+ }
+ throw res.data;
}).catch(err => {
- reject(err);
+ reject(err);
});
- });
- }
- sendUpdate(json) {
- return new Promise((resolve, reject) => {
- if (!this.deviceMap.get(json.deviceid).online) {
- throw "device does not support LAN mode";
- }
- let apiKey, suffix, params = {};
- if (json.params.hasOwnProperty("switches")) {
- params.switches = json.params.switches;
- suffix = "switches";
- } else if (json.params.hasOwnProperty("switch")) {
- params.switch = json.params.switch;
- suffix = "switch";
- } else {
- throw "plugin does not support lan mode for this device yet - feel free to create a github issue";
- }
- if ((apiKey = this.deviceMap.get(json.deviceid).apiKey)) {
- let key = crypto.createHash('md5').update(Buffer.from(apiKey, 'utf8')).digest(),
- iv = crypto.randomBytes(16),
- enc = crypto.createCipheriv('aes-128-cbc', key, iv),
- data = {
- data: Buffer.concat([enc.update(JSON.stringify(params)), enc.final()]).toString('base64'),
- deviceid: json.deviceid,
- encrypt: true,
- iv: iv.toString('base64'),
- selfApikey: "123",
- sequence: Date.now().toString()
- };
- if (this.debugReqRes) {
- let msg = JSON.stringify(json, null, 2).replace(json.apikey, "**hidden**").replace(json.apikey, "**hidden**").replace(json.deviceid, "**hidden**");
- this.log.warn("LAN mode message sent. This text is yellow for clarity.\n%s", msg);
- } else if (this.debug) {
- this.log("LAN mode message sent.");
- }
- axios({
- method: "post",
- url: "http://" + this.deviceMap.get(json.deviceid).ip + ":8081/zeroconf/" + suffix,
- headers: {
- Accept: "application/json",
- "Content-Type": "application/json"
- },
- data
- }).then(res => {
- if (res.data.hasOwnProperty("error") && res.data.error === 0) {
- resolve();
- }
- throw res.data;
- }).catch(err => {
- reject(err);
- });
- }
- });
- }
- receiveUpdate(f) {
- this.emitter.addListener("update", f);
- }
- closeConnection() {
- dns.stopMonitoring();
- this.log("LAN monitoring stopped as part of Homebridge shutdown.");
- }
+ }
+ });
+ }
+ receiveUpdate(f) {
+ this.emitter.addListener("update", f);
+ }
+ closeConnection() {
+ dns.stopMonitoring();
+ this.log("LAN monitoring stopped as part of Homebridge shutdown.");
+ }
};
\ No newline at end of file
From ada5c535e49ee35bab65466a0954cfaae5c91a50 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 6 Sep 2020 01:25:13 +0100
Subject: [PATCH 0069/3183] close lan/ws on error
---
lib/eWeLink.js | 10 +++++++++-
lib/eWeLinkLAN.js | 2 +-
lib/eWeLinkWS.js | 2 +-
3 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index c780b194..38b8fdc4 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -86,7 +86,15 @@ class eWeLink {
this.log.warn("You have 'Request & Response Logging' enabled. This setting is not recommended for long-term use.");
}
})();
- }).catch(err => this.log.error("đ´ Cannot load homebridge-ewelink - %s", err));
+ }).catch(err => {
+ this.log.error("đ´ Cannot load homebridge-ewelink - %s", err)
+ if (this.lanClient) {
+ this.lanClient.closeConnection();
+ }
+ if (this.wsClient) {
+ this.wsClient.closeConnection();
+ }
+ });
});
this.api.on('shutdown', () => {
if (this.lanClient) {
diff --git a/lib/eWeLinkLAN.js b/lib/eWeLinkLAN.js
index 098be312..7a22f442 100644
--- a/lib/eWeLinkLAN.js
+++ b/lib/eWeLinkLAN.js
@@ -163,6 +163,6 @@ module.exports = class eWeLinkLAN {
}
closeConnection() {
dns.stopMonitoring();
- this.log("LAN monitoring stopped as part of Homebridge shutdown.");
+ this.log("LAN monitoring gracefully stopped.");
}
};
\ No newline at end of file
diff --git a/lib/eWeLinkWS.js b/lib/eWeLinkWS.js
index fb5ba293..73180031 100644
--- a/lib/eWeLinkWS.js
+++ b/lib/eWeLinkWS.js
@@ -151,7 +151,7 @@ module.exports = class eWeLinkWS {
});
this.ws.on("close", (e, m) => {
if (m === "Stopping Homebridge") {
- this.log("Web socket closed as part of Homebridge shutdown.");
+ this.log("Web socket gracefully closed.");
} else {
this.log.warn("Web socket closed - [%s - %s].", e, m);
if (e !== 1000) {
From 204420cea8712b90538a99d1e3bce41491628575 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 6 Sep 2020 01:26:42 +0100
Subject: [PATCH 0070/3183] 2.24.3
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 6aaae582..e19dacd6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.24.2",
+ "version": "2.24.3",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index a8d8bcaf..ea228f70 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.24.2",
+ "version": "2.24.3",
"author": "bwp91",
"contributors": [
"gbro115",
From bb7c39b940dce94a71e9ae2b32e0165f7df55799 Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Sun, 6 Sep 2020 15:54:44 +0100
Subject: [PATCH 0071/3183] Update README.md
---
README.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/README.md b/README.md
index f0c86501..501eea7f 100644
--- a/README.md
+++ b/README.md
@@ -26,6 +26,7 @@
* [How to copy Homebridge logs](https://github.com/bwp91/homebridge-ewelink/wiki/How-to-copy-Homebridge-logs)
* [How to enable/disable plugin extended logging](https://github.com/bwp91/homebridge-ewelink/wiki/How-to-enable-disable-plugin-extended-logging)
* [How to set up RF Bridge sensors](https://github.com/bwp91/homebridge-ewelink/wiki/How-to-set-up-RF-Bridge-sensors)
+* [How to set up Sonoff Camera (GK-200MP2-B)](https://github.com/bwp91/homebridge-ewelink/wiki/How-to-set-up-Sonoff-Camera)
### About
* [Support Request](https://github.com/bwp91/homebridge-ewelink/issues)
* [Roadmap](https://github.com/bwp91/homebridge-ewelink/wiki/Roadmap)
From 05951ebbbbf7735b51ae66b796b72e35a7d56a97 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 6 Sep 2020 16:28:24 +0100
Subject: [PATCH 0072/3183] garagedoor fix attempt
---
lib/eWeLink.js | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 38b8fdc4..2eb7de37 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -439,6 +439,7 @@ class eWeLink {
});
break;
case "garage":
+ accessory.context.inUse = false;
accessory.getService(Service.GarageDoorOpener).getCharacteristic(Characteristic.TargetDoorState)
.on("set", (value, callback) => {
accessory.getService(Service.GarageDoorOpener).getCharacteristic(Characteristic.TargetDoorState).value !== value ?
@@ -865,6 +866,10 @@ class eWeLink {
}
internalGarageUpdate(accessory, value, callback) {
try {
+ if (accessory.context.inUse) {
+ throw "it is currently in use";
+ }
+ accessory.context.inUse = true;
if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
throw "it is currently offline";
}
@@ -928,9 +933,11 @@ class eWeLink {
setTimeout(() => {
accessory.getService(Service.GarageDoorOpener)
.updateCharacteristic(Characteristic.CurrentDoorState, value === 0 ? 0 : 1);
+ accessory.context.inUse = false;
callback();
}, parseInt(garageConfig.operationTime) * 100);
} else {
+ accessory.context.inUse = false;
callback();
}
} catch (err) {
@@ -1395,6 +1402,10 @@ class eWeLink {
}
externalGarageUpdate(accessory, params) {
try {
+ if (accessory.context.inUse) {
+ throw "it is currently in use";
+ }
+ accessory.context.inUse = true;
let garageConfig, nSte;
if (!(garageConfig = this.cusG.get(accessory.context.hbDeviceId))) {
throw "group config missing";
@@ -1425,6 +1436,7 @@ class eWeLink {
.updateCharacteristic(Characteristic.CurrentDoorState, nSte - 2);
}, parseInt(garageConfig.operationTime) * 100);
}
+ accessory.context.inUse = false;
} catch (err) {
this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
}
From b459a73051bc25e445f3e895b6d1e3eb7a66cb88 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 6 Sep 2020 16:29:40 +0100
Subject: [PATCH 0073/3183] 2.24.4-0
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index e19dacd6..d6087665 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.24.3",
+ "version": "2.24.4-0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index ea228f70..16e7198d 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.24.3",
+ "version": "2.24.4-0",
"author": "bwp91",
"contributors": [
"gbro115",
From 8fe8af13fefd0f73b0f191643c9295ab68a873a1 Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Sun, 6 Sep 2020 17:59:09 +0100
Subject: [PATCH 0074/3183] Update README.md
---
README.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 501eea7f..cbd907d0 100644
--- a/README.md
+++ b/README.md
@@ -16,7 +16,8 @@
### Setup
-* [Installation](https://github.com/bwp91/homebridge-ewelink/wiki/Installation)
+* [Installation (Homebridge)](https://github.com/bwp91/homebridge-ewelink/wiki/Installation-(Homebridge))
+* [Installation (HOOBS)](https://github.com/bwp91/homebridge-ewelink/wiki/Installation-(HOOBS))
* [Configuration](https://github.com/bwp91/homebridge-ewelink/wiki/Configuration)
* [Beta Version](https://github.com/bwp91/homebridge-ewelink/wiki/Beta-Version)
### Features
From 0fe6611e678da03c34345d67b3e9ccbf667d9de1 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 6 Sep 2020 18:06:57 +0100
Subject: [PATCH 0075/3183] added kofi link
---
package.json | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/package.json b/package.json
index 16e7198d..a9cca3b7 100644
--- a/package.json
+++ b/package.json
@@ -45,6 +45,10 @@
"ws": "7.3.1"
},
"funding": [
+ {
+ "type": "kofi",
+ "url": "https://ko-fi.com/bwp91"
+ },
{
"type": "patreon",
"url": "https://www.patreon.com/bwp91"
From 9d95d70a998e4e4ef62a1791a3664c678c192329 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Mon, 7 Sep 2020 11:13:34 +0100
Subject: [PATCH 0076/3183] rename variable
---
lib/eWeLink.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 2eb7de37..2c3c4aea 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -44,7 +44,7 @@ class eWeLink {
return this.lanClient.getHosts();
}).then(res => { //*** Set up the LAN mode listener ***\\
this.lanDevices = res.map;
- this.lanDeviceOnline = res.count;
+ this.lanDevicesOnline = res.count;
return this.lanClient.startMonitor();
}).then(() => { //*** Use the device list to refresh Homebridge accessories ***\\
(() => {
@@ -70,7 +70,7 @@ class eWeLink {
//*** Logging always helps to see if everything is okay so far ***\\
this.log("[%s] eWeLink devices were loaded from the Homebridge cache.", this.devicesInHB.size);
this.log("[%s] primary devices were loaded from your eWeLink account.", this.devicesInEwe.size);
- this.log("[%s] primary devices were discovered on your local network.", this.lanDeviceOnline);
+ this.log("[%s] primary devices were discovered on your local network.", this.lanDevicesOnline);
//*** Remove Homebridge accessories that don't appear in eWeLink ***\\
this.devicesInHB.forEach(accessory => {
if (!this.devicesInEwe.has(accessory.context.eweDeviceId)) {
From 71a4000b42d563de4d16926daf5d2268ec8385cf Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Mon, 7 Sep 2020 11:13:57 +0100
Subject: [PATCH 0077/3183] feat: ip address update
---
lib/eWeLinkLAN.js | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/lib/eWeLinkLAN.js b/lib/eWeLinkLAN.js
index 7a22f442..e6db8410 100644
--- a/lib/eWeLinkLAN.js
+++ b/lib/eWeLinkLAN.js
@@ -58,15 +58,25 @@ module.exports = class eWeLinkLAN {
.filter(value => this.deviceMap.has(value.rdata.id))
.forEach(value => {
let rdata = value.rdata,
- deviceKey = this.deviceMap.get(rdata.id).apiKey,
+ deviceInfo = this.deviceMap.get(rdata.id),
data = rdata.data1 +
(rdata.hasOwnProperty("data2") ? rdata.data2 : "") +
(rdata.hasOwnProperty("data3") ? rdata.data3 : "") +
(rdata.hasOwnProperty("data4") ? rdata.data4 : ""),
- key = crypto.createHash("md5").update(Buffer.from(deviceKey, "utf8")).digest(),
+ key = crypto.createHash("md5").update(Buffer.from(deviceInfo.apiKey, "utf8")).digest(),
dText = crypto.createDecipheriv("aes-128-cbc", key, Buffer.from(rdata.iv, "base64")),
pText = Buffer.concat([dText.update(Buffer.from(data, "base64")), dText.final()]).toString("utf8"),
params;
+ if (packet.address !== deviceInfo.ip) {
+ this.deviceMap.set(rdata.id, {
+ apiKey: deviceInfo.apiKey,
+ online: true,
+ ip: packet.address
+ });
+ if (this.debug) {
+ this.log.warn("[%s] updating IP address to [%s].", rdata.id, packet.address);
+ }
+ }
try {
params = JSON.parse(pText);
} catch (e) {
From 058982df175fe0359eba1219b142f3a0d7ce4630 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Mon, 7 Sep 2020 13:10:32 +0100
Subject: [PATCH 0078/3183] garage door bug fix?
---
lib/eWeLink.js | 27 +++++++++++++++++++--------
1 file changed, 19 insertions(+), 8 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 2c3c4aea..298a1ca6 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -87,7 +87,7 @@ class eWeLink {
}
})();
}).catch(err => {
- this.log.error("đ´ Cannot load homebridge-ewelink - %s", err)
+ this.log.error("đ´ Cannot load homebridge-ewelink - %s", err);
if (this.lanClient) {
this.lanClient.closeConnection();
}
@@ -157,7 +157,7 @@ class eWeLink {
} else if (cns.devicesZB.includes(device.extra.uiid)) {
this.addAccessory(device, device.deviceid + "SWX", "zb_sub");
} else if (cns.devicesCamera.includes(device.extra.uiid)) {
- this.log.warn("[%s] please consider using homebridge-camera-ffmpeg to use this camera.", device.name);
+ this.log.warn("[%s] please see \"https://github.com/bwp91/homebridge-ewelink/wiki/How-to-set-up-Sonoff-Camera\".", device.name);
return;
} else {
this.log.warn("[%s] cannot be added as it is not supported by this plugin. Please make a GitHub issue request.", device.name);
@@ -172,6 +172,7 @@ class eWeLink {
accessory.getService(Service.AccessoryInformation).setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion);
accessory.context.reachableWAN = accessory.context.eweUIID !== 102 ? device.online : true; //*** DW2 ***\\
accessory.context.reachableLAN = this.lanDevices.get(device.deviceid).online || false;
+ accessory.context.inUse = false;
let str = accessory.context.reachableLAN ?
"and locally with IP [" + this.lanDevices.get(device.deviceid).ip + "]" :
"but LAN mode unavailable as unsupported/shared device";
@@ -439,7 +440,6 @@ class eWeLink {
});
break;
case "garage":
- accessory.context.inUse = false;
accessory.getService(Service.GarageDoorOpener).getCharacteristic(Characteristic.TargetDoorState)
.on("set", (value, callback) => {
accessory.getService(Service.GarageDoorOpener).getCharacteristic(Characteristic.TargetDoorState).value !== value ?
@@ -866,13 +866,16 @@ class eWeLink {
}
internalGarageUpdate(accessory, value, callback) {
try {
- if (accessory.context.inUse) {
- throw "it is currently in use";
- }
- accessory.context.inUse = true;
if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
throw "it is currently offline";
}
+ if (accessory.context.inUse) {
+ let str = "[" + accessory.displayName + "] skipping update as it is currently moving.";
+ this.log.warn(str);
+ callback(str);
+ return;
+ }
+ accessory.context.inUse = true;
let garageConfig;
if (!(garageConfig = this.cusG.get(accessory.context.hbDeviceId))) {
throw "group config missing";
@@ -894,6 +897,7 @@ class eWeLink {
accessory.getService(Service.GarageDoorOpener)
.updateCharacteristic(Characteristic.TargetDoorState, value)
.updateCharacteristic(Characteristic.CurrentDoorState, value);
+ accessory.context.inUse = false;
callback();
return;
}
@@ -941,6 +945,7 @@ class eWeLink {
callback();
}
} catch (err) {
+ accessory.context.inUse = false;
let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
@@ -1403,7 +1408,9 @@ class eWeLink {
externalGarageUpdate(accessory, params) {
try {
if (accessory.context.inUse) {
- throw "it is currently in use";
+ let str = "[" + accessory.displayName + "] skipping update as it is currently moving.";
+ this.log.warn(str);
+ return;
}
accessory.context.inUse = true;
let garageConfig, nSte;
@@ -1416,15 +1423,18 @@ class eWeLink {
switch (garageConfig.setup) {
case "oneSwitch":
if (params.switch === "off" || garageConfig.sensorId) {
+ accessory.context.inUse = false;
return;
}
nSte = [0, 2].includes(accessory.getService(Service.GarageDoorOpener).getCharacteristic(Characteristic.CurrentDoorState).value) ? 3 : 2;
break;
case "twoSwitch":
if (params.switches[0].switch === "off" && params.switches[1].switch === "off") {
+ accessory.context.inUse = false;
return;
}
// @TODO twoSwitch garage external update
+ accessory.context.inUse = false;
return;
}
if (garageConfig.setup !== "oneSwitch" || !garageConfig.sensorId) {
@@ -1438,6 +1448,7 @@ class eWeLink {
}
accessory.context.inUse = false;
} catch (err) {
+ accessory.context.inUse = false;
this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
}
}
From e441e76347db9c8c5d1a48f01ea2561f54b11bce Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Mon, 7 Sep 2020 13:11:31 +0100
Subject: [PATCH 0079/3183] 2.24.4-1
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index d6087665..d082ba02 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.24.4-0",
+ "version": "2.24.4-1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index a9cca3b7..1a370dc4 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.24.4-0",
+ "version": "2.24.4-1",
"author": "bwp91",
"contributors": [
"gbro115",
From 238a32a47a1f6ee73bfdfa1a987feb5157e4787b Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Mon, 7 Sep 2020 18:04:28 +0100
Subject: [PATCH 0080/3183] remove inching setting
---
config.schema.json | 7 -------
1 file changed, 7 deletions(-)
diff --git a/config.schema.json b/config.schema.json
index 9362768b..5d56f513 100644
--- a/config.schema.json
+++ b/config.schema.json
@@ -143,12 +143,6 @@
"description":"Total time in deciseconds to fully open/close the blind/door. Count the time in seconds and multiply by 10, for example 100 for 10 seconds or 75 for 7.5 seconds.",
"default":100
},
- "inched":{
- "title":"Device Inching",
- "type":"boolean",
- "description":"If device inching is already setup in your eWeLink account then set this to true. Otherwise this plugin will send an 'off' command after half a second to mimic the inching behaviour.",
- "default":true
- },
"sensorId":{
"type":"string",
"title":"Sensor",
@@ -274,7 +268,6 @@
"groups[].deviceId",
"groups[].setup",
"groups[].operationTime",
- "groups[].inched",
"groups[].sensorId"
]
}
From a15195d92bacbf8a07dead1a435954578aa02e99 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Mon, 7 Sep 2020 18:04:43 +0100
Subject: [PATCH 0081/3183] consistency in text
---
lib/eWeLinkLAN.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/eWeLinkLAN.js b/lib/eWeLinkLAN.js
index e6db8410..8a2d82d3 100644
--- a/lib/eWeLinkLAN.js
+++ b/lib/eWeLinkLAN.js
@@ -145,9 +145,9 @@ module.exports = class eWeLinkLAN {
};
if (this.debugReqRes) {
let msg = JSON.stringify(json, null, 2).replace(json.apikey, "**hidden**").replace(json.apikey, "**hidden**").replace(json.deviceid, "**hidden**");
- this.log.warn("LAN mode message sent. This text is yellow for clarity.\n%s", msg);
+ this.log.warn("LAN message sent. This text is yellow for clarity.\n%s", msg);
} else if (this.debug) {
- this.log("LAN mode message sent.");
+ this.log("LAN message sent.");
}
axios({
method: "post",
From 3cf55cfca10eb62b817631b9d62601e112b8b926 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Mon, 7 Sep 2020 18:35:30 +0100
Subject: [PATCH 0082/3183] garage door rewrites
---
lib/eWeLink.js | 103 +++++++++++++++----------------------------------
1 file changed, 31 insertions(+), 72 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 298a1ca6..9b149e63 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -810,13 +810,13 @@ class eWeLink {
if (blindConfig.type !== "blind" || !["oneSwitch", "twoSwitch"].includes(blindConfig.setup)) {
throw "improper configuration";
}
- let pSte, params = {};
+ let oldPos, params = {};
value = value >= 50 ? 100 : 0;
- pSte = accessory.getService(Service.WindowCovering).getCharacteristic(Characteristic.PositionState).value;
- if (value === pSte * 100) {
+ oldPos = accessory.getService(Service.WindowCovering).getCharacteristic(Characteristic.PositionState).value;
+ if (value === oldPos * 100) {
accessory.getService(Service.WindowCovering)
.updateCharacteristic(Characteristic.TargetPosition, value)
- .updateCharacteristic(Characteristic.PositionState, pSte);
+ .updateCharacteristic(Characteristic.PositionState, oldPos);
callback();
return;
}
@@ -836,22 +836,6 @@ class eWeLink {
accessory.getService(Service.WindowCovering)
.updateCharacteristic(Characteristic.TargetPosition, value)
.updateCharacteristic(Characteristic.PositionState, (value / 100));
- if (!blindConfig.inched || blindConfig.inched === "false") {
- setTimeout(() => {
- switch (blindConfig.setup) {
- case "oneSwitch":
- params.switch = "off";
- break;
- case "twoSwitch":
- params.switches[0].switch = "off";
- params.switches[1].switch = "off";
- break;
- }
- this.sendDeviceUpdate(accessory, params, function() {
- return;
- });
- }, 500);
- }
setTimeout(() => {
accessory.getService(Service.WindowCovering)
.updateCharacteristic(Characteristic.CurrentPosition, value)
@@ -866,16 +850,10 @@ class eWeLink {
}
internalGarageUpdate(accessory, value, callback) {
try {
+ accessory.context.inUse = true;
if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
throw "it is currently offline";
}
- if (accessory.context.inUse) {
- let str = "[" + accessory.displayName + "] skipping update as it is currently moving.";
- this.log.warn(str);
- callback(str);
- return;
- }
- accessory.context.inUse = true;
let garageConfig;
if (!(garageConfig = this.cusG.get(accessory.context.hbDeviceId))) {
throw "group config missing";
@@ -885,65 +863,45 @@ class eWeLink {
}
let sensorDefinition = garageConfig.sensorId || false,
sAccessory = false,
- pSte,
+ oldPos,
+ newPos = value,
params = {};
if (sensorDefinition && !(sAccessory = this.devicesInHB.get(garageConfig.sensorId + "SWX"))) {
throw "defined sensor doesn't exist";
}
- this.log("[%s] has received request to [%s].", accessory.displayName, value === 0 ? "open" : "close");
- pSte = sAccessory ?
- sAccessory.getService(Service.ContactSensor).getCharacteristic(Characteristic.ContactSensorState).value === 0 ? 1 : 0 : [0, 2].includes(accessory.getService(Service.GarageDoorOpener).getCharacteristic(Characteristic.CurrentDoorState).value) ? 0 : 1;
- if (value === pSte) {
- accessory.getService(Service.GarageDoorOpener)
- .updateCharacteristic(Characteristic.TargetDoorState, value)
- .updateCharacteristic(Characteristic.CurrentDoorState, value);
+ this.log("[%s] has received request to [%s].", accessory.displayName, newPos === 0 ? "open" : "close");
+ oldPos = sAccessory ?
+ sAccessory.getService(Service.ContactSensor).getCharacteristic(Characteristic.ContactSensorState).value === 0 ? 1 : 0 :
+ accessory.getService(Service.GarageDoorOpener).getCharacteristic(Characteristic.CurrentDoorState).value;
+ if (newPos === (oldPos % 2)) {
accessory.context.inUse = false;
callback();
return;
}
+ accessory.getService(Service.GarageDoorOpener)
+ .updateCharacteristic(Characteristic.TargetDoorState, newPos)
+ .updateCharacteristic(Characteristic.CurrentDoorState, newPos + 2);
switch (garageConfig.setup) {
case "oneSwitch":
params.switch = "on";
break;
case "twoSwitch":
params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
- params.switches[0].switch = value === 0 ? "on" : "off";
- params.switches[1].switch = value === 1 ? "on" : "off";
+ params.switches[0].switch = newPos === 0 ? "on" : "off";
+ params.switches[1].switch = newPos === 1 ? "on" : "off";
break;
}
this.sendDeviceUpdate(accessory, params, function() {
return;
});
- accessory.getService(Service.GarageDoorOpener)
- .updateCharacteristic(Characteristic.TargetDoorState, value)
- .updateCharacteristic(Characteristic.CurrentDoorState, value === 0 ? 2 : 3);
- if (!garageConfig.inched || garageConfig.inched === "false") {
- setTimeout(() => {
- switch (garageConfig.setup) {
- case "oneSwitch":
- params.switch = "off";
- break;
- case "twoSwitch":
- params.switches[0].switch = "off";
- params.switches[1].switch = "off";
- break;
- }
- this.sendDeviceUpdate(accessory, params, function() {
- return;
- });
- }, 500);
- }
- if (!sAccessory) {
- setTimeout(() => {
+ setTimeout(() => {
+ if (!sAccessory) {
accessory.getService(Service.GarageDoorOpener)
- .updateCharacteristic(Characteristic.CurrentDoorState, value === 0 ? 0 : 1);
- accessory.context.inUse = false;
- callback();
- }, parseInt(garageConfig.operationTime) * 100);
- } else {
+ .updateCharacteristic(Characteristic.CurrentDoorState, newPos === 0 ? 0 : 1);
+ }
accessory.context.inUse = false;
- callback();
- }
+ }, parseInt(garageConfig.operationTime) * 100);
+ callback();
} catch (err) {
accessory.context.inUse = false;
let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
@@ -1408,12 +1366,14 @@ class eWeLink {
externalGarageUpdate(accessory, params) {
try {
if (accessory.context.inUse) {
- let str = "[" + accessory.displayName + "] skipping update as it is currently moving.";
+ let str = "[" + accessory.displayName + "] ignoring update as it is already moving.";
this.log.warn(str);
return;
}
accessory.context.inUse = true;
- let garageConfig, nSte;
+ let garageConfig,
+ oldPos = accessory.getService(Service.GarageDoorOpener).getCharacteristic(Characteristic.CurrentDoorState).value,
+ newPos = [0, 2].includes(oldPos) ? 3 : 2;
if (!(garageConfig = this.cusG.get(accessory.context.hbDeviceId))) {
throw "group config missing";
}
@@ -1426,7 +1386,6 @@ class eWeLink {
accessory.context.inUse = false;
return;
}
- nSte = [0, 2].includes(accessory.getService(Service.GarageDoorOpener).getCharacteristic(Characteristic.CurrentDoorState).value) ? 3 : 2;
break;
case "twoSwitch":
if (params.switches[0].switch === "off" && params.switches[1].switch === "off") {
@@ -1437,13 +1396,13 @@ class eWeLink {
accessory.context.inUse = false;
return;
}
- if (garageConfig.setup !== "oneSwitch" || !garageConfig.sensorId) {
+ if (!garageConfig.sensorId) {
accessory.getService(Service.GarageDoorOpener)
- .updateCharacteristic(Characteristic.CurrentDoorState, nSte)
- .updateCharacteristic(Characteristic.TargetDoorState, nSte - 2);
+ .updateCharacteristic(Characteristic.CurrentDoorState, newPos)
+ .updateCharacteristic(Characteristic.TargetDoorState, newPos - 2);
setTimeout(() => {
accessory.getService(Service.GarageDoorOpener)
- .updateCharacteristic(Characteristic.CurrentDoorState, nSte - 2);
+ .updateCharacteristic(Characteristic.CurrentDoorState, newPos - 2);
}, parseInt(garageConfig.operationTime) * 100);
}
accessory.context.inUse = false;
From 4e09194256c315b5b84183b0217380a40485c5ad Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Mon, 7 Sep 2020 20:42:12 +0100
Subject: [PATCH 0083/3183] more garage improvements
---
lib/eWeLink.js | 70 ++++++++++++++++++++++++++++----------------------
1 file changed, 40 insertions(+), 30 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 9b149e63..d6462e40 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -851,6 +851,7 @@ class eWeLink {
internalGarageUpdate(accessory, value, callback) {
try {
accessory.context.inUse = true;
+ accessory.context.state = value;
if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
throw "it is currently offline";
}
@@ -865,7 +866,8 @@ class eWeLink {
sAccessory = false,
oldPos,
newPos = value,
- params = {};
+ params = {},
+ wsDelay = 0;
if (sensorDefinition && !(sAccessory = this.devicesInHB.get(garageConfig.sensorId + "SWX"))) {
throw "defined sensor doesn't exist";
}
@@ -878,29 +880,39 @@ class eWeLink {
callback();
return;
}
- accessory.getService(Service.GarageDoorOpener)
- .updateCharacteristic(Characteristic.TargetDoorState, newPos)
- .updateCharacteristic(Characteristic.CurrentDoorState, newPos + 2);
- switch (garageConfig.setup) {
- case "oneSwitch":
- params.switch = "on";
- break;
- case "twoSwitch":
- params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
- params.switches[0].switch = newPos === 0 ? "on" : "off";
- params.switches[1].switch = newPos === 1 ? "on" : "off";
- break;
+ if (garageConfig.setup === "oneSwitch" && [2, 3].includes(oldPos)) {
+ accessory.getService(Service.GarageDoorOpener)
+ .updateCharacteristic(Characteristic.CurrentDoorState, oldPos * 2 % 3 + 2);
+ wsDelay = 1500;
}
- this.sendDeviceUpdate(accessory, params, function() {
- return;
- });
setTimeout(() => {
- if (!sAccessory) {
+ // final check to continue
+ if (accessory.context.state === newPos) {
accessory.getService(Service.GarageDoorOpener)
- .updateCharacteristic(Characteristic.CurrentDoorState, newPos === 0 ? 0 : 1);
+ .updateCharacteristic(Characteristic.TargetDoorState, newPos)
+ .updateCharacteristic(Characteristic.CurrentDoorState, newPos + 2);
+ switch (garageConfig.setup) {
+ case "oneSwitch":
+ params.switch = "on";
+ break;
+ case "twoSwitch":
+ params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
+ params.switches[0].switch = newPos === 0 ? "on" : "off";
+ params.switches[1].switch = newPos === 1 ? "on" : "off";
+ break;
+ }
+ this.sendDeviceUpdate(accessory, params, function() {
+ return;
+ });
+ setTimeout(() => {
+ if (!sAccessory) {
+ accessory.getService(Service.GarageDoorOpener)
+ .updateCharacteristic(Characteristic.CurrentDoorState, newPos === 0 ? 0 : 1);
+ }
+ accessory.context.inUse = false;
+ }, parseInt(garageConfig.operationTime) * 100);
}
- accessory.context.inUse = false;
- }, parseInt(garageConfig.operationTime) * 100);
+ }, wsDelay);
callback();
} catch (err) {
accessory.context.inUse = false;
@@ -1365,12 +1377,6 @@ class eWeLink {
}
externalGarageUpdate(accessory, params) {
try {
- if (accessory.context.inUse) {
- let str = "[" + accessory.displayName + "] ignoring update as it is already moving.";
- this.log.warn(str);
- return;
- }
- accessory.context.inUse = true;
let garageConfig,
oldPos = accessory.getService(Service.GarageDoorOpener).getCharacteristic(Characteristic.CurrentDoorState).value,
newPos = [0, 2].includes(oldPos) ? 3 : 2;
@@ -1383,19 +1389,20 @@ class eWeLink {
switch (garageConfig.setup) {
case "oneSwitch":
if (params.switch === "off" || garageConfig.sensorId) {
- accessory.context.inUse = false;
return;
}
break;
case "twoSwitch":
if (params.switches[0].switch === "off" && params.switches[1].switch === "off") {
- accessory.context.inUse = false;
return;
}
// @TODO twoSwitch garage external update
- accessory.context.inUse = false;
return;
}
+ if (accessory.context.inUse) {
+ return;
+ }
+ accessory.context.inUse = true;
if (!garageConfig.sensorId) {
accessory.getService(Service.GarageDoorOpener)
.updateCharacteristic(Characteristic.CurrentDoorState, newPos)
@@ -1405,7 +1412,10 @@ class eWeLink {
.updateCharacteristic(Characteristic.CurrentDoorState, newPos - 2);
}, parseInt(garageConfig.operationTime) * 100);
}
- accessory.context.inUse = false;
+ setTimeout(() => {
+ accessory.context.inUse = false;
+ }, parseInt(garageConfig.operationTime) * 100);
+
} catch (err) {
accessory.context.inUse = false;
this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
From 726b759357dd8a9724aed4ae1a87aed7f23fd356 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Mon, 7 Sep 2020 20:43:11 +0100
Subject: [PATCH 0084/3183] 2.25.0-0
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index d082ba02..6b2b69da 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.24.4-1",
+ "version": "2.25.0-0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 1a370dc4..fa68bb8d 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.24.4-1",
+ "version": "2.25.0-0",
"author": "bwp91",
"contributors": [
"gbro115",
From df03e5f2309350239d014f178e0377f9846648d2 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Mon, 7 Sep 2020 21:37:45 +0100
Subject: [PATCH 0085/3183] initial lock support
---
config.schema.json | 8 ++++-
lib/eWeLink.js | 83 +++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 82 insertions(+), 9 deletions(-)
diff --git a/config.schema.json b/config.schema.json
index 5d56f513..65074d0d 100644
--- a/config.schema.json
+++ b/config.schema.json
@@ -88,7 +88,7 @@
"groups":{
"type":"array",
"title":"Custom Groups",
- "description":"You can group channels of Sonoff devices to simulate another HomeKit accessory instead of having each switch separately. Currently only blinds and garage doors are supported.",
+ "description":"You can group channels of Sonoff devices to simulate another HomeKit accessory instead of having each switch separately. Currently only blinds, garage doors and locks are supported.",
"items":{
"type":"object",
"properties":{
@@ -109,6 +109,12 @@
"enum":[
"garage"
]
+ },
+ {
+ "title":"Lock",
+ "enum":[
+ "lock"
+ ]
}
]
},
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index d6462e40..87220176 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -123,6 +123,8 @@ class eWeLink {
this.addAccessory(device, device.deviceid + "SWX", "blind");
} else if (this.cusG.has(device.deviceid + "SWX") && this.cusG.get(device.deviceid + "SWX").type === "garage") {
this.addAccessory(device, device.deviceid + "SWX", "garage");
+ } else if (this.cusG.has(device.deviceid + "SWX") && this.cusG.get(device.deviceid + "SWX").type === "lock") {
+ this.addAccessory(device, device.deviceid + "SWX", "lock");
} else if (cns.devicesSensor.includes(device.extra.uiid)) {
this.addAccessory(device, device.deviceid + "SWX", "sensor");
} else if (cns.devicesFan.includes(device.extra.uiid)) {
@@ -277,6 +279,11 @@ class eWeLink {
.setCharacteristic(Characteristic.TargetDoorState, 1)
.setCharacteristic(Characteristic.ObstructionDetected, false);
break;
+ case "lock":
+ accessory.addService(Service.LockMechanism)
+ .setCharacteristic(Characteristic.LockCurrentState, 1)
+ .setCharacteristic(Characteristic.LockTargetState, 1);
+ break;
case "sensor":
accessory.addService(Service.ContactSensor);
break;
@@ -447,6 +454,14 @@ class eWeLink {
callback();
});
break;
+ case "lock":
+ accessory.getService(Service.LockMechanism).getCharacteristic(Characteristic.LockTargetState)
+ .on("set", (value, callback) => {
+ accessory.getService(Service.LockMechanism).getCharacteristic(Characteristic.LockTargetState).value !== value ?
+ this.internalLockUpdate(accessory, value, callback) :
+ callback();
+ });
+ break;
case "fan":
accessory.getService(Service.Fanv2).getCharacteristic(Characteristic.Active)
.on("set", (value, callback) => {
@@ -603,6 +618,11 @@ class eWeLink {
this.externalGarageUpdate(accessory, newParams);
}
return true;
+ case "lock":
+ if (newParams.hasOwnProperty("switch")) {
+ this.externalLockUpdate(accessory, newParams);
+ }
+ return true;
case "sensor":
if (newParams.hasOwnProperty("switch")) {
this.externalSensorUpdate(accessory, newParams);
@@ -850,8 +870,6 @@ class eWeLink {
}
internalGarageUpdate(accessory, value, callback) {
try {
- accessory.context.inUse = true;
- accessory.context.state = value;
if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
throw "it is currently offline";
}
@@ -862,6 +880,8 @@ class eWeLink {
if (garageConfig.type !== "garage" || !["oneSwitch", "twoSwitch"].includes(garageConfig.setup)) {
throw "improper configuration";
}
+ accessory.context.inUse = true;
+ accessory.context.state = value;
let sensorDefinition = garageConfig.sensorId || false,
sAccessory = false,
oldPos,
@@ -921,6 +941,36 @@ class eWeLink {
callback(str);
}
}
+ internalLockUpdate(accessory, value, callback) {
+ try {
+ if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
+ throw "it is currently offline";
+ }
+ let lockConfig;
+ if (!(lockConfig = this.cusG.get(accessory.context.hbDeviceId))) {
+ throw "group config missing";
+ }
+ if (lockConfig.type !== "lock") {
+ throw "improper configuration";
+ }
+ accessory.context.inUse = true;
+ let params = {};
+ this.log("[%s] has received request to [%s].", accessory.displayName, value === 0 ? "unlock" : "lock");
+ accessory.getService(Service.LockMechanism)
+ .updateCharacteristic(Characteristic.LockTargetState, value);
+ params.switch = "on";
+ this.sendDeviceUpdate(accessory, params, callback);
+ setTimeout(() => {
+ accessory.context.inUse = false;
+ accessory.getService(Service.LockMechanism)
+ .updateCharacteristic(Characteristic.LockCurrentState, value);
+ }, 3000);
+ } catch (err) {
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ this.log.error(str);
+ callback(str);
+ }
+ }
internalFanUpdate(accessory, type, value, callback) {
try {
if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
@@ -1388,20 +1438,17 @@ class eWeLink {
}
switch (garageConfig.setup) {
case "oneSwitch":
- if (params.switch === "off" || garageConfig.sensorId) {
+ if (params.switch === "off" || garageConfig.sensorId || accessory.context.inUse) {
return;
}
break;
case "twoSwitch":
- if (params.switches[0].switch === "off" && params.switches[1].switch === "off") {
+ if ((params.switches[0].switch === "off" && params.switches[1].switch === "off") || accessory.context.inUse) {
return;
}
// @TODO twoSwitch garage external update
return;
}
- if (accessory.context.inUse) {
- return;
- }
accessory.context.inUse = true;
if (!garageConfig.sensorId) {
accessory.getService(Service.GarageDoorOpener)
@@ -1415,12 +1462,32 @@ class eWeLink {
setTimeout(() => {
accessory.context.inUse = false;
}, parseInt(garageConfig.operationTime) * 100);
-
} catch (err) {
accessory.context.inUse = false;
this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
}
}
+ externalLockUpdate(accessory, params) {
+ try {
+ let lockConfig,
+ oldPos = accessory.getService(Service.LockMechanism).getCharacteristic(Characteristic.LockCurrentState).value,
+ newPos = oldPos === 0 ? 1 : 0;
+ if (!(lockConfig = this.cusG.get(accessory.context.hbDeviceId))) {
+ throw "group config missing";
+ }
+ if (lockConfig.type !== "lock") {
+ throw "improper configuration";
+ }
+ if (params.switch === "off" || accessory.context.inUse) {
+ return;
+ }
+ accessory.getService(Service.LockMechanism)
+ .updateCharacteristic(Characteristic.LockCurrentState, newPos)
+ .updateCharacteristic(Characteristic.LockTargetState, newPos);
+ } catch (err) {
+ this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
+ }
+ }
externalSensorUpdate(accessory, params) {
try {
let oldState = accessory.getService(Service.ContactSensor).getCharacteristic(Characteristic.ContactSensorState).value,
From b51e09f7e0772851d888074f5c9963007eee86a6 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Mon, 7 Sep 2020 21:38:23 +0100
Subject: [PATCH 0086/3183] 2.25.0-1
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 6b2b69da..f64d553a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.25.0-0",
+ "version": "2.25.0-1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index fa68bb8d..1cdcd8e8 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.25.0-0",
+ "version": "2.25.0-1",
"author": "bwp91",
"contributors": [
"gbro115",
From c6cef109b8ff8b25c27702f52a4bdb6aeda5ee57 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Mon, 7 Sep 2020 22:59:01 +0100
Subject: [PATCH 0087/3183] changes to lock
---
lib/eWeLink.js | 39 +++++++++++++++++++++------------------
1 file changed, 21 insertions(+), 18 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 87220176..f97540fd 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -456,11 +456,7 @@ class eWeLink {
break;
case "lock":
accessory.getService(Service.LockMechanism).getCharacteristic(Characteristic.LockTargetState)
- .on("set", (value, callback) => {
- accessory.getService(Service.LockMechanism).getCharacteristic(Characteristic.LockTargetState).value !== value ?
- this.internalLockUpdate(accessory, value, callback) :
- callback();
- });
+ .on("set", (value, callback) => this.internalLockUpdate(accessory, value, callback));
break;
case "fan":
accessory.getService(Service.Fanv2).getCharacteristic(Characteristic.Active)
@@ -906,7 +902,6 @@ class eWeLink {
wsDelay = 1500;
}
setTimeout(() => {
- // final check to continue
if (accessory.context.state === newPos) {
accessory.getService(Service.GarageDoorOpener)
.updateCharacteristic(Characteristic.TargetDoorState, newPos)
@@ -946,7 +941,7 @@ class eWeLink {
if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
throw "it is currently offline";
}
- let lockConfig;
+ let lockConfig, params = {};
if (!(lockConfig = this.cusG.get(accessory.context.hbDeviceId))) {
throw "group config missing";
}
@@ -954,18 +949,20 @@ class eWeLink {
throw "improper configuration";
}
accessory.context.inUse = true;
- let params = {};
- this.log("[%s] has received request to [%s].", accessory.displayName, value === 0 ? "unlock" : "lock");
+ this.log("[%s] has received request to unlock.", accessory.displayName);
accessory.getService(Service.LockMechanism)
- .updateCharacteristic(Characteristic.LockTargetState, value);
+ .updateCharacteristic(Characteristic.LockTargetState, 0)
+ .updateCharacteristic(Characteristic.LockCurrentState, 0);
params.switch = "on";
this.sendDeviceUpdate(accessory, params, callback);
setTimeout(() => {
- accessory.context.inUse = false;
accessory.getService(Service.LockMechanism)
- .updateCharacteristic(Characteristic.LockCurrentState, value);
- }, 3000);
+ .updateCharacteristic(Characteristic.LockTargetState, 1)
+ .updateCharacteristic(Characteristic.LockCurrentState, 1);
+ accessory.context.inUse = false;
+ }, parseInt(lockConfig.operationTime) * 100);
} catch (err) {
+ accessory.context.inUse = false;
let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
@@ -1469,9 +1466,7 @@ class eWeLink {
}
externalLockUpdate(accessory, params) {
try {
- let lockConfig,
- oldPos = accessory.getService(Service.LockMechanism).getCharacteristic(Characteristic.LockCurrentState).value,
- newPos = oldPos === 0 ? 1 : 0;
+ let lockConfig;
if (!(lockConfig = this.cusG.get(accessory.context.hbDeviceId))) {
throw "group config missing";
}
@@ -1481,10 +1476,18 @@ class eWeLink {
if (params.switch === "off" || accessory.context.inUse) {
return;
}
+ accessory.context.inUse = true;
accessory.getService(Service.LockMechanism)
- .updateCharacteristic(Characteristic.LockCurrentState, newPos)
- .updateCharacteristic(Characteristic.LockTargetState, newPos);
+ .updateCharacteristic(Characteristic.LockCurrentState, 0)
+ .updateCharacteristic(Characteristic.LockTargetState, 0);
+ setTimeout(() => {
+ accessory.getService(Service.LockMechanism)
+ .updateCharacteristic(Characteristic.LockCurrentState, 1)
+ .updateCharacteristic(Characteristic.LockTargetState, 1);
+ accessory.context.inUse = false;
+ }, parseInt(lockConfig.operationTime) * 100);
} catch (err) {
+ accessory.context.inUse = false;
this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
}
}
From 9d3d76428c3029be135da751211019e0e4f7ca69 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Mon, 7 Sep 2020 23:20:56 +0100
Subject: [PATCH 0088/3183] #82 fix?
---
lib/eWeLink.js | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index f97540fd..ded8ce26 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -729,9 +729,9 @@ class eWeLink {
case "sysmsg":
if ((accessory = this.devicesInHB.get(device.deviceid + "SWX") || this.devicesInHB.get(device.deviceid + "SW0"))) {
let isX = accessory.context.hbDeviceId.substr(-1) === "X";
- if (source === "ws" && accessory.context.reachableWAN !== device.params.online) {
+ if (source === "WS" && accessory.context.reachableWAN !== device.params.online) {
accessory.context.reachableWAN = device.params.online;
- this.log("[%s] has been reported [%s].", accessory.displayName, accessory.context.reachableWAN ? "online" : "offline");
+ this.log("[%s] has been reported [%s] via [WS].", accessory.displayName, accessory.context.reachableWAN ? "online" : "offline");
this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
if (accessory.context.reachableWAN) {
this.wsClient.requestUpdate(accessory);
@@ -750,11 +750,13 @@ class eWeLink {
break;
case "update":
if ((accessory = this.devicesInHB.get(device.deviceid + "SWX") || this.devicesInHB.get(device.deviceid + "SW0"))) {
- if (source === "ws" && !accessory.context.reachableWAN) {
+ if (source === "WS" && !accessory.context.reachableWAN) {
accessory.context.reachableWAN = true;
+ this.log("[%s] has been reported [online] via [WS].", accessory.displayName);
}
- if (source === "lan" && !accessory.context.reachableLAN) {
+ if (source === "LAN" && !accessory.context.reachableLAN) {
accessory.context.reachableLAN = true;
+ this.log("[%s] has been reported [online] via [LAN].", accessory.displayName);
}
if (this.config.debug) {
this.log("[%s] externally updated from above %s message and will be refreshed.", accessory.displayName, source);
From bb784067f196c39742a584e1ac45efc3101b5b16 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Mon, 7 Sep 2020 23:22:48 +0100
Subject: [PATCH 0089/3183] 2.25.0-2
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index f64d553a..13f0eb35 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.25.0-1",
+ "version": "2.25.0-2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 1cdcd8e8..bbe0307b 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.25.0-1",
+ "version": "2.25.0-2",
"author": "bwp91",
"contributors": [
"gbro115",
From 6d52c26eba25b8109071eeaa04f45c3299931d1b Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 8 Sep 2020 07:42:23 +0100
Subject: [PATCH 0090/3183] log text consistency
---
lib/eWeLinkWS.js | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/lib/eWeLinkWS.js b/lib/eWeLinkWS.js
index 73180031..eb50d15e 100644
--- a/lib/eWeLinkWS.js
+++ b/lib/eWeLinkWS.js
@@ -203,7 +203,9 @@ module.exports = class eWeLinkWS {
this.ws.send(req);
if (this.debugReqRes) {
let msg = JSON.stringify(json, null, 2).replace(json.apikey, "**hidden**").replace(json.apiKey, "**hidden**").replace(json.deviceid, "**hidden**");
- this.log.warn("Web socket message sent. This text is yellow for clarity.\n%s", msg);
+ this.log.warn("WS message sent. This text is yellow for clarity.\n%s", msg);
+ } else if (this.debug) {
+ this.log("WS message sent.");
}
return;
}
@@ -246,7 +248,9 @@ module.exports = class eWeLinkWS {
this.ws.send(req);
if (this.debugReqRes) {
let msg = JSON.stringify(json, null, 2).replace(json.apikey, "**hidden**").replace(json.apiKey, "**hidden**").replace(json.deviceid, "**hidden**");
- this.log.warn("Web socket message sent. This text is yellow for clarity.\n%s", msg);
+ this.log.warn("WS message sent. This text is yellow for clarity.\n%s", msg);
+ } else if (this.debug) {
+ this.log("WS message sent.");
}
return;
}
From 6e33f28e984285066abb5cda76b3dc0a0eb764b4 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 8 Sep 2020 07:50:46 +0100
Subject: [PATCH 0091/3183] rename groups to custom types
---
config.schema.json | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/config.schema.json b/config.schema.json
index 65074d0d..4175f7cb 100644
--- a/config.schema.json
+++ b/config.schema.json
@@ -87,16 +87,21 @@
},
"groups":{
"type":"array",
- "title":"Custom Groups",
- "description":"You can group channels of Sonoff devices to simulate another HomeKit accessory instead of having each switch separately. Currently only blinds, garage doors and locks are supported.",
+ "title":"Custom Device Types",
+ "description":"You can use this setting to set up custom device types within Homebridge. Currently only blinds, garage doors and locks are supported.",
"items":{
"type":"object",
"properties":{
+ "deviceId":{
+ "type":"string",
+ "title":"Device ID",
+ "description":"Device ID from your eWeLink app (ten digits normally in the format 1000******)."
+ },
"type":{
"type":"string",
"title":"Type",
"default":"null",
- "description":"A description of this group.",
+ "description":"The new type for this device.",
"oneOf":[
{
"title":"Blind",
@@ -118,16 +123,11 @@
}
]
},
- "deviceId":{
- "type":"string",
- "title":"Device ID",
- "description":"Device ID from your eWeLink app (ten digits normally in the format 1000******)."
- },
"setup":{
"type":"string",
"title":"Device Setup",
"default":"null",
- "description":"The device setup.",
+ "description":"The device setup. Please ignore this setting for locks",
"oneOf":[
{
"title":"One Switch - for up and down",
@@ -146,13 +146,13 @@
"operationTime":{
"type":"number",
"title":"Operation Time",
- "description":"Total time in deciseconds to fully open/close the blind/door. Count the time in seconds and multiply by 10, for example 100 for 10 seconds or 75 for 7.5 seconds.",
+ "description":"For blinds and garage doors this is the total time in deciseconds to fully open/close the device. For locks this is the time to show the Home app tile as unlocked. Count the time in seconds and multiply by 10, for example 100 for 10 seconds or 75 for 7.5 seconds.",
"default":100
},
"sensorId":{
"type":"string",
"title":"Sensor",
- "description":"A Sonoff DW2 sensor can be used for a 'one switch' setup. This is to determine the current open/closed state of this device. Please enter the 10 digit device ID. Otherwise leave this blank."
+ "description":"A Sonoff DW2 sensor can optionally be used for blinds and garage doors. This is to determine the current open/closed state of the device. Please enter the 10 digit device ID. Otherwise leave this blank."
}
}
}
@@ -263,15 +263,15 @@
{
"key":"groups",
"expandable":true,
- "title":"Custom Groups",
- "add":"Add Another Group",
+ "title":"Custom Device Types",
+ "add":"Add Another Type",
"type":"array",
"items":[
{
"type":"fieldset",
"items":[
- "groups[].type",
"groups[].deviceId",
+ "groups[].type",
"groups[].setup",
"groups[].operationTime",
"groups[].sensorId"
From fa43686eecfc88e8250778a2fd33898cb489e18c Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 8 Sep 2020 09:16:03 +0100
Subject: [PATCH 0092/3183] add updateSource to params
---
lib/constants.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/constants.js b/lib/constants.js
index 1a11a419..354c4736 100644
--- a/lib/constants.js
+++ b/lib/constants.js
@@ -20,7 +20,7 @@ module.exports = {
devicesRFBridge: [28],
devicesZBBridge: [66],
devicesZB: [1000, 1770, 2026, 3026],
- paramsToKeep: ["bright", "brightness", "channel", "cmd", "colorB", "colorG", "colorR", "currentHumidity", "currentTemperature", "fan", "humidity", "key", "light", "lock", "mainSwitch", "mode", "online", "rfChl", "rfList", "rfTrig", "sensorType", "speed", "state", "switch", "switches", "temperature", "type", "zyx_mode"],
+ paramsToKeep: ["bright", "brightness", "channel", "cmd", "colorB", "colorG", "colorR", "currentHumidity", "currentTemperature", "fan", "humidity", "key", "light", "lock", "mainSwitch", "mode", "online", "rfChl", "rfList", "rfTrig", "sensorType", "speed", "state", "switch", "switches", "temperature", "type", "updateSource", "zyx_mode"],
chansFromUiid: {
1: 1, // "SOCKET" \\ 20, MINI, BASIC, S26
2: 2, // "SOCKET_2" \\
From 16c22a26fd5b15fb27b78266a0354d60bcba4c60 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 8 Sep 2020 09:16:22 +0100
Subject: [PATCH 0093/3183] updateSource changes
---
lib/eWeLinkLAN.js | 2 +-
lib/eWeLinkWS.js | 14 ++++++--------
2 files changed, 7 insertions(+), 9 deletions(-)
diff --git a/lib/eWeLinkLAN.js b/lib/eWeLinkLAN.js
index 8a2d82d3..89e1a337 100644
--- a/lib/eWeLinkLAN.js
+++ b/lib/eWeLinkLAN.js
@@ -90,7 +90,7 @@ module.exports = class eWeLinkLAN {
}
}
}
- params.updateSource = "lan";
+ params.updateSource = "LAN";
if (Object.keys(params).length > 0) {
let returnTemplate = {
deviceid: rdata.id,
diff --git a/lib/eWeLinkWS.js b/lib/eWeLinkWS.js
index eb50d15e..8afe3926 100644
--- a/lib/eWeLinkWS.js
+++ b/lib/eWeLinkWS.js
@@ -96,9 +96,9 @@ module.exports = class eWeLinkWS {
this.ws.send("ping");
}, (device.config.hbInterval + 7) * 1000);
} else if (device.hasOwnProperty("action")) {
+ device.params.updateSource = "WS";
switch (device.action) {
case "sysmsg":
- device.params.updateSource = "ws";
let returnTemplate = {
deviceid: device.deviceid,
action: "sysmsg",
@@ -113,20 +113,18 @@ module.exports = class eWeLinkWS {
this.emitter.emit("update", returnTemplate);
break;
case "update":
- let params = device.params;
- for (let param in params) {
- if (params.hasOwnProperty(param)) {
+ for (let param in device.params) {
+ if (device.params.hasOwnProperty(param)) {
if (!constants.paramsToKeep.includes(param.replace(/[0-9]/g, ""))) {
- delete params[param];
+ delete device.params[param];
}
}
}
- if (Object.keys(params).length > 0) {
- params.updateSource = "ws";
+ if (Object.keys(device.params).length > 0) {
let returnTemplate = {
deviceid: device.deviceid,
action: "update",
- params
+ params: device.params
};
if (this.debugReqRes) {
let msg = JSON.stringify(returnTemplate, null, 2).replace(device.deviceid, "**hidden**");
From b7b5947d7fbff9f692106db8c4a37ae912ea2107 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 8 Sep 2020 10:34:49 +0100
Subject: [PATCH 0094/3183] updates
---
lib/constants.js | 3 +-
lib/eWeLink.js | 322 ++++++++++++++++++----------------------------
lib/eWeLinkLAN.js | 2 +-
lib/eWeLinkWS.js | 3 +-
4 files changed, 129 insertions(+), 201 deletions(-)
diff --git a/lib/constants.js b/lib/constants.js
index 354c4736..534514f0 100644
--- a/lib/constants.js
+++ b/lib/constants.js
@@ -20,7 +20,8 @@ module.exports = {
devicesRFBridge: [28],
devicesZBBridge: [66],
devicesZB: [1000, 1770, 2026, 3026],
- paramsToKeep: ["bright", "brightness", "channel", "cmd", "colorB", "colorG", "colorR", "currentHumidity", "currentTemperature", "fan", "humidity", "key", "light", "lock", "mainSwitch", "mode", "online", "rfChl", "rfList", "rfTrig", "sensorType", "speed", "state", "switch", "switches", "temperature", "type", "updateSource", "zyx_mode"],
+ allowedGroups: ["blind", "garage", "lock"],
+ paramsToKeep: ["bright", "brightness", "channel", "cmd", "colorB", "colorG", "colorR", "currentHumidity", "currentTemperature", "fan", "humidity", "key", "light", "lock", "mainSwitch", "mode", "online", "rfChl", "rfList", "rfTrig", "sensorType", "speed", "state", "switch", "switches", "temperature", "type", "zyx_mode"],
chansFromUiid: {
1: 1, // "SOCKET" \\ 20, MINI, BASIC, S26
2: 2, // "SOCKET_2" \\
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index ded8ce26..ddf238bb 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -37,6 +37,8 @@ class eWeLink {
return this.httpClient.getDevices();
}).then(res => { //*** Get device IP addresses for LAN mode ***\\
this.httpDevices = res
+ .filter(device => device.hasOwnProperty("extra"))
+ .filter(device => device.extra.hasOwnProperty("uiid"))
.filter(device => !(this.config.hideDevFromHB || "").includes(device.deviceid))
.forEach(device => this.devicesInEwe.set(device.deviceid, device));
this.httpDevices = res;
@@ -59,6 +61,7 @@ class eWeLink {
if (Object.keys(this.config.groups || []).length > 0) {
this.config.groups
.filter(g => g.hasOwnProperty("deviceId") && this.devicesInEwe.has(g.deviceId.toLowerCase()))
+ .filter(g => g.hasOwnProperty("type") && cns.allowedGroups.includes(g.type))
.forEach(g => this.cusG.set(g.deviceId + "SWX", g));
}
//*** Make a map of RF Bridge custom sensors from Homebridge config ***\\
@@ -106,15 +109,8 @@ class eWeLink {
});
}
initialiseDevice(device) {
- if (!device.hasOwnProperty("extra") || !device.extra.hasOwnProperty("uiid")) {
- let deviceName = device.hasOwnProperty("name") ?
- device.name :
- device.hasOwnProperty("deviceid") ? device.deviceid : "Unknown Device";
- this.log.warn("[%s] could not be synchronised due to missing uiid parameter.", deviceName);
- return;
- }
let accessory;
- device.params.updateSource = "http";
+ device.params.updateSource = "HTTP";
//*** First add the device if it isn't already in Homebridge. Yeah this code looks a mess :| ***\\
if (!this.devicesInHB.has(device.deviceid + "SWX") && !this.devicesInHB.has(device.deviceid + "SW0")) {
if (device.extra.uiid === 2 && device.brandName === "coolkit" && device.productModel === "0285") {
@@ -231,7 +227,7 @@ class eWeLink {
if (["1", "2", "3", "4"].includes(switchNumber) && type !== "rf_sub") {
newDeviceName += " SW" + switchNumber;
if ((this.config.hideFromHB || "").includes(hbDeviceId) && cns.devicesHideable.includes(type)) {
- this.log.warn("[%s] has not been added as per configuration", newDeviceName);
+ this.log.warn("[%s] will not be added as per configuration.", newDeviceName);
return;
}
}
@@ -440,19 +436,11 @@ class eWeLink {
.setProps({
minStep: 100
})
- .on("set", (value, callback) => {
- accessory.getService(Service.WindowCovering).getCharacteristic(Characteristic.TargetPosition).value !== value ?
- this.internalBlindUpdate(accessory, value, callback) :
- callback();
- });
+ .on("set", (value, callback) => this.internalBlindUpdate(accessory, value, callback));
break;
case "garage":
accessory.getService(Service.GarageDoorOpener).getCharacteristic(Characteristic.TargetDoorState)
- .on("set", (value, callback) => {
- accessory.getService(Service.GarageDoorOpener).getCharacteristic(Characteristic.TargetDoorState).value !== value ?
- this.internalGarageUpdate(accessory, value, callback) :
- callback();
- });
+ .on("set", (value, callback) => this.internalGarageUpdate(accessory, value, callback));
break;
case "lock":
accessory.getService(Service.LockMechanism).getCharacteristic(Characteristic.LockTargetState)
@@ -460,82 +448,48 @@ class eWeLink {
break;
case "fan":
accessory.getService(Service.Fanv2).getCharacteristic(Characteristic.Active)
- .on("set", (value, callback) => {
- accessory.getService(Service.Fanv2).getCharacteristic(Characteristic.Active).value !== value ?
- this.internalFanUpdate(accessory, "power", value, callback) :
- callback();
- });
+ .on("set", (value, callback) => this.internalFanUpdate(accessory, "power", value, callback));
accessory.getService(Service.Fanv2).getCharacteristic(Characteristic.RotationSpeed)
.setProps({
minStep: 33
})
- .on("set", (value, callback) => {
- accessory.getService(Service.Fanv2).getCharacteristic(Characteristic.RotationSpeed).value !== value ?
- this.internalFanUpdate(accessory, "speed", value, callback) :
- callback();
- });
+ .on("set", (value, callback) => this.internalFanUpdate(accessory, "speed", value, callback));
accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => {
- accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value !== value ?
- this.internalFanUpdate(accessory, "light", value, callback) :
- callback();
- });
+ .on("set", (value, callback) => this.internalFanUpdate(accessory, "light", value, callback));
break;
case "thermostat":
if (!this.config.hideTHSwitch) {
accessory.getService(Service.Switch).getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => {
- accessory.getService(Service.Switch).getCharacteristic(Characteristic.On).value !== value ?
- this.internalThermostatUpdate(accessory, value, callback) :
- callback();
- });
+ .on("set", (value, callback) => this.internalThermostatUpdate(accessory, value, callback));
}
break;
case "outlet":
accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => {
- accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On).value !== value ?
- this.internalOutletUpdate(accessory, value, callback) :
- callback();
- });
+ .on("set", (value, callback) => this.internalOutletUpdate(accessory, value, callback));
break;
case "usb":
accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => {
- accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On).value !== value ?
- this.internalUSBUpdate(accessory, value, callback) :
- callback();
- });
+ .on("set", (value, callback) => this.internalUSBUpdate(accessory, value, callback));
break;
case "scm":
accessory.getService(Service.Switch).getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => {
- accessory.getService(Service.Switch).getCharacteristic(Characteristic.On).value !== value ?
- this.internalSCMUpdate(accessory, value, callback) :
- callback();
- });
+ .on("set", (value, callback) => this.internalSCMUpdate(accessory, value, callback));
break;
case "light":
accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => {
- accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value !== value ?
- this.internalLightbulbUpdate(accessory, value, callback) :
- callback();
- });
+ .on("set", (value, callback) => this.internalLightbulbUpdate(accessory, value, callback));
if (cns.devicesBrightable.includes(accessory.context.eweUIID)) {
accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Brightness)
.on("set", (value, callback) => {
if (value > 0) {
if (!accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value) {
- this.internalLightbulbUpdate(accessory, true, callback);
+ this.internalLightbulbUpdate(accessory, true, function() {
+ return;
+ });
}
- accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Brightness).value !== value ?
- this.internalBrightnessUpdate(accessory, value, callback) :
- callback();
+ this.internalBrightnessUpdate(accessory, value, callback);
} else {
- accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value ?
- this.internalLightbulbUpdate(accessory, false, callback) :
- callback();
+ this.internalLightbulbUpdate(accessory, false, callback);
}
});
} else if (cns.devicesColourable.includes(accessory.context.eweUIID)) {
@@ -543,37 +497,24 @@ class eWeLink {
.on("set", (value, callback) => {
if (value > 0) {
if (!accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value) {
- this.internalLightbulbUpdate(accessory, true, callback);
+ this.internalLightbulbUpdate(accessory, true, function() {
+ return;
+ });
}
- accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Brightness).value !== value ?
- this.internalHSBUpdate(accessory, "bri", value, callback) :
- callback();
+ this.internalHSBUpdate(accessory, "bri", value, callback);
} else {
- accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value ?
- this.internalLightbulbUpdate(accessory, false, callback) :
- callback();
+ this.internalLightbulbUpdate(accessory, false, callback);
}
});
accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Hue)
- .on("set", (value, callback) => {
- accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Hue).value !== value ?
- this.internalHSBUpdate(accessory, "hue", value, callback) :
- callback();
- });
+ .on("set", (value, callback) => this.internalHSBUpdate(accessory, "hue", value, callback));
accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Saturation)
- .on("set", (value, callback) => {
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Saturation, value);
- callback();
- });
+ .on("set", (value, callback) => callback());
}
break;
case "switch":
accessory.getService(Service.Switch).getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => {
- accessory.getService(Service.Switch).getCharacteristic(Characteristic.On).value !== value ?
- this.internalSwitchUpdate(accessory, value, callback) :
- callback();
- });
+ .on("set", (value, callback) => this.internalSwitchUpdate(accessory, value, callback));
break;
case "rf_sub":
accessory.context.rfChls = accessory.context.rfChls || {};
@@ -582,9 +523,7 @@ class eWeLink {
accessory.getService(v).updateCharacteristic(Characteristic.On, false);
accessory.getService(v).getCharacteristic(Characteristic.On)
.on("set", (value, callback) => {
- value ?
- this.internalRFDeviceUpdate(accessory, k, callback) :
- callback();
+ value ? this.internalRFDeviceUpdate(accessory, k, callback) : callback();
});
});
}
@@ -708,13 +647,11 @@ class eWeLink {
callback("Device has failed to update");
}
};
- if (cns.devicesNonLAN.includes(accessory.context.eweUIID) || !this.lanDevices.get(accessory.context.eweDeviceId).online) {
+ if (cns.devicesNonLAN.includes(accessory.context.eweUIID) || !accessory.context.reachableLAN) {
sendViaWS();
} else {
this.lanClient.sendUpdate(payload)
- .then(res => {
- callback();
- })
+ .then(res => callback())
.catch(err => {
if (this.config.debug) {
this.log.warn("[%s] Reverting to web socket as %s.", accessory.displayName, err);
@@ -724,12 +661,12 @@ class eWeLink {
}
}
receiveDeviceUpdate(device) {
- let accessory, source = device.params.updateSource === "ws" ? "WS" : "LAN";
+ let accessory;
switch (device.action) {
case "sysmsg":
if ((accessory = this.devicesInHB.get(device.deviceid + "SWX") || this.devicesInHB.get(device.deviceid + "SW0"))) {
let isX = accessory.context.hbDeviceId.substr(-1) === "X";
- if (source === "WS" && accessory.context.reachableWAN !== device.params.online) {
+ if (device.params.updateSource === "WS" && accessory.context.reachableWAN !== device.params.online) {
accessory.context.reachableWAN = device.params.online;
this.log("[%s] has been reported [%s] via [WS].", accessory.displayName, accessory.context.reachableWAN ? "online" : "offline");
this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
@@ -750,23 +687,23 @@ class eWeLink {
break;
case "update":
if ((accessory = this.devicesInHB.get(device.deviceid + "SWX") || this.devicesInHB.get(device.deviceid + "SW0"))) {
- if (source === "WS" && !accessory.context.reachableWAN) {
+ if (device.params.updateSource === "WS" && !accessory.context.reachableWAN) {
accessory.context.reachableWAN = true;
this.log("[%s] has been reported [online] via [WS].", accessory.displayName);
}
- if (source === "LAN" && !accessory.context.reachableLAN) {
+ if (device.params.updateSource === "LAN" && !accessory.context.reachableLAN) {
accessory.context.reachableLAN = true;
this.log("[%s] has been reported [online] via [LAN].", accessory.displayName);
}
if (this.config.debug) {
- this.log("[%s] externally updated from above %s message and will be refreshed.", accessory.displayName, source);
+ this.log("[%s] externally updated from above %s message and will be refreshed.", accessory.displayName, device.params.updateSource);
}
if (!this.refreshAccessory(accessory, device.params)) {
this.log.warn("[%s] cannot be refreshed. Please try removing accessory from the Homebridge cache along with any secondary devices (SW1, SW2, etc.). [debug:%s:%s]", accessory.displayName, accessory.context.type, accessory.context.channelCount);
}
} else {
if (!(this.config.hideDevFromHB || "").includes(device.deviceid)) {
- this.log.warn("[%s] Accessory received via %s update does not exist in Homebridge. If it's a new accessory please restart Homebridge so it is added.", device.deviceid, source);
+ this.log.warn("[%s] Accessory received via %s update does not exist in Homebridge. If it's a new accessory please restart Homebridge so it is added.", device.deviceid, device.params.updateSource);
}
}
break;
@@ -924,7 +861,7 @@ class eWeLink {
setTimeout(() => {
if (!sAccessory) {
accessory.getService(Service.GarageDoorOpener)
- .updateCharacteristic(Characteristic.CurrentDoorState, newPos === 0 ? 0 : 1);
+ .updateCharacteristic(Characteristic.CurrentDoorState, newPos);
}
accessory.context.inUse = false;
}, parseInt(garageConfig.operationTime) * 100);
@@ -1360,7 +1297,7 @@ class eWeLink {
}
});
} catch (err) {
- this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
internalRFDeviceUpdate(accessory, rfChl, callback) {
@@ -1421,7 +1358,7 @@ class eWeLink {
.updateCharacteristic(Characteristic.CurrentPosition, nSte * 100);
}, parseInt(blindConfig.operationTime) * 100);
} catch (err) {
- this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalGarageUpdate(accessory, params) {
@@ -1463,7 +1400,7 @@ class eWeLink {
}, parseInt(garageConfig.operationTime) * 100);
} catch (err) {
accessory.context.inUse = false;
- this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalLockUpdate(accessory, params) {
@@ -1490,7 +1427,7 @@ class eWeLink {
}, parseInt(lockConfig.operationTime) * 100);
} catch (err) {
accessory.context.inUse = false;
- this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalSensorUpdate(accessory, params) {
@@ -1525,7 +1462,7 @@ class eWeLink {
}
});
} catch (err) {
- this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalFanUpdate(accessory, params) {
@@ -1562,7 +1499,7 @@ class eWeLink {
.updateCharacteristic(Characteristic.Active, status)
.updateCharacteristic(Characteristic.RotationSpeed, speed);
} catch (err) {
- this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalThermostatUpdate(accessory, params) {
@@ -1580,28 +1517,28 @@ class eWeLink {
accessory.getService(Service.HumiditySensor).updateCharacteristic(Characteristic.CurrentRelativeHumidity, currentHumi);
}
} catch (err) {
- this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalOutletUpdate(accessory, params) {
try {
accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, params.switch === "on");
} catch (err) {
- this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalUSBUpdate(accessory, params) {
try {
accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, params.switches[0].switch === "on");
} catch (err) {
- this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalSCMUpdate(accessory, params) {
try {
accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, params.switches[0].switch === "on");
} catch (err) {
- this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalSingleLightUpdate(accessory, params) {
@@ -1665,7 +1602,7 @@ class eWeLink {
accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, false);
}
} catch (err) {
- this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalMultiLightUpdate(accessory, params) {
@@ -1683,14 +1620,14 @@ class eWeLink {
}
accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, primaryState);
} catch (err) {
- this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalSingleSwitchUpdate(accessory, params) {
try {
accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, params.switch === "on");
} catch (err) {
- this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalMultiSwitchUpdate(accessory, params) {
@@ -1708,12 +1645,12 @@ class eWeLink {
}
accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, primaryState);
} catch (err) {
- this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalRFDeviceUpdate(accessory, params) {
try {
- if (params.updateSource === "http") {
+ if (params.updateSource === "HTTP") {
return;
}
let idToCheck = accessory.context.hbDeviceId.slice(0, -1),
@@ -1729,83 +1666,80 @@ class eWeLink {
throw "rf button not found in Homebridge";
}
} else if (params.hasOwnProperty("cmd") && params.cmd === "trigger") { // RF Sensor
- let rfChan = Object.keys(params).filter(name => /rfTrig/.test(name));
- rfChan.forEach(chan => {
- let chanNum = chan.substr(-1).toString(),
- accessoryNum = accessory.context.rfChlMap[chanNum],
- oAccessory;
- if ((oAccessory = this.devicesInHB.get(idToCheck + accessoryNum))) {
- let timeOfMotion = new Date(params[chan]),
- timeDifference = (timeNow.getTime() - timeOfMotion.getTime()) / 1000;
- if (timeDifference < (this.config.sensorTimeDifference || 120)) {
- switch (oAccessory.context.sensorType) {
- case "button":
- break;
- case "water":
- oAccessory.getService(Service.LeakSensor).updateCharacteristic(Characteristic.LeakDetected, 1);
- setTimeout(() => {
- oAccessory.getService(Service.LeakSensor).updateCharacteristic(Characteristic.LeakDetected, 0);
- }, (this.config.sensorTimeLength || 2) * 1000);
- break;
- case "fire":
- case "smoke":
- oAccessory.getService(Service.SmokeSensor).updateCharacteristic(Characteristic.SmokeDetected, 1);
- setTimeout(() => {
- oAccessory.getService(Service.SmokeSensor).updateCharacteristic(Characteristic.SmokeDetected, 0);
- }, (this.config.sensorTimeLength || 2) * 1000);
- break;
- case "co":
- oAccessory.getService(Service.CarbonMonoxideSensor).updateCharacteristic(Characteristic.CarbonMonoxideDetected, 1);
- setTimeout(() => {
- oAccessory.getService(Service.CarbonMonoxideSensor).updateCharacteristic(Characteristic.CarbonMonoxideDetected, 0);
- }, (this.config.sensorTimeLength || 2) * 1000);
- break;
- case "co2":
- oAccessory.getService(Service.CarbonDioxideSensor).updateCharacteristic(Characteristic.CarbonDioxideDetected, 1);
- setTimeout(() => {
- oAccessory.getService(Service.CarbonDioxideSensor).updateCharacteristic(Characteristic.CarbonDioxideDetected, 0);
- }, (this.config.sensorTimeLength || 2) * 1000);
- break;
- case "contact":
- oAccessory.getService(Service.ContactSensor).updateCharacteristic(Characteristic.ContactSensorState, 1);
- setTimeout(() => {
- oAccessory.getService(Service.ContactSensor).updateCharacteristic(Characteristic.ContactSensorState, 0);
- }, (this.config.sensorTimeLength || 2) * 1000);
- break;
- case "occupancy":
- oAccessory.getService(Service.OccupancySensor).updateCharacteristic(Characteristic.OccupancyDetected, 1);
- setTimeout(() => {
- oAccessory.getService(Service.OccupancySensor).updateCharacteristic(Characteristic.OccupancyDetected, 0);
- }, (this.config.sensorTimeLength || 2) * 1000);
- break;
- default:
- oAccessory.getService(Service.MotionSensor).updateCharacteristic(Characteristic.MotionDetected, true);
- setTimeout(() => {
- oAccessory.getService(Service.MotionSensor).updateCharacteristic(Characteristic.MotionDetected, false);
- }, (this.config.sensorTimeLength || 2) * 1000);
- break;
- }
- if (this.config.debug) {
- this.log("[%s] has detected [%s].", oAccessory.displayName, oAccessory.context.sensorType);
+ Object.keys(params)
+ .filter(name => /rfTrig/.test(name))
+ .forEach(chan => {
+ let chanNum = chan.substr(-1).toString(),
+ accessoryNum = accessory.context.rfChlMap[chanNum],
+ oAccessory;
+ if ((oAccessory = this.devicesInHB.get(idToCheck + accessoryNum))) {
+ let timeOfMotion = new Date(params[chan]),
+ timeDifference = (timeNow.getTime() - timeOfMotion.getTime()) / 1000;
+ if (timeDifference < (this.config.sensorTimeDifference || 120)) {
+ switch (oAccessory.context.sensorType) {
+ case "button":
+ break;
+ case "water":
+ oAccessory.getService(Service.LeakSensor).updateCharacteristic(Characteristic.LeakDetected, 1);
+ setTimeout(() => {
+ oAccessory.getService(Service.LeakSensor).updateCharacteristic(Characteristic.LeakDetected, 0);
+ }, (this.config.sensorTimeLength || 2) * 1000);
+ break;
+ case "fire":
+ case "smoke":
+ oAccessory.getService(Service.SmokeSensor).updateCharacteristic(Characteristic.SmokeDetected, 1);
+ setTimeout(() => {
+ oAccessory.getService(Service.SmokeSensor).updateCharacteristic(Characteristic.SmokeDetected, 0);
+ }, (this.config.sensorTimeLength || 2) * 1000);
+ break;
+ case "co":
+ oAccessory.getService(Service.CarbonMonoxideSensor).updateCharacteristic(Characteristic.CarbonMonoxideDetected, 1);
+ setTimeout(() => {
+ oAccessory.getService(Service.CarbonMonoxideSensor).updateCharacteristic(Characteristic.CarbonMonoxideDetected, 0);
+ }, (this.config.sensorTimeLength || 2) * 1000);
+ break;
+ case "co2":
+ oAccessory.getService(Service.CarbonDioxideSensor).updateCharacteristic(Characteristic.CarbonDioxideDetected, 1);
+ setTimeout(() => {
+ oAccessory.getService(Service.CarbonDioxideSensor).updateCharacteristic(Characteristic.CarbonDioxideDetected, 0);
+ }, (this.config.sensorTimeLength || 2) * 1000);
+ break;
+ case "contact":
+ oAccessory.getService(Service.ContactSensor).updateCharacteristic(Characteristic.ContactSensorState, 1);
+ setTimeout(() => {
+ oAccessory.getService(Service.ContactSensor).updateCharacteristic(Characteristic.ContactSensorState, 0);
+ }, (this.config.sensorTimeLength || 2) * 1000);
+ break;
+ case "occupancy":
+ oAccessory.getService(Service.OccupancySensor).updateCharacteristic(Characteristic.OccupancyDetected, 1);
+ setTimeout(() => {
+ oAccessory.getService(Service.OccupancySensor).updateCharacteristic(Characteristic.OccupancyDetected, 0);
+ }, (this.config.sensorTimeLength || 2) * 1000);
+ break;
+ default:
+ oAccessory.getService(Service.MotionSensor).updateCharacteristic(Characteristic.MotionDetected, true);
+ setTimeout(() => {
+ oAccessory.getService(Service.MotionSensor).updateCharacteristic(Characteristic.MotionDetected, false);
+ }, (this.config.sensorTimeLength || 2) * 1000);
+ break;
+ }
+ if (this.config.debug) {
+ this.log("[%s] has detected [%s].", oAccessory.displayName, oAccessory.context.sensorType);
+ }
}
}
- }
- });
+ });
}
} catch (err) {
- this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalZBDeviceUpdate(accessory, params) {
- try {
+ try { //*** credit @tasict ***\\
switch (accessory.context.eweUIID) {
case 1000:
- if (params.hasOwnProperty("key")) {
- if ([0, 1, 2].includes(params.key)) {
- accessory.getService(Service.StatelessProgrammableSwitch).updateCharacteristic(Characteristic.ProgrammableSwitchEvent, params.key); //*** credit @tasict ***\\
- } else {
- throw "unknown 'key' parameter received [" + params.key + "]";
- }
+ if (params.hasOwnProperty("key") && [0, 1, 2].includes(params.key)) {
+ accessory.getService(Service.StatelessProgrammableSwitch).updateCharacteristic(Characteristic.ProgrammableSwitchEvent, params.key);
}
break;
case 1770:
@@ -1819,28 +1753,20 @@ class eWeLink {
}
break;
case 2026:
- if (params.hasOwnProperty("motion")) {
- if ([0, 1].includes(params.lock)) {
- accessory.getService(Service.MotionSensor).updateCharacteristic(Characteristic.MotionDetected, params.motion);
- } else {
- throw "unknown 'motion' parameter received [" + params.motion + "]";
- }
+ if (params.hasOwnProperty("motion") && [0, 1].includes(params.lock)) {
+ accessory.getService(Service.MotionSensor).updateCharacteristic(Characteristic.MotionDetected, params.motion);
}
break;
case 3026:
- if (params.hasOwnProperty("lock")) {
- if ([0, 1].includes(params.lock)) {
- accessory.getService(Service.ContactSensor).updateCharacteristic(Characteristic.ContactSensorState, params.lock);
- } else {
- throw "unknown 'lock' parameter received [" + params.lock + "]";
- }
+ if (params.hasOwnProperty("lock") && [0, 1].includes(params.lock)) {
+ accessory.getService(Service.ContactSensor).updateCharacteristic(Characteristic.ContactSensorState, params.lock);
}
break;
default:
- throw "unsupported zigbee device type";
+ throw "unsupported zigbee device type [" + accessory.context.eweUIID + "]. Please create an issue on GitHub";
}
} catch (err) {
- this.log.warn("[%s] could not be updated - [%s].", accessory.displayName, err);
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
}
diff --git a/lib/eWeLinkLAN.js b/lib/eWeLinkLAN.js
index 89e1a337..4582825b 100644
--- a/lib/eWeLinkLAN.js
+++ b/lib/eWeLinkLAN.js
@@ -90,8 +90,8 @@ module.exports = class eWeLinkLAN {
}
}
}
- params.updateSource = "LAN";
if (Object.keys(params).length > 0) {
+ params.updateSource = "LAN";
let returnTemplate = {
deviceid: rdata.id,
action: "update",
diff --git a/lib/eWeLinkWS.js b/lib/eWeLinkWS.js
index 8afe3926..0052d5d6 100644
--- a/lib/eWeLinkWS.js
+++ b/lib/eWeLinkWS.js
@@ -96,9 +96,9 @@ module.exports = class eWeLinkWS {
this.ws.send("ping");
}, (device.config.hbInterval + 7) * 1000);
} else if (device.hasOwnProperty("action")) {
- device.params.updateSource = "WS";
switch (device.action) {
case "sysmsg":
+ device.params.updateSource = "WS";
let returnTemplate = {
deviceid: device.deviceid,
action: "sysmsg",
@@ -121,6 +121,7 @@ module.exports = class eWeLinkWS {
}
}
if (Object.keys(device.params).length > 0) {
+ device.params.updateSource = "WS";
let returnTemplate = {
deviceid: device.deviceid,
action: "update",
From 69ea1e39b60c4dac434d9f3fd53297db145ef43c Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 8 Sep 2020 11:24:57 +0100
Subject: [PATCH 0095/3183] small changes
---
lib/eWeLink.js | 46 ++++++++++++++++++++++++----------------------
1 file changed, 24 insertions(+), 22 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index ddf238bb..969e215a 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -205,7 +205,7 @@ class eWeLink {
}
}
if (rfBridgeChange) {
- this.log.warn("[%s] bridge configuration changed - devices will be removed and readded.", accessory.displayName);
+ this.log.warn("[%s] bridge configuration changed so devices will be removed and readded.", accessory.displayName);
for (let i = 0; i <= accessory.context.channelCount; i++) {
let oAccessory = this.devicesInHB.get(device.deviceid + "SW" + i);
this.removeAccessory(oAccessory);
@@ -390,18 +390,18 @@ class eWeLink {
accessory.addService(Service.ContactSensor);
break;
default:
- throw "unsupported zigbee device type with uiid [" + device.extra.uiid + "]";
+ throw "unsupported zigbee device type [" + device.extra.uiid + "]. Please create an issue on GitHub";
}
break;
default:
- throw "device is not supported by this plugin";
+ throw "device is not supported by this plugin. Please create an issue on GitHub";
}
this.devicesInHB.set(hbDeviceId, accessory);
this.api.registerPlatformAccessories("homebridge-ewelink", "eWeLink", [accessory]);
this.configureAccessory(accessory);
this.log("[%s] has been added to Homebridge.", newDeviceName);
} catch (err) {
- this.log.warn("[%s] could not be added - %s.", newDeviceName, err);
+ this.log.warn("[%s] could not be added as %s.", newDeviceName, err);
}
}
configureAccessory(accessory) {
@@ -533,7 +533,7 @@ class eWeLink {
accessory.context.reachableLAN = true;
this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
} catch (err) {
- this.log.warn("[%s] could not be refreshed - [%s].", accessory.displayName, err);
+ this.log.warn("[%s] could not be refreshed as %s.", accessory.displayName, err);
}
}
refreshAccessory(accessory, newParams) {
@@ -629,7 +629,7 @@ class eWeLink {
this.api.unregisterPlatformAccessories("homebridge-ewelink", "eWeLink", [accessory]);
this.log("[%s] has been removed from Homebridge.", accessory.displayName);
} catch (err) {
- this.log.warn("[%s] needed to be removed but couldn't - [%s].", accessory.displayName, err);
+ this.log.warn("[%s] needed to be removed but couldn't as %s.", accessory.displayName, err);
}
}
sendDeviceUpdate(accessory, params, callback) {
@@ -651,7 +651,7 @@ class eWeLink {
sendViaWS();
} else {
this.lanClient.sendUpdate(payload)
- .then(res => callback())
+ .then(() => callback())
.catch(err => {
if (this.config.debug) {
this.log.warn("[%s] Reverting to web socket as %s.", accessory.displayName, err);
@@ -666,12 +666,18 @@ class eWeLink {
case "sysmsg":
if ((accessory = this.devicesInHB.get(device.deviceid + "SWX") || this.devicesInHB.get(device.deviceid + "SW0"))) {
let isX = accessory.context.hbDeviceId.substr(-1) === "X";
- if (device.params.updateSource === "WS" && accessory.context.reachableWAN !== device.params.online) {
- accessory.context.reachableWAN = device.params.online;
- this.log("[%s] has been reported [%s] via [WS].", accessory.displayName, accessory.context.reachableWAN ? "online" : "offline");
- this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
- if (accessory.context.reachableWAN) {
- this.wsClient.requestUpdate(accessory);
+ if (device.params.updateSource === "WS") {
+ if (accessory.context.reachableWAN !== device.params.online) {
+ accessory.context.reachableWAN = device.params.online;
+ this.log("[%s] has been reported [%s] via [WS].", accessory.displayName, accessory.context.reachableWAN ? "online" : "offline");
+ this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
+ if (accessory.context.reachableWAN) {
+ this.wsClient.requestUpdate(accessory);
+ }
+ } else {
+ if (this.debug) {
+ this.log("[%s] Nothing to update from above WS message.", accessory.displayName);
+ }
}
}
if (!isX) {
@@ -822,7 +828,7 @@ class eWeLink {
oldPos,
newPos = value,
params = {},
- wsDelay = 0;
+ delay = 0;
if (sensorDefinition && !(sAccessory = this.devicesInHB.get(garageConfig.sensorId + "SWX"))) {
throw "defined sensor doesn't exist";
}
@@ -836,9 +842,8 @@ class eWeLink {
return;
}
if (garageConfig.setup === "oneSwitch" && [2, 3].includes(oldPos)) {
- accessory.getService(Service.GarageDoorOpener)
- .updateCharacteristic(Characteristic.CurrentDoorState, oldPos * 2 % 3 + 2);
- wsDelay = 1500;
+ accessory.getService(Service.GarageDoorOpener).updateCharacteristic(Characteristic.CurrentDoorState, oldPos * 2 % 3 + 2);
+ delay = 1500;
}
setTimeout(() => {
if (accessory.context.state === newPos) {
@@ -860,13 +865,12 @@ class eWeLink {
});
setTimeout(() => {
if (!sAccessory) {
- accessory.getService(Service.GarageDoorOpener)
- .updateCharacteristic(Characteristic.CurrentDoorState, newPos);
+ accessory.getService(Service.GarageDoorOpener).updateCharacteristic(Characteristic.CurrentDoorState, newPos);
}
accessory.context.inUse = false;
}, parseInt(garageConfig.operationTime) * 100);
}
- }, wsDelay);
+ }, delay);
callback();
} catch (err) {
accessory.context.inUse = false;
@@ -1762,8 +1766,6 @@ class eWeLink {
accessory.getService(Service.ContactSensor).updateCharacteristic(Characteristic.ContactSensorState, params.lock);
}
break;
- default:
- throw "unsupported zigbee device type [" + accessory.context.eweUIID + "]. Please create an issue on GitHub";
}
} catch (err) {
this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
From 4e1a204ec89f73b91a79f43eeb4d838b78fd0366 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 8 Sep 2020 11:26:02 +0100
Subject: [PATCH 0096/3183] 2.25.0-3
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 13f0eb35..2a277e50 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.25.0-2",
+ "version": "2.25.0-3",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index bbe0307b..42c59d5b 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.25.0-2",
+ "version": "2.25.0-3",
"author": "bwp91",
"contributors": [
"gbro115",
From 0f60d15462b848fcad41ea2a219b2cfc277049ec Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 8 Sep 2020 16:28:12 +0100
Subject: [PATCH 0097/3183] 2.25.0
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 2a277e50..41e52d3d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.25.0-3",
+ "version": "2.25.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 42c59d5b..f2e18280 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.25.0-3",
+ "version": "2.25.0",
"author": "bwp91",
"contributors": [
"gbro115",
From 100e71094040a0e069e4c5926a10161a7e15af98 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Wed, 9 Sep 2020 06:42:44 +0100
Subject: [PATCH 0098/3183] bug: rf bridge with no devices
---
lib/eWeLink.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 969e215a..6e9fb4db 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -221,7 +221,7 @@ class eWeLink {
}
}
addAccessory(device, hbDeviceId, type) {
- let channelCount = type === "rf_pri" ? Object.keys(device.tags.zyx_info).length : cns.chansFromUiid[device.extra.uiid],
+ let channelCount = type === "rf_pri" ? Object.keys(device.tags.zyx_info || []).length : cns.chansFromUiid[device.extra.uiid],
switchNumber = hbDeviceId.substr(-1).toString(),
newDeviceName = type === "rf_sub" ? device.tags.zyx_info[switchNumber - 1].name : device.name;
if (["1", "2", "3", "4"].includes(switchNumber) && type !== "rf_sub") {
From d616b3d14c62bc9efd6b0b101b77352b78c99ab4 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Wed, 9 Sep 2020 06:43:31 +0100
Subject: [PATCH 0099/3183] bug: can't close if not open
#85
---
lib/eWeLinkWS.js | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/lib/eWeLinkWS.js b/lib/eWeLinkWS.js
index 0052d5d6..a44b1431 100644
--- a/lib/eWeLinkWS.js
+++ b/lib/eWeLinkWS.js
@@ -275,6 +275,8 @@ module.exports = class eWeLinkWS {
this.emitter.addListener("update", f);
}
closeConnection() {
- this.ws.close(1000, "Stopping Homebridge");
+ if (this.ws && this.wsIsOpen) {
+ this.ws.close(1000, "Stopping Homebridge");
+ }
}
};
\ No newline at end of file
From a441bf4dc28964d02ae5d2769b81ef4b5b9a1e93 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Wed, 9 Sep 2020 06:43:58 +0100
Subject: [PATCH 0100/3183] feat: custom ip definition
---
lib/eWeLinkLAN.js | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/lib/eWeLinkLAN.js b/lib/eWeLinkLAN.js
index 4582825b..f43869b7 100644
--- a/lib/eWeLinkLAN.js
+++ b/lib/eWeLinkLAN.js
@@ -10,12 +10,13 @@ module.exports = class eWeLinkLAN {
this.config = config;
this.log = log;
this.devices = devices;
+ this.ipOverrides = this.config.ipOverride || {};
let deviceMap = new Map();
devices.forEach(device => {
deviceMap.set(device.deviceid, {
apiKey: device.devicekey,
- online: false,
- ip: null
+ online: this.ipOverrides.hasOwnProperty(device.deviceid) ? true : false,
+ ip: this.ipOverrides.hasOwnProperty(device.deviceid) ? this.ipOverrides[device.deviceid] : null
});
});
this.deviceMap = deviceMap;
@@ -32,11 +33,13 @@ module.exports = class eWeLinkLAN {
res.forEach(device => {
let d, deviceId = device.fqdn.replace("._ewelink._tcp.local", "").replace("eWeLink_", "");
if ((d = this.deviceMap.get(deviceId))) {
- this.deviceMap.set(deviceId, {
- apiKey: d.apiKey,
- online: true,
- ip: device.address
- });
+ if (!this.ipOverrides.hasOwnProperty(deviceId)) {
+ this.deviceMap.set(deviceId, {
+ apiKey: d.apiKey,
+ online: true,
+ ip: device.address
+ });
+ }
onlineCount++;
}
});
@@ -67,7 +70,7 @@ module.exports = class eWeLinkLAN {
dText = crypto.createDecipheriv("aes-128-cbc", key, Buffer.from(rdata.iv, "base64")),
pText = Buffer.concat([dText.update(Buffer.from(data, "base64")), dText.final()]).toString("utf8"),
params;
- if (packet.address !== deviceInfo.ip) {
+ if (packet.address !== deviceInfo.ip && !this.ipOverrides.hasOwnProperty(rdata.id)) {
this.deviceMap.set(rdata.id, {
apiKey: deviceInfo.apiKey,
online: true,
From cc4c55c664745f331f755f8891764cd4a7a9023a Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Wed, 9 Sep 2020 06:56:30 +0100
Subject: [PATCH 0101/3183] 2.25.1
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 41e52d3d..ca38ffdb 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.25.0",
+ "version": "2.25.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index f2e18280..d6d5a820 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.25.0",
+ "version": "2.25.1",
"author": "bwp91",
"contributors": [
"gbro115",
From 77305516003e311ffc1a76d3e94cb52682e292f6 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Wed, 9 Sep 2020 20:00:33 +0100
Subject: [PATCH 0102/3183] bugs definition
---
package.json | 3 +++
1 file changed, 3 insertions(+)
diff --git a/package.json b/package.json
index d6d5a820..04d63730 100644
--- a/package.json
+++ b/package.json
@@ -38,6 +38,9 @@
"type": "git",
"url": "https://github.com/bwp91/homebridge-ewelink"
},
+ "bugs": {
+ "url": "https://github.com/bwp91/homebridge-ewelink/issues"
+ },
"dependencies": {
"axios": "0.20.0",
"color-convert": "2.0.1",
From 782806340b9364a0f7154011bce55ce0c623f05b Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Wed, 9 Sep 2020 20:04:04 +0100
Subject: [PATCH 0103/3183] garage and rf bug fixes
---
lib/eWeLink.js | 190 ++++++++++++++++++++++++-------------------------
1 file changed, 95 insertions(+), 95 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 6e9fb4db..397cee30 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -22,91 +22,91 @@ class eWeLink {
this.devicesInEwe = new Map();
this.cusG = new Map();
this.cusS = new Map();
- this.api.on("didFinishLaunching", () => {
- this.log("Plugin has finished initialising. Starting synchronisation with eWeLink account.");
- //*** Set up HTTP client and get the user HTTP host ***\\
- this.httpClient = new eWeLinkHTTP(this.config, this.log);
- this.httpClient.getHost()
- .then(res => { //*** Use the HTTP API host to log into eWeLink ***\\
- return this.httpClient.login();
- }).then(res => { //*** Set up the web socket client ***\\
- this.wsClient = new eWeLinkWS(this.config, this.log, res);
- return this.wsClient.getHost();
- }).then(() => { //*** Open web socket connection and get device list via HTTP ***\\
- this.wsClient.login();
- return this.httpClient.getDevices();
- }).then(res => { //*** Get device IP addresses for LAN mode ***\\
- this.httpDevices = res
- .filter(device => device.hasOwnProperty("extra"))
- .filter(device => device.extra.hasOwnProperty("uiid"))
- .filter(device => !(this.config.hideDevFromHB || "").includes(device.deviceid))
- .forEach(device => this.devicesInEwe.set(device.deviceid, device));
- this.httpDevices = res;
- this.lanClient = new eWeLinkLAN(this.config, this.log, this.httpDevices);
- return this.lanClient.getHosts();
- }).then(res => { //*** Set up the LAN mode listener ***\\
- this.lanDevices = res.map;
- this.lanDevicesOnline = res.count;
- return this.lanClient.startMonitor();
- }).then(() => { //*** Use the device list to refresh Homebridge accessories ***\\
- (() => {
- //*** Remove all Homebridge accessories if none found ***\\
- if (Object.keys(this.httpDevices).length === 0 && Object.keys(this.lanDevices).length === 0) {
- Array.from(this.devicesInHB.values()).forEach(a => this.removeAccessory(a));
- this.devicesInHB.clear();
- this.log.warn("đ No devices were found registered to your eWeLink account so disabling plugin.");
- return;
- }
- //*** Make a map of custom groups from Homebridge config ***\\
- if (Object.keys(this.config.groups || []).length > 0) {
- this.config.groups
- .filter(g => g.hasOwnProperty("deviceId") && this.devicesInEwe.has(g.deviceId.toLowerCase()))
- .filter(g => g.hasOwnProperty("type") && cns.allowedGroups.includes(g.type))
- .forEach(g => this.cusG.set(g.deviceId + "SWX", g));
- }
- //*** Make a map of RF Bridge custom sensors from Homebridge config ***\\
- if (Object.keys(this.config.bridgeSensors || []).length > 0) {
- this.config.bridgeSensors
- .filter(s => s.hasOwnProperty("deviceId") && this.devicesInEwe.has(s.deviceId.toLowerCase()))
- .forEach(s => this.cusS.set(s.fullDeviceId, s));
- }
- //*** Logging always helps to see if everything is okay so far ***\\
- this.log("[%s] eWeLink devices were loaded from the Homebridge cache.", this.devicesInHB.size);
- this.log("[%s] primary devices were loaded from your eWeLink account.", this.devicesInEwe.size);
- this.log("[%s] primary devices were discovered on your local network.", this.lanDevicesOnline);
- //*** Remove Homebridge accessories that don't appear in eWeLink ***\\
- this.devicesInHB.forEach(accessory => {
- if (!this.devicesInEwe.has(accessory.context.eweDeviceId)) {
- this.removeAccessory(accessory);
+ this.api
+ .on("didFinishLaunching", () => {
+ this.log("Plugin has finished initialising. Starting synchronisation with eWeLink account.");
+ //*** Set up HTTP client and get the user HTTP host ***\\
+ this.httpClient = new eWeLinkHTTP(this.config, this.log);
+ this.httpClient.getHost()
+ .then(res => { //*** Use the HTTP API host to log into eWeLink ***\\
+ return this.httpClient.login();
+ }).then(res => { //*** Set up the web socket client ***\\
+ this.wsClient = new eWeLinkWS(this.config, this.log, res);
+ return this.wsClient.getHost();
+ }).then(() => { //*** Open web socket connection and get device list via HTTP ***\\
+ this.wsClient.login();
+ return this.httpClient.getDevices();
+ }).then(res => { //*** Get device IP addresses for LAN mode ***\\
+ this.httpDevices = res
+ .filter(device => device.hasOwnProperty("extra") && device.extra.hasOwnProperty("uiid"))
+ .filter(device => !(this.config.hideDevFromHB || "").includes(device.deviceid))
+ .forEach(device => this.devicesInEwe.set(device.deviceid, device));
+ this.httpDevices = res;
+ this.lanClient = new eWeLinkLAN(this.config, this.log, this.httpDevices);
+ return this.lanClient.getHosts();
+ }).then(res => { //*** Set up the LAN mode listener ***\\
+ this.lanDevices = res.map;
+ this.lanDevicesOnline = res.count;
+ return this.lanClient.startMonitor();
+ }).then(() => { //*** Use the device list to refresh Homebridge accessories ***\\
+ (() => {
+ //*** Remove all Homebridge accessories if none found ***\\
+ if (Object.keys(this.httpDevices).length === 0 && Object.keys(this.lanDevices).length === 0) {
+ Array.from(this.devicesInHB.values()).forEach(a => this.removeAccessory(a));
+ this.devicesInHB.clear();
+ this.log.warn("đ No devices were found registered to your eWeLink account so disabling plugin.");
+ return;
}
- });
- //*** Synchronise devices between eWeLink and Homebridge and set up ws/lan listeners ***\\
- this.devicesInEwe.forEach(device => this.initialiseDevice(device));
- this.wsClient.receiveUpdate(device => this.receiveDeviceUpdate(device));
- this.lanClient.receiveUpdate(device => this.receiveDeviceUpdate(device));
- this.log("đĸ eWeLink setup complete. If you're enjoying this package please consider a âī¸ on GitHub!");
- if (this.config.debugReqRes) {
- this.log.warn("You have 'Request & Response Logging' enabled. This setting is not recommended for long-term use.");
+ //*** Make a map of custom groups from Homebridge config ***\\
+ if (Object.keys(this.config.groups || []).length > 0) {
+ this.config.groups
+ .filter(g => g.hasOwnProperty("deviceId") && this.devicesInEwe.has(g.deviceId.toLowerCase()))
+ .filter(g => g.hasOwnProperty("type") && cns.allowedGroups.includes(g.type))
+ .forEach(g => this.cusG.set(g.deviceId + "SWX", g));
+ }
+ //*** Make a map of RF Bridge custom sensors from Homebridge config ***\\
+ if (Object.keys(this.config.bridgeSensors || []).length > 0) {
+ this.config.bridgeSensors
+ .filter(s => s.hasOwnProperty("deviceId") && this.devicesInEwe.has(s.deviceId.toLowerCase()))
+ .forEach(s => this.cusS.set(s.fullDeviceId, s));
+ }
+ //*** Logging always helps to see if everything is okay so far ***\\
+ this.log("[%s] eWeLink devices were loaded from the Homebridge cache.", this.devicesInHB.size);
+ this.log("[%s] primary devices were loaded from your eWeLink account.", this.devicesInEwe.size);
+ this.log("[%s] primary devices were discovered on your local network.", this.lanDevicesOnline);
+ //*** Remove Homebridge accessories that don't appear in eWeLink ***\\
+ this.devicesInHB.forEach(accessory => {
+ if (!this.devicesInEwe.has(accessory.context.eweDeviceId)) {
+ this.removeAccessory(accessory);
+ }
+ });
+ //*** Synchronise devices between eWeLink and Homebridge and set up ws/lan listeners ***\\
+ this.devicesInEwe.forEach(device => this.initialiseDevice(device));
+ this.wsClient.receiveUpdate(device => this.receiveDeviceUpdate(device));
+ this.lanClient.receiveUpdate(device => this.receiveDeviceUpdate(device));
+ this.log("đĸ eWeLink setup complete. If you're enjoying this package please consider a âī¸ on GitHub!");
+ if (this.config.debugReqRes) {
+ this.log.warn("You have 'Request & Response Logging' enabled. This setting is not recommended for long-term use.");
+ }
+ })();
+ }).catch(err => {
+ this.log.error("đ´ Cannot load homebridge-ewelink - %s", err);
+ if (this.lanClient) {
+ this.lanClient.closeConnection();
}
- })();
- }).catch(err => {
- this.log.error("đ´ Cannot load homebridge-ewelink - %s", err);
- if (this.lanClient) {
- this.lanClient.closeConnection();
- }
- if (this.wsClient) {
- this.wsClient.closeConnection();
- }
- });
- });
- this.api.on('shutdown', () => {
- if (this.lanClient) {
- this.lanClient.closeConnection();
- }
- if (this.wsClient) {
- this.wsClient.closeConnection();
- }
- });
+ if (this.wsClient) {
+ this.wsClient.closeConnection();
+ }
+ });
+ })
+ .on('shutdown', () => {
+ if (this.lanClient) {
+ this.lanClient.closeConnection();
+ }
+ if (this.wsClient) {
+ this.wsClient.closeConnection();
+ }
+ });
}
initialiseDevice(device) {
let accessory;
@@ -147,8 +147,10 @@ class eWeLink {
}
} else if (cns.devicesRFBridge.includes(device.extra.uiid)) {
this.addAccessory(device, device.deviceid + "SW0", "rf_pri");
- for (let i = 1; i <= Object.keys(device.tags.zyx_info).length; i++) {
- this.addAccessory(device, device.deviceid + "SW" + i, "rf_sub");
+ if (Object.keys((device.tags && device.tags.zyx_info) || []).length > 0) {
+ for (let i = 1; i <= Object.keys(device.tags.zyx_info).length; i++) {
+ this.addAccessory(device, device.deviceid + "SW" + i, "rf_sub");
+ }
}
} else if (cns.devicesZBBridge.includes(device.extra.uiid)) {
this.addAccessory(device, device.deviceid + "SWX", "zb_pri");
@@ -221,7 +223,7 @@ class eWeLink {
}
}
addAccessory(device, hbDeviceId, type) {
- let channelCount = type === "rf_pri" ? Object.keys(device.tags.zyx_info || []).length : cns.chansFromUiid[device.extra.uiid],
+ let channelCount = type === "rf_pri" ? Object.keys((device.tags && device.tags.zyx_info) || []).length : cns.chansFromUiid[device.extra.uiid],
switchNumber = hbDeviceId.substr(-1).toString(),
newDeviceName = type === "rf_sub" ? device.tags.zyx_info[switchNumber - 1].name : device.name;
if (["1", "2", "3", "4"].includes(switchNumber) && type !== "rf_sub") {
@@ -832,7 +834,6 @@ class eWeLink {
if (sensorDefinition && !(sAccessory = this.devicesInHB.get(garageConfig.sensorId + "SWX"))) {
throw "defined sensor doesn't exist";
}
- this.log("[%s] has received request to [%s].", accessory.displayName, newPos === 0 ? "open" : "close");
oldPos = sAccessory ?
sAccessory.getService(Service.ContactSensor).getCharacteristic(Characteristic.ContactSensorState).value === 0 ? 1 : 0 :
accessory.getService(Service.GarageDoorOpener).getCharacteristic(Characteristic.CurrentDoorState).value;
@@ -1376,18 +1377,20 @@ class eWeLink {
if (garageConfig.type !== "garage" || !["oneSwitch", "twoSwitch"].includes(garageConfig.setup)) {
throw "improper configuration";
}
+ if (accessory.context.inUse || garageConfig.sensorId) {
+ return;
+ }
switch (garageConfig.setup) {
case "oneSwitch":
- if (params.switch === "off" || garageConfig.sensorId || accessory.context.inUse) {
+ if (params.switch === "off") {
return;
}
break;
case "twoSwitch":
- if ((params.switches[0].switch === "off" && params.switches[1].switch === "off") || accessory.context.inUse) {
+ if (params.switches[0].switch === params.switches[1].switch || params.switches[oldPos % 2].switch === "on") {
return;
}
- // @TODO twoSwitch garage external update
- return;
+ break;
}
accessory.context.inUse = true;
if (!garageConfig.sensorId) {
@@ -1440,7 +1443,6 @@ class eWeLink {
newState = params.switch === "on" ? 1 : 0,
oAccessory = false;
accessory.getService(Service.ContactSensor).updateCharacteristic(Characteristic.ContactSensorState, newState);
- this.log("[%s] sent update that it was [%s] and is now [%s].", accessory.displayName, oldState ? "apart" : "joined", newState ? "apart" : "joined");
this.cusG.forEach(group => {
if (group.sensorId === accessory.context.eweDeviceId && group.type === "garage") {
if ((oAccessory = this.devicesInHB.get(group.deviceId + "SWX"))) {
@@ -1449,18 +1451,16 @@ class eWeLink {
oAccessory.getService(Service.GarageDoorOpener)
.updateCharacteristic(Characteristic.TargetDoorState, 1)
.updateCharacteristic(Characteristic.CurrentDoorState, 1);
- this.log("[%s] updating to [closed] based on sensor.", oAccessory.displayName);
break;
case 1:
setTimeout(() => {
oAccessory.getService(Service.GarageDoorOpener)
.updateCharacteristic(Characteristic.TargetDoorState, 0)
.updateCharacteristic(Characteristic.CurrentDoorState, 0);
- this.log("[%s] updating to [open] based on sensor.", oAccessory.displayName);
}, group.operationTime * 100);
break;
default:
- throw "unknown sensor status received";
+ throw "unknown sensor status received [" + newState + "]";
}
}
}
From 069c3d4aca80865b5a71a58ecdd036d2eeebd8ae Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Wed, 9 Sep 2020 20:13:43 +0100
Subject: [PATCH 0104/3183] unused var
---
lib/eWeLink.js | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 397cee30..a5e87086 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -1439,8 +1439,7 @@ class eWeLink {
}
externalSensorUpdate(accessory, params) {
try {
- let oldState = accessory.getService(Service.ContactSensor).getCharacteristic(Characteristic.ContactSensorState).value,
- newState = params.switch === "on" ? 1 : 0,
+ let newState = params.switch === "on" ? 1 : 0,
oAccessory = false;
accessory.getService(Service.ContactSensor).updateCharacteristic(Characteristic.ContactSensorState, newState);
this.cusG.forEach(group => {
From 76050162243c895cd9757ecd1e5eab221d9eaabe Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Wed, 9 Sep 2020 20:15:16 +0100
Subject: [PATCH 0105/3183] 2.25.2
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index ca38ffdb..d7a67f06 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.25.1",
+ "version": "2.25.2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 04d63730..17650b7e 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.25.1",
+ "version": "2.25.2",
"author": "bwp91",
"contributors": [
"gbro115",
From 140f355b975fc429f489354b920fa7c64cdadf27 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Thu, 10 Sep 2020 10:54:31 +0100
Subject: [PATCH 0106/3183] Update package.json
---
package.json | 1 +
1 file changed, 1 insertion(+)
diff --git a/package.json b/package.json
index 17650b7e..7e070066 100644
--- a/package.json
+++ b/package.json
@@ -27,6 +27,7 @@
"keywords": [
"homebridge",
"homebridge-plugin",
+ "homekit",
"sonoff",
"ewelink"
],
From f694e1b622c36f39a26542c1a0944499faf6b670 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Fri, 11 Sep 2020 00:07:26 +0100
Subject: [PATCH 0107/3183] params per device type
---
lib/constants.js | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/lib/constants.js b/lib/constants.js
index 534514f0..0a53039b 100644
--- a/lib/constants.js
+++ b/lib/constants.js
@@ -5,23 +5,39 @@ module.exports = {
devicesHideable: ["switch", "light", "valve"],
devicesNonLAN: [22, 59, 102],
devicesSingleSwitch: [1, 5, 6, 14, 15, 22, 24, 27, 32, 36, 44, 59],
- devicesSingleSwitchLight: ["T1 1C", "L1", "B1", "B1_R2", "TX1C", "D1", "D1R1", "KING-M4", "Slampher", "GTTA59"],
+ devicesSingleSwitchParams: ["switch"],
devicesMultiSwitch: [2, 3, 4, 7, 8, 9, 29, 30, 31, 34, 41],
+ devicesMultiSwitchParams: ["switches"],
+ devicesSingleSwitchLight: ["T1 1C", "L1", "B1", "B1_R2", "TX1C", "D1", "D1R1", "KING-M4", "Slampher", "GTTA59"],
+ devicesSingleSwitchLightParams: ["switch", "state", "bright", "colorR", "brightness", "channel0", "channel2", "xyz_mode"],
devicesMultiSwitchLight: ["T1 2C", "T1 3C", "TX2C", "TX3C"],
+ devicesMultiSwitchLightParams: ["switches"],
devicesBrightable: [36, 44],
devicesColourable: [22, 59],
devicesSensor: [102],
+ devicesSensorParams: ["switch"],
devicesThermostat: [15],
+ devicesThermostatParams: ["currentTemperature", "currentHumidity", "switch", "masterSwitch"],
devicesFan: [34],
+ devicesFanParams: ["switches", "light", "fan", "speed"],
devicesOutlet: [32],
+ devicesOutletParams: ["switch", "power", "voltage", "current"],
devicesCamera: [87],
devicesUSB: [77],
+ devicesUSBParams: ["switches"],
devicesSCM: [78],
+ devicesSCMParams: ["switches"],
devicesRFBridge: [28],
+ devicesRFBridgeParams: ["cmd"],
devicesZBBridge: [66],
+ devicesZBBridgeParams: ["key", "temperature", "humidity", "motion", "lock"],
devicesZB: [1000, 1770, 2026, 3026],
+ devicesValveParams: ["switches"],
+ devicesBlindParams: ["switch", "switches"],
+ devicesGarageParams: ["switch", "switches"],
+ devicesLockParams: ["switch"],
allowedGroups: ["blind", "garage", "lock"],
- paramsToKeep: ["bright", "brightness", "channel", "cmd", "colorB", "colorG", "colorR", "currentHumidity", "currentTemperature", "fan", "humidity", "key", "light", "lock", "mainSwitch", "mode", "online", "rfChl", "rfList", "rfTrig", "sensorType", "speed", "state", "switch", "switches", "temperature", "type", "zyx_mode"],
+ paramsToKeep: ["bright", "brightness", "channel", "cmd", "colorB", "colorG", "colorR", "current", "currentHumidity", "currentTemperature", "fan", "humidity", "key", "light", "lock", "mainSwitch", "mode", "online", "power", "rfChl", "rfList", "rfTrig", "sensorType", "speed", "state", "switch", "switches", "temperature", "type", "voltage", "zyx_mode"],
chansFromUiid: {
1: 1, // "SOCKET" \\ 20, MINI, BASIC, S26
2: 2, // "SOCKET_2" \\
From 4b823fa632718e1290ed510f582a55cd6ffa4d2d Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Fri, 11 Sep 2020 00:07:43 +0100
Subject: [PATCH 0108/3183] deps for power readings
---
package-lock.json | 575 ++++++++++++++++++++++++++++++++++++++++++++++
package.json | 2 +
2 files changed, 577 insertions(+)
diff --git a/package-lock.json b/package-lock.json
index d7a67f06..0e0ca51e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4,6 +4,61 @@
"lockfileVersion": 1,
"requires": true,
"dependencies": {
+ "@types/color-name": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
+ "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ=="
+ },
+ "abort-controller": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
+ "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
+ "requires": {
+ "event-target-shim": "^5.0.0"
+ }
+ },
+ "agent-base": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.1.tgz",
+ "integrity": "sha512-01q25QQDwLSsyfhrKbn8yuur+JNw0H+0Y4JiGIKd3z9aYk/w/2kxD/Upc+t2ZBBSUNff50VjPsSW2YxM8QYKVg==",
+ "requires": {
+ "debug": "4"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ }
+ }
+ },
+ "ansi-styles": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+ "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+ "requires": {
+ "@types/color-name": "^1.1.1",
+ "color-convert": "^2.0.1"
+ }
+ },
+ "array-flatten": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz",
+ "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ=="
+ },
+ "arrify": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz",
+ "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug=="
+ },
"axios": {
"version": "0.20.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.20.0.tgz",
@@ -12,6 +67,48 @@
"follow-redirects": "^1.10.0"
}
},
+ "base64-js": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
+ "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g=="
+ },
+ "bignumber.js": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz",
+ "integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A=="
+ },
+ "bonjour": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz",
+ "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=",
+ "requires": {
+ "array-flatten": "^2.1.0",
+ "deep-equal": "^1.0.1",
+ "dns-equal": "^1.0.0",
+ "dns-txt": "^2.0.2",
+ "multicast-dns": "^6.0.1",
+ "multicast-dns-service-types": "^1.1.0"
+ }
+ },
+ "buffer-equal-constant-time": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
+ "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk="
+ },
+ "buffer-indexof": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz",
+ "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g=="
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
@@ -25,20 +122,498 @@
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "deep-equal": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz",
+ "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==",
+ "requires": {
+ "is-arguments": "^1.0.4",
+ "is-date-object": "^1.0.1",
+ "is-regex": "^1.0.4",
+ "object-is": "^1.0.1",
+ "object-keys": "^1.1.1",
+ "regexp.prototype.flags": "^1.2.0"
+ }
+ },
+ "define-properties": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
+ "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
+ "requires": {
+ "object-keys": "^1.0.12"
+ }
+ },
+ "dns-equal": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz",
+ "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0="
+ },
+ "dns-packet": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz",
+ "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==",
+ "requires": {
+ "ip": "^1.1.0",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "dns-txt": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz",
+ "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=",
+ "requires": {
+ "buffer-indexof": "^1.0.0"
+ }
+ },
+ "ecdsa-sig-formatter": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
+ "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
+ "requires": {
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "es-abstract": {
+ "version": "1.17.6",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz",
+ "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==",
+ "requires": {
+ "es-to-primitive": "^1.2.1",
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1",
+ "is-callable": "^1.2.0",
+ "is-regex": "^1.1.0",
+ "object-inspect": "^1.7.0",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.0",
+ "string.prototype.trimend": "^1.0.1",
+ "string.prototype.trimstart": "^1.0.1"
+ }
+ },
+ "es-to-primitive": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
+ "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+ "requires": {
+ "is-callable": "^1.1.4",
+ "is-date-object": "^1.0.1",
+ "is-symbol": "^1.0.2"
+ }
+ },
+ "event-target-shim": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
+ "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="
+ },
+ "extend": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
+ },
+ "fakegato-history": {
+ "version": "0.5.6",
+ "resolved": "https://registry.npmjs.org/fakegato-history/-/fakegato-history-0.5.6.tgz",
+ "integrity": "sha512-LlsOkiw9LntVlRlBkssD5ozhEkQzYuEJUlvXk5YAgBQcWzk19PQ5g+NoKfs6SRY1qAeC1onb65hes4mCvY+JmA==",
+ "requires": {
+ "debug": "^2.2.0",
+ "googleapis": ">39.1.0",
+ "moment": "*"
+ }
+ },
+ "fast-text-encoding": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz",
+ "integrity": "sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig=="
+ },
"follow-redirects": {
"version": "1.13.0",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz",
"integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA=="
},
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+ },
+ "gaxios": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-3.1.0.tgz",
+ "integrity": "sha512-DDTn3KXVJJigtz+g0J3vhcfbDbKtAroSTxauWsdnP57sM5KZ3d2c/3D9RKFJ86s43hfw6WULg6TXYw/AYiBlpA==",
+ "requires": {
+ "abort-controller": "^3.0.0",
+ "extend": "^3.0.2",
+ "https-proxy-agent": "^5.0.0",
+ "is-stream": "^2.0.0",
+ "node-fetch": "^2.3.0"
+ }
+ },
+ "gcp-metadata": {
+ "version": "4.1.4",
+ "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.1.4.tgz",
+ "integrity": "sha512-5J/GIH0yWt/56R3dNaNWPGQ/zXsZOddYECfJaqxFWgrZ9HC2Kvc5vl9upOgUUHKzURjAVf2N+f6tEJiojqXUuA==",
+ "requires": {
+ "gaxios": "^3.0.0",
+ "json-bigint": "^1.0.0"
+ }
+ },
+ "google-auth-library": {
+ "version": "6.0.6",
+ "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-6.0.6.tgz",
+ "integrity": "sha512-fWYdRdg55HSJoRq9k568jJA1lrhg9i2xgfhVIMJbskUmbDpJGHsbv9l41DGhCDXM21F9Kn4kUwdysgxSYBYJUw==",
+ "requires": {
+ "arrify": "^2.0.0",
+ "base64-js": "^1.3.0",
+ "ecdsa-sig-formatter": "^1.0.11",
+ "fast-text-encoding": "^1.0.0",
+ "gaxios": "^3.0.0",
+ "gcp-metadata": "^4.1.0",
+ "gtoken": "^5.0.0",
+ "jws": "^4.0.0",
+ "lru-cache": "^6.0.0"
+ }
+ },
+ "google-p12-pem": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.0.3.tgz",
+ "integrity": "sha512-wS0ek4ZtFx/ACKYF3JhyGe5kzH7pgiQ7J5otlumqR9psmWMYc+U9cErKlCYVYHoUaidXHdZ2xbo34kB+S+24hA==",
+ "requires": {
+ "node-forge": "^0.10.0"
+ }
+ },
+ "googleapis": {
+ "version": "59.0.0",
+ "resolved": "https://registry.npmjs.org/googleapis/-/googleapis-59.0.0.tgz",
+ "integrity": "sha512-GV/E4KRN89a4GxSk7D7cwUfRYgcJHR05sOgm/WGdwc/u8dxNXG5lWmz9gF5ZwFGk2yKtVxL4VZNn4zBuZ6rmGg==",
+ "requires": {
+ "google-auth-library": "^6.0.0",
+ "googleapis-common": "^4.4.0"
+ }
+ },
+ "googleapis-common": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/googleapis-common/-/googleapis-common-4.4.0.tgz",
+ "integrity": "sha512-Bgrs8/1OZQFFIfVuX38L9t48rPAkVUXttZy6NzhhXxFOEMSHgfFIjxou7RIXOkBHxmx2pVwct9WjKkbnqMYImQ==",
+ "requires": {
+ "extend": "^3.0.2",
+ "gaxios": "^3.0.0",
+ "google-auth-library": "^6.0.0",
+ "qs": "^6.7.0",
+ "url-template": "^2.0.8",
+ "uuid": "^8.0.0"
+ }
+ },
+ "gtoken": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.0.3.tgz",
+ "integrity": "sha512-Nyd1wZCMRc2dj/mAD0LlfQLcAO06uKdpKJXvK85SGrF5+5+Bpfil9u/2aw35ltvEHjvl0h5FMKN5knEU+9JrOg==",
+ "requires": {
+ "gaxios": "^3.0.0",
+ "google-p12-pem": "^3.0.0",
+ "jws": "^4.0.0",
+ "mime": "^2.2.0"
+ }
+ },
+ "has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "requires": {
+ "function-bind": "^1.1.1"
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
+ },
+ "has-symbols": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
+ "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg=="
+ },
+ "homebridge-lib": {
+ "version": "4.7.14",
+ "resolved": "https://registry.npmjs.org/homebridge-lib/-/homebridge-lib-4.7.14.tgz",
+ "integrity": "sha512-8eUGTVrCRd7WHwEH49CgqYUu2q9WjeTVDnEA5WXL2ZvPevTMCck5GcVIXtvVWxr9we8Ay0ybFp0N5RRlrIzH/g==",
+ "requires": {
+ "bonjour": "^3.5.0",
+ "chalk": "^4.1.0",
+ "debug": "^4.1.1",
+ "semver": "^7.3.2"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ }
+ }
+ },
+ "https-proxy-agent": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
+ "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
+ "requires": {
+ "agent-base": "6",
+ "debug": "4"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ }
+ }
+ },
+ "ip": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
+ "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo="
+ },
+ "is-arguments": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz",
+ "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA=="
+ },
+ "is-callable": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.1.tgz",
+ "integrity": "sha512-wliAfSzx6V+6WfMOmus1xy0XvSgf/dlStkvTfq7F0g4bOIW0PSUbnyse3NhDwdyYS1ozfUtAAySqTws3z9Eqgg=="
+ },
+ "is-date-object": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz",
+ "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g=="
+ },
+ "is-regex": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz",
+ "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==",
+ "requires": {
+ "has-symbols": "^1.0.1"
+ }
+ },
+ "is-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
+ "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw=="
+ },
+ "is-symbol": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz",
+ "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==",
+ "requires": {
+ "has-symbols": "^1.0.1"
+ }
+ },
+ "json-bigint": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz",
+ "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==",
+ "requires": {
+ "bignumber.js": "^9.0.0"
+ }
+ },
+ "jwa": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz",
+ "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==",
+ "requires": {
+ "buffer-equal-constant-time": "1.0.1",
+ "ecdsa-sig-formatter": "1.0.11",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "jws": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz",
+ "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==",
+ "requires": {
+ "jwa": "^2.0.0",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "requires": {
+ "yallist": "^4.0.0"
+ }
+ },
+ "mime": {
+ "version": "2.4.6",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz",
+ "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA=="
+ },
+ "moment": {
+ "version": "2.27.0",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.27.0.tgz",
+ "integrity": "sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ=="
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ },
+ "multicast-dns": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz",
+ "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==",
+ "requires": {
+ "dns-packet": "^1.3.1",
+ "thunky": "^1.0.2"
+ }
+ },
+ "multicast-dns-service-types": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz",
+ "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE="
+ },
"node-dns-sd": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/node-dns-sd/-/node-dns-sd-0.4.1.tgz",
"integrity": "sha512-x+WSuMgvDBQv24OCq75YHcZj1SOzvP5fU4Tz+PBUiVvVBsfc+9XAHAuIftaCpf2nPLl+ys71uZoGr/v9fVDa6A=="
},
+ "node-fetch": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
+ "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
+ },
+ "node-forge": {
+ "version": "0.10.0",
+ "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz",
+ "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA=="
+ },
+ "object-inspect": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz",
+ "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA=="
+ },
+ "object-is": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.2.tgz",
+ "integrity": "sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ==",
+ "requires": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.5"
+ }
+ },
+ "object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="
+ },
+ "object.assign": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
+ "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
+ "requires": {
+ "define-properties": "^1.1.2",
+ "function-bind": "^1.1.1",
+ "has-symbols": "^1.0.0",
+ "object-keys": "^1.0.11"
+ }
+ },
+ "qs": {
+ "version": "6.9.4",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz",
+ "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ=="
+ },
+ "regexp.prototype.flags": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz",
+ "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==",
+ "requires": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.0-next.1"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
+ },
+ "semver": {
+ "version": "7.3.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
+ "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ=="
+ },
+ "string.prototype.trimend": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz",
+ "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==",
+ "requires": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.5"
+ }
+ },
+ "string.prototype.trimstart": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz",
+ "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==",
+ "requires": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.5"
+ }
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ },
+ "thunky": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz",
+ "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA=="
+ },
+ "url-template": {
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz",
+ "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE="
+ },
+ "uuid": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.0.tgz",
+ "integrity": "sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ=="
+ },
"ws": {
"version": "7.3.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz",
"integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA=="
+ },
+ "yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
}
}
}
diff --git a/package.json b/package.json
index 7e070066..21d8fd47 100644
--- a/package.json
+++ b/package.json
@@ -45,6 +45,8 @@
"dependencies": {
"axios": "0.20.0",
"color-convert": "2.0.1",
+ "fakegato-history": "0.5.6",
+ "homebridge-lib": "4.7.14",
"node-dns-sd": "0.4.1",
"ws": "7.3.1"
},
From 5cba7192f8d496cb90dd92469a8ac19053532f1d Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Fri, 11 Sep 2020 00:08:01 +0100
Subject: [PATCH 0109/3183] code formatting
---
lib/eWeLinkHTTP.js | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/lib/eWeLinkHTTP.js b/lib/eWeLinkHTTP.js
index f7701ed7..4756c48b 100644
--- a/lib/eWeLinkHTTP.js
+++ b/lib/eWeLinkHTTP.js
@@ -145,9 +145,7 @@ module.exports = class eWeLinkHTTP {
}
let deviceList = [];
if (body.data.thingList && body.data.thingList.length > 0) {
- body.data.thingList.forEach(device => {
- deviceList.push(device.itemData);
- });
+ body.data.thingList.forEach(device => deviceList.push(device.itemData));
}
resolve(deviceList);
}).catch(err => {
From c549111b91770a41e9325c496aeee167b39c1ffb Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Fri, 11 Sep 2020 00:09:32 +0100
Subject: [PATCH 0110/3183] eve readings
---
lib/eWeLink.js | 64 ++++++++++++++++++++++++++++++++++----------------
1 file changed, 44 insertions(+), 20 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index a5e87086..55212147 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -5,7 +5,9 @@ const convert = require("color-convert");
const eWeLinkHTTP = require("./eWeLinkHTTP");
const eWeLinkWS = require("./eWeLinkWS");
const eWeLinkLAN = require("./eWeLinkLAN");
-let Accessory, Service, Characteristic, UUIDGen;
+const fakegato = require("fakegato-history");
+const hbLib = require("homebridge-lib");
+let Accessory, Characteristic, EveService, EveHistoryService, Service, UUIDGen;
class eWeLink {
constructor(log, config, api) {
if (!log || !api) {
@@ -299,6 +301,11 @@ class eWeLink {
}
break;
case "outlet":
+ accessory.addService(Service.Outlet);
+ accessory.getService(Service.Outlet).addCharacteristic(EveService.Characteristics.Voltage);
+ accessory.getService(Service.Outlet).addCharacteristic(EveService.Characteristics.CurrentConsumption);
+ accessory.getService(Service.Outlet).addCharacteristic(EveService.Characteristics.ElectricCurrent);
+ break;
case "usb":
accessory.addService(Service.Outlet);
break;
@@ -541,85 +548,89 @@ class eWeLink {
refreshAccessory(accessory, newParams) {
switch (accessory.context.type) {
case "valve":
- if (Array.isArray(newParams.switches)) {
+ if (Object.keys(newParams).some(v => cns.devicesValveParams.includes(v)) && Array.isArray(newParams.switches)) {
this.externalValveUpdate(accessory, newParams);
}
return true;
case "blind":
- if (Array.isArray(newParams.switches)) {
+ if (Object.keys(newParams).some(v => cns.devicesBlindParams.includes(v)) && Array.isArray(newParams.switches)) {
this.externalBlindUpdate(accessory, newParams);
}
return true;
case "garage":
- if (newParams.hasOwnProperty("switch") || Array.isArray(newParams.switches)) {
+ if (Object.keys(newParams).some(v => cns.devicesGarageParams.includes(v)) && Array.isArray(newParams.switches)) {
this.externalGarageUpdate(accessory, newParams);
}
return true;
case "lock":
- if (newParams.hasOwnProperty("switch")) {
+ if (Object.keys(newParams).some(v => cns.devicesLockParams.includes(v))) {
this.externalLockUpdate(accessory, newParams);
}
return true;
case "sensor":
- if (newParams.hasOwnProperty("switch")) {
+ if (Object.keys(newParams).some(v => cns.devicesSensorParams.includes(v))) {
this.externalSensorUpdate(accessory, newParams);
}
return true;
case "fan":
- if (Array.isArray(newParams.switches) || (newParams.hasOwnProperty("light") && newParams.hasOwnProperty("fan") && newParams.hasOwnProperty("speed"))) {
+ if (Object.keys(newParams).some(v => cns.devicesFanParams.includes(v))) {
this.externalFanUpdate(accessory, newParams);
}
return true;
case "thermostat":
- if (newParams.hasOwnProperty("currentTemperature") || newParams.hasOwnProperty("currentHumidity") || newParams.hasOwnProperty("switch") || newParams.hasOwnProperty("masterSwitch")) {
+ if (Object.keys(newParams).some(v => cns.devicesThermostatParams.includes(v))) {
this.externalThermostatUpdate(accessory, newParams);
}
return true;
case "outlet":
- if (newParams.hasOwnProperty("switch")) {
+ if (Object.keys(newParams).some(v => cns.devicesOutletParams.includes(v))) {
this.externalOutletUpdate(accessory, newParams);
}
return true;
case "usb":
- if (Array.isArray(newParams.switches)) {
+ if (Object.keys(newParams).some(v => cns.devicesUSBParams.includes(v)) && Array.isArray(newParams.switches)) {
this.externalUSBUpdate(accessory, newParams);
}
return true;
case "scm":
- if (Array.isArray(newParams.switches)) {
+ if (Object.keys(newParams).some(v => cns.devicesSCMParams.includes(v)) && Array.isArray(newParams.switches)) {
this.externalSCMUpdate(accessory, newParams);
}
return true;
case "light":
if (cns.devicesSingleSwitch.includes(accessory.context.eweUIID) && cns.devicesSingleSwitchLight.includes(accessory.context.eweModel)) {
- if (newParams.hasOwnProperty("switch") || newParams.hasOwnProperty("state") || newParams.hasOwnProperty("bright") || newParams.hasOwnProperty("colorR") || newParams.hasOwnProperty("brightness") || newParams.hasOwnProperty("channel0") || newParams.hasOwnProperty("channel2") || newParams.hasOwnProperty("zyx_mode")) {
+ if (Object.keys(newParams).some(v => cns.devicesSingleSwitchLightParams.includes(v))) {
this.externalSingleLightUpdate(accessory, newParams);
}
} else if (cns.devicesMultiSwitch.includes(accessory.context.eweUIID) && cns.devicesMultiSwitchLight.includes(accessory.context.eweModel)) {
- if (Array.isArray(newParams.switches)) {
+ if (Object.keys(newParams).some(v => cns.devicesMultiSwitchLightParams.includes(v)) && Array.isArray(newParams.switches)) {
this.externalMultiLightUpdate(accessory, newParams);
}
}
return true;
case "switch":
if (cns.devicesSingleSwitch.includes(accessory.context.eweUIID)) {
- if (newParams.hasOwnProperty("switch")) {
+ if (Object.keys(newParams).some(v => cns.devicesSingleSwitchParams.includes(v))) {
this.externalSingleSwitchUpdate(accessory, newParams);
}
} else if (cns.devicesMultiSwitch.includes(accessory.context.eweUIID)) {
- if (Array.isArray(newParams.switches)) {
+ if (Object.keys(newParams).some(v => cns.devicesMultiSwitchParams.includes(v)) && Array.isArray(newParams.switches)) {
this.externalMultiSwitchUpdate(accessory, newParams);
}
}
return true;
case "rf_pri":
- this.externalRFDeviceUpdate(accessory, newParams);
+ if (Object.keys(newParams).some(v => cns.devicesRFBridgeParams.includes(v))) {
+ this.externalRFDeviceUpdate(accessory, newParams);
+ }
return true;
case "rf_sub":
case "zb_pri":
return true;
case "zb_sub":
- this.externalZBDeviceUpdate(accessory, newParams);
+ if (Object.keys(newParams).some(v => cns.devicesZBBridgeParams.includes(v))) {
+ this.externalZBDeviceUpdate(accessory, newParams);
+ }
return true;
default:
return false;
@@ -988,7 +999,7 @@ class eWeLink {
if (this.config.debug) {
this.log("[%s] requesting to turn [%s].", accessory.displayName, value ? "on" : "off");
}
- accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, value);
+ accessory.getService(Outlet).updateCharacteristic(Characteristic.On, value);
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
callback("[" + accessory.displayName + "] " + err + ".");
@@ -1525,7 +1536,18 @@ class eWeLink {
}
externalOutletUpdate(accessory, params) {
try {
- accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, params.switch === "on");
+ if (params.hasOwnProperty("switch")) {
+ accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, params.switch === "on");
+ }
+ if (params.hasOwnProperty("power")) {
+ accessory.getService(Service.Outlet).updateCharacteristic(EveService.Characteristics.CurrentConsumption, parseFloat(params.power));
+ }
+ if (params.hasOwnProperty("voltage")) {
+ accessory.getService(Service.Outlet).updateCharacteristic(EveService.Characteristics.Voltage, parseFloat(params.voltage));
+ }
+ if (params.hasOwnProperty("current")) {
+ accessory.getService(Service.Outlet).updateCharacteristic(EveService.Characteristics.ElectricCurrent, parseFloat(params.current));
+ }
} catch (err) {
this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
@@ -1773,8 +1795,10 @@ class eWeLink {
}
module.exports = function(homebridge) {
Accessory = homebridge.platformAccessory;
- Service = homebridge.hap.Service;
Characteristic = homebridge.hap.Characteristic;
+ EveService = new hbLib.EveHomeKitTypes(homebridge);
+ EveHistoryService = fakegato(homebridge);
+ Service = homebridge.hap.Service;
UUIDGen = homebridge.hap.uuid;
return eWeLink;
};
\ No newline at end of file
From 671a970241975eebbc970de85ed3c2699d77d5e1 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Fri, 11 Sep 2020 00:12:23 +0100
Subject: [PATCH 0111/3183] 2.26.0-0
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 0e0ca51e..873013f6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.25.2",
+ "version": "2.26.0-0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 21d8fd47..06f177bb 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.25.2",
+ "version": "2.26.0-0",
"author": "bwp91",
"contributors": [
"gbro115",
From 74aeae4a564420da4f963b6e1f0a64c665860f88 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Fri, 11 Sep 2020 00:22:59 +0100
Subject: [PATCH 0112/3183] outlet type line 1001
---
lib/eWeLink.js | 26 ++++++++------------------
1 file changed, 8 insertions(+), 18 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 55212147..9db0619b 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -30,9 +30,8 @@ class eWeLink {
//*** Set up HTTP client and get the user HTTP host ***\\
this.httpClient = new eWeLinkHTTP(this.config, this.log);
this.httpClient.getHost()
- .then(res => { //*** Use the HTTP API host to log into eWeLink ***\\
- return this.httpClient.login();
- }).then(res => { //*** Set up the web socket client ***\\
+ .then(() => this.httpClient.login())
+ .then(res => { //*** Set up the web socket client ***\\
this.wsClient = new eWeLinkWS(this.config, this.log, res);
return this.wsClient.getHost();
}).then(() => { //*** Open web socket connection and get device list via HTTP ***\\
@@ -999,7 +998,7 @@ class eWeLink {
if (this.config.debug) {
this.log("[%s] requesting to turn [%s].", accessory.displayName, value ? "on" : "off");
}
- accessory.getService(Outlet).updateCharacteristic(Characteristic.On, value);
+ accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, value);
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
callback("[" + accessory.displayName + "] " + err + ".");
@@ -1141,9 +1140,7 @@ class eWeLink {
if (this.config.debug) {
this.log("[%s] updating brightness to [%s%].", accessory.displayName, value);
}
- setTimeout(() => {
- this.sendDeviceUpdate(accessory, params, callback);
- }, 250);
+ setTimeout(() => this.sendDeviceUpdate(accessory, params, callback), 250);
} catch (err) {
let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
@@ -1219,9 +1216,7 @@ class eWeLink {
default:
throw "unknown device UIID";
}
- setTimeout(() => {
- this.sendDeviceUpdate(accessory, params, callback);
- }, 250);
+ setTimeout(() => this.sendDeviceUpdate(accessory, params, callback), 250);
} catch (err) {
let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
@@ -1331,9 +1326,7 @@ class eWeLink {
}
accessory.getService(accessory.context.rfChls[rfChl]).updateCharacteristic(Characteristic.On, true);
this.sendDeviceUpdate(accessory, params, callback);
- setTimeout(() => {
- accessory.getService(accessory.context.rfChls[rfChl]).updateCharacteristic(Characteristic.On, false);
- }, 3000);
+ setTimeout(() => accessory.getService(accessory.context.rfChls[rfChl]).updateCharacteristic(Characteristic.On, false), 3000);
} catch (err) {
let str = "[" + accessory.displayName + " " + name + "] could not be updated as " + err + ".";
this.log.error(str);
@@ -1409,8 +1402,7 @@ class eWeLink {
.updateCharacteristic(Characteristic.CurrentDoorState, newPos)
.updateCharacteristic(Characteristic.TargetDoorState, newPos - 2);
setTimeout(() => {
- accessory.getService(Service.GarageDoorOpener)
- .updateCharacteristic(Characteristic.CurrentDoorState, newPos - 2);
+ accessory.getService(Service.GarageDoorOpener).updateCharacteristic(Characteristic.CurrentDoorState, newPos - 2);
}, parseInt(garageConfig.operationTime) * 100);
}
setTimeout(() => {
@@ -1684,9 +1676,7 @@ class eWeLink {
let bAccessory;
if ((bAccessory = this.devicesInHB.get(idToCheck + accessory.context.rfChlMap[params.rfChl]))) {
bAccessory.getService(bAccessory.context.rfChls[params.rfChl]).updateCharacteristic(Characteristic.On, 1);
- setTimeout(() => {
- bAccessory.getService(bAccessory.context.rfChls[params.rfChl]).updateCharacteristic(Characteristic.On, 0);
- }, 3000);
+ setTimeout(() => bAccessory.getService(bAccessory.context.rfChls[params.rfChl]).updateCharacteristic(Characteristic.On, 0), 3000);
} else {
throw "rf button not found in Homebridge";
}
From bb1eb3cfc2b6077f8f05891c737a742c513202f8 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Fri, 11 Sep 2020 14:08:18 +0100
Subject: [PATCH 0113/3183] Update index.js
---
index.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/index.js b/index.js
index 624be64e..4902dd17 100644
--- a/index.js
+++ b/index.js
@@ -1,6 +1,6 @@
/* jshint esversion: 9, -W030, node: true */
"use strict";
module.exports = function (homebridge) {
- let eWeLink = require("./lib/eWeLink.js")(homebridge);
+ const eWeLink = require("./lib/eWeLink.js")(homebridge);
homebridge.registerPlatform("homebridge-ewelink", "eWeLink", eWeLink, true);
};
\ No newline at end of file
From c967ba8b677a3476a04f33b8cd0baf2758a0a257 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Fri, 11 Sep 2020 14:09:13 +0100
Subject: [PATCH 0114/3183] refactoring
---
lib/eWeLink.js | 182 ++++++++++++++++++++++++++-----------------------
1 file changed, 98 insertions(+), 84 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 9db0619b..b5c6ff68 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -1,20 +1,20 @@
/* jshint esversion: 9, -W030, node: true */
"use strict";
-const cns = require("./constants");
-const convert = require("color-convert");
-const eWeLinkHTTP = require("./eWeLinkHTTP");
-const eWeLinkWS = require("./eWeLinkWS");
-const eWeLinkLAN = require("./eWeLinkLAN");
-const fakegato = require("fakegato-history");
-const hbLib = require("homebridge-lib");
let Accessory, Characteristic, EveService, EveHistoryService, Service, UUIDGen;
+const cns = require("./constants"),
+ convert = require("color-convert"),
+ eWeLinkHTTP = require("./eWeLinkHTTP"),
+ eWeLinkWS = require("./eWeLinkWS"),
+ eWeLinkLAN = require("./eWeLinkLAN"),
+ fakegato = require("fakegato-history"),
+ hbLib = require("homebridge-lib");
class eWeLink {
constructor(log, config, api) {
- if (!log || !api) {
- return;
- }
- if (!config || (!config.username || !config.password || !config.countryCode)) {
- log.error("đ´ Cannot load homebridge-ewelink - please check your eWeLink credentials in the plugin settings.");
+ if (!log || !api || !config) return;
+ if (!config.username || !config.password || !config.countryCode) {
+ log.error("************** Cannot load homebridge-ewelink **************");
+ log.error("Your eWeLink credentials missing from the Homebridge config.");
+ log.error("************************************************************");
return;
}
this.log = log;
@@ -24,6 +24,7 @@ class eWeLink {
this.devicesInEwe = new Map();
this.cusG = new Map();
this.cusS = new Map();
+ this.eveLogPath = this.api.user.persistPath() + "/homebridge-ewelink";
this.api
.on("didFinishLaunching", () => {
this.log("Plugin has finished initialising. Starting synchronisation with eWeLink account.");
@@ -40,10 +41,9 @@ class eWeLink {
}).then(res => { //*** Get device IP addresses for LAN mode ***\\
this.httpDevices = res
.filter(device => device.hasOwnProperty("extra") && device.extra.hasOwnProperty("uiid"))
- .filter(device => !(this.config.hideDevFromHB || "").includes(device.deviceid))
- .forEach(device => this.devicesInEwe.set(device.deviceid, device));
- this.httpDevices = res;
+ .filter(device => !(this.config.hideDevFromHB || "").includes(device.deviceid));
this.lanClient = new eWeLinkLAN(this.config, this.log, this.httpDevices);
+ this.httpDevices.forEach(device => this.devicesInEwe.set(device.deviceid, device));
return this.lanClient.getHosts();
}).then(res => { //*** Set up the LAN mode listener ***\\
this.lanDevices = res.map;
@@ -55,14 +55,16 @@ class eWeLink {
if (Object.keys(this.httpDevices).length === 0 && Object.keys(this.lanDevices).length === 0) {
Array.from(this.devicesInHB.values()).forEach(a => this.removeAccessory(a));
this.devicesInHB.clear();
- this.log.warn("đ No devices were found registered to your eWeLink account so disabling plugin.");
+ this.log.warn("******* Not loading homebridge-ewelink *******");
+ this.log.warn("No devices were found in your eWeLink account.");
+ this.log.warn("**********************************************");
return;
}
//*** Make a map of custom groups from Homebridge config ***\\
if (Object.keys(this.config.groups || []).length > 0) {
this.config.groups
- .filter(g => g.hasOwnProperty("deviceId") && this.devicesInEwe.has(g.deviceId.toLowerCase()))
.filter(g => g.hasOwnProperty("type") && cns.allowedGroups.includes(g.type))
+ .filter(g => g.hasOwnProperty("deviceId") && this.devicesInEwe.has(g.deviceId.toLowerCase()))
.forEach(g => this.cusG.set(g.deviceId + "SWX", g));
}
//*** Make a map of RF Bridge custom sensors from Homebridge config ***\\
@@ -76,42 +78,35 @@ class eWeLink {
this.log("[%s] primary devices were loaded from your eWeLink account.", this.devicesInEwe.size);
this.log("[%s] primary devices were discovered on your local network.", this.lanDevicesOnline);
//*** Remove Homebridge accessories that don't appear in eWeLink ***\\
- this.devicesInHB.forEach(accessory => {
- if (!this.devicesInEwe.has(accessory.context.eweDeviceId)) {
- this.removeAccessory(accessory);
+ this.devicesInHB.forEach(a => {
+ if (!this.devicesInEwe.has(a.context.eweDeviceId)) {
+ this.removeAccessory(a);
}
});
//*** Synchronise devices between eWeLink and Homebridge and set up ws/lan listeners ***\\
- this.devicesInEwe.forEach(device => this.initialiseDevice(device));
- this.wsClient.receiveUpdate(device => this.receiveDeviceUpdate(device));
- this.lanClient.receiveUpdate(device => this.receiveDeviceUpdate(device));
- this.log("đĸ eWeLink setup complete. If you're enjoying this package please consider a âī¸ on GitHub!");
+ this.devicesInEwe.forEach(d => this.initialiseDevice(d));
+ this.wsClient.receiveUpdate(d => this.receiveDeviceUpdate(d));
+ this.lanClient.receiveUpdate(d => this.receiveDeviceUpdate(d));
+ this.log("eWeLink setup complete. If you're enjoying this package please consider a âī¸ on GitHub :).");
if (this.config.debugReqRes) {
this.log.warn("You have 'Request & Response Logging' enabled. This setting is not recommended for long-term use.");
}
})();
}).catch(err => {
- this.log.error("đ´ Cannot load homebridge-ewelink - %s", err);
- if (this.lanClient) {
- this.lanClient.closeConnection();
- }
- if (this.wsClient) {
- this.wsClient.closeConnection();
- }
+ this.log.error("************** Cannot load homebridge-ewelink **************");
+ this.log.error(err);
+ this.log.error("************************************************************");
+ if (this.lanClient) this.lanClient.closeConnection();
+ if (this.wsClient) this.wsClient.closeConnection();
});
})
.on('shutdown', () => {
- if (this.lanClient) {
- this.lanClient.closeConnection();
- }
- if (this.wsClient) {
- this.wsClient.closeConnection();
- }
+ if (this.lanClient) this.lanClient.closeConnection();
+ if (this.wsClient) this.wsClient.closeConnection();
});
}
initialiseDevice(device) {
let accessory;
- device.params.updateSource = "HTTP";
//*** First add the device if it isn't already in Homebridge. Yeah this code looks a mess :| ***\\
if (!this.devicesInHB.has(device.deviceid + "SWX") && !this.devicesInHB.has(device.deviceid + "SW0")) {
if (device.extra.uiid === 2 && device.brandName === "coolkit" && device.productModel === "0285") {
@@ -170,8 +165,9 @@ class eWeLink {
let isX = accessory.context.hbDeviceId.substr(-1) === "X",
isRfBridge = cns.devicesRFBridge.includes(accessory.context.eweUIID),
rfBridgeChange = false;
- accessory.getService(Service.AccessoryInformation).setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion);
- accessory.context.reachableWAN = accessory.context.eweUIID !== 102 ? device.online : true; //*** DW2 ***\\
+ accessory.getService(Service.AccessoryInformation)
+ .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion);
+ accessory.context.reachableWAN = accessory.context.eweUIID !== 102 ? device.online : true;
accessory.context.reachableLAN = this.lanDevices.get(device.deviceid).online || false;
accessory.context.inUse = false;
let str = accessory.context.reachableLAN ?
@@ -197,11 +193,10 @@ class eWeLink {
}
if (isRfBridge && oAccessory.context.sensorType !== "button") {
let ct = this.cusS.has(oAccessory.context.hbDeviceId) ? this.cusS.get(oAccessory.context.hbDeviceId).type : "motion";
- if (ct !== oAccessory.context.sensorType || typeof accessory.context.updated === "undefined") {
- rfBridgeChange = true;
- }
+ if (ct !== oAccessory.context.sensorType) rfBridgeChange = true;
}
- oAccessory.getService(Service.AccessoryInformation).setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion);
+ oAccessory.getService(Service.AccessoryInformation)
+ .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion);
oAccessory.context.reachableWAN = device.online;
oAccessory.context.reachableLAN = this.lanDevices.get(device.deviceid).online || false;
this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory);
@@ -224,13 +219,15 @@ class eWeLink {
}
}
addAccessory(device, hbDeviceId, type) {
- let channelCount = type === "rf_pri" ? Object.keys((device.tags && device.tags.zyx_info) || []).length : cns.chansFromUiid[device.extra.uiid],
- switchNumber = hbDeviceId.substr(-1).toString(),
- newDeviceName = type === "rf_sub" ? device.tags.zyx_info[switchNumber - 1].name : device.name;
+ let switchNumber = hbDeviceId.substr(-1).toString(),
+ newDeviceName = type === "rf_sub" ? device.tags.zyx_info[switchNumber - 1].name : device.name,
+ channelCount = type === "rf_pri" ?
+ Object.keys((device.tags && device.tags.zyx_info) || []).length :
+ cns.chansFromUiid[device.extra.uiid];
if (["1", "2", "3", "4"].includes(switchNumber) && type !== "rf_sub") {
newDeviceName += " SW" + switchNumber;
if ((this.config.hideFromHB || "").includes(hbDeviceId) && cns.devicesHideable.includes(type)) {
- this.log.warn("[%s] will not be added as per configuration.", newDeviceName);
+ this.log("[%s] will not be added as per configuration.", newDeviceName);
return;
}
}
@@ -291,18 +288,15 @@ class eWeLink {
accessory.addService(Service.Lightbulb);
break;
case "thermostat":
- if (!this.config.hideTHSwitch) {
- accessory.addService(Service.Switch);
- }
+ if (!this.config.hideTHSwitch) accessory.addService(Service.Switch);
accessory.addService(Service.TemperatureSensor);
- if (device.params.sensorType !== "DS18B20") {
- accessory.addService(Service.HumiditySensor);
- }
+ if (device.params.sensorType !== "DS18B20") accessory.addService(Service.HumiditySensor);
break;
case "outlet":
accessory.addService(Service.Outlet);
accessory.getService(Service.Outlet).addCharacteristic(EveService.Characteristics.Voltage);
accessory.getService(Service.Outlet).addCharacteristic(EveService.Characteristics.CurrentConsumption);
+ accessory.getService(Service.Outlet).addCharacteristic(EveService.Characteristics.TotalConsumption);
accessory.getService(Service.Outlet).addCharacteristic(EveService.Characteristics.ElectricCurrent);
break;
case "usb":
@@ -317,7 +311,6 @@ class eWeLink {
break;
case "rf_pri":
accessory.context.rfChlMap = {};
- accessory.context.updated = true;
break;
case "zb_pri":
break;
@@ -334,20 +327,20 @@ class eWeLink {
accessory.context.sensorType = this.cusS.has(hbDeviceId) ? this.cusS.get(hbDeviceId).type : "motion";
break;
default:
- throw "RF device type is not supported";
+ throw "unsupported rf device type [" + device.tags.zyx_info[parseInt(switchNumber) - 1].remote_type + "]. Please create an issue on GitHub";
}
let mAccessory = this.devicesInHB.get(device.deviceid + "SW0");
device.tags.zyx_info[parseInt(switchNumber) - 1].buttonName.forEach(button => {
- let rfChan, name;
- Object.entries(button).forEach(([k, v]) => {
- rfChan = k;
- name = v;
+ let rfData;
+ Object.entries(button).forEach(([k, v]) => rfData = {
+ rfChan: k,
+ name: v
});
- accessory.context.rfChls[rfChan] = name;
- mAccessory.context.rfChlMap[rfChan] = switchNumber;
+ accessory.context.rfChls[rfData.rfChan] = rfData.name;
+ mAccessory.context.rfChlMap[rfData.rfChan] = switchNumber;
switch (accessory.context.sensorType) {
case "button":
- accessory.addService(Service.Switch, name, "switch" + rfChan);
+ accessory.addService(Service.Switch, rfData.name, "switch" + rfData.rfChan);
break;
case "water":
accessory.addService(Service.LeakSensor);
@@ -413,19 +406,15 @@ class eWeLink {
}
}
configureAccessory(accessory) {
- if (!this.log) {
- return;
- }
+ if (!this.log) return;
try {
+ accessory.context.reachableWAN = true;
+ accessory.context.reachableLAN = true;
switch (accessory.context.type) {
case "valve":
["A", "B"].forEach(v => {
accessory.getService("Valve " + v).getCharacteristic(Characteristic.Active)
- .on("set", (value, callback) => {
- accessory.getService("Valve " + v).getCharacteristic(Characteristic.Active).value !== value ?
- this.internalValveUpdate(accessory, "Valve " + v, value, callback) :
- callback();
- });
+ .on("set", (value, callback) => this.internalValveUpdate(accessory, "Valve " + v, value, callback));
accessory.getService("Valve " + v).getCharacteristic(Characteristic.SetDuration)
.on("set", (value, callback) => {
if (accessory.getService("Valve " + v).getCharacteristic(Characteristic.InUse).value) {
@@ -433,7 +422,7 @@ class eWeLink {
clearTimeout(accessory.getService("Valve " + v).timer);
accessory.getService("Valve " + v).timer = setTimeout(() => {
accessory.getService("Valve " + v).setCharacteristic(Characteristic.Active, 0);
- }, (value * 1000));
+ }, value * 1000);
}
callback();
});
@@ -441,10 +430,10 @@ class eWeLink {
break;
case "blind":
accessory.getService(Service.WindowCovering).getCharacteristic(Characteristic.TargetPosition)
+ .on("set", (value, callback) => this.internalBlindUpdate(accessory, value, callback))
.setProps({
minStep: 100
- })
- .on("set", (value, callback) => this.internalBlindUpdate(accessory, value, callback));
+ });
break;
case "garage":
accessory.getService(Service.GarageDoorOpener).getCharacteristic(Characteristic.TargetDoorState)
@@ -458,10 +447,10 @@ class eWeLink {
accessory.getService(Service.Fanv2).getCharacteristic(Characteristic.Active)
.on("set", (value, callback) => this.internalFanUpdate(accessory, "power", value, callback));
accessory.getService(Service.Fanv2).getCharacteristic(Characteristic.RotationSpeed)
+ .on("set", (value, callback) => this.internalFanUpdate(accessory, "speed", value, callback))
.setProps({
minStep: 33
- })
- .on("set", (value, callback) => this.internalFanUpdate(accessory, "speed", value, callback));
+ });
accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On)
.on("set", (value, callback) => this.internalFanUpdate(accessory, "light", value, callback));
break;
@@ -474,6 +463,12 @@ class eWeLink {
case "outlet":
accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On)
.on("set", (value, callback) => this.internalOutletUpdate(accessory, value, callback));
+ accessory.log = this.log;
+ accessory.eveLogger = new EveHistoryService("energy", accessory, {
+ storage: "fs",
+ path: this.eveLogPath
+ });
+ accessory.context.totalEnergyTemp = 0;
break;
case "usb":
accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On)
@@ -537,8 +532,6 @@ class eWeLink {
}
break;
}
- accessory.context.reachableWAN = true;
- accessory.context.reachableLAN = true;
this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
} catch (err) {
this.log.warn("[%s] could not be refreshed as %s.", accessory.displayName, err);
@@ -683,9 +676,7 @@ class eWeLink {
accessory.context.reachableWAN = device.params.online;
this.log("[%s] has been reported [%s] via [WS].", accessory.displayName, accessory.context.reachableWAN ? "online" : "offline");
this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
- if (accessory.context.reachableWAN) {
- this.wsClient.requestUpdate(accessory);
- }
+ if (accessory.context.reachableWAN) this.wsClient.requestUpdate(accessory);
} else {
if (this.debug) {
this.log("[%s] Nothing to update from above WS message.", accessory.displayName);
@@ -1533,6 +1524,31 @@ class eWeLink {
}
if (params.hasOwnProperty("power")) {
accessory.getService(Service.Outlet).updateCharacteristic(EveService.Characteristics.CurrentConsumption, parseFloat(params.power));
+ accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.OutletInUse, parseFloat(params.power) > 0);
+ if (accessory.eveLogger.isHistoryLoaded()) {
+ let extraPersistedData = accessory.eveLogger.getExtraPersistedData();
+ if (extraPersistedData !== undefined) {
+ let totalEnergy = extraPersistedData.totalenergy + accessory.context.totalEnergyTemp + parseFloat(params.power) * (30000 / 1000) / 3600 / 1000;
+ accessory.eveLogger.setExtraPersistedData({
+ totalEnergy,
+ lastReset: extraPersistedData.lastReset
+ });
+ } else {
+ let totalEnergy = accessory.context.totalEnergyTemp + parseFloat(params.power) * (30000 / 1000) / 3600 / 1000;
+ accessory.eveLogger.setExtraPersistedData({
+ totalEnergy,
+ lastReset: 0
+ });
+ }
+ accessory.context.totalEnergyTemp = 0;
+ } else {
+ accessory.context.totalEnergyTemp += parseFloat(params.power) * (30000 / 1000) / 3600 / 1000;
+ let totalEnergy = accessory.context.totalEnergyTemp;
+ }
+ accessory.eveLogger.addEntry({
+ time: Math.floor((new Date()).getTime() / 1000),
+ power: parseFloat(params.power)
+ });
}
if (params.hasOwnProperty("voltage")) {
accessory.getService(Service.Outlet).updateCharacteristic(EveService.Characteristics.Voltage, parseFloat(params.voltage));
@@ -1667,9 +1683,7 @@ class eWeLink {
}
externalRFDeviceUpdate(accessory, params) {
try {
- if (params.updateSource === "HTTP") {
- return;
- }
+ if (!params.hasOwnProperty("updateSource")) return;
let idToCheck = accessory.context.hbDeviceId.slice(0, -1),
timeNow = new Date();
if (params.hasOwnProperty("cmd") && params.cmd === "transmit" && params.hasOwnProperty("rfChl")) { // RF Button
From 05da65457b40afea4b6bad83b05bb200c5f3073c Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Fri, 11 Sep 2020 14:10:01 +0100
Subject: [PATCH 0115/3183] 2.26.0-1
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 873013f6..976b4433 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.26.0-0",
+ "version": "2.26.0-1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 06f177bb..2ffd7773 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.26.0-0",
+ "version": "2.26.0-1",
"author": "bwp91",
"contributors": [
"gbro115",
From 157bba8ebf8933a90e3d6550845283426fa94aab Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sat, 12 Sep 2020 13:37:04 +0100
Subject: [PATCH 0116/3183] add correcting-inteval dep
---
package-lock.json | 5 +++++
package.json | 1 +
2 files changed, 6 insertions(+)
diff --git a/package-lock.json b/package-lock.json
index 976b4433..529f274a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -122,6 +122,11 @@
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
+ "correcting-interval": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/correcting-interval/-/correcting-interval-2.0.0.tgz",
+ "integrity": "sha1-iTdklFcN+C7axTQRHV8n/z6gstM="
+ },
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
diff --git a/package.json b/package.json
index 2ffd7773..fba6c4dd 100644
--- a/package.json
+++ b/package.json
@@ -45,6 +45,7 @@
"dependencies": {
"axios": "0.20.0",
"color-convert": "2.0.1",
+ "correcting-interval": "2.0.0",
"fakegato-history": "0.5.6",
"homebridge-lib": "4.7.14",
"node-dns-sd": "0.4.1",
From 6622c561a84e3ce00e7afcb34018a1c04c4e58a0 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sat, 12 Sep 2020 13:37:48 +0100
Subject: [PATCH 0117/3183] EVE temp/power logging
---
lib/eWeLink.js | 125 +++++++++++++++++++++++++++++++++++++++----------
1 file changed, 101 insertions(+), 24 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index b5c6ff68..338f40ba 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -3,6 +3,7 @@
let Accessory, Characteristic, EveService, EveHistoryService, Service, UUIDGen;
const cns = require("./constants"),
convert = require("color-convert"),
+ corrInterval = require("correcting-interval"),
eWeLinkHTTP = require("./eWeLinkHTTP"),
eWeLinkWS = require("./eWeLinkWS"),
eWeLinkLAN = require("./eWeLinkLAN"),
@@ -24,7 +25,7 @@ class eWeLink {
this.devicesInEwe = new Map();
this.cusG = new Map();
this.cusS = new Map();
- this.eveLogPath = this.api.user.persistPath() + "/homebridge-ewelink";
+ this.eveLogPath = this.api.user.storagePath() + "/persist/";
this.api
.on("didFinishLaunching", () => {
this.log("Plugin has finished initialising. Starting synchronisation with eWeLink account.");
@@ -291,13 +292,32 @@ class eWeLink {
if (!this.config.hideTHSwitch) accessory.addService(Service.Switch);
accessory.addService(Service.TemperatureSensor);
if (device.params.sensorType !== "DS18B20") accessory.addService(Service.HumiditySensor);
+ accessory.log = this.log;
+ accessory.eveLogger = new EveHistoryService("weather", accessory, {
+ storage: "fs",
+ path: this.eveLogPath
+ });
break;
case "outlet":
accessory.addService(Service.Outlet);
accessory.getService(Service.Outlet).addCharacteristic(EveService.Characteristics.Voltage);
accessory.getService(Service.Outlet).addCharacteristic(EveService.Characteristics.CurrentConsumption);
- accessory.getService(Service.Outlet).addCharacteristic(EveService.Characteristics.TotalConsumption);
accessory.getService(Service.Outlet).addCharacteristic(EveService.Characteristics.ElectricCurrent);
+ accessory.getService(Service.Outlet).addCharacteristic(EveService.Characteristics.TotalConsumption);
+ accessory.getService(Service.Outlet).addCharacteristic(EveService.Characteristics.ResetTotal);
+ accessory.context = {
+ ...accessory.context,
+ ...{
+ extraPersistedData: {},
+ lastReset: 0,
+ totalEnergy: 0,
+ totalEnergyTemp: 0
+ }
+ };
+ accessory.eveLogger = new EveHistoryService("energy", accessory, {
+ storage: "fs",
+ path: this.eveLogPath
+ });
break;
case "usb":
accessory.addService(Service.Outlet);
@@ -459,6 +479,23 @@ class eWeLink {
accessory.getService(Service.Switch).getCharacteristic(Characteristic.On)
.on("set", (value, callback) => this.internalThermostatUpdate(accessory, value, callback));
}
+ accessory.log = this.log;
+ accessory.eveLogger = new EveHistoryService("weather", accessory, {
+ storage: "fs",
+ path: this.eveLogPath
+ });
+ corrInterval.setCorrectingInterval(() => {
+ let currentTemp = accessory.getService(Service.TemperatureSensor).getCharacteristic(Characteristic.CurrentTemperature).value,
+ dataToAdd = {
+ time: Date.now(),
+ temp: currentTemp
+ };
+ if (accessory.getService(Service.HumiditySensor)) {
+ dataToAdd.humidity = accessory.getService(Service.HumiditySensor).getCharacteristic(Characteristic.CurrentRelativeHumidity).value;
+ }
+ this.log.warn("[%s] 10 minute inteval recorded [%s°C].", accessory.displayName, currentTemp);
+ accessory.eveLogger.addEntry(dataToAdd);
+ }, 60000);
break;
case "outlet":
accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On)
@@ -468,7 +505,60 @@ class eWeLink {
storage: "fs",
path: this.eveLogPath
});
- accessory.context.totalEnergyTemp = 0;
+ corrInterval.setCorrectingInterval(() => {
+ let currentWatt = accessory.getService(Service.Outlet)
+ .getCharacteristic(EveService.Characteristics.CurrentConsumption).value;
+ this.log.warn("[%s] 10 minute inteval recorded [%sW].", accessory.displayName, currentWatt);
+ if (accessory.eveLogger.isHistoryLoaded()) {
+ accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData();
+ if (accessory.context.extraPersistedData !== undefined) {
+ accessory.context.totalEnergy = accessory.context.extraPersistedData.totalenergy + accessory.context.totalEnergyTemp + currentWatt * 10 / 3600 / 1000;
+ accessory.eveLogger.setExtraPersistedData({
+ totalenergy: accessory.context.totalEnergy,
+ lastReset: accessory.context.extraPersistedData.lastReset
+ });
+ } else {
+ accessory.context.totalEnergy = accessory.context.totalEnergyTemp + currentWatt * 10 / 3600 / 1000;
+ accessory.eveLogger.setExtraPersistedData({
+ totalenergy: accessory.context.totalEnergy,
+ lastReset: 0
+ });
+ }
+ accessory.context.totalEnergytemp = 0;
+ } else {
+ accessory.context.totalEnergyTemp += currentWatt * 10 / 3600 / 1000;
+ accessory.context.totalEnergy = accessory.context.totalEnergyTemp;
+ }
+ accessory.eveLogger.addEntry({
+ time: Date.now(),
+ power: currentWatt
+ });
+ }, 60000);
+ accessory.getService(Service.Outlet).getCharacteristic(EveService.Characteristics.TotalConsumption)
+ .on("get", callback => {
+ accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData();
+ if (accessory.context.extraPersistedData !== undefined) {
+ accessory.context.totalPower = accessory.context.extraPersistedData.totalPower;
+ }
+ callback(null, accessory.context.totalPower);
+ });
+ accessory.getService(Service.Outlet).getCharacteristic(EveService.Characteristics.ResetTotal)
+ .on("set", (value, callback) => {
+ accessory.context.totalPower = 0;
+ accessory.context.lastReset = value;
+ accessory.eveLogger.setExtraPersistedData({
+ totalPower: 0,
+ lastReset: value
+ });
+ callback();
+ })
+ .on("get", callback => {
+ accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData();
+ if (accessory.context.extraPersistedData !== undefined) {
+ accessory.context.lastReset = accessory.context.extraPersistedData.lastReset;
+ }
+ callback(null, accessory.context.lastReset);
+ });
break;
case "usb":
accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On)
@@ -1505,14 +1595,21 @@ class eWeLink {
let newState = params.hasOwnProperty("switch") ? params.switch === "on" : params.mainSwitch === "on";
accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, newState);
}
+ let eveLog = false;
if (params.hasOwnProperty("currentTemperature") && accessory.getService(Service.TemperatureSensor)) {
let currentTemp = params.currentTemperature !== "unavailable" ? params.currentTemperature : 0;
accessory.getService(Service.TemperatureSensor).updateCharacteristic(Characteristic.CurrentTemperature, currentTemp);
+ eveLog = {
+ time: Date.now(),
+ temp: currentTemp
+ };
}
if (params.hasOwnProperty("currentHumidity") && accessory.getService(Service.HumiditySensor)) {
let currentHumi = params.currentHumidity !== "unavailable" ? params.currentHumidity : 0;
accessory.getService(Service.HumiditySensor).updateCharacteristic(Characteristic.CurrentRelativeHumidity, currentHumi);
+ eveLog.humidity = currentHumi;
}
+ if (eveLog) accessory.eveLogger.addEntry(eveLog);
} catch (err) {
this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
@@ -1525,28 +1622,8 @@ class eWeLink {
if (params.hasOwnProperty("power")) {
accessory.getService(Service.Outlet).updateCharacteristic(EveService.Characteristics.CurrentConsumption, parseFloat(params.power));
accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.OutletInUse, parseFloat(params.power) > 0);
- if (accessory.eveLogger.isHistoryLoaded()) {
- let extraPersistedData = accessory.eveLogger.getExtraPersistedData();
- if (extraPersistedData !== undefined) {
- let totalEnergy = extraPersistedData.totalenergy + accessory.context.totalEnergyTemp + parseFloat(params.power) * (30000 / 1000) / 3600 / 1000;
- accessory.eveLogger.setExtraPersistedData({
- totalEnergy,
- lastReset: extraPersistedData.lastReset
- });
- } else {
- let totalEnergy = accessory.context.totalEnergyTemp + parseFloat(params.power) * (30000 / 1000) / 3600 / 1000;
- accessory.eveLogger.setExtraPersistedData({
- totalEnergy,
- lastReset: 0
- });
- }
- accessory.context.totalEnergyTemp = 0;
- } else {
- accessory.context.totalEnergyTemp += parseFloat(params.power) * (30000 / 1000) / 3600 / 1000;
- let totalEnergy = accessory.context.totalEnergyTemp;
- }
accessory.eveLogger.addEntry({
- time: Math.floor((new Date()).getTime() / 1000),
+ time: Date.now(),
power: parseFloat(params.power)
});
}
From f26836d8bdbbe266d5adfb377779d5cb1da588b3 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sat, 12 Sep 2020 13:52:42 +0100
Subject: [PATCH 0118/3183] energy typo
---
lib/eWeLink.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 338f40ba..7dbc5f6f 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -538,13 +538,13 @@ class eWeLink {
.on("get", callback => {
accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData();
if (accessory.context.extraPersistedData !== undefined) {
- accessory.context.totalPower = accessory.context.extraPersistedData.totalPower;
+ accessory.context.totalEnergy = accessory.context.extraPersistedData.totalPower;
}
- callback(null, accessory.context.totalPower);
+ callback(null, accessory.context.totalEnergy);
});
accessory.getService(Service.Outlet).getCharacteristic(EveService.Characteristics.ResetTotal)
.on("set", (value, callback) => {
- accessory.context.totalPower = 0;
+ accessory.context.totalEnergy = 0;
accessory.context.lastReset = value;
accessory.eveLogger.setExtraPersistedData({
totalPower: 0,
From 55e1e17c72500ce2c5398973c71246ac011160e6 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sat, 12 Sep 2020 13:53:17 +0100
Subject: [PATCH 0119/3183] 2.26.0-2
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 529f274a..9f86cb85 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.26.0-1",
+ "version": "2.26.0-2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index fba6c4dd..92c69284 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.26.0-1",
+ "version": "2.26.0-2",
"author": "bwp91",
"contributors": [
"gbro115",
From 2e3457c80a5bf6ad396fd38ed37918631f76993d Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sat, 12 Sep 2020 14:31:10 +0100
Subject: [PATCH 0120/3183] eve log bugs
---
lib/eWeLink.js | 54 +++++++++++++++++++++++++-------------------------
1 file changed, 27 insertions(+), 27 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 7dbc5f6f..fd806aa3 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -493,7 +493,6 @@ class eWeLink {
if (accessory.getService(Service.HumiditySensor)) {
dataToAdd.humidity = accessory.getService(Service.HumiditySensor).getCharacteristic(Characteristic.CurrentRelativeHumidity).value;
}
- this.log.warn("[%s] 10 minute inteval recorded [%s°C].", accessory.displayName, currentTemp);
accessory.eveLogger.addEntry(dataToAdd);
}, 60000);
break;
@@ -506,9 +505,9 @@ class eWeLink {
path: this.eveLogPath
});
corrInterval.setCorrectingInterval(() => {
- let currentWatt = accessory.getService(Service.Outlet)
- .getCharacteristic(EveService.Characteristics.CurrentConsumption).value;
- this.log.warn("[%s] 10 minute inteval recorded [%sW].", accessory.displayName, currentWatt);
+ let isOn = accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On).value,
+ currentWatt = isOn ? accessory.getService(Service.Outlet)
+ .getCharacteristic(EveService.Characteristics.CurrentConsumption).value : 0;
if (accessory.eveLogger.isHistoryLoaded()) {
accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData();
if (accessory.context.extraPersistedData !== undefined) {
@@ -1371,27 +1370,6 @@ class eWeLink {
callback(str);
}
}
- externalValveUpdate(accessory, params) {
- try {
- ["A", "B"].forEach((v, k) => {
- accessory.getService("Valve " + v)
- .updateCharacteristic(Characteristic.Active, params.switches[k].switch === "on")
- .updateCharacteristic(Characteristic.InUse, params.switches[k].switch === "on");
- if (params.switches[k].switch === "on") {
- let timer = accessory.getService("Valve " + v).getCharacteristic(Characteristic.SetDuration).value;
- accessory.getService("Valve " + v).updateCharacteristic(Characteristic.RemainingDuration, timer);
- accessory.getService("Valve " + v).timer = setTimeout(() => {
- accessory.getService("Valve " + v).setCharacteristic(Characteristic.Active, 0);
- }, (timer * 1000));
- } else {
- accessory.getService("Valve " + v).updateCharacteristic(Characteristic.RemainingDuration, 0);
- clearTimeout(accessory.getService("Valve " + v).timer);
- }
- });
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
internalRFDeviceUpdate(accessory, rfChl, callback) {
try {
if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
@@ -1414,6 +1392,27 @@ class eWeLink {
callback(str);
}
}
+ externalValveUpdate(accessory, params) {
+ try {
+ ["A", "B"].forEach((v, k) => {
+ accessory.getService("Valve " + v)
+ .updateCharacteristic(Characteristic.Active, params.switches[k].switch === "on")
+ .updateCharacteristic(Characteristic.InUse, params.switches[k].switch === "on");
+ if (params.switches[k].switch === "on") {
+ let timer = accessory.getService("Valve " + v).getCharacteristic(Characteristic.SetDuration).value;
+ accessory.getService("Valve " + v).updateCharacteristic(Characteristic.RemainingDuration, timer);
+ accessory.getService("Valve " + v).timer = setTimeout(() => {
+ accessory.getService("Valve " + v).setCharacteristic(Characteristic.Active, 0);
+ }, (timer * 1000));
+ } else {
+ accessory.getService("Valve " + v).updateCharacteristic(Characteristic.RemainingDuration, 0);
+ clearTimeout(accessory.getService("Valve " + v).timer);
+ }
+ });
+ } catch (err) {
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
externalBlindUpdate(accessory, params) {
try {
let blindConfig, nSte;
@@ -1601,7 +1600,7 @@ class eWeLink {
accessory.getService(Service.TemperatureSensor).updateCharacteristic(Characteristic.CurrentTemperature, currentTemp);
eveLog = {
time: Date.now(),
- temp: currentTemp
+ temp: parseFloat(currentTemp)
};
}
if (params.hasOwnProperty("currentHumidity") && accessory.getService(Service.HumiditySensor)) {
@@ -1622,9 +1621,10 @@ class eWeLink {
if (params.hasOwnProperty("power")) {
accessory.getService(Service.Outlet).updateCharacteristic(EveService.Characteristics.CurrentConsumption, parseFloat(params.power));
accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.OutletInUse, parseFloat(params.power) > 0);
+ let isOn = accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On).value;
accessory.eveLogger.addEntry({
time: Date.now(),
- power: parseFloat(params.power)
+ power: isOn ? parseFloat(params.power) : 0
});
}
if (params.hasOwnProperty("voltage")) {
From c85d865a3f01e9244ce78b54df14e3cbee21975f Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sat, 12 Sep 2020 14:49:22 +0100
Subject: [PATCH 0121/3183] eve final changes
---
lib/eWeLink.js | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index fd806aa3..5c70de5f 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -485,16 +485,15 @@ class eWeLink {
path: this.eveLogPath
});
corrInterval.setCorrectingInterval(() => {
- let currentTemp = accessory.getService(Service.TemperatureSensor).getCharacteristic(Characteristic.CurrentTemperature).value,
- dataToAdd = {
- time: Date.now(),
- temp: currentTemp
- };
+ let dataToAdd = {
+ time: Date.now(),
+ temp: accessory.getService(Service.TemperatureSensor).getCharacteristic(Characteristic.CurrentTemperature).value
+ };
if (accessory.getService(Service.HumiditySensor)) {
dataToAdd.humidity = accessory.getService(Service.HumiditySensor).getCharacteristic(Characteristic.CurrentRelativeHumidity).value;
}
accessory.eveLogger.addEntry(dataToAdd);
- }, 60000);
+ }, 600000);
break;
case "outlet":
accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On)
@@ -532,7 +531,7 @@ class eWeLink {
time: Date.now(),
power: currentWatt
});
- }, 60000);
+ }, 600000);
accessory.getService(Service.Outlet).getCharacteristic(EveService.Characteristics.TotalConsumption)
.on("get", callback => {
accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData();
From 23d53138e1ca9761234377b553f548f7dd236bd6 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sat, 12 Sep 2020 15:12:44 +0100
Subject: [PATCH 0122/3183] eve log timer to 5 mins
---
lib/eWeLink.js | 15 ++++-----------
1 file changed, 4 insertions(+), 11 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 5c70de5f..2ef060cb 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -292,11 +292,6 @@ class eWeLink {
if (!this.config.hideTHSwitch) accessory.addService(Service.Switch);
accessory.addService(Service.TemperatureSensor);
if (device.params.sensorType !== "DS18B20") accessory.addService(Service.HumiditySensor);
- accessory.log = this.log;
- accessory.eveLogger = new EveHistoryService("weather", accessory, {
- storage: "fs",
- path: this.eveLogPath
- });
break;
case "outlet":
accessory.addService(Service.Outlet);
@@ -314,10 +309,6 @@ class eWeLink {
totalEnergyTemp: 0
}
};
- accessory.eveLogger = new EveHistoryService("energy", accessory, {
- storage: "fs",
- path: this.eveLogPath
- });
break;
case "usb":
accessory.addService(Service.Outlet);
@@ -482,6 +473,7 @@ class eWeLink {
accessory.log = this.log;
accessory.eveLogger = new EveHistoryService("weather", accessory, {
storage: "fs",
+ minutes: 5,
path: this.eveLogPath
});
corrInterval.setCorrectingInterval(() => {
@@ -493,7 +485,7 @@ class eWeLink {
dataToAdd.humidity = accessory.getService(Service.HumiditySensor).getCharacteristic(Characteristic.CurrentRelativeHumidity).value;
}
accessory.eveLogger.addEntry(dataToAdd);
- }, 600000);
+ }, 300000);
break;
case "outlet":
accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On)
@@ -501,6 +493,7 @@ class eWeLink {
accessory.log = this.log;
accessory.eveLogger = new EveHistoryService("energy", accessory, {
storage: "fs",
+ minutes: 5,
path: this.eveLogPath
});
corrInterval.setCorrectingInterval(() => {
@@ -531,7 +524,7 @@ class eWeLink {
time: Date.now(),
power: currentWatt
});
- }, 600000);
+ }, 300000);
accessory.getService(Service.Outlet).getCharacteristic(EveService.Characteristics.TotalConsumption)
.on("get", callback => {
accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData();
From 9e6f378e862de843871666419b1c03468d46aac5 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sat, 12 Sep 2020 15:30:39 +0100
Subject: [PATCH 0123/3183] eve logging directory
---
lib/eWeLink.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 2ef060cb..4a1676ae 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -25,7 +25,7 @@ class eWeLink {
this.devicesInEwe = new Map();
this.cusG = new Map();
this.cusS = new Map();
- this.eveLogPath = this.api.user.storagePath() + "/persist/";
+ this.eveLogPath = this.api.user.storagePath() + "/homebridge-ewelink/";
this.api
.on("didFinishLaunching", () => {
this.log("Plugin has finished initialising. Starting synchronisation with eWeLink account.");
From 82bf6886274a2e8c80c599582614e2ccbcd50875 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sat, 12 Sep 2020 15:31:12 +0100
Subject: [PATCH 0124/3183] 2.26.0-3
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 9f86cb85..3075e4c5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.26.0-2",
+ "version": "2.26.0-3",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 92c69284..a27267fd 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.26.0-2",
+ "version": "2.26.0-3",
"author": "bwp91",
"contributors": [
"gbro115",
From a9c91778cf0d029a007f32bb31bc6c3280d449d9 Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Sat, 12 Sep 2020 17:01:46 +0100
Subject: [PATCH 0125/3183] Create dependabot.yml
---
.github/dependabot.yml | 11 +++++++++++
1 file changed, 11 insertions(+)
create mode 100644 .github/dependabot.yml
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 00000000..8abca405
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,11 @@
+# To get started with Dependabot version updates, you'll need to specify which
+# package ecosystems to update and where the package manifests are located.
+# Please see the documentation for all configuration options:
+# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
+
+version: 2
+updates:
+ - package-ecosystem: "npm" # See documentation for possible values
+ directory: "/" # Location of package manifests
+ schedule:
+ interval: "daily"
From 7e867251c0386c30b22176102263c32c5356f811 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sat, 12 Sep 2020 18:51:57 +0100
Subject: [PATCH 0126/3183] typos
---
lib/eWeLink.js | 7 ++++---
lib/eWeLinkHTTP.js | 6 +++---
lib/eWeLinkLAN.js | 10 +++++-----
lib/eWeLinkWS.js | 8 ++++----
4 files changed, 16 insertions(+), 15 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 4a1676ae..27fa8ad0 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -13,14 +13,15 @@ class eWeLink {
constructor(log, config, api) {
if (!log || !api || !config) return;
if (!config.username || !config.password || !config.countryCode) {
- log.error("************** Cannot load homebridge-ewelink **************");
- log.error("Your eWeLink credentials missing from the Homebridge config.");
- log.error("************************************************************");
+ log.error("**************** Cannot load homebridge-ewelink ****************");
+ log.error("Your eWeLink credentials are missing from the Homebridge config.");
+ log.error("****************************************************************");
return;
}
this.log = log;
this.config = config;
this.api = api;
+ this.debug = this.config.debug || false;
this.devicesInHB = new Map();
this.devicesInEwe = new Map();
this.cusG = new Map();
diff --git a/lib/eWeLinkHTTP.js b/lib/eWeLinkHTTP.js
index 4756c48b..6df6fbb9 100644
--- a/lib/eWeLinkHTTP.js
+++ b/lib/eWeLinkHTTP.js
@@ -1,8 +1,8 @@
/* jshint esversion: 9, -W030, node: true */
"use strict";
-const axios = require("axios");
-const constants = require("./constants");
-const crypto = require("crypto");
+const axios = require("axios"),
+ constants = require("./constants"),
+ crypto = require("crypto");
module.exports = class eWeLinkHTTP {
constructor(config, log) {
this.config = config;
diff --git a/lib/eWeLinkLAN.js b/lib/eWeLinkLAN.js
index f43869b7..f6ff9188 100644
--- a/lib/eWeLinkLAN.js
+++ b/lib/eWeLinkLAN.js
@@ -1,10 +1,10 @@
/* jshint esversion: 9, -W030, node: true */
"use strict";
-const axios = require("axios");
-const constants = require("./constants");
-const crypto = require("crypto");
-const dns = require("node-dns-sd");
-const eventemitter = require("events");
+const axios = require("axios"),
+ constants = require("./constants"),
+ crypto = require("crypto"),
+ dns = require("node-dns-sd"),
+ eventemitter = require("events");
module.exports = class eWeLinkLAN {
constructor(config, log, devices) {
this.config = config;
diff --git a/lib/eWeLinkWS.js b/lib/eWeLinkWS.js
index a44b1431..9cb70c1c 100644
--- a/lib/eWeLinkWS.js
+++ b/lib/eWeLinkWS.js
@@ -1,9 +1,9 @@
/* jshint esversion: 9, -W030, node: true */
"use strict";
-const axios = require("axios");
-const constants = require("./constants");
-const eventemitter = require("events");
-const ws = require("ws");
+const axios = require("axios"),
+ constants = require("./constants"),
+ eventemitter = require("events"),
+ ws = require("ws");
module.exports = class eWeLinkWS {
constructor(config, log, res) {
this.config = config;
From aaa15f6451a891a6ab263eca800ab75f3a640394 Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Sun, 13 Sep 2020 10:23:09 +0100
Subject: [PATCH 0127/3183] Update README.md
---
README.md | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index cbd907d0..6db17853 100644
--- a/README.md
+++ b/README.md
@@ -24,10 +24,11 @@
* [Supported Devices](https://github.com/bwp91/homebridge-ewelink/wiki/Supported-Devices)
* [Connection Methods](https://github.com/bwp91/homebridge-ewelink/wiki/Connection-Methods)
### How-to Guides
-* [How to copy Homebridge logs](https://github.com/bwp91/homebridge-ewelink/wiki/How-to-copy-Homebridge-logs)
-* [How to enable/disable plugin extended logging](https://github.com/bwp91/homebridge-ewelink/wiki/How-to-enable-disable-plugin-extended-logging)
* [How to set up RF Bridge sensors](https://github.com/bwp91/homebridge-ewelink/wiki/How-to-set-up-RF-Bridge-sensors)
* [How to set up Sonoff Camera (GK-200MP2-B)](https://github.com/bwp91/homebridge-ewelink/wiki/How-to-set-up-Sonoff-Camera)
+* [How to copy Homebridge logs](https://github.com/bwp91/homebridge-ewelink/wiki/How-to-copy-Homebridge-logs)
+* [How to enable/disable plugin extended logging](https://github.com/bwp91/homebridge-ewelink/wiki/How-to-enable-disable-plugin-extended-logging)
+* [How to remove an accessory from the cache](https://github.com/bwp91/homebridge-ewelink/wiki/How-to-remove-an-accessory-from-the-cache)
### About
* [Support Request](https://github.com/bwp91/homebridge-ewelink/issues)
* [Roadmap](https://github.com/bwp91/homebridge-ewelink/wiki/Roadmap)
From 6256c4c9c2eb59db88afaa47a3a7debd6d5a289a Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 13 Sep 2020 10:34:32 +0100
Subject: [PATCH 0128/3183] log check and outlet fix
---
lib/eWeLink.js | 49 ++++++++++++++++++++++++++++++-------------------
1 file changed, 30 insertions(+), 19 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 27fa8ad0..2c596ad9 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -90,7 +90,7 @@ class eWeLink {
this.wsClient.receiveUpdate(d => this.receiveDeviceUpdate(d));
this.lanClient.receiveUpdate(d => this.receiveDeviceUpdate(d));
this.log("eWeLink setup complete. If you're enjoying this package please consider a âī¸ on GitHub :).");
- if (this.config.debugReqRes) {
+ if (this.config.debugReqRes || false) {
this.log.warn("You have 'Request & Response Logging' enabled. This setting is not recommended for long-term use.");
}
})();
@@ -497,6 +497,17 @@ class eWeLink {
minutes: 5,
path: this.eveLogPath
});
+ if (!accessory.context.hasOwnProperty("lastReset")) {
+ accessory.context = {
+ ...accessory.context,
+ ...{
+ extraPersistedData: {},
+ lastReset: 0,
+ totalEnergy: 0,
+ totalEnergyTemp: 0
+ }
+ };
+ }
corrInterval.setCorrectingInterval(() => {
let isOn = accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On).value,
currentWatt = isOn ? accessory.getService(Service.Outlet)
@@ -740,7 +751,7 @@ class eWeLink {
this.lanClient.sendUpdate(payload)
.then(() => callback())
.catch(err => {
- if (this.config.debug) {
+ if (this.debug) {
this.log.warn("[%s] Reverting to web socket as %s.", accessory.displayName, err);
}
sendViaWS();
@@ -786,7 +797,7 @@ class eWeLink {
accessory.context.reachableLAN = true;
this.log("[%s] has been reported [online] via [LAN].", accessory.displayName);
}
- if (this.config.debug) {
+ if (this.debug) {
this.log("[%s] externally updated from above %s message and will be refreshed.", accessory.displayName, device.params.updateSource);
}
if (!this.refreshAccessory(accessory, device.params)) {
@@ -1029,7 +1040,7 @@ class eWeLink {
params.switches[1].switch = (newPower === 1 && newSpeed >= 33) ? "on" : "off";
params.switches[2].switch = (newPower === 1 && newSpeed >= 66 && newSpeed < 99) ? "on" : "off";
params.switches[3].switch = (newPower === 1 && newSpeed >= 99) ? "on" : "off";
- if (this.config.debug) {
+ if (this.debug) {
this.log.warn("Fan Update - setting " + type + " to " + value);
this.log("[%s] new stats: power [%s], speed [%s%], light [%s].", accessory.displayName, newPower, newSpeed, newLight);
}
@@ -1049,7 +1060,7 @@ class eWeLink {
switch: value ? "on" : "off",
mainSwitch: value ? "on" : "off"
};
- if (this.config.debug) {
+ if (this.debug) {
this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
}
accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
@@ -1068,7 +1079,7 @@ class eWeLink {
let params = {
switch: value ? "on" : "off"
};
- if (this.config.debug) {
+ if (this.debug) {
this.log("[%s] requesting to turn [%s].", accessory.displayName, value ? "on" : "off");
}
accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, value);
@@ -1086,7 +1097,7 @@ class eWeLink {
switches: this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches
};
params.switches[0].switch = value ? "on" : "off";
- if (this.config.debug) {
+ if (this.debug) {
this.log("[%s] requesting to turn [%s].", accessory.displayName, value ? "on" : "off");
}
accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, value);
@@ -1104,7 +1115,7 @@ class eWeLink {
switches: this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches
};
params.switches[0].switch = value ? "on" : "off";
- if (this.config.debug) {
+ if (this.debug) {
this.log("[%s] requesting to turn [%s].", accessory.displayName, value ? "on" : "off");
}
accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
@@ -1126,7 +1137,7 @@ class eWeLink {
} else {
params.switch = value ? "on" : "off";
}
- if (this.config.debug) {
+ if (this.debug) {
this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
}
accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
@@ -1137,7 +1148,7 @@ class eWeLink {
params.switches[1].switch = value ? "on" : "off";
params.switches[2].switch = value ? "on" : "off";
params.switches[3].switch = value ? "on" : "off";
- if (this.config.debug) {
+ if (this.debug) {
this.log("[%s] updating to turn group [%s].", accessory.displayName, value ? "on" : "off");
}
accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
@@ -1152,7 +1163,7 @@ class eWeLink {
case "2":
case "3":
case "4":
- if (this.config.debug) {
+ if (this.debug) {
this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
}
accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
@@ -1210,7 +1221,7 @@ class eWeLink {
}
accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Brightness, value);
}
- if (this.config.debug) {
+ if (this.debug) {
this.log("[%s] updating brightness to [%s%].", accessory.displayName, value);
}
setTimeout(() => this.sendDeviceUpdate(accessory, params, callback), 250);
@@ -1255,7 +1266,7 @@ class eWeLink {
default:
throw "unknown device UIID";
}
- if (this.config.debug) {
+ if (this.debug) {
this.log("[%s] updating hue to [%s°].", accessory.displayName, value);
}
accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Hue, value);
@@ -1281,7 +1292,7 @@ class eWeLink {
};
break;
}
- if (this.config.debug) {
+ if (this.debug) {
this.log("[%s] updating brightness to [%s%].", accessory.displayName, value);
}
accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Brightness, value);
@@ -1305,7 +1316,7 @@ class eWeLink {
switch (accessory.context.switchNumber) {
case "X":
params.switch = value ? "on" : "off";
- if (this.config.debug) {
+ if (this.debug) {
this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
}
accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
@@ -1316,7 +1327,7 @@ class eWeLink {
params.switches[1].switch = value ? "on" : "off";
params.switches[2].switch = value ? "on" : "off";
params.switches[3].switch = value ? "on" : "off";
- if (this.config.debug) {
+ if (this.debug) {
this.log("[%s] updating to turn group [%s].", accessory.displayName, value ? "on" : "off");
}
accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
@@ -1331,7 +1342,7 @@ class eWeLink {
case "2":
case "3":
case "4":
- if (this.config.debug) {
+ if (this.debug) {
this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
}
accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
@@ -1373,7 +1384,7 @@ class eWeLink {
cmd: "transmit",
rfChl
};
- if (this.config.debug) {
+ if (this.debug) {
this.log("[%s %s] mimicking RF button press.", accessory.displayName, accessory.context.rfChls[rfChl]);
}
accessory.getService(accessory.context.rfChls[rfChl]).updateCharacteristic(Characteristic.On, true);
@@ -1822,7 +1833,7 @@ class eWeLink {
}, (this.config.sensorTimeLength || 2) * 1000);
break;
}
- if (this.config.debug) {
+ if (this.debug) {
this.log("[%s] has detected [%s].", oAccessory.displayName, oAccessory.context.sensorType);
}
}
From 6404f83cf4b91c9fcc22e0200a352ef8fc571ee6 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 13 Sep 2020 11:08:22 +0100
Subject: [PATCH 0129/3183] 2.26.0
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 3075e4c5..cdf0592f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.26.0-3",
+ "version": "2.26.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index a27267fd..638621b7 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.26.0-3",
+ "version": "2.26.0",
"author": "bwp91",
"contributors": [
"gbro115",
From c76cf88d0b4d5d824f6049b6614d47a8f4929b1c Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Sun, 13 Sep 2020 11:13:53 +0100
Subject: [PATCH 0130/3183] Update README.md
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 6db17853..0225eb9e 100644
--- a/README.md
+++ b/README.md
@@ -30,6 +30,6 @@
* [How to enable/disable plugin extended logging](https://github.com/bwp91/homebridge-ewelink/wiki/How-to-enable-disable-plugin-extended-logging)
* [How to remove an accessory from the cache](https://github.com/bwp91/homebridge-ewelink/wiki/How-to-remove-an-accessory-from-the-cache)
### About
-* [Support Request](https://github.com/bwp91/homebridge-ewelink/issues)
+* [Support Request](https://github.com/bwp91/homebridge-ewelink/issues/new/choose)
* [Roadmap](https://github.com/bwp91/homebridge-ewelink/wiki/Roadmap)
* [Credits](https://github.com/bwp91/homebridge-ewelink/wiki/Credits)
From 808d5c46ae207b90b1835822eab9fd81b627c08f Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Mon, 14 Sep 2020 16:29:24 +0100
Subject: [PATCH 0131/3183] Create config.yml
---
.github/ISSUE_TEMPLATE/config.yml | 5 +++++
1 file changed, 5 insertions(+)
create mode 100644 .github/ISSUE_TEMPLATE/config.yml
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 00000000..d4cc064a
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1,5 @@
+blank_issues_enabled: false
+contact_links:
+ - name: Test
+ url: https://github.community/
+ about: Please ask and answer questions here.
From 0f50118d443dcd169d85a12cd8aebfe2e4fd6a83 Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Mon, 14 Sep 2020 16:33:10 +0100
Subject: [PATCH 0132/3183] Update config.yml
---
.github/ISSUE_TEMPLATE/config.yml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
index d4cc064a..2194a932 100644
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -1,5 +1,5 @@
blank_issues_enabled: false
contact_links:
- - name: Test
- url: https://github.community/
- about: Please ask and answer questions here.
+ - name: Homebridge Discord
+ url: https://discord.gg/Z8jmyvb
+ about: Chat to me on Discord - my username is bwp91.
From 5cb0d109cfbfe74aa09f0f8beecb14ade83f6f18 Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Mon, 14 Sep 2020 16:35:17 +0100
Subject: [PATCH 0133/3183] Create feedback.md
---
.github/ISSUE_TEMPLATE/feedback.md | 9 +++++++++
1 file changed, 9 insertions(+)
create mode 100644 .github/ISSUE_TEMPLATE/feedback.md
diff --git a/.github/ISSUE_TEMPLATE/feedback.md b/.github/ISSUE_TEMPLATE/feedback.md
new file mode 100644
index 00000000..31941559
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feedback.md
@@ -0,0 +1,9 @@
+---
+name: Feedback
+about: Give feedback that I might have asked for.
+title: ''
+labels: ''
+assignees: ''
+
+---
+
From 1a047f21232fddbb5ee217e9e2f48e1e3dd1e940 Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Mon, 14 Sep 2020 16:35:51 +0100
Subject: [PATCH 0134/3183] Update feature-request.md
---
.github/ISSUE_TEMPLATE/feature-request.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md
index 47b2c95b..5ba9ddfc 100644
--- a/.github/ISSUE_TEMPLATE/feature-request.md
+++ b/.github/ISSUE_TEMPLATE/feature-request.md
@@ -1,6 +1,6 @@
---
name: Feature Request
-about: I have an idea for the package!
+about: I have an idea for the package or have a device that isn't supported.
title: ''
labels: ''
assignees: ''
From e2fb269c652a0910cdc374a0095300948155bb9d Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Mon, 14 Sep 2020 16:36:21 +0100
Subject: [PATCH 0135/3183] Update new-issue.md
---
.github/ISSUE_TEMPLATE/new-issue.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/ISSUE_TEMPLATE/new-issue.md b/.github/ISSUE_TEMPLATE/new-issue.md
index 32cfb7df..fb970abc 100644
--- a/.github/ISSUE_TEMPLATE/new-issue.md
+++ b/.github/ISSUE_TEMPLATE/new-issue.md
@@ -1,6 +1,6 @@
---
name: New Issue
-about: I have a problem with the package!
+about: I have a problem with the package or it's showing an error.
title: ''
labels: ''
assignees: ''
From 0bcba58c6713ac14bee6d6ed6acfe30beabb5228 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Mon, 14 Sep 2020 20:24:59 +0100
Subject: [PATCH 0136/3183] zb motion sensor bug
---
lib/constants.js | 4 ++--
lib/eWeLink.js | 12 ++++++++++--
2 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/lib/constants.js b/lib/constants.js
index 0a53039b..34ce9a38 100644
--- a/lib/constants.js
+++ b/lib/constants.js
@@ -30,14 +30,14 @@ module.exports = {
devicesRFBridge: [28],
devicesRFBridgeParams: ["cmd"],
devicesZBBridge: [66],
- devicesZBBridgeParams: ["key", "temperature", "humidity", "motion", "lock"],
+ devicesZBBridgeParams: ["key", "temperature", "humidity", "motion", "lock", "trigTime"],
devicesZB: [1000, 1770, 2026, 3026],
devicesValveParams: ["switches"],
devicesBlindParams: ["switch", "switches"],
devicesGarageParams: ["switch", "switches"],
devicesLockParams: ["switch"],
allowedGroups: ["blind", "garage", "lock"],
- paramsToKeep: ["bright", "brightness", "channel", "cmd", "colorB", "colorG", "colorR", "current", "currentHumidity", "currentTemperature", "fan", "humidity", "key", "light", "lock", "mainSwitch", "mode", "online", "power", "rfChl", "rfList", "rfTrig", "sensorType", "speed", "state", "switch", "switches", "temperature", "type", "voltage", "zyx_mode"],
+ paramsToKeep: ["bright", "brightness", "channel", "cmd", "colorB", "colorG", "colorR", "current", "currentHumidity", "currentTemperature", "fan", "humidity", "key", "light", "lock", "mainSwitch", "mode", "motion", "online", "power", "rfChl", "rfList", "rfTrig", "sensorType", "speed", "state", "switch", "switches", "temperature", "trigTime", "type", "voltage", "zyx_mode"],
chansFromUiid: {
1: 1, // "SOCKET" \\ 20, MINI, BASIC, S26
2: 2, // "SOCKET_2" \\
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 2c596ad9..ec37aeca 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -1863,8 +1863,16 @@ class eWeLink {
}
break;
case 2026:
- if (params.hasOwnProperty("motion") && [0, 1].includes(params.lock)) {
- accessory.getService(Service.MotionSensor).updateCharacteristic(Characteristic.MotionDetected, params.motion);
+ if (params.hasOwnProperty("motion") && params.motion === 1 && params.hasOwnProperty("trigTime")) {
+ let timeNow = new Date(),
+ timeDifference = (timeNow.getTime() - params.trigTime) / 1000;
+ if (timeDifference < (this.config.sensorTimeDifference || 120)) {
+ accessory.getService(Service.MotionSensor).updateCharacteristic(Characteristic.MotionDetected, 1);
+ setTimeout(() => {
+ accessory.getService(Service.MotionSensor).updateCharacteristic(Characteristic.MotionDetected, 0);
+ }, (this.config.sensorTimeLength || 2) * 1000);
+ }
+ break;
}
break;
case 3026:
From ae1aacb589e8d3ba6c57c15bfcec15c1a05b9c92 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Mon, 14 Sep 2020 20:26:32 +0100
Subject: [PATCH 0137/3183] 2.26.1
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index cdf0592f..81baac0a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.26.0",
+ "version": "2.26.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 638621b7..a572eac9 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.26.0",
+ "version": "2.26.1",
"author": "bwp91",
"contributors": [
"gbro115",
From 5d15ea647689a825927d5386d4353ca3dadc5b02 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Mon, 14 Sep 2020 23:17:13 +0100
Subject: [PATCH 0138/3183] implement sliders
---
config.schema.json | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)
diff --git a/config.schema.json b/config.schema.json
index 4175f7cb..b3ce4afe 100644
--- a/config.schema.json
+++ b/config.schema.json
@@ -56,22 +56,25 @@
"type":"integer",
"title":"Sensor Length",
"description":"The number of seconds which the sensor tile in the Home app will light up for if a sensor detects something.",
- "default":"2",
- "maximum":999
+ "default":60,
+ "minimum":1,
+ "maximum":120
},
"sensorTimeDifference":{
"type":"integer",
"title":"Sensor Lag",
"description":"An offset in seconds to ignore any notifications if they is a delay between a sensor detecting something and Homebridge receiving the notification.",
- "default":"120",
- "maximum":999
+ "default":120,
+ "minimum":10,
+ "maximum":300
},
"valveTimeLength":{
"type":"integer",
"title":"Valve Duration",
"description":"The default number of seconds that irrigation valves will run for.",
- "default":"20",
- "maximum":999
+ "default":20,
+ "minimum": 10,
+ "maximum":1800
},
"hideTHSwitch":{
"title":"Hide TH10/TH16 Switch",
@@ -147,7 +150,9 @@
"type":"number",
"title":"Operation Time",
"description":"For blinds and garage doors this is the total time in deciseconds to fully open/close the device. For locks this is the time to show the Home app tile as unlocked. Count the time in seconds and multiply by 10, for example 100 for 10 seconds or 75 for 7.5 seconds.",
- "default":100
+ "default":100,
+ "minimum":10,
+ "maximum":600
},
"sensorId":{
"type":"string",
From bf9d4ca1e7143a4fdf7a10b5f3a07311aeaeb102 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Mon, 14 Sep 2020 23:17:40 +0100
Subject: [PATCH 0139/3183] eve for zb temp sensor
---
lib/eWeLink.js | 41 ++++++++++++++++++++++++++++++++++-------
1 file changed, 34 insertions(+), 7 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index ec37aeca..50335be5 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -624,6 +624,24 @@ class eWeLink {
});
}
break;
+ case "zb_sub":
+ if (accessory.context.eweUIID === 1770) {
+ accessory.log = this.log;
+ accessory.eveLogger = new EveHistoryService("weather", accessory, {
+ storage: "fs",
+ minutes: 5,
+ path: this.eveLogPath
+ });
+ corrInterval.setCorrectingInterval(() => {
+ let dataToAdd = {
+ time: Date.now(),
+ temp: accessory.getService(Service.TemperatureSensor).getCharacteristic(Characteristic.CurrentTemperature).value,
+ humidity: accessory.getService(Service.HumiditySensor).getCharacteristic(Characteristic.CurrentRelativeHumidity).value
+ };
+ accessory.eveLogger.addEntry(dataToAdd);
+ }, 300000);
+ }
+ break;
}
this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
} catch (err) {
@@ -1598,21 +1616,22 @@ class eWeLink {
let newState = params.hasOwnProperty("switch") ? params.switch === "on" : params.mainSwitch === "on";
accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, newState);
}
- let eveLog = false;
+ let eveLog = {
+ time: Date.now()
+ };
if (params.hasOwnProperty("currentTemperature") && accessory.getService(Service.TemperatureSensor)) {
let currentTemp = params.currentTemperature !== "unavailable" ? params.currentTemperature : 0;
accessory.getService(Service.TemperatureSensor).updateCharacteristic(Characteristic.CurrentTemperature, currentTemp);
- eveLog = {
- time: Date.now(),
- temp: parseFloat(currentTemp)
- };
+ eveLog.temp = parseFloat(currentTemp);
}
if (params.hasOwnProperty("currentHumidity") && accessory.getService(Service.HumiditySensor)) {
let currentHumi = params.currentHumidity !== "unavailable" ? params.currentHumidity : 0;
accessory.getService(Service.HumiditySensor).updateCharacteristic(Characteristic.CurrentRelativeHumidity, currentHumi);
- eveLog.humidity = currentHumi;
+ eveLog.humidity = parseFloat(currentHumi);
+ }
+ if (eveLog.hasOwnProperty("temp") || eveLog.hasOwnProperty("humidity")) {
+ accessory.eveLogger.addEntry(eveLog);
}
- if (eveLog) accessory.eveLogger.addEntry(eveLog);
} catch (err) {
this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
@@ -1853,13 +1872,21 @@ class eWeLink {
}
break;
case 1770:
+ let eveLog = {
+ time: Date.now()
+ };
if (params.hasOwnProperty("temperature")) {
let currentTemp = parseInt(params.temperature) / 100;
accessory.getService(Service.TemperatureSensor).updateCharacteristic(Characteristic.CurrentTemperature, currentTemp);
+ eveLog.temp = parseFloat(currentTemp);
}
if (params.hasOwnProperty("humidity")) {
let currentHumi = parseInt(params.humidity) / 100;
accessory.getService(Service.HumiditySensor).updateCharacteristic(Characteristic.CurrentRelativeHumidity, currentHumi);
+ eveLog.humidity = parseFloat(currentHumi);
+ }
+ if (eveLog.hasOwnProperty("temp") || eveLog.hasOwnProperty("humidity")) {
+ accessory.eveLogger.addEntry(eveLog);
}
break;
case 2026:
From fe1c23d2933dbbc12fa673a5c7b584a2a0bc2153 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 15 Sep 2020 06:54:51 +0100
Subject: [PATCH 0140/3183] number -> integer
---
config.schema.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/config.schema.json b/config.schema.json
index b3ce4afe..664f3935 100644
--- a/config.schema.json
+++ b/config.schema.json
@@ -147,7 +147,7 @@
]
},
"operationTime":{
- "type":"number",
+ "type":"integer",
"title":"Operation Time",
"description":"For blinds and garage doors this is the total time in deciseconds to fully open/close the device. For locks this is the time to show the Home app tile as unlocked. Count the time in seconds and multiply by 10, for example 100 for 10 seconds or 75 for 7.5 seconds.",
"default":100,
From 0e5c58d86a03c10f61ae8b49603d06f698babca5 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 15 Sep 2020 06:56:08 +0100
Subject: [PATCH 0141/3183] 2.26.2
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 81baac0a..89e609db 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.26.1",
+ "version": "2.26.2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index a572eac9..5e90fe89 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.26.1",
+ "version": "2.26.2",
"author": "bwp91",
"contributors": [
"gbro115",
From 05bf298fa9f220694e0d7458cef72d4a1683e1bd Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 15 Sep 2020 08:10:48 +0100
Subject: [PATCH 0142/3183] allow battery parameter
---
lib/constants.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/constants.js b/lib/constants.js
index 34ce9a38..464ac8ab 100644
--- a/lib/constants.js
+++ b/lib/constants.js
@@ -30,14 +30,14 @@ module.exports = {
devicesRFBridge: [28],
devicesRFBridgeParams: ["cmd"],
devicesZBBridge: [66],
- devicesZBBridgeParams: ["key", "temperature", "humidity", "motion", "lock", "trigTime"],
+ devicesZBBridgeParams: ["key", "temperature", "humidity", "motion", "lock", "trigTime", "battery"],
devicesZB: [1000, 1770, 2026, 3026],
devicesValveParams: ["switches"],
devicesBlindParams: ["switch", "switches"],
devicesGarageParams: ["switch", "switches"],
devicesLockParams: ["switch"],
allowedGroups: ["blind", "garage", "lock"],
- paramsToKeep: ["bright", "brightness", "channel", "cmd", "colorB", "colorG", "colorR", "current", "currentHumidity", "currentTemperature", "fan", "humidity", "key", "light", "lock", "mainSwitch", "mode", "motion", "online", "power", "rfChl", "rfList", "rfTrig", "sensorType", "speed", "state", "switch", "switches", "temperature", "trigTime", "type", "voltage", "zyx_mode"],
+ paramsToKeep: ["battery", "bright", "brightness", "channel", "cmd", "colorB", "colorG", "colorR", "current", "currentHumidity", "currentTemperature", "fan", "humidity", "key", "light", "lock", "mainSwitch", "mode", "motion", "online", "power", "rfChl", "rfList", "rfTrig", "sensorType", "speed", "state", "switch", "switches", "temperature", "trigTime", "type", "voltage", "zyx_mode"],
chansFromUiid: {
1: 1, // "SOCKET" \\ 20, MINI, BASIC, S26
2: 2, // "SOCKET_2" \\
From 20340fd2f0be88eef1170c1cdfa0598f131748e6 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 15 Sep 2020 08:12:18 +0100
Subject: [PATCH 0143/3183] battery service for zb devices
---
lib/eWeLink.js | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 50335be5..f4b62df6 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -1865,6 +1865,11 @@ class eWeLink {
}
externalZBDeviceUpdate(accessory, params) {
try { //*** credit @tasict ***\\
+ if (params.hasOwnProperty("battery")) {
+ let batteryService = accessory.getService(Service.BatteryService) || accessory.addService(Service.BatteryService);
+ batteryService.updateCharacteristic(Characteristic.BatteryLevel, params.battery);
+ batteryService.updateCharacteristic(Characteristic.StatusLowBattery, params.battery <= 25);
+ }
switch (accessory.context.eweUIID) {
case 1000:
if (params.hasOwnProperty("key") && [0, 1, 2].includes(params.key)) {
From c9800aa437deef9613ddf08cccf311849b5b6d96 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 15 Sep 2020 09:47:24 +0100
Subject: [PATCH 0144/3183] clarify device format
---
config.schema.json | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/config.schema.json b/config.schema.json
index 664f3935..a6d6cd98 100644
--- a/config.schema.json
+++ b/config.schema.json
@@ -98,7 +98,7 @@
"deviceId":{
"type":"string",
"title":"Device ID",
- "description":"Device ID from your eWeLink app (ten digits normally in the format 1000******)."
+ "description":"Device ID from your eWeLink app (ten digits normally in the format 1000ab23cd)."
},
"type":{
"type":"string",
@@ -157,7 +157,7 @@
"sensorId":{
"type":"string",
"title":"Sensor",
- "description":"A Sonoff DW2 sensor can optionally be used for blinds and garage doors. This is to determine the current open/closed state of the device. Please enter the 10 digit device ID. Otherwise leave this blank."
+ "description":"A Sonoff DW2 sensor can optionally be used for blinds and garage doors. This is to determine the current open/closed state of the device. Please enter the 10 digit device ID (normally in the format 1000ab23cd). Otherwise leave this blank."
}
}
}
From 80c82f6c07a1c92bbc1b1f832f217ff3fcef6d47 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 15 Sep 2020 10:32:36 +0100
Subject: [PATCH 0145/3183] Update constants.js
---
lib/constants.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/constants.js b/lib/constants.js
index 464ac8ab..3543d717 100644
--- a/lib/constants.js
+++ b/lib/constants.js
@@ -15,7 +15,7 @@ module.exports = {
devicesBrightable: [36, 44],
devicesColourable: [22, 59],
devicesSensor: [102],
- devicesSensorParams: ["switch"],
+ devicesSensorParams: ["switch", "battery", "type"],
devicesThermostat: [15],
devicesThermostatParams: ["currentTemperature", "currentHumidity", "switch", "masterSwitch"],
devicesFan: [34],
From 31754a36a9fcf20eea37be3bf316f010f4055ccb Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 15 Sep 2020 10:33:15 +0100
Subject: [PATCH 0146/3183] DW2 battery
---
lib/eWeLink.js | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index f4b62df6..8dec569e 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -109,6 +109,7 @@ class eWeLink {
}
initialiseDevice(device) {
let accessory;
+ // if (device.extra.uiid === 102) this.log.warn(device);
//*** First add the device if it isn't already in Homebridge. Yeah this code looks a mess :| ***\\
if (!this.devicesInHB.has(device.deviceid + "SWX") && !this.devicesInHB.has(device.deviceid + "SW0")) {
if (device.extra.uiid === 2 && device.brandName === "coolkit" && device.productModel === "0285") {
@@ -381,6 +382,7 @@ class eWeLink {
});
break;
case "zb_sub": //*** credit @tasict ***\\
+ accessory.addService(Service.BatteryService);
switch (device.extra.uiid) {
case 1000:
accessory.addService(Service.StatelessProgrammableSwitch);
@@ -944,7 +946,10 @@ class eWeLink {
params = {},
delay = 0;
if (sensorDefinition && !(sAccessory = this.devicesInHB.get(garageConfig.sensorId + "SWX"))) {
- throw "defined sensor doesn't exist";
+ throw "defined DW2 sensor doesn't exist";
+ }
+ if (sAccessory.context.type !== "sensor") {
+ throw "defined DW2 sensor isn't a sensor";
}
oldPos = sAccessory ?
sAccessory.getService(Service.ContactSensor).getCharacteristic(Characteristic.ContactSensorState).value === 0 ? 1 : 0 :
@@ -1547,6 +1552,11 @@ class eWeLink {
let newState = params.switch === "on" ? 1 : 0,
oAccessory = false;
accessory.getService(Service.ContactSensor).updateCharacteristic(Characteristic.ContactSensorState, newState);
+ if (params.hasOwnProperty("battery")) {
+ let batteryService = accessory.getService(Service.BatteryService) || accessory.addService(Service.BatteryService);
+ batteryService.updateCharacteristic(Characteristic.BatteryLevel, params.battery);
+ batteryService.updateCharacteristic(Characteristic.StatusLowBattery, params.battery <= 25);
+ }
this.cusG.forEach(group => {
if (group.sensorId === accessory.context.eweDeviceId && group.type === "garage") {
if ((oAccessory = this.devicesInHB.get(group.deviceId + "SWX"))) {
From 81e566d75802c6443bff8a9936949fa4a7efc2d9 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 15 Sep 2020 10:48:04 +0100
Subject: [PATCH 0147/3183] appSecret to constants
---
lib/constants.js | 3 ++-
lib/eWeLinkHTTP.js | 2 +-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/lib/constants.js b/lib/constants.js
index 3543d717..0751d683 100644
--- a/lib/constants.js
+++ b/lib/constants.js
@@ -1,7 +1,8 @@
/* jshint esversion: 9, -W030, node: true */
"use strict";
module.exports = {
- appId: "oeVkj2lYFGnJu5XUtWisfW4utiN4u9Mq",
+ appId: "Uw83EKZFxdif7XFXEsrpduz5YyjP7nTl", // "oeVkj2lYFGnJu5XUtWisfW4utiN4u9Mq"
+ appSecret: "mXLOjea0woSMvK9gw7Fjsy7YlFO4iSu6", // "6Nz4n0xA8s8qdxQf2GqurZj2Fs55FUvM"
devicesHideable: ["switch", "light", "valve"],
devicesNonLAN: [22, 59, 102],
devicesSingleSwitch: [1, 5, 6, 14, 15, 22, 24, 27, 32, 36, 44, 59],
diff --git a/lib/eWeLinkHTTP.js b/lib/eWeLinkHTTP.js
index 6df6fbb9..0382542b 100644
--- a/lib/eWeLinkHTTP.js
+++ b/lib/eWeLinkHTTP.js
@@ -24,7 +24,7 @@ module.exports = class eWeLinkHTTP {
} else if (this.debug) {
this.log("Sending HTTP login request.");
}
- let dataToSign = crypto.createHmac("sha256", "6Nz4n0xA8s8qdxQf2GqurZj2Fs55FUvM").update(JSON.stringify(data)).digest("base64");
+ let dataToSign = crypto.createHmac("sha256", constants.appSecret).update(JSON.stringify(data)).digest("base64");
return new Promise((resolve, reject) => {
axios({
url: "https://" + this.httpHost + "/v2/user/login",
From c9ce9c77993e542394fbc1fca4b5e90b935b4e1b Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Tue, 15 Sep 2020 12:55:11 +0100
Subject: [PATCH 0148/3183] Create stale.yml
---
.github/stale.yml | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
create mode 100644 .github/stale.yml
diff --git a/.github/stale.yml b/.github/stale.yml
new file mode 100644
index 00000000..89b61309
--- /dev/null
+++ b/.github/stale.yml
@@ -0,0 +1,16 @@
+# Number of days of inactivity before an issue becomes stale
+daysUntilStale: 7
+# Number of days of inactivity before a stale issue is closed
+daysUntilClose: 7
+# Issues with these labels will never be considered stale
+exemptLabels:
+# Label to use when marking an issue as stale
+staleLabel: inactive
+# Comment to post when marking an issue as stale. Set to `false` to disable
+markComment: >
+ This issue has been automatically marked as inactive because it has not had
+ recent activity. It will be closed if no further activity occurs. Thank you
+ for your contributions.
+# Comment to post when closing a stale issue. Set to `false` to disable
+closeComment: >
+ This issue has been automatically closed.
From 1b6f9c4560a9e10a890c4c55befc8ca9b02a25b4 Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Tue, 15 Sep 2020 16:23:53 +0100
Subject: [PATCH 0149/3183] Update README.md
---
README.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 0225eb9e..60323284 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,8 @@
[![verified-by-homebridge](https://badgen.net/badge/homebridge/verified/purple)](https://github.com/homebridge/homebridge/wiki/Verified-Plugins)
[![Discord](https://img.shields.io/discord/432663330281226270?color=728ED5&logo=discord&label=discord)](https://discord.com/channels/432663330281226270/742733745743855627)
- [![npm](https://img.shields.io/npm/dt/homebridge-ewelink)](https://www.npmjs.com/package/homebridge-ewelink)
+ [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/prettier/prettier)
+ [![npm](https://img.shields.io/npm/dt/homebridge-ewelink)](https://www.npmjs.com/package/homebridge-ewelink)
[![npm](https://img.shields.io/npm/v/homebridge-ewelink/latest?label=release)](https://www.npmjs.com/package/homebridge-ewelink)
[![npm](https://img.shields.io/npm/v/homebridge-ewelink/beta?label=beta)](https://www.npmjs.com/package/homebridge-ewelink)
From bb1be253518800f38ff67aab154e10b45bc928d6 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 15 Sep 2020 16:25:56 +0100
Subject: [PATCH 0150/3183] prettier code
---
.prettier.ignore | 5 +
.prettierrc.json | 4 +
config.schema.json | 558 +++---
index.js | 6 +-
lib/constants.js | 316 ++--
lib/eWeLink.js | 4061 +++++++++++++++++++++++---------------------
lib/eWeLinkHTTP.js | 316 ++--
lib/eWeLinkLAN.js | 365 ++--
lib/eWeLinkWS.js | 551 +++---
package-lock.json | 1248 +++++++-------
package.json | 135 +-
11 files changed, 3955 insertions(+), 3610 deletions(-)
create mode 100644 .prettier.ignore
create mode 100644 .prettierrc.json
diff --git a/.prettier.ignore b/.prettier.ignore
new file mode 100644
index 00000000..45fb205e
--- /dev/null
+++ b/.prettier.ignore
@@ -0,0 +1,5 @@
+.DS_Store
+.nova
+.github
+.npm
+node_modules/
\ No newline at end of file
diff --git a/.prettierrc.json b/.prettierrc.json
new file mode 100644
index 00000000..163a0a7e
--- /dev/null
+++ b/.prettierrc.json
@@ -0,0 +1,4 @@
+{
+ "arrowParens": "avoid",
+ "printWidth": 120
+}
diff --git a/config.schema.json b/config.schema.json
index a6d6cd98..ee24e05b 100644
--- a/config.schema.json
+++ b/config.schema.json
@@ -1,305 +1,269 @@
{
- "pluginAlias":"eWeLink",
- "pluginType":"platform",
- "singular":true,
- "headerDisplay":"Homebridge plugin to control eWeLink devices with original firmware.",
- "footerDisplay":"For help and support please visit our [GitHub Wiki](https://github.com/bwp91/homebridge-ewelink/wiki).",
- "schema":{
- "type":"object",
- "properties":{
- "name":{
- "type":"string",
- "default":"eWeLink"
- },
- "countryCode":{
- "type":"string",
- "title":"Country Code",
- "description":"The telephone country code linked to your eWeLink account (without the +)."
- },
- "username":{
- "type":"string",
- "title":"Username",
- "description":"The phone number or email address linked to your eWeLink account. If you use a phone number please enter the country code (with the +), for example +8613185260282."
- },
- "password":{
- "type":"string",
- "title":"Password",
- "description":"The password for your eWeLink account."
- },
- "debug":{
- "title":"Debug Logging",
- "type":"boolean",
- "required":true,
- "description":"If enabled, more information will be added to the Homebridge log.",
- "default":false
- },
- "debugReqRes":{
- "title":"Request & Response Logging",
- "type":"boolean",
- "required":true,
- "description":"If enabled, HTTP, web socket and LAN mode messages will be added to the log. Not recommended for long-term use.",
- "default":false
- },
- "hideDevFromHB":{
- "type":"string",
- "title":"Hide Devices",
- "description":"A list of eWeLink devices to hide from Homebridge. For example '10009553c8' or multiple devices separated with a comma '10009553c8,10009553c9'.",
- "default":""
- },
- "hideFromHB":{
- "type":"string",
- "title":"Hide Device Channels",
- "description":"A list of device channels to hide from Homebridge. For example '10009553c8SW1' or multiple channels separated with a comma '10009553c8SW1,10009553c9SW2'. Only channels from switches, lights and irrigation valves can be hidden.",
- "default":""
- },
- "sensorTimeLength":{
- "type":"integer",
- "title":"Sensor Length",
- "description":"The number of seconds which the sensor tile in the Home app will light up for if a sensor detects something.",
- "default":60,
- "minimum":1,
- "maximum":120
- },
- "sensorTimeDifference":{
- "type":"integer",
- "title":"Sensor Lag",
- "description":"An offset in seconds to ignore any notifications if they is a delay between a sensor detecting something and Homebridge receiving the notification.",
- "default":120,
- "minimum":10,
- "maximum":300
- },
- "valveTimeLength":{
- "type":"integer",
- "title":"Valve Duration",
- "description":"The default number of seconds that irrigation valves will run for.",
- "default":20,
- "minimum": 10,
- "maximum":1800
- },
- "hideTHSwitch":{
- "title":"Hide TH10/TH16 Switch",
- "type":"boolean",
- "description":"If enabled, the switch for the TH10/TH16 devices will be hidden from Homebridge.",
- "default":false
- },
- "hideZBLDPress":{
- "title":"Hide Double/Long Press",
- "type":"boolean",
- "description":"If enabled, double and long press options will be hidden for the ZigBee button.",
- "default":false
- },
- "groups":{
- "type":"array",
- "title":"Custom Device Types",
- "description":"You can use this setting to set up custom device types within Homebridge. Currently only blinds, garage doors and locks are supported.",
- "items":{
- "type":"object",
- "properties":{
- "deviceId":{
- "type":"string",
- "title":"Device ID",
- "description":"Device ID from your eWeLink app (ten digits normally in the format 1000ab23cd)."
- },
- "type":{
- "type":"string",
- "title":"Type",
- "default":"null",
- "description":"The new type for this device.",
- "oneOf":[
- {
- "title":"Blind",
- "enum":[
- "blind"
- ]
- },
- {
- "title":"Garage Door",
- "enum":[
- "garage"
- ]
- },
- {
- "title":"Lock",
- "enum":[
- "lock"
- ]
- }
- ]
- },
- "setup":{
- "type":"string",
- "title":"Device Setup",
- "default":"null",
- "description":"The device setup. Please ignore this setting for locks",
- "oneOf":[
- {
- "title":"One Switch - for up and down",
- "enum":[
- "oneSwitch"
- ]
- },
- {
- "title":"Two Switches - one for up and one for down",
- "enum":[
- "twoSwitch"
- ]
- }
- ]
- },
- "operationTime":{
- "type":"integer",
- "title":"Operation Time",
- "description":"For blinds and garage doors this is the total time in deciseconds to fully open/close the device. For locks this is the time to show the Home app tile as unlocked. Count the time in seconds and multiply by 10, for example 100 for 10 seconds or 75 for 7.5 seconds.",
- "default":100,
- "minimum":10,
- "maximum":600
- },
- "sensorId":{
- "type":"string",
- "title":"Sensor",
- "description":"A Sonoff DW2 sensor can optionally be used for blinds and garage doors. This is to determine the current open/closed state of the device. Please enter the 10 digit device ID (normally in the format 1000ab23cd). Otherwise leave this blank."
- }
- }
- }
- },
- "bridgeSensors":{
- "type":"array",
- "title":"Sensors",
- "description":"You can expose different types of sensors connected to your RF Bridge in HomeKit.",
- "items":{
- "type":"object",
- "properties":{
- "deviceId":{
- "type":"string",
- "title":"RF Bridge Device ID",
- "description":"Device ID of your RF Bridge from your eWeLink app (10 digits normally in the format 1000******)."
- },
- "fullDeviceId":{
- "type":"string",
- "title":"Sensor Device ID",
- "description":"Device ID of the sensor from Homebridge (13 digits normally in the format 1000******SW*)."
- },
- "type":{
- "type":"string",
- "title":"Sensor Type",
- "default":"motion",
- "description":"Select the type of sensor you would like to expose this as in Homebridge.",
- "oneOf":[
- {
- "title":"Motion",
- "enum":[
- "motion"
- ]
- },
- {
- "title":"Smoke/Fire",
- "enum":[
- "smoke"
- ]
- },
- {
- "title":"Water/Leak",
- "enum":[
- "water"
- ]
- },
- {
- "title":"Carbon Monoxide",
- "enum":[
- "co"
- ]
- },
- {
- "title":"Carbon Dioxide",
- "enum":[
- "co2"
- ]
- },
- {
- "title":"Occupancy",
- "enum":[
- "occupancy"
- ]
- },
- {
- "title":"Contact",
- "enum":[
- "contact"
- ]
- }
- ]
- }
- }
- }
- }
+ "pluginAlias": "eWeLink",
+ "pluginType": "platform",
+ "singular": true,
+ "headerDisplay": "Homebridge plugin to control eWeLink devices with original firmware.",
+ "footerDisplay": "For help and support please visit our [GitHub Wiki](https://github.com/bwp91/homebridge-ewelink/wiki).",
+ "schema": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "default": "eWeLink"
},
- "required":[
- "countryCode",
- "username",
- "password"
- ]
- },
- "layout":[
- {
- "type":"fieldset",
- "items":[
- "countryCode",
- "username",
- "password"
- ]
+ "countryCode": {
+ "type": "string",
+ "title": "Country Code",
+ "description": "The telephone country code linked to your eWeLink account (without the +)."
+ },
+ "username": {
+ "type": "string",
+ "title": "Username",
+ "description": "The phone number or email address linked to your eWeLink account. If you use a phone number please enter the country code (with the +), for example +8613185260282."
+ },
+ "password": {
+ "type": "string",
+ "title": "Password",
+ "description": "The password for your eWeLink account."
+ },
+ "debug": {
+ "title": "Debug Logging",
+ "type": "boolean",
+ "required": true,
+ "description": "If enabled, more information will be added to the Homebridge log.",
+ "default": false
+ },
+ "debugReqRes": {
+ "title": "Request & Response Logging",
+ "type": "boolean",
+ "required": true,
+ "description": "If enabled, HTTP, web socket and LAN mode messages will be added to the log. Not recommended for long-term use.",
+ "default": false
+ },
+ "hideDevFromHB": {
+ "type": "string",
+ "title": "Hide Devices",
+ "description": "A list of eWeLink devices to hide from Homebridge. For example '10009553c8' or multiple devices separated with a comma '10009553c8,10009553c9'.",
+ "default": ""
},
- {
- "type":"fieldset",
- "title":"Optional",
- "description":"Only adjust these settings if you know what you are doing.",
- "expandable":true,
- "items":[
- "debug",
- "debugReqRes",
- "hideDevFromHB",
- "hideFromHB",
- "sensorTimeLength",
- "sensorTimeDifference",
- "valveTimeLength",
- "hideTHSwitch",
- "hideZBLDPress"
- ]
+ "hideFromHB": {
+ "type": "string",
+ "title": "Hide Device Channels",
+ "description": "A list of device channels to hide from Homebridge. For example '10009553c8SW1' or multiple channels separated with a comma '10009553c8SW1,10009553c9SW2'. Only channels from switches, lights and irrigation valves can be hidden.",
+ "default": ""
},
- {
- "key":"groups",
- "expandable":true,
- "title":"Custom Device Types",
- "add":"Add Another Type",
- "type":"array",
- "items":[
- {
- "type":"fieldset",
- "items":[
- "groups[].deviceId",
- "groups[].type",
- "groups[].setup",
- "groups[].operationTime",
- "groups[].sensorId"
- ]
+ "sensorTimeLength": {
+ "type": "integer",
+ "title": "Sensor Length",
+ "description": "The number of seconds which the sensor tile in the Home app will light up for if a sensor detects something.",
+ "default": 60,
+ "minimum": 1,
+ "maximum": 120
+ },
+ "sensorTimeDifference": {
+ "type": "integer",
+ "title": "Sensor Lag",
+ "description": "An offset in seconds to ignore any notifications if they is a delay between a sensor detecting something and Homebridge receiving the notification.",
+ "default": 120,
+ "minimum": 10,
+ "maximum": 300
+ },
+ "valveTimeLength": {
+ "type": "integer",
+ "title": "Valve Duration",
+ "description": "The default number of seconds that irrigation valves will run for.",
+ "default": 20,
+ "minimum": 10,
+ "maximum": 1800
+ },
+ "hideTHSwitch": {
+ "title": "Hide TH10/TH16 Switch",
+ "type": "boolean",
+ "description": "If enabled, the switch for the TH10/TH16 devices will be hidden from Homebridge.",
+ "default": false
+ },
+ "hideZBLDPress": {
+ "title": "Hide Double/Long Press",
+ "type": "boolean",
+ "description": "If enabled, double and long press options will be hidden for the ZigBee button.",
+ "default": false
+ },
+ "groups": {
+ "type": "array",
+ "title": "Custom Device Types",
+ "description": "You can use this setting to set up custom device types within Homebridge. Currently only blinds, garage doors and locks are supported.",
+ "items": {
+ "type": "object",
+ "properties": {
+ "deviceId": {
+ "type": "string",
+ "title": "Device ID",
+ "description": "Device ID from your eWeLink app (ten digits normally in the format 1000ab23cd)."
+ },
+ "type": {
+ "type": "string",
+ "title": "Type",
+ "default": "null",
+ "description": "The new type for this device.",
+ "oneOf": [
+ {
+ "title": "Blind",
+ "enum": ["blind"]
+ },
+ {
+ "title": "Garage Door",
+ "enum": ["garage"]
+ },
+ {
+ "title": "Lock",
+ "enum": ["lock"]
+ }
+ ]
+ },
+ "setup": {
+ "type": "string",
+ "title": "Device Setup",
+ "default": "null",
+ "description": "The device setup. Please ignore this setting for locks",
+ "oneOf": [
+ {
+ "title": "One Switch - for up and down",
+ "enum": ["oneSwitch"]
+ },
+ {
+ "title": "Two Switches - one for up and one for down",
+ "enum": ["twoSwitch"]
+ }
+ ]
+ },
+ "operationTime": {
+ "type": "integer",
+ "title": "Operation Time",
+ "description": "For blinds and garage doors this is the total time in deciseconds to fully open/close the device. For locks this is the time to show the Home app tile as unlocked. Count the time in seconds and multiply by 10, for example 100 for 10 seconds or 75 for 7.5 seconds.",
+ "default": 100,
+ "minimum": 10,
+ "maximum": 600
+ },
+ "sensorId": {
+ "type": "string",
+ "title": "Sensor",
+ "description": "A Sonoff DW2 sensor can optionally be used for blinds and garage doors. This is to determine the current open/closed state of the device. Please enter the 10 digit device ID (normally in the format 1000ab23cd). Otherwise leave this blank."
}
- ]
+ }
+ }
},
- {
- "key":"bridgeSensors",
- "title":"RF Bridge Sensors",
- "expandable":true,
- "add":"Add Another Sensor",
- "type":"array",
- "items":[
- {
- "type":"fieldset",
- "items":[
- "bridgeSensors[].deviceId",
- "bridgeSensors[].fullDeviceId",
- "bridgeSensors[].type"
- ]
+ "bridgeSensors": {
+ "type": "array",
+ "title": "Sensors",
+ "description": "You can expose different types of sensors connected to your RF Bridge in HomeKit.",
+ "items": {
+ "type": "object",
+ "properties": {
+ "deviceId": {
+ "type": "string",
+ "title": "RF Bridge Device ID",
+ "description": "Device ID of your RF Bridge from your eWeLink app (10 digits normally in the format 1000******)."
+ },
+ "fullDeviceId": {
+ "type": "string",
+ "title": "Sensor Device ID",
+ "description": "Device ID of the sensor from Homebridge (13 digits normally in the format 1000******SW*)."
+ },
+ "type": {
+ "type": "string",
+ "title": "Sensor Type",
+ "default": "motion",
+ "description": "Select the type of sensor you would like to expose this as in Homebridge.",
+ "oneOf": [
+ {
+ "title": "Motion",
+ "enum": ["motion"]
+ },
+ {
+ "title": "Smoke/Fire",
+ "enum": ["smoke"]
+ },
+ {
+ "title": "Water/Leak",
+ "enum": ["water"]
+ },
+ {
+ "title": "Carbon Monoxide",
+ "enum": ["co"]
+ },
+ {
+ "title": "Carbon Dioxide",
+ "enum": ["co2"]
+ },
+ {
+ "title": "Occupancy",
+ "enum": ["occupancy"]
+ },
+ {
+ "title": "Contact",
+ "enum": ["contact"]
+ }
+ ]
}
- ]
+ }
+ }
}
- ]
-}
\ No newline at end of file
+ },
+ "required": ["countryCode", "username", "password"]
+ },
+ "layout": [
+ {
+ "type": "fieldset",
+ "items": ["countryCode", "username", "password"]
+ },
+ {
+ "type": "fieldset",
+ "title": "Optional",
+ "description": "Only adjust these settings if you know what you are doing.",
+ "expandable": true,
+ "items": [
+ "debug",
+ "debugReqRes",
+ "hideDevFromHB",
+ "hideFromHB",
+ "sensorTimeLength",
+ "sensorTimeDifference",
+ "valveTimeLength",
+ "hideTHSwitch",
+ "hideZBLDPress"
+ ]
+ },
+ {
+ "key": "groups",
+ "expandable": true,
+ "title": "Custom Device Types",
+ "add": "Add Another Type",
+ "type": "array",
+ "items": [
+ {
+ "type": "fieldset",
+ "items": [
+ "groups[].deviceId",
+ "groups[].type",
+ "groups[].setup",
+ "groups[].operationTime",
+ "groups[].sensorId"
+ ]
+ }
+ ]
+ },
+ {
+ "key": "bridgeSensors",
+ "title": "RF Bridge Sensors",
+ "expandable": true,
+ "add": "Add Another Sensor",
+ "type": "array",
+ "items": [
+ {
+ "type": "fieldset",
+ "items": ["bridgeSensors[].deviceId", "bridgeSensors[].fullDeviceId", "bridgeSensors[].type"]
+ }
+ ]
+ }
+ ]
+}
diff --git a/index.js b/index.js
index 4902dd17..d25bb094 100644
--- a/index.js
+++ b/index.js
@@ -1,6 +1,6 @@
/* jshint esversion: 9, -W030, node: true */
"use strict";
module.exports = function (homebridge) {
- const eWeLink = require("./lib/eWeLink.js")(homebridge);
- homebridge.registerPlatform("homebridge-ewelink", "eWeLink", eWeLink, true);
-};
\ No newline at end of file
+ const eWeLink = require("./lib/eWeLink.js")(homebridge);
+ homebridge.registerPlatform("homebridge-ewelink", "eWeLink", eWeLink, true);
+};
diff --git a/lib/constants.js b/lib/constants.js
index 0751d683..c8a8f17f 100644
--- a/lib/constants.js
+++ b/lib/constants.js
@@ -1,138 +1,184 @@
/* jshint esversion: 9, -W030, node: true */
"use strict";
module.exports = {
- appId: "Uw83EKZFxdif7XFXEsrpduz5YyjP7nTl", // "oeVkj2lYFGnJu5XUtWisfW4utiN4u9Mq"
- appSecret: "mXLOjea0woSMvK9gw7Fjsy7YlFO4iSu6", // "6Nz4n0xA8s8qdxQf2GqurZj2Fs55FUvM"
- devicesHideable: ["switch", "light", "valve"],
- devicesNonLAN: [22, 59, 102],
- devicesSingleSwitch: [1, 5, 6, 14, 15, 22, 24, 27, 32, 36, 44, 59],
- devicesSingleSwitchParams: ["switch"],
- devicesMultiSwitch: [2, 3, 4, 7, 8, 9, 29, 30, 31, 34, 41],
- devicesMultiSwitchParams: ["switches"],
- devicesSingleSwitchLight: ["T1 1C", "L1", "B1", "B1_R2", "TX1C", "D1", "D1R1", "KING-M4", "Slampher", "GTTA59"],
- devicesSingleSwitchLightParams: ["switch", "state", "bright", "colorR", "brightness", "channel0", "channel2", "xyz_mode"],
- devicesMultiSwitchLight: ["T1 2C", "T1 3C", "TX2C", "TX3C"],
- devicesMultiSwitchLightParams: ["switches"],
- devicesBrightable: [36, 44],
- devicesColourable: [22, 59],
- devicesSensor: [102],
- devicesSensorParams: ["switch", "battery", "type"],
- devicesThermostat: [15],
- devicesThermostatParams: ["currentTemperature", "currentHumidity", "switch", "masterSwitch"],
- devicesFan: [34],
- devicesFanParams: ["switches", "light", "fan", "speed"],
- devicesOutlet: [32],
- devicesOutletParams: ["switch", "power", "voltage", "current"],
- devicesCamera: [87],
- devicesUSB: [77],
- devicesUSBParams: ["switches"],
- devicesSCM: [78],
- devicesSCMParams: ["switches"],
- devicesRFBridge: [28],
- devicesRFBridgeParams: ["cmd"],
- devicesZBBridge: [66],
- devicesZBBridgeParams: ["key", "temperature", "humidity", "motion", "lock", "trigTime", "battery"],
- devicesZB: [1000, 1770, 2026, 3026],
- devicesValveParams: ["switches"],
- devicesBlindParams: ["switch", "switches"],
- devicesGarageParams: ["switch", "switches"],
- devicesLockParams: ["switch"],
- allowedGroups: ["blind", "garage", "lock"],
- paramsToKeep: ["battery", "bright", "brightness", "channel", "cmd", "colorB", "colorG", "colorR", "current", "currentHumidity", "currentTemperature", "fan", "humidity", "key", "light", "lock", "mainSwitch", "mode", "motion", "online", "power", "rfChl", "rfList", "rfTrig", "sensorType", "speed", "state", "switch", "switches", "temperature", "trigTime", "type", "voltage", "zyx_mode"],
- chansFromUiid: {
- 1: 1, // "SOCKET" \\ 20, MINI, BASIC, S26
- 2: 2, // "SOCKET_2" \\
- 3: 3, // "SOCKET_3" \\
- 4: 4, // "SOCKET_4", \\
- 5: 1, // "SOCKET_POWER" \\
- 6: 1, // "SWITCH" \\ T1 1C, TX1C
- 7: 2, // "SWITCH_2" \\ T1 2C, TX2C
- 8: 3, // "SWITCH_3" \\ T1 3C, TX3C
- 9: 4, // "SWITCH_4" \\
- 10: 0, // "OSPF" \\
- 11: 0, // "CURTAIN" \\ King Q4 Cover
- 12: 0, // "EW-RE" \\
- 13: 0, // "FIREPLACE" \\
- 14: 1, // "SWITCH_CHANGE" \\
- 15: 1, // "THERMOSTAT" \\ TH10, TH16
- 16: 0, // "COLD_WARM_LED" \\
- 17: 0, // "THREE_GEAR_FAN" \\
- 18: 0, // "SENSORS_CENTER" \\
- 19: 0, // "HUMIDIFIER" \\
- 22: 1, // "RGB_BALL_LIGHT" \\ B1, B1_R2
- 23: 0, // "NEST_THERMOSTAT" \\
- 24: 1, // "GSM_SOCKET" \\
- 25: 0, // "AROMATHERAPY", \\ Diffuser
- 26: 0, // "RuiMiTeWenKongQi" \\
- 27: 1, // "GSM_UNLIMIT_SOCKET" \\
- 28: 1, // "RF_BRIDGE" \\ RFBridge, RF_Bridge
- 29: 2, // "GSM_SOCKET_2" \\
- 30: 3, // "GSM_SOCKET_3" \\
- 31: 4, // "GSM_SOCKET_4" \\
- 32: 1, // "POWER_DETECTION_SOCKET" \\ Pow_R2 POW
- 33: 0, // "LIGHT_BELT", \\
- 34: 4, // "FAN_LIGHT" \\ iFan02, iFan
- 35: 0, // "EZVIZ_CAMERA", \\
- 36: 1, // "SINGLE_CHANNEL_DIMMER_SWITCH" \\ KING-M4
- 38: 0, // "HOME_KIT_BRIDGE", \\
- 40: 0, // "FUJIN_OPS" \\
- 41: 4, // "CUN_YOU_DOOR" \\
- 42: 0, // "SMART_BEDSIDE_AND_NEW_RGB_BALL_LIGHT" \\
- 43: 0, // "?" \\
- 44: 1, // "SNOFF_LIGHT" \\ D1
- 45: 0, // "DOWN_CEILING_LIGHT" \\
- 46: 0, // "AIR_CLEANER" \\
- 49: 0, // "MACHINE_BED" \\
- 51: 0, // "COLD_WARM_DESK_LIGHT" \\
- 52: 0, // "DOUBLE_COLOR_DEMO_LIGHT" \\
- 53: 0, // "ELECTRIC_FAN_WITH_LAMP" \\
- 55: 0, // "SWEEPING_ROBOT" \\
- 56: 0, // "RGB_BALL_LIGHT_4" \\
- 57: 0, // "MONOCHROMATIC_BALL_LIGHT" \\
- 59: 1, // "MUSIC_LIGHT_BELT" \\ L1
- 60: 0, // "NEW_HUMIDIFIER" \\
- 61: 0, // "KAI_WEI_ROUTER" \\
- 62: 0, // "MEARICAMERA" \\
- 64: 0, // "HeatingTable" \\
- 65: 0, // "CustomCamera" \\
- 66: 0, // "ZIGBEE_MAIN_DEVICE" \\
- 67: 0, // "RollingDoor" \\
- 68: 0, // "KOOCHUWAH" \\
- 69: 0, // "ATMOSPHERE_LAMP" \\
- 76: 0, // "YI_GE_ER_LAMP" \\
- 77: 4, // "SINGLE_SOCKET_MULTIPLE" \\ (1 socket device using data structure of four :()
- 78: 4, // "SINGLE_SWITCH_MULTIPLE" \\ (1 switch device using data structure of four :()
- 79: 0, // "CHRISTMAS_LIGHT" \\
- 80: 0, // "HANYUAN_AIR_CONDITION" \\
- 81: 1, // "GSM_SOCKET_NO_FLOW" \\
- 82: 2, // "GSM_SOCKET_2_NO_FLOW" \\
- 83: 3, // "GSM_SOCKET_3_NO_FLOW" \\
- 84: 4, // "GSM_SOCKET_4_NO_FLOW" \\
- 86: 0, // "CLEAR_BOOT" \\
- 87: 0, // "EWELINK_IOT_CAMERA" \\ GK-200MP2B
- 88: 0, // "YK_INFRARED" \\
- 89: 0, // "SMART_OPEN_MACHINE" \\
- 90: 0, // "GSM_RFBridge" \\
- 91: 0, // "ROLLING_DOOR_91" \\
- 93: 0, // "HTHD_AIR_CLEANER" \\
- 94: 0, // "YIAN_ELECTRIC_PROTECT" \\
- 98: 0, // "DOORBELL_RFBRIDGE" \\
- 102: 1, // "DOOR_MAGNETIC" \\ OPL-DMA, DW2
- 103: 0, // "WOTEWODE_TEM_LIGHT" \\
- 104: 0, // "WOTEWODE_RGB_TEM_LIGHT" \\
- 107: 0, // "GSM_SOCKET_NO_FLOW" \\
- 109: 0, // "YK_INFRARED_2" \\
- 1000: 1, // "ZIGBEE_WIRELESS_SWITCH" \\
- 1001: 0, // "BLADELESS_FAN" \\
- 1002: 0, // "NEW_HUMIDIFIER" \\
- 1003: 0, // "WARM_AIR_BLOWER" \\
- 1256: 1, // "ZIGBEE_SINGLE_SWITCH" \\
- 1770: 1, // "ZIGBEE_TEMPERATURE_SENSOR" \\
- 2026: 1, // "ZIGBEE_MOBILE_SENSOR" \\
- 2256: 2, // "ZIGBEE_SWITCH_2" \\
- 3026: 1, // "ZIGBEE_DOOR_AND_WINDOW_SENSOR" \\
- 3256: 3, // "ZIGBEE_SWITCH_3" \\
- 4026: 1, // "ZIGBEE_WATER_SENSOR" \\
- 4256: 4, // "ZIGBEE_SWITCH_4" \\
- }
-};
\ No newline at end of file
+ // appId: "Uw83EKZFxdif7XFXEsrpduz5YyjP7nTl",
+ appId: "oeVkj2lYFGnJu5XUtWisfW4utiN4u9Mq",
+ // appSecret: "mXLOjea0woSMvK9gw7Fjsy7YlFO4iSu6",
+ appSecret: "6Nz4n0xA8s8qdxQf2GqurZj2Fs55FUvM",
+ devicesHideable: ["switch", "light", "valve"],
+ devicesNonLAN: [22, 59, 102],
+ devicesSingleSwitch: [1, 5, 6, 14, 15, 22, 24, 27, 32, 36, 44, 59],
+ devicesSingleSwitchParams: ["switch"],
+ devicesMultiSwitch: [2, 3, 4, 7, 8, 9, 29, 30, 31, 34, 41],
+ devicesMultiSwitchParams: ["switches"],
+ devicesSingleSwitchLight: ["T1 1C", "L1", "B1", "B1_R2", "TX1C", "D1", "D1R1", "KING-M4", "Slampher", "GTTA59"],
+ devicesSingleSwitchLightParams: [
+ "switch",
+ "state",
+ "bright",
+ "colorR",
+ "brightness",
+ "channel0",
+ "channel2",
+ "xyz_mode",
+ ],
+ devicesMultiSwitchLight: ["T1 2C", "T1 3C", "TX2C", "TX3C"],
+ devicesMultiSwitchLightParams: ["switches"],
+ devicesBrightable: [36, 44],
+ devicesColourable: [22, 59],
+ devicesSensor: [102],
+ devicesSensorParams: ["switch", "battery", "type"],
+ devicesThermostat: [15],
+ devicesThermostatParams: ["currentTemperature", "currentHumidity", "switch", "masterSwitch"],
+ devicesFan: [34],
+ devicesFanParams: ["switches", "light", "fan", "speed"],
+ devicesOutlet: [32],
+ devicesOutletParams: ["switch", "power", "voltage", "current"],
+ devicesCamera: [87],
+ devicesUSB: [77],
+ devicesUSBParams: ["switches"],
+ devicesSCM: [78],
+ devicesSCMParams: ["switches"],
+ devicesRFBridge: [28],
+ devicesRFBridgeParams: ["cmd"],
+ devicesZBBridge: [66],
+ devicesZBBridgeParams: ["key", "temperature", "humidity", "motion", "lock", "trigTime", "battery"],
+ devicesZB: [1000, 1770, 2026, 3026],
+ devicesValveParams: ["switches"],
+ devicesBlindParams: ["switch", "switches"],
+ devicesGarageParams: ["switch", "switches"],
+ devicesLockParams: ["switch"],
+ allowedGroups: ["blind", "garage", "lock"],
+ paramsToKeep: [
+ "battery",
+ "bright",
+ "brightness",
+ "channel",
+ "cmd",
+ "colorB",
+ "colorG",
+ "colorR",
+ "current",
+ "currentHumidity",
+ "currentTemperature",
+ "fan",
+ "humidity",
+ "key",
+ "light",
+ "lock",
+ "mainSwitch",
+ "mode",
+ "motion",
+ "online",
+ "power",
+ "rfChl",
+ "rfList",
+ "rfTrig",
+ "sensorType",
+ "speed",
+ "state",
+ "switch",
+ "switches",
+ "temperature",
+ "trigTime",
+ "type",
+ "voltage",
+ "zyx_mode",
+ ],
+ chansFromUiid: {
+ 1: 1, // "SOCKET" \\ 20, MINI, BASIC, S26
+ 2: 2, // "SOCKET_2" \\
+ 3: 3, // "SOCKET_3" \\
+ 4: 4, // "SOCKET_4", \\
+ 5: 1, // "SOCKET_POWER" \\
+ 6: 1, // "SWITCH" \\ T1 1C, TX1C
+ 7: 2, // "SWITCH_2" \\ T1 2C, TX2C
+ 8: 3, // "SWITCH_3" \\ T1 3C, TX3C
+ 9: 4, // "SWITCH_4" \\
+ 10: 0, // "OSPF" \\
+ 11: 0, // "CURTAIN" \\ King Q4 Cover
+ 12: 0, // "EW-RE" \\
+ 13: 0, // "FIREPLACE" \\
+ 14: 1, // "SWITCH_CHANGE" \\
+ 15: 1, // "THERMOSTAT" \\ TH10, TH16
+ 16: 0, // "COLD_WARM_LED" \\
+ 17: 0, // "THREE_GEAR_FAN" \\
+ 18: 0, // "SENSORS_CENTER" \\
+ 19: 0, // "HUMIDIFIER" \\
+ 22: 1, // "RGB_BALL_LIGHT" \\ B1, B1_R2
+ 23: 0, // "NEST_THERMOSTAT" \\
+ 24: 1, // "GSM_SOCKET" \\
+ 25: 0, // "AROMATHERAPY", \\ Diffuser
+ 26: 0, // "RuiMiTeWenKongQi" \\
+ 27: 1, // "GSM_UNLIMIT_SOCKET" \\
+ 28: 1, // "RF_BRIDGE" \\ RFBridge, RF_Bridge
+ 29: 2, // "GSM_SOCKET_2" \\
+ 30: 3, // "GSM_SOCKET_3" \\
+ 31: 4, // "GSM_SOCKET_4" \\
+ 32: 1, // "POWER_DETECTION_SOCKET" \\ Pow_R2 POW
+ 33: 0, // "LIGHT_BELT", \\
+ 34: 4, // "FAN_LIGHT" \\ iFan02, iFan
+ 35: 0, // "EZVIZ_CAMERA", \\
+ 36: 1, // "SINGLE_CHANNEL_DIMMER_SWITCH" \\ KING-M4
+ 38: 0, // "HOME_KIT_BRIDGE", \\
+ 40: 0, // "FUJIN_OPS" \\
+ 41: 4, // "CUN_YOU_DOOR" \\
+ 42: 0, // "SMART_BEDSIDE_AND_NEW_RGB_BALL_LIGHT" \\
+ 43: 0, // "?" \\
+ 44: 1, // "SNOFF_LIGHT" \\ D1
+ 45: 0, // "DOWN_CEILING_LIGHT" \\
+ 46: 0, // "AIR_CLEANER" \\
+ 49: 0, // "MACHINE_BED" \\
+ 51: 0, // "COLD_WARM_DESK_LIGHT" \\
+ 52: 0, // "DOUBLE_COLOR_DEMO_LIGHT" \\
+ 53: 0, // "ELECTRIC_FAN_WITH_LAMP" \\
+ 55: 0, // "SWEEPING_ROBOT" \\
+ 56: 0, // "RGB_BALL_LIGHT_4" \\
+ 57: 0, // "MONOCHROMATIC_BALL_LIGHT" \\
+ 59: 1, // "MUSIC_LIGHT_BELT" \\ L1
+ 60: 0, // "NEW_HUMIDIFIER" \\
+ 61: 0, // "KAI_WEI_ROUTER" \\
+ 62: 0, // "MEARICAMERA" \\
+ 64: 0, // "HeatingTable" \\
+ 65: 0, // "CustomCamera" \\
+ 66: 0, // "ZIGBEE_MAIN_DEVICE" \\
+ 67: 0, // "RollingDoor" \\
+ 68: 0, // "KOOCHUWAH" \\
+ 69: 0, // "ATMOSPHERE_LAMP" \\
+ 76: 0, // "YI_GE_ER_LAMP" \\
+ 77: 4, // "SINGLE_SOCKET_MULTIPLE" \\ (1 socket device using data structure of four :()
+ 78: 4, // "SINGLE_SWITCH_MULTIPLE" \\ (1 switch device using data structure of four :()
+ 79: 0, // "CHRISTMAS_LIGHT" \\
+ 80: 0, // "HANYUAN_AIR_CONDITION" \\
+ 81: 1, // "GSM_SOCKET_NO_FLOW" \\
+ 82: 2, // "GSM_SOCKET_2_NO_FLOW" \\
+ 83: 3, // "GSM_SOCKET_3_NO_FLOW" \\
+ 84: 4, // "GSM_SOCKET_4_NO_FLOW" \\
+ 86: 0, // "CLEAR_BOOT" \\
+ 87: 0, // "EWELINK_IOT_CAMERA" \\ GK-200MP2B
+ 88: 0, // "YK_INFRARED" \\
+ 89: 0, // "SMART_OPEN_MACHINE" \\
+ 90: 0, // "GSM_RFBridge" \\
+ 91: 0, // "ROLLING_DOOR_91" \\
+ 93: 0, // "HTHD_AIR_CLEANER" \\
+ 94: 0, // "YIAN_ELECTRIC_PROTECT" \\
+ 98: 0, // "DOORBELL_RFBRIDGE" \\
+ 102: 1, // "DOOR_MAGNETIC" \\ OPL-DMA, DW2
+ 103: 0, // "WOTEWODE_TEM_LIGHT" \\
+ 104: 0, // "WOTEWODE_RGB_TEM_LIGHT" \\
+ 107: 0, // "GSM_SOCKET_NO_FLOW" \\
+ 109: 0, // "YK_INFRARED_2" \\
+ 1000: 1, // "ZIGBEE_WIRELESS_SWITCH" \\
+ 1001: 0, // "BLADELESS_FAN" \\
+ 1002: 0, // "NEW_HUMIDIFIER" \\
+ 1003: 0, // "WARM_AIR_BLOWER" \\
+ 1256: 1, // "ZIGBEE_SINGLE_SWITCH" \\
+ 1770: 1, // "ZIGBEE_TEMPERATURE_SENSOR" \\
+ 2026: 1, // "ZIGBEE_MOBILE_SENSOR" \\
+ 2256: 2, // "ZIGBEE_SWITCH_2" \\
+ 3026: 1, // "ZIGBEE_DOOR_AND_WINDOW_SENSOR" \\
+ 3256: 3, // "ZIGBEE_SWITCH_3" \\
+ 4026: 1, // "ZIGBEE_WATER_SENSOR" \\
+ 4256: 4, // "ZIGBEE_SWITCH_4" \\
+ },
+};
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 8dec569e..5b87acf8 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -2,1938 +2,2203 @@
"use strict";
let Accessory, Characteristic, EveService, EveHistoryService, Service, UUIDGen;
const cns = require("./constants"),
- convert = require("color-convert"),
- corrInterval = require("correcting-interval"),
- eWeLinkHTTP = require("./eWeLinkHTTP"),
- eWeLinkWS = require("./eWeLinkWS"),
- eWeLinkLAN = require("./eWeLinkLAN"),
- fakegato = require("fakegato-history"),
- hbLib = require("homebridge-lib");
+ convert = require("color-convert"),
+ corrInterval = require("correcting-interval"),
+ eWeLinkHTTP = require("./eWeLinkHTTP"),
+ eWeLinkWS = require("./eWeLinkWS"),
+ eWeLinkLAN = require("./eWeLinkLAN"),
+ fakegato = require("fakegato-history"),
+ hbLib = require("homebridge-lib");
class eWeLink {
- constructor(log, config, api) {
- if (!log || !api || !config) return;
- if (!config.username || !config.password || !config.countryCode) {
- log.error("**************** Cannot load homebridge-ewelink ****************");
- log.error("Your eWeLink credentials are missing from the Homebridge config.");
- log.error("****************************************************************");
- return;
- }
- this.log = log;
- this.config = config;
- this.api = api;
- this.debug = this.config.debug || false;
- this.devicesInHB = new Map();
- this.devicesInEwe = new Map();
- this.cusG = new Map();
- this.cusS = new Map();
- this.eveLogPath = this.api.user.storagePath() + "/homebridge-ewelink/";
- this.api
- .on("didFinishLaunching", () => {
- this.log("Plugin has finished initialising. Starting synchronisation with eWeLink account.");
- //*** Set up HTTP client and get the user HTTP host ***\\
- this.httpClient = new eWeLinkHTTP(this.config, this.log);
- this.httpClient.getHost()
- .then(() => this.httpClient.login())
- .then(res => { //*** Set up the web socket client ***\\
- this.wsClient = new eWeLinkWS(this.config, this.log, res);
- return this.wsClient.getHost();
- }).then(() => { //*** Open web socket connection and get device list via HTTP ***\\
- this.wsClient.login();
- return this.httpClient.getDevices();
- }).then(res => { //*** Get device IP addresses for LAN mode ***\\
- this.httpDevices = res
- .filter(device => device.hasOwnProperty("extra") && device.extra.hasOwnProperty("uiid"))
- .filter(device => !(this.config.hideDevFromHB || "").includes(device.deviceid));
- this.lanClient = new eWeLinkLAN(this.config, this.log, this.httpDevices);
- this.httpDevices.forEach(device => this.devicesInEwe.set(device.deviceid, device));
- return this.lanClient.getHosts();
- }).then(res => { //*** Set up the LAN mode listener ***\\
- this.lanDevices = res.map;
- this.lanDevicesOnline = res.count;
- return this.lanClient.startMonitor();
- }).then(() => { //*** Use the device list to refresh Homebridge accessories ***\\
- (() => {
- //*** Remove all Homebridge accessories if none found ***\\
- if (Object.keys(this.httpDevices).length === 0 && Object.keys(this.lanDevices).length === 0) {
- Array.from(this.devicesInHB.values()).forEach(a => this.removeAccessory(a));
- this.devicesInHB.clear();
- this.log.warn("******* Not loading homebridge-ewelink *******");
- this.log.warn("No devices were found in your eWeLink account.");
- this.log.warn("**********************************************");
- return;
- }
- //*** Make a map of custom groups from Homebridge config ***\\
- if (Object.keys(this.config.groups || []).length > 0) {
- this.config.groups
- .filter(g => g.hasOwnProperty("type") && cns.allowedGroups.includes(g.type))
- .filter(g => g.hasOwnProperty("deviceId") && this.devicesInEwe.has(g.deviceId.toLowerCase()))
- .forEach(g => this.cusG.set(g.deviceId + "SWX", g));
- }
- //*** Make a map of RF Bridge custom sensors from Homebridge config ***\\
- if (Object.keys(this.config.bridgeSensors || []).length > 0) {
- this.config.bridgeSensors
- .filter(s => s.hasOwnProperty("deviceId") && this.devicesInEwe.has(s.deviceId.toLowerCase()))
- .forEach(s => this.cusS.set(s.fullDeviceId, s));
- }
- //*** Logging always helps to see if everything is okay so far ***\\
- this.log("[%s] eWeLink devices were loaded from the Homebridge cache.", this.devicesInHB.size);
- this.log("[%s] primary devices were loaded from your eWeLink account.", this.devicesInEwe.size);
- this.log("[%s] primary devices were discovered on your local network.", this.lanDevicesOnline);
- //*** Remove Homebridge accessories that don't appear in eWeLink ***\\
- this.devicesInHB.forEach(a => {
- if (!this.devicesInEwe.has(a.context.eweDeviceId)) {
- this.removeAccessory(a);
- }
- });
- //*** Synchronise devices between eWeLink and Homebridge and set up ws/lan listeners ***\\
- this.devicesInEwe.forEach(d => this.initialiseDevice(d));
- this.wsClient.receiveUpdate(d => this.receiveDeviceUpdate(d));
- this.lanClient.receiveUpdate(d => this.receiveDeviceUpdate(d));
- this.log("eWeLink setup complete. If you're enjoying this package please consider a âī¸ on GitHub :).");
- if (this.config.debugReqRes || false) {
- this.log.warn("You have 'Request & Response Logging' enabled. This setting is not recommended for long-term use.");
- }
- })();
- }).catch(err => {
- this.log.error("************** Cannot load homebridge-ewelink **************");
- this.log.error(err);
- this.log.error("************************************************************");
- if (this.lanClient) this.lanClient.closeConnection();
- if (this.wsClient) this.wsClient.closeConnection();
- });
- })
- .on('shutdown', () => {
+ constructor(log, config, api) {
+ if (!log || !api || !config) return;
+ if (!config.username || !config.password || !config.countryCode) {
+ log.error("**************** Cannot load homebridge-ewelink ****************");
+ log.error("Your eWeLink credentials are missing from the Homebridge config.");
+ log.error("****************************************************************");
+ return;
+ }
+ this.log = log;
+ this.config = config;
+ this.api = api;
+ this.debug = this.config.debug || false;
+ this.devicesInHB = new Map();
+ this.devicesInEwe = new Map();
+ this.cusG = new Map();
+ this.cusS = new Map();
+ this.eveLogPath = this.api.user.storagePath() + "/homebridge-ewelink/";
+ this.api
+ .on("didFinishLaunching", () => {
+ this.log("Plugin has finished initialising. Starting synchronisation with eWeLink account.");
+ //*** Set up HTTP client and get the user HTTP host ***\\
+ this.httpClient = new eWeLinkHTTP(this.config, this.log);
+ this.httpClient
+ .getHost()
+ .then(() => this.httpClient.login())
+ .then(res => {
+ //*** Set up the web socket client ***\\
+ this.wsClient = new eWeLinkWS(this.config, this.log, res);
+ return this.wsClient.getHost();
+ })
+ .then(() => {
+ //*** Open web socket connection and get device list via HTTP ***\\
+ this.wsClient.login();
+ return this.httpClient.getDevices();
+ })
+ .then(res => {
+ //*** Get device IP addresses for LAN mode ***\\
+ this.httpDevices = res
+ .filter(device => device.hasOwnProperty("extra") && device.extra.hasOwnProperty("uiid"))
+ .filter(device => !(this.config.hideDevFromHB || "").includes(device.deviceid));
+ this.lanClient = new eWeLinkLAN(this.config, this.log, this.httpDevices);
+ this.httpDevices.forEach(device => this.devicesInEwe.set(device.deviceid, device));
+ return this.lanClient.getHosts();
+ })
+ .then(res => {
+ //*** Set up the LAN mode listener ***\\
+ this.lanDevices = res.map;
+ this.lanDevicesOnline = res.count;
+ return this.lanClient.startMonitor();
+ })
+ .then(() => {
+ //*** Use the device list to refresh Homebridge accessories ***\\
+ (() => {
+ //*** Remove all Homebridge accessories if none found ***\\
+ if (Object.keys(this.httpDevices).length === 0 && Object.keys(this.lanDevices).length === 0) {
+ Array.from(this.devicesInHB.values()).forEach(a => this.removeAccessory(a));
+ this.devicesInHB.clear();
+ this.log.warn("******* Not loading homebridge-ewelink *******");
+ this.log.warn("No devices were found in your eWeLink account.");
+ this.log.warn("**********************************************");
+ return;
+ }
+ //*** Make a map of custom groups from Homebridge config ***\\
+ if (Object.keys(this.config.groups || []).length > 0) {
+ this.config.groups
+ .filter(g => g.hasOwnProperty("type") && cns.allowedGroups.includes(g.type))
+ .filter(g => g.hasOwnProperty("deviceId") && this.devicesInEwe.has(g.deviceId.toLowerCase()))
+ .forEach(g => this.cusG.set(g.deviceId + "SWX", g));
+ }
+ //*** Make a map of RF Bridge custom sensors from Homebridge config ***\\
+ if (Object.keys(this.config.bridgeSensors || []).length > 0) {
+ this.config.bridgeSensors
+ .filter(s => s.hasOwnProperty("deviceId") && this.devicesInEwe.has(s.deviceId.toLowerCase()))
+ .forEach(s => this.cusS.set(s.fullDeviceId, s));
+ }
+ //*** Logging always helps to see if everything is okay so far ***\\
+ this.log("[%s] eWeLink devices were loaded from the Homebridge cache.", this.devicesInHB.size);
+ this.log("[%s] primary devices were loaded from your eWeLink account.", this.devicesInEwe.size);
+ this.log("[%s] primary devices were discovered on your local network.", this.lanDevicesOnline);
+ //*** Remove Homebridge accessories that don't appear in eWeLink ***\\
+ this.devicesInHB.forEach(a => {
+ if (!this.devicesInEwe.has(a.context.eweDeviceId)) {
+ this.removeAccessory(a);
+ }
+ });
+ //*** Synchronise devices between eWeLink and Homebridge and set up ws/lan listeners ***\\
+ this.devicesInEwe.forEach(d => this.initialiseDevice(d));
+ this.wsClient.receiveUpdate(d => this.receiveDeviceUpdate(d));
+ this.lanClient.receiveUpdate(d => this.receiveDeviceUpdate(d));
+ this.log("eWeLink setup complete. If you're enjoying this package please consider a âī¸ on GitHub :).");
+ if (this.config.debugReqRes || false) {
+ this.log.warn(
+ "You have 'Request & Response Logging' enabled. This setting is not recommended for long-term use."
+ );
+ }
+ })();
+ })
+ .catch(err => {
+ this.log.error("************** Cannot load homebridge-ewelink **************");
+ this.log.error(err);
+ this.log.error("************************************************************");
if (this.lanClient) this.lanClient.closeConnection();
if (this.wsClient) this.wsClient.closeConnection();
- });
- }
- initialiseDevice(device) {
- let accessory;
- // if (device.extra.uiid === 102) this.log.warn(device);
- //*** First add the device if it isn't already in Homebridge. Yeah this code looks a mess :| ***\\
- if (!this.devicesInHB.has(device.deviceid + "SWX") && !this.devicesInHB.has(device.deviceid + "SW0")) {
- if (device.extra.uiid === 2 && device.brandName === "coolkit" && device.productModel === "0285") {
- this.addAccessory(device, device.deviceid + "SWX", "valve");
- } else if (this.cusG.has(device.deviceid + "SWX") && this.cusG.get(device.deviceid + "SWX").type === "blind") {
- this.addAccessory(device, device.deviceid + "SWX", "blind");
- } else if (this.cusG.has(device.deviceid + "SWX") && this.cusG.get(device.deviceid + "SWX").type === "garage") {
- this.addAccessory(device, device.deviceid + "SWX", "garage");
- } else if (this.cusG.has(device.deviceid + "SWX") && this.cusG.get(device.deviceid + "SWX").type === "lock") {
- this.addAccessory(device, device.deviceid + "SWX", "lock");
- } else if (cns.devicesSensor.includes(device.extra.uiid)) {
- this.addAccessory(device, device.deviceid + "SWX", "sensor");
- } else if (cns.devicesFan.includes(device.extra.uiid)) {
- this.addAccessory(device, device.deviceid + "SWX", "fan");
- } else if (cns.devicesThermostat.includes(device.extra.uiid)) {
- this.addAccessory(device, device.deviceid + "SWX", "thermostat");
- } else if (cns.devicesOutlet.includes(device.extra.uiid)) {
- this.addAccessory(device, device.deviceid + "SWX", "outlet");
- } else if (cns.devicesUSB.includes(device.extra.uiid)) {
- this.addAccessory(device, device.deviceid + "SWX", "usb");
- } else if (cns.devicesSCM.includes(device.extra.uiid)) {
- this.addAccessory(device, device.deviceid + "SWX", "scm");
- } else if (cns.devicesSingleSwitch.includes(device.extra.uiid) && cns.devicesSingleSwitchLight.includes(device.productModel)) {
- this.addAccessory(device, device.deviceid + "SWX", "light");
- } else if (cns.devicesMultiSwitch.includes(device.extra.uiid) && cns.devicesMultiSwitchLight.includes(device.productModel)) {
- for (let i = 0; i <= cns.chansFromUiid[device.extra.uiid]; i++) {
- this.addAccessory(device, device.deviceid + "SW" + i, "light");
- }
- } else if (cns.devicesSingleSwitch.includes(device.extra.uiid)) {
- this.addAccessory(device, device.deviceid + "SWX", "switch");
- } else if (cns.devicesMultiSwitch.includes(device.extra.uiid)) {
- for (let i = 0; i <= cns.chansFromUiid[device.extra.uiid]; i++) {
- this.addAccessory(device, device.deviceid + "SW" + i, "switch");
- }
- } else if (cns.devicesRFBridge.includes(device.extra.uiid)) {
- this.addAccessory(device, device.deviceid + "SW0", "rf_pri");
- if (Object.keys((device.tags && device.tags.zyx_info) || []).length > 0) {
- for (let i = 1; i <= Object.keys(device.tags.zyx_info).length; i++) {
- this.addAccessory(device, device.deviceid + "SW" + i, "rf_sub");
- }
+ });
+ })
+ .on("shutdown", () => {
+ if (this.lanClient) this.lanClient.closeConnection();
+ if (this.wsClient) this.wsClient.closeConnection();
+ });
+ }
+ initialiseDevice(device) {
+ let accessory;
+ // if (device.extra.uiid === 102) this.log.warn(device);
+ //*** First add the device if it isn't already in Homebridge. Yeah this code looks a mess :| ***\\
+ if (!this.devicesInHB.has(device.deviceid + "SWX") && !this.devicesInHB.has(device.deviceid + "SW0")) {
+ if (device.extra.uiid === 2 && device.brandName === "coolkit" && device.productModel === "0285") {
+ this.addAccessory(device, device.deviceid + "SWX", "valve");
+ } else if (this.cusG.has(device.deviceid + "SWX") && this.cusG.get(device.deviceid + "SWX").type === "blind") {
+ this.addAccessory(device, device.deviceid + "SWX", "blind");
+ } else if (this.cusG.has(device.deviceid + "SWX") && this.cusG.get(device.deviceid + "SWX").type === "garage") {
+ this.addAccessory(device, device.deviceid + "SWX", "garage");
+ } else if (this.cusG.has(device.deviceid + "SWX") && this.cusG.get(device.deviceid + "SWX").type === "lock") {
+ this.addAccessory(device, device.deviceid + "SWX", "lock");
+ } else if (cns.devicesSensor.includes(device.extra.uiid)) {
+ this.addAccessory(device, device.deviceid + "SWX", "sensor");
+ } else if (cns.devicesFan.includes(device.extra.uiid)) {
+ this.addAccessory(device, device.deviceid + "SWX", "fan");
+ } else if (cns.devicesThermostat.includes(device.extra.uiid)) {
+ this.addAccessory(device, device.deviceid + "SWX", "thermostat");
+ } else if (cns.devicesOutlet.includes(device.extra.uiid)) {
+ this.addAccessory(device, device.deviceid + "SWX", "outlet");
+ } else if (cns.devicesUSB.includes(device.extra.uiid)) {
+ this.addAccessory(device, device.deviceid + "SWX", "usb");
+ } else if (cns.devicesSCM.includes(device.extra.uiid)) {
+ this.addAccessory(device, device.deviceid + "SWX", "scm");
+ } else if (
+ cns.devicesSingleSwitch.includes(device.extra.uiid) &&
+ cns.devicesSingleSwitchLight.includes(device.productModel)
+ ) {
+ this.addAccessory(device, device.deviceid + "SWX", "light");
+ } else if (
+ cns.devicesMultiSwitch.includes(device.extra.uiid) &&
+ cns.devicesMultiSwitchLight.includes(device.productModel)
+ ) {
+ for (let i = 0; i <= cns.chansFromUiid[device.extra.uiid]; i++) {
+ this.addAccessory(device, device.deviceid + "SW" + i, "light");
+ }
+ } else if (cns.devicesSingleSwitch.includes(device.extra.uiid)) {
+ this.addAccessory(device, device.deviceid + "SWX", "switch");
+ } else if (cns.devicesMultiSwitch.includes(device.extra.uiid)) {
+ for (let i = 0; i <= cns.chansFromUiid[device.extra.uiid]; i++) {
+ this.addAccessory(device, device.deviceid + "SW" + i, "switch");
+ }
+ } else if (cns.devicesRFBridge.includes(device.extra.uiid)) {
+ this.addAccessory(device, device.deviceid + "SW0", "rf_pri");
+ if (Object.keys((device.tags && device.tags.zyx_info) || []).length > 0) {
+ for (let i = 1; i <= Object.keys(device.tags.zyx_info).length; i++) {
+ this.addAccessory(device, device.deviceid + "SW" + i, "rf_sub");
+ }
+ }
+ } else if (cns.devicesZBBridge.includes(device.extra.uiid)) {
+ this.addAccessory(device, device.deviceid + "SWX", "zb_pri");
+ } else if (cns.devicesZB.includes(device.extra.uiid)) {
+ this.addAccessory(device, device.deviceid + "SWX", "zb_sub");
+ } else if (cns.devicesCamera.includes(device.extra.uiid)) {
+ this.log.warn(
+ '[%s] please see "https://github.com/bwp91/homebridge-ewelink/wiki/How-to-set-up-Sonoff-Camera".',
+ device.name
+ );
+ return;
+ } else {
+ this.log.warn(
+ "[%s] cannot be added as it is not supported by this plugin. Please make a GitHub issue request.",
+ device.name
+ );
+ return;
+ }
+ }
+ //*** Next refresh the device ***\\
+ if ((accessory = this.devicesInHB.get(device.deviceid + "SWX") || this.devicesInHB.get(device.deviceid + "SW0"))) {
+ let isX = accessory.context.hbDeviceId.substr(-1) === "X",
+ isRfBridge = cns.devicesRFBridge.includes(accessory.context.eweUIID),
+ rfBridgeChange = false;
+ accessory
+ .getService(Service.AccessoryInformation)
+ .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion);
+ accessory.context.reachableWAN = accessory.context.eweUIID !== 102 ? device.online : true;
+ accessory.context.reachableLAN = this.lanDevices.get(device.deviceid).online || false;
+ accessory.context.inUse = false;
+ let str = accessory.context.reachableLAN
+ ? "and locally with IP [" + this.lanDevices.get(device.deviceid).ip + "]"
+ : "but LAN mode unavailable as unsupported/shared device";
+ this.log("[%s] found in eWeLink %s.", accessory.displayName, str);
+ this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
+ if (!isX) {
+ for (let i = 1; i <= accessory.context.channelCount; i++) {
+ if (!this.devicesInHB.has(device.deviceid + "SW" + i)) {
+ if (cns.devicesHideable.includes(accessory.context.type)) {
+ if ((this.config.hideFromHB || "").includes(device.deviceid + "SW" + i)) {
+ continue;
+ } else {
+ this.addAccessory(device, device.deviceid + "SW" + i, "switch");
+ }
}
- } else if (cns.devicesZBBridge.includes(device.extra.uiid)) {
- this.addAccessory(device, device.deviceid + "SWX", "zb_pri");
- } else if (cns.devicesZB.includes(device.extra.uiid)) {
- this.addAccessory(device, device.deviceid + "SWX", "zb_sub");
- } else if (cns.devicesCamera.includes(device.extra.uiid)) {
- this.log.warn("[%s] please see \"https://github.com/bwp91/homebridge-ewelink/wiki/How-to-set-up-Sonoff-Camera\".", device.name);
- return;
- } else {
- this.log.warn("[%s] cannot be added as it is not supported by this plugin. Please make a GitHub issue request.", device.name);
- return;
- }
- }
- //*** Next refresh the device ***\\
- if ((accessory = this.devicesInHB.get(device.deviceid + "SWX") || this.devicesInHB.get(device.deviceid + "SW0"))) {
- let isX = accessory.context.hbDeviceId.substr(-1) === "X",
- isRfBridge = cns.devicesRFBridge.includes(accessory.context.eweUIID),
- rfBridgeChange = false;
- accessory.getService(Service.AccessoryInformation)
+ }
+ let oAccessory = this.devicesInHB.get(device.deviceid + "SW" + i);
+ if (
+ (this.config.hideFromHB || "").includes(device.deviceid + "SW" + i) &&
+ cns.devicesHideable.includes(accessory.context.type)
+ ) {
+ this.removeAccessory(oAccessory);
+ continue;
+ }
+ if (isRfBridge && oAccessory.context.sensorType !== "button") {
+ let ct = this.cusS.has(oAccessory.context.hbDeviceId)
+ ? this.cusS.get(oAccessory.context.hbDeviceId).type
+ : "motion";
+ if (ct !== oAccessory.context.sensorType) rfBridgeChange = true;
+ }
+ oAccessory
+ .getService(Service.AccessoryInformation)
.setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion);
- accessory.context.reachableWAN = accessory.context.eweUIID !== 102 ? device.online : true;
- accessory.context.reachableLAN = this.lanDevices.get(device.deviceid).online || false;
- accessory.context.inUse = false;
- let str = accessory.context.reachableLAN ?
- "and locally with IP [" + this.lanDevices.get(device.deviceid).ip + "]" :
- "but LAN mode unavailable as unsupported/shared device";
- this.log("[%s] found in eWeLink %s.", accessory.displayName, str);
- this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
- if (!isX) {
- for (let i = 1; i <= accessory.context.channelCount; i++) {
- if (!this.devicesInHB.has(device.deviceid + "SW" + i)) {
- if (cns.devicesHideable.includes(accessory.context.type)) {
- if ((this.config.hideFromHB || "").includes(device.deviceid + "SW" + i)) {
- continue;
- } else {
- this.addAccessory(device, device.deviceid + "SW" + i, "switch");
- }
- }
- }
- let oAccessory = this.devicesInHB.get(device.deviceid + "SW" + i);
- if ((this.config.hideFromHB || "").includes(device.deviceid + "SW" + i) && cns.devicesHideable.includes(accessory.context.type)) {
- this.removeAccessory(oAccessory);
- continue;
- }
- if (isRfBridge && oAccessory.context.sensorType !== "button") {
- let ct = this.cusS.has(oAccessory.context.hbDeviceId) ? this.cusS.get(oAccessory.context.hbDeviceId).type : "motion";
- if (ct !== oAccessory.context.sensorType) rfBridgeChange = true;
- }
- oAccessory.getService(Service.AccessoryInformation)
- .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion);
- oAccessory.context.reachableWAN = device.online;
- oAccessory.context.reachableLAN = this.lanDevices.get(device.deviceid).online || false;
- this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory);
- }
- }
- if (rfBridgeChange) {
- this.log.warn("[%s] bridge configuration changed so devices will be removed and readded.", accessory.displayName);
- for (let i = 0; i <= accessory.context.channelCount; i++) {
- let oAccessory = this.devicesInHB.get(device.deviceid + "SW" + i);
- this.removeAccessory(oAccessory);
- }
- this.initialiseDevice(device);
- return;
- }
- if (!this.refreshAccessory(accessory, device.params)) {
- this.log.warn("[%s] could not be initialised. Please try removing accessory from the Homebridge cache along with any secondary devices (SW1, SW2, etc.) [debug:%s:%s].", accessory.displayName, accessory.context.type, accessory.context.channelCount);
- }
- } else {
- this.log.warn("[%s] cannot be initialised as it wasn't found in Homebridge.", device.name);
- }
- }
- addAccessory(device, hbDeviceId, type) {
- let switchNumber = hbDeviceId.substr(-1).toString(),
- newDeviceName = type === "rf_sub" ? device.tags.zyx_info[switchNumber - 1].name : device.name,
- channelCount = type === "rf_pri" ?
- Object.keys((device.tags && device.tags.zyx_info) || []).length :
- cns.chansFromUiid[device.extra.uiid];
- if (["1", "2", "3", "4"].includes(switchNumber) && type !== "rf_sub") {
- newDeviceName += " SW" + switchNumber;
- if ((this.config.hideFromHB || "").includes(hbDeviceId) && cns.devicesHideable.includes(type)) {
- this.log("[%s] will not be added as per configuration.", newDeviceName);
- return;
- }
- }
- if ((this.config.nameOverride || {}).hasOwnProperty(hbDeviceId)) {
- newDeviceName = this.config.nameOverride[hbDeviceId];
- }
- const accessory = new Accessory(newDeviceName, UUIDGen.generate(hbDeviceId).toString());
- try {
- accessory.getService(Service.AccessoryInformation)
- .setCharacteristic(Characteristic.SerialNumber, hbDeviceId)
- .setCharacteristic(Characteristic.Manufacturer, device.brandName)
- .setCharacteristic(Characteristic.Model, device.productModel + " (" + device.extra.model + ")")
- .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion)
- .setCharacteristic(Characteristic.Identify, false);
- accessory.context = {
- hbDeviceId,
- eweDeviceId: device.deviceid,
- eweUIID: device.extra.uiid,
- eweModel: device.productModel,
- eweApiKey: device.apikey,
- switchNumber,
- channelCount,
- type
- };
- switch (type) {
- case "valve":
- ["A", "B"].forEach(v => {
- accessory.addService(Service.Valve, "Valve " + v, "valve" + v.toLowerCase())
- .setCharacteristic(Characteristic.Active, 0)
- .setCharacteristic(Characteristic.InUse, 0)
- .setCharacteristic(Characteristic.ValveType, 1)
- .setCharacteristic(Characteristic.SetDuration, (this.config.valveTimeLength || 120))
- .addCharacteristic(Characteristic.RemainingDuration);
- });
- break;
- case "blind":
- accessory.addService(Service.WindowCovering)
- .setCharacteristic(Characteristic.CurrentPosition, 100)
- .setCharacteristic(Characteristic.TargetPosition, 100)
- .setCharacteristic(Characteristic.PositionState, 2);
- break;
- case "garage":
- accessory.addService(Service.GarageDoorOpener)
- .setCharacteristic(Characteristic.CurrentDoorState, 1)
- .setCharacteristic(Characteristic.TargetDoorState, 1)
- .setCharacteristic(Characteristic.ObstructionDetected, false);
- break;
- case "lock":
- accessory.addService(Service.LockMechanism)
- .setCharacteristic(Characteristic.LockCurrentState, 1)
- .setCharacteristic(Characteristic.LockTargetState, 1);
- break;
- case "sensor":
- accessory.addService(Service.ContactSensor);
- break;
- case "fan":
- accessory.addService(Service.Fanv2);
- accessory.addService(Service.Lightbulb);
- break;
- case "thermostat":
- if (!this.config.hideTHSwitch) accessory.addService(Service.Switch);
- accessory.addService(Service.TemperatureSensor);
- if (device.params.sensorType !== "DS18B20") accessory.addService(Service.HumiditySensor);
- break;
- case "outlet":
- accessory.addService(Service.Outlet);
- accessory.getService(Service.Outlet).addCharacteristic(EveService.Characteristics.Voltage);
- accessory.getService(Service.Outlet).addCharacteristic(EveService.Characteristics.CurrentConsumption);
- accessory.getService(Service.Outlet).addCharacteristic(EveService.Characteristics.ElectricCurrent);
- accessory.getService(Service.Outlet).addCharacteristic(EveService.Characteristics.TotalConsumption);
- accessory.getService(Service.Outlet).addCharacteristic(EveService.Characteristics.ResetTotal);
- accessory.context = {
- ...accessory.context,
- ...{
- extraPersistedData: {},
- lastReset: 0,
- totalEnergy: 0,
- totalEnergyTemp: 0
- }
- };
- break;
- case "usb":
- accessory.addService(Service.Outlet);
- break;
- case "light":
- accessory.addService(Service.Lightbulb);
- break;
- case "switch":
- case "scm":
- accessory.addService(Service.Switch);
- break;
- case "rf_pri":
- accessory.context.rfChlMap = {};
- break;
- case "zb_pri":
- break;
- case "rf_sub":
- accessory.context.rfChls = {};
- switch (device.tags.zyx_info[parseInt(switchNumber) - 1].remote_type) {
- case "1":
- case "2":
- case "3":
- case "4":
- accessory.context.sensorType = "button";
- break;
- case "6":
- accessory.context.sensorType = this.cusS.has(hbDeviceId) ? this.cusS.get(hbDeviceId).type : "motion";
- break;
- default:
- throw "unsupported rf device type [" + device.tags.zyx_info[parseInt(switchNumber) - 1].remote_type + "]. Please create an issue on GitHub";
- }
- let mAccessory = this.devicesInHB.get(device.deviceid + "SW0");
- device.tags.zyx_info[parseInt(switchNumber) - 1].buttonName.forEach(button => {
- let rfData;
- Object.entries(button).forEach(([k, v]) => rfData = {
- rfChan: k,
- name: v
- });
- accessory.context.rfChls[rfData.rfChan] = rfData.name;
- mAccessory.context.rfChlMap[rfData.rfChan] = switchNumber;
- switch (accessory.context.sensorType) {
- case "button":
- accessory.addService(Service.Switch, rfData.name, "switch" + rfData.rfChan);
- break;
- case "water":
- accessory.addService(Service.LeakSensor);
- break;
- case "fire":
- case "smoke":
- accessory.addService(Service.SmokeSensor);
- break;
- case "co":
- accessory.addService(Service.CarbonMonoxideSensor);
- break;
- case "co2":
- accessory.addService(Service.CarbonDioxideSensor);
- break;
- case "contact":
- accessory.addService(Service.ContactSensor);
- break;
- case "occupancy":
- accessory.addService(Service.OccupancySensor);
- break;
- default:
- accessory.addService(Service.MotionSensor);
- break;
- }
- this.devicesInHB.set(mAccessory.context.hbDeviceId, mAccessory);
- });
- break;
- case "zb_sub": //*** credit @tasict ***\\
- accessory.addService(Service.BatteryService);
- switch (device.extra.uiid) {
- case 1000:
- accessory.addService(Service.StatelessProgrammableSwitch);
- if (this.config.hideZBLDPress) {
- accessory.getService(Service.StatelessProgrammableSwitch)
- .getCharacteristic(Characteristic.ProgrammableSwitchEvent)
- .setProps({
- validValues: [0]
- });
- }
- break;
- case 1770:
- accessory.addService(Service.TemperatureSensor);
- accessory.addService(Service.HumiditySensor);
- break;
- case 2026:
- accessory.addService(Service.MotionSensor);
- break;
- case 3026:
- accessory.addService(Service.ContactSensor);
- break;
- default:
- throw "unsupported zigbee device type [" + device.extra.uiid + "]. Please create an issue on GitHub";
- }
- break;
+ oAccessory.context.reachableWAN = device.online;
+ oAccessory.context.reachableLAN = this.lanDevices.get(device.deviceid).online || false;
+ this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory);
+ }
+ }
+ if (rfBridgeChange) {
+ this.log.warn(
+ "[%s] bridge configuration changed so devices will be removed and readded.",
+ accessory.displayName
+ );
+ for (let i = 0; i <= accessory.context.channelCount; i++) {
+ let oAccessory = this.devicesInHB.get(device.deviceid + "SW" + i);
+ this.removeAccessory(oAccessory);
+ }
+ this.initialiseDevice(device);
+ return;
+ }
+ if (!this.refreshAccessory(accessory, device.params)) {
+ this.log.warn(
+ "[%s] could not be initialised. Please try removing accessory from the Homebridge cache along with any secondary devices (SW1, SW2, etc.) [debug:%s:%s].",
+ accessory.displayName,
+ accessory.context.type,
+ accessory.context.channelCount
+ );
+ }
+ } else {
+ this.log.warn("[%s] cannot be initialised as it wasn't found in Homebridge.", device.name);
+ }
+ }
+ addAccessory(device, hbDeviceId, type) {
+ let switchNumber = hbDeviceId.substr(-1).toString(),
+ newDeviceName = type === "rf_sub" ? device.tags.zyx_info[switchNumber - 1].name : device.name,
+ channelCount =
+ type === "rf_pri"
+ ? Object.keys((device.tags && device.tags.zyx_info) || []).length
+ : cns.chansFromUiid[device.extra.uiid];
+ if (["1", "2", "3", "4"].includes(switchNumber) && type !== "rf_sub") {
+ newDeviceName += " SW" + switchNumber;
+ if ((this.config.hideFromHB || "").includes(hbDeviceId) && cns.devicesHideable.includes(type)) {
+ this.log("[%s] will not be added as per configuration.", newDeviceName);
+ return;
+ }
+ }
+ if ((this.config.nameOverride || {}).hasOwnProperty(hbDeviceId)) {
+ newDeviceName = this.config.nameOverride[hbDeviceId];
+ }
+ const accessory = new Accessory(newDeviceName, UUIDGen.generate(hbDeviceId).toString());
+ try {
+ accessory
+ .getService(Service.AccessoryInformation)
+ .setCharacteristic(Characteristic.SerialNumber, hbDeviceId)
+ .setCharacteristic(Characteristic.Manufacturer, device.brandName)
+ .setCharacteristic(Characteristic.Model, device.productModel + " (" + device.extra.model + ")")
+ .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion)
+ .setCharacteristic(Characteristic.Identify, false);
+ accessory.context = {
+ hbDeviceId,
+ eweDeviceId: device.deviceid,
+ eweUIID: device.extra.uiid,
+ eweModel: device.productModel,
+ eweApiKey: device.apikey,
+ switchNumber,
+ channelCount,
+ type,
+ };
+ switch (type) {
+ case "valve":
+ ["A", "B"].forEach(v => {
+ accessory
+ .addService(Service.Valve, "Valve " + v, "valve" + v.toLowerCase())
+ .setCharacteristic(Characteristic.Active, 0)
+ .setCharacteristic(Characteristic.InUse, 0)
+ .setCharacteristic(Characteristic.ValveType, 1)
+ .setCharacteristic(Characteristic.SetDuration, this.config.valveTimeLength || 120)
+ .addCharacteristic(Characteristic.RemainingDuration);
+ });
+ break;
+ case "blind":
+ accessory
+ .addService(Service.WindowCovering)
+ .setCharacteristic(Characteristic.CurrentPosition, 100)
+ .setCharacteristic(Characteristic.TargetPosition, 100)
+ .setCharacteristic(Characteristic.PositionState, 2);
+ break;
+ case "garage":
+ accessory
+ .addService(Service.GarageDoorOpener)
+ .setCharacteristic(Characteristic.CurrentDoorState, 1)
+ .setCharacteristic(Characteristic.TargetDoorState, 1)
+ .setCharacteristic(Characteristic.ObstructionDetected, false);
+ break;
+ case "lock":
+ accessory
+ .addService(Service.LockMechanism)
+ .setCharacteristic(Characteristic.LockCurrentState, 1)
+ .setCharacteristic(Characteristic.LockTargetState, 1);
+ break;
+ case "sensor":
+ accessory.addService(Service.ContactSensor);
+ break;
+ case "fan":
+ accessory.addService(Service.Fanv2);
+ accessory.addService(Service.Lightbulb);
+ break;
+ case "thermostat":
+ if (!this.config.hideTHSwitch) accessory.addService(Service.Switch);
+ accessory.addService(Service.TemperatureSensor);
+ if (device.params.sensorType !== "DS18B20") accessory.addService(Service.HumiditySensor);
+ break;
+ case "outlet":
+ accessory.addService(Service.Outlet);
+ accessory.getService(Service.Outlet).addCharacteristic(EveService.Characteristics.Voltage);
+ accessory.getService(Service.Outlet).addCharacteristic(EveService.Characteristics.CurrentConsumption);
+ accessory.getService(Service.Outlet).addCharacteristic(EveService.Characteristics.ElectricCurrent);
+ accessory.getService(Service.Outlet).addCharacteristic(EveService.Characteristics.TotalConsumption);
+ accessory.getService(Service.Outlet).addCharacteristic(EveService.Characteristics.ResetTotal);
+ accessory.context = {
+ ...accessory.context,
+ ...{
+ extraPersistedData: {},
+ lastReset: 0,
+ totalEnergy: 0,
+ totalEnergyTemp: 0,
+ },
+ };
+ break;
+ case "usb":
+ accessory.addService(Service.Outlet);
+ break;
+ case "light":
+ accessory.addService(Service.Lightbulb);
+ break;
+ case "switch":
+ case "scm":
+ accessory.addService(Service.Switch);
+ break;
+ case "rf_pri":
+ accessory.context.rfChlMap = {};
+ break;
+ case "zb_pri":
+ break;
+ case "rf_sub":
+ accessory.context.rfChls = {};
+ switch (device.tags.zyx_info[parseInt(switchNumber) - 1].remote_type) {
+ case "1":
+ case "2":
+ case "3":
+ case "4":
+ accessory.context.sensorType = "button";
+ break;
+ case "6":
+ accessory.context.sensorType = this.cusS.has(hbDeviceId) ? this.cusS.get(hbDeviceId).type : "motion";
+ break;
default:
- throw "device is not supported by this plugin. Please create an issue on GitHub";
- }
- this.devicesInHB.set(hbDeviceId, accessory);
- this.api.registerPlatformAccessories("homebridge-ewelink", "eWeLink", [accessory]);
- this.configureAccessory(accessory);
- this.log("[%s] has been added to Homebridge.", newDeviceName);
- } catch (err) {
- this.log.warn("[%s] could not be added as %s.", newDeviceName, err);
- }
- }
- configureAccessory(accessory) {
- if (!this.log) return;
- try {
- accessory.context.reachableWAN = true;
- accessory.context.reachableLAN = true;
- switch (accessory.context.type) {
- case "valve":
- ["A", "B"].forEach(v => {
- accessory.getService("Valve " + v).getCharacteristic(Characteristic.Active)
- .on("set", (value, callback) => this.internalValveUpdate(accessory, "Valve " + v, value, callback));
- accessory.getService("Valve " + v).getCharacteristic(Characteristic.SetDuration)
- .on("set", (value, callback) => {
- if (accessory.getService("Valve " + v).getCharacteristic(Characteristic.InUse).value) {
- accessory.getService("Valve " + v).updateCharacteristic(Characteristic.RemainingDuration, value);
- clearTimeout(accessory.getService("Valve " + v).timer);
- accessory.getService("Valve " + v).timer = setTimeout(() => {
- accessory.getService("Valve " + v).setCharacteristic(Characteristic.Active, 0);
- }, value * 1000);
- }
- callback();
- });
- });
- break;
- case "blind":
- accessory.getService(Service.WindowCovering).getCharacteristic(Characteristic.TargetPosition)
- .on("set", (value, callback) => this.internalBlindUpdate(accessory, value, callback))
- .setProps({
- minStep: 100
- });
- break;
- case "garage":
- accessory.getService(Service.GarageDoorOpener).getCharacteristic(Characteristic.TargetDoorState)
- .on("set", (value, callback) => this.internalGarageUpdate(accessory, value, callback));
- break;
- case "lock":
- accessory.getService(Service.LockMechanism).getCharacteristic(Characteristic.LockTargetState)
- .on("set", (value, callback) => this.internalLockUpdate(accessory, value, callback));
- break;
- case "fan":
- accessory.getService(Service.Fanv2).getCharacteristic(Characteristic.Active)
- .on("set", (value, callback) => this.internalFanUpdate(accessory, "power", value, callback));
- accessory.getService(Service.Fanv2).getCharacteristic(Characteristic.RotationSpeed)
- .on("set", (value, callback) => this.internalFanUpdate(accessory, "speed", value, callback))
+ throw (
+ "unsupported rf device type [" +
+ device.tags.zyx_info[parseInt(switchNumber) - 1].remote_type +
+ "]. Please create an issue on GitHub"
+ );
+ }
+ let mAccessory = this.devicesInHB.get(device.deviceid + "SW0");
+ device.tags.zyx_info[parseInt(switchNumber) - 1].buttonName.forEach(button => {
+ let rfData;
+ Object.entries(button).forEach(
+ ([k, v]) =>
+ (rfData = {
+ rfChan: k,
+ name: v,
+ })
+ );
+ accessory.context.rfChls[rfData.rfChan] = rfData.name;
+ mAccessory.context.rfChlMap[rfData.rfChan] = switchNumber;
+ switch (accessory.context.sensorType) {
+ case "button":
+ accessory.addService(Service.Switch, rfData.name, "switch" + rfData.rfChan);
+ break;
+ case "water":
+ accessory.addService(Service.LeakSensor);
+ break;
+ case "fire":
+ case "smoke":
+ accessory.addService(Service.SmokeSensor);
+ break;
+ case "co":
+ accessory.addService(Service.CarbonMonoxideSensor);
+ break;
+ case "co2":
+ accessory.addService(Service.CarbonDioxideSensor);
+ break;
+ case "contact":
+ accessory.addService(Service.ContactSensor);
+ break;
+ case "occupancy":
+ accessory.addService(Service.OccupancySensor);
+ break;
+ default:
+ accessory.addService(Service.MotionSensor);
+ break;
+ }
+ this.devicesInHB.set(mAccessory.context.hbDeviceId, mAccessory);
+ });
+ break;
+ case "zb_sub": //*** credit @tasict ***\\
+ accessory.addService(Service.BatteryService);
+ switch (device.extra.uiid) {
+ case 1000:
+ accessory.addService(Service.StatelessProgrammableSwitch);
+ if (this.config.hideZBLDPress) {
+ accessory
+ .getService(Service.StatelessProgrammableSwitch)
+ .getCharacteristic(Characteristic.ProgrammableSwitchEvent)
.setProps({
- minStep: 33
- });
- accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => this.internalFanUpdate(accessory, "light", value, callback));
- break;
- case "thermostat":
- if (!this.config.hideTHSwitch) {
- accessory.getService(Service.Switch).getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => this.internalThermostatUpdate(accessory, value, callback));
- }
- accessory.log = this.log;
- accessory.eveLogger = new EveHistoryService("weather", accessory, {
- storage: "fs",
- minutes: 5,
- path: this.eveLogPath
- });
- corrInterval.setCorrectingInterval(() => {
- let dataToAdd = {
- time: Date.now(),
- temp: accessory.getService(Service.TemperatureSensor).getCharacteristic(Characteristic.CurrentTemperature).value
- };
- if (accessory.getService(Service.HumiditySensor)) {
- dataToAdd.humidity = accessory.getService(Service.HumiditySensor).getCharacteristic(Characteristic.CurrentRelativeHumidity).value;
- }
- accessory.eveLogger.addEntry(dataToAdd);
- }, 300000);
- break;
- case "outlet":
- accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => this.internalOutletUpdate(accessory, value, callback));
- accessory.log = this.log;
- accessory.eveLogger = new EveHistoryService("energy", accessory, {
- storage: "fs",
- minutes: 5,
- path: this.eveLogPath
- });
- if (!accessory.context.hasOwnProperty("lastReset")) {
- accessory.context = {
- ...accessory.context,
- ...{
- extraPersistedData: {},
- lastReset: 0,
- totalEnergy: 0,
- totalEnergyTemp: 0
- }
- };
- }
- corrInterval.setCorrectingInterval(() => {
- let isOn = accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On).value,
- currentWatt = isOn ? accessory.getService(Service.Outlet)
- .getCharacteristic(EveService.Characteristics.CurrentConsumption).value : 0;
- if (accessory.eveLogger.isHistoryLoaded()) {
- accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData();
- if (accessory.context.extraPersistedData !== undefined) {
- accessory.context.totalEnergy = accessory.context.extraPersistedData.totalenergy + accessory.context.totalEnergyTemp + currentWatt * 10 / 3600 / 1000;
- accessory.eveLogger.setExtraPersistedData({
- totalenergy: accessory.context.totalEnergy,
- lastReset: accessory.context.extraPersistedData.lastReset
- });
- } else {
- accessory.context.totalEnergy = accessory.context.totalEnergyTemp + currentWatt * 10 / 3600 / 1000;
- accessory.eveLogger.setExtraPersistedData({
- totalenergy: accessory.context.totalEnergy,
- lastReset: 0
- });
- }
- accessory.context.totalEnergytemp = 0;
- } else {
- accessory.context.totalEnergyTemp += currentWatt * 10 / 3600 / 1000;
- accessory.context.totalEnergy = accessory.context.totalEnergyTemp;
- }
- accessory.eveLogger.addEntry({
- time: Date.now(),
- power: currentWatt
- });
- }, 300000);
- accessory.getService(Service.Outlet).getCharacteristic(EveService.Characteristics.TotalConsumption)
- .on("get", callback => {
- accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData();
- if (accessory.context.extraPersistedData !== undefined) {
- accessory.context.totalEnergy = accessory.context.extraPersistedData.totalPower;
- }
- callback(null, accessory.context.totalEnergy);
- });
- accessory.getService(Service.Outlet).getCharacteristic(EveService.Characteristics.ResetTotal)
- .on("set", (value, callback) => {
- accessory.context.totalEnergy = 0;
- accessory.context.lastReset = value;
- accessory.eveLogger.setExtraPersistedData({
- totalPower: 0,
- lastReset: value
- });
- callback();
- })
- .on("get", callback => {
- accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData();
- if (accessory.context.extraPersistedData !== undefined) {
- accessory.context.lastReset = accessory.context.extraPersistedData.lastReset;
- }
- callback(null, accessory.context.lastReset);
+ validValues: [0],
});
- break;
- case "usb":
- accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => this.internalUSBUpdate(accessory, value, callback));
- break;
- case "scm":
- accessory.getService(Service.Switch).getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => this.internalSCMUpdate(accessory, value, callback));
- break;
- case "light":
- accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => this.internalLightbulbUpdate(accessory, value, callback));
- if (cns.devicesBrightable.includes(accessory.context.eweUIID)) {
- accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Brightness)
- .on("set", (value, callback) => {
- if (value > 0) {
- if (!accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value) {
- this.internalLightbulbUpdate(accessory, true, function() {
- return;
- });
- }
- this.internalBrightnessUpdate(accessory, value, callback);
- } else {
- this.internalLightbulbUpdate(accessory, false, callback);
- }
- });
- } else if (cns.devicesColourable.includes(accessory.context.eweUIID)) {
- accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Brightness)
- .on("set", (value, callback) => {
- if (value > 0) {
- if (!accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value) {
- this.internalLightbulbUpdate(accessory, true, function() {
- return;
- });
- }
- this.internalHSBUpdate(accessory, "bri", value, callback);
- } else {
- this.internalLightbulbUpdate(accessory, false, callback);
- }
- });
- accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Hue)
- .on("set", (value, callback) => this.internalHSBUpdate(accessory, "hue", value, callback));
- accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Saturation)
- .on("set", (value, callback) => callback());
- }
- break;
- case "switch":
- accessory.getService(Service.Switch).getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => this.internalSwitchUpdate(accessory, value, callback));
- break;
- case "rf_sub":
- accessory.context.rfChls = accessory.context.rfChls || {};
- if (accessory.context.sensorType === "button") {
- Object.entries(accessory.context.rfChls).forEach(([k, v]) => {
- accessory.getService(v).updateCharacteristic(Characteristic.On, false);
- accessory.getService(v).getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => {
- value ? this.internalRFDeviceUpdate(accessory, k, callback) : callback();
- });
- });
- }
- break;
- case "zb_sub":
- if (accessory.context.eweUIID === 1770) {
- accessory.log = this.log;
- accessory.eveLogger = new EveHistoryService("weather", accessory, {
- storage: "fs",
- minutes: 5,
- path: this.eveLogPath
- });
- corrInterval.setCorrectingInterval(() => {
- let dataToAdd = {
- time: Date.now(),
- temp: accessory.getService(Service.TemperatureSensor).getCharacteristic(Characteristic.CurrentTemperature).value,
- humidity: accessory.getService(Service.HumiditySensor).getCharacteristic(Characteristic.CurrentRelativeHumidity).value
- };
- accessory.eveLogger.addEntry(dataToAdd);
- }, 300000);
- }
- break;
- }
- this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
- } catch (err) {
- this.log.warn("[%s] could not be refreshed as %s.", accessory.displayName, err);
- }
- }
- refreshAccessory(accessory, newParams) {
+ }
+ break;
+ case 1770:
+ accessory.addService(Service.TemperatureSensor);
+ accessory.addService(Service.HumiditySensor);
+ break;
+ case 2026:
+ accessory.addService(Service.MotionSensor);
+ break;
+ case 3026:
+ accessory.addService(Service.ContactSensor);
+ break;
+ default:
+ throw "unsupported zigbee device type [" + device.extra.uiid + "]. Please create an issue on GitHub";
+ }
+ break;
+ default:
+ throw "device is not supported by this plugin. Please create an issue on GitHub";
+ }
+ this.devicesInHB.set(hbDeviceId, accessory);
+ this.api.registerPlatformAccessories("homebridge-ewelink", "eWeLink", [accessory]);
+ this.configureAccessory(accessory);
+ this.log("[%s] has been added to Homebridge.", newDeviceName);
+ } catch (err) {
+ this.log.warn("[%s] could not be added as %s.", newDeviceName, err);
+ }
+ }
+ configureAccessory(accessory) {
+ if (!this.log) return;
+ try {
+ accessory.context.reachableWAN = true;
+ accessory.context.reachableLAN = true;
switch (accessory.context.type) {
- case "valve":
- if (Object.keys(newParams).some(v => cns.devicesValveParams.includes(v)) && Array.isArray(newParams.switches)) {
- this.externalValveUpdate(accessory, newParams);
- }
- return true;
- case "blind":
- if (Object.keys(newParams).some(v => cns.devicesBlindParams.includes(v)) && Array.isArray(newParams.switches)) {
- this.externalBlindUpdate(accessory, newParams);
- }
- return true;
- case "garage":
- if (Object.keys(newParams).some(v => cns.devicesGarageParams.includes(v)) && Array.isArray(newParams.switches)) {
- this.externalGarageUpdate(accessory, newParams);
- }
- return true;
- case "lock":
- if (Object.keys(newParams).some(v => cns.devicesLockParams.includes(v))) {
- this.externalLockUpdate(accessory, newParams);
- }
- return true;
- case "sensor":
- if (Object.keys(newParams).some(v => cns.devicesSensorParams.includes(v))) {
- this.externalSensorUpdate(accessory, newParams);
- }
- return true;
- case "fan":
- if (Object.keys(newParams).some(v => cns.devicesFanParams.includes(v))) {
- this.externalFanUpdate(accessory, newParams);
- }
- return true;
- case "thermostat":
- if (Object.keys(newParams).some(v => cns.devicesThermostatParams.includes(v))) {
- this.externalThermostatUpdate(accessory, newParams);
- }
- return true;
- case "outlet":
- if (Object.keys(newParams).some(v => cns.devicesOutletParams.includes(v))) {
- this.externalOutletUpdate(accessory, newParams);
- }
- return true;
- case "usb":
- if (Object.keys(newParams).some(v => cns.devicesUSBParams.includes(v)) && Array.isArray(newParams.switches)) {
- this.externalUSBUpdate(accessory, newParams);
- }
- return true;
- case "scm":
- if (Object.keys(newParams).some(v => cns.devicesSCMParams.includes(v)) && Array.isArray(newParams.switches)) {
- this.externalSCMUpdate(accessory, newParams);
- }
- return true;
- case "light":
- if (cns.devicesSingleSwitch.includes(accessory.context.eweUIID) && cns.devicesSingleSwitchLight.includes(accessory.context.eweModel)) {
- if (Object.keys(newParams).some(v => cns.devicesSingleSwitchLightParams.includes(v))) {
- this.externalSingleLightUpdate(accessory, newParams);
- }
- } else if (cns.devicesMultiSwitch.includes(accessory.context.eweUIID) && cns.devicesMultiSwitchLight.includes(accessory.context.eweModel)) {
- if (Object.keys(newParams).some(v => cns.devicesMultiSwitchLightParams.includes(v)) && Array.isArray(newParams.switches)) {
- this.externalMultiLightUpdate(accessory, newParams);
- }
- }
- return true;
- case "switch":
- if (cns.devicesSingleSwitch.includes(accessory.context.eweUIID)) {
- if (Object.keys(newParams).some(v => cns.devicesSingleSwitchParams.includes(v))) {
- this.externalSingleSwitchUpdate(accessory, newParams);
- }
- } else if (cns.devicesMultiSwitch.includes(accessory.context.eweUIID)) {
- if (Object.keys(newParams).some(v => cns.devicesMultiSwitchParams.includes(v)) && Array.isArray(newParams.switches)) {
- this.externalMultiSwitchUpdate(accessory, newParams);
- }
- }
- return true;
- case "rf_pri":
- if (Object.keys(newParams).some(v => cns.devicesRFBridgeParams.includes(v))) {
- this.externalRFDeviceUpdate(accessory, newParams);
+ case "valve":
+ ["A", "B"].forEach(v => {
+ accessory
+ .getService("Valve " + v)
+ .getCharacteristic(Characteristic.Active)
+ .on("set", (value, callback) => this.internalValveUpdate(accessory, "Valve " + v, value, callback));
+ accessory
+ .getService("Valve " + v)
+ .getCharacteristic(Characteristic.SetDuration)
+ .on("set", (value, callback) => {
+ if (accessory.getService("Valve " + v).getCharacteristic(Characteristic.InUse).value) {
+ accessory.getService("Valve " + v).updateCharacteristic(Characteristic.RemainingDuration, value);
+ clearTimeout(accessory.getService("Valve " + v).timer);
+ accessory.getService("Valve " + v).timer = setTimeout(() => {
+ accessory.getService("Valve " + v).setCharacteristic(Characteristic.Active, 0);
+ }, value * 1000);
+ }
+ callback();
+ });
+ });
+ break;
+ case "blind":
+ accessory
+ .getService(Service.WindowCovering)
+ .getCharacteristic(Characteristic.TargetPosition)
+ .on("set", (value, callback) => this.internalBlindUpdate(accessory, value, callback))
+ .setProps({
+ minStep: 100,
+ });
+ break;
+ case "garage":
+ accessory
+ .getService(Service.GarageDoorOpener)
+ .getCharacteristic(Characteristic.TargetDoorState)
+ .on("set", (value, callback) => this.internalGarageUpdate(accessory, value, callback));
+ break;
+ case "lock":
+ accessory
+ .getService(Service.LockMechanism)
+ .getCharacteristic(Characteristic.LockTargetState)
+ .on("set", (value, callback) => this.internalLockUpdate(accessory, value, callback));
+ break;
+ case "fan":
+ accessory
+ .getService(Service.Fanv2)
+ .getCharacteristic(Characteristic.Active)
+ .on("set", (value, callback) => this.internalFanUpdate(accessory, "power", value, callback));
+ accessory
+ .getService(Service.Fanv2)
+ .getCharacteristic(Characteristic.RotationSpeed)
+ .on("set", (value, callback) => this.internalFanUpdate(accessory, "speed", value, callback))
+ .setProps({
+ minStep: 33,
+ });
+ accessory
+ .getService(Service.Lightbulb)
+ .getCharacteristic(Characteristic.On)
+ .on("set", (value, callback) => this.internalFanUpdate(accessory, "light", value, callback));
+ break;
+ case "thermostat":
+ if (!this.config.hideTHSwitch) {
+ accessory
+ .getService(Service.Switch)
+ .getCharacteristic(Characteristic.On)
+ .on("set", (value, callback) => this.internalThermostatUpdate(accessory, value, callback));
+ }
+ accessory.log = this.log;
+ accessory.eveLogger = new EveHistoryService("weather", accessory, {
+ storage: "fs",
+ minutes: 5,
+ path: this.eveLogPath,
+ });
+ corrInterval.setCorrectingInterval(() => {
+ let dataToAdd = {
+ time: Date.now(),
+ temp: accessory.getService(Service.TemperatureSensor).getCharacteristic(Characteristic.CurrentTemperature)
+ .value,
+ };
+ if (accessory.getService(Service.HumiditySensor)) {
+ dataToAdd.humidity = accessory
+ .getService(Service.HumiditySensor)
+ .getCharacteristic(Characteristic.CurrentRelativeHumidity).value;
}
- return true;
- case "rf_sub":
- case "zb_pri":
- return true;
- case "zb_sub":
- if (Object.keys(newParams).some(v => cns.devicesZBBridgeParams.includes(v))) {
- this.externalZBDeviceUpdate(accessory, newParams);
+ accessory.eveLogger.addEntry(dataToAdd);
+ }, 300000);
+ break;
+ case "outlet":
+ accessory
+ .getService(Service.Outlet)
+ .getCharacteristic(Characteristic.On)
+ .on("set", (value, callback) => this.internalOutletUpdate(accessory, value, callback));
+ accessory.log = this.log;
+ accessory.eveLogger = new EveHistoryService("energy", accessory, {
+ storage: "fs",
+ minutes: 5,
+ path: this.eveLogPath,
+ });
+ if (!accessory.context.hasOwnProperty("lastReset")) {
+ accessory.context = {
+ ...accessory.context,
+ ...{
+ extraPersistedData: {},
+ lastReset: 0,
+ totalEnergy: 0,
+ totalEnergyTemp: 0,
+ },
+ };
+ }
+ corrInterval.setCorrectingInterval(() => {
+ let isOn = accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On).value,
+ currentWatt = isOn
+ ? accessory.getService(Service.Outlet).getCharacteristic(EveService.Characteristics.CurrentConsumption)
+ .value
+ : 0;
+ if (accessory.eveLogger.isHistoryLoaded()) {
+ accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData();
+ if (accessory.context.extraPersistedData !== undefined) {
+ accessory.context.totalEnergy =
+ accessory.context.extraPersistedData.totalenergy +
+ accessory.context.totalEnergyTemp +
+ (currentWatt * 10) / 3600 / 1000;
+ accessory.eveLogger.setExtraPersistedData({
+ totalenergy: accessory.context.totalEnergy,
+ lastReset: accessory.context.extraPersistedData.lastReset,
+ });
+ } else {
+ accessory.context.totalEnergy = accessory.context.totalEnergyTemp + (currentWatt * 10) / 3600 / 1000;
+ accessory.eveLogger.setExtraPersistedData({
+ totalenergy: accessory.context.totalEnergy,
+ lastReset: 0,
+ });
+ }
+ accessory.context.totalEnergytemp = 0;
+ } else {
+ accessory.context.totalEnergyTemp += (currentWatt * 10) / 3600 / 1000;
+ accessory.context.totalEnergy = accessory.context.totalEnergyTemp;
}
- return true;
- default:
- return false;
- }
- }
- removeAccessory(accessory) {
- try {
- this.devicesInHB.delete(accessory.context.hbDeviceId);
- this.api.unregisterPlatformAccessories("homebridge-ewelink", "eWeLink", [accessory]);
- this.log("[%s] has been removed from Homebridge.", accessory.displayName);
- } catch (err) {
- this.log.warn("[%s] needed to be removed but couldn't as %s.", accessory.displayName, err);
- }
- }
- sendDeviceUpdate(accessory, params, callback) {
- let payload = {
- apikey: accessory.context.eweApiKey,
- deviceid: accessory.context.eweDeviceId,
- params
- };
- let sendViaWS = () => {
- if (accessory.context.reachableWAN) {
- this.wsClient.sendUpdate(payload);
- callback();
- } else {
- this.log.error("[%s] could not be updated as it appears to be offline.", accessory.displayName);
- callback("Device has failed to update");
- }
- };
- if (cns.devicesNonLAN.includes(accessory.context.eweUIID) || !accessory.context.reachableLAN) {
- sendViaWS();
- } else {
- this.lanClient.sendUpdate(payload)
- .then(() => callback())
- .catch(err => {
- if (this.debug) {
- this.log.warn("[%s] Reverting to web socket as %s.", accessory.displayName, err);
- }
- sendViaWS();
+ accessory.eveLogger.addEntry({
+ time: Date.now(),
+ power: currentWatt,
});
- }
- }
- receiveDeviceUpdate(device) {
- let accessory;
- switch (device.action) {
- case "sysmsg":
- if ((accessory = this.devicesInHB.get(device.deviceid + "SWX") || this.devicesInHB.get(device.deviceid + "SW0"))) {
- let isX = accessory.context.hbDeviceId.substr(-1) === "X";
- if (device.params.updateSource === "WS") {
- if (accessory.context.reachableWAN !== device.params.online) {
- accessory.context.reachableWAN = device.params.online;
- this.log("[%s] has been reported [%s] via [WS].", accessory.displayName, accessory.context.reachableWAN ? "online" : "offline");
- this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
- if (accessory.context.reachableWAN) this.wsClient.requestUpdate(accessory);
- } else {
- if (this.debug) {
- this.log("[%s] Nothing to update from above WS message.", accessory.displayName);
- }
+ }, 300000);
+ accessory
+ .getService(Service.Outlet)
+ .getCharacteristic(EveService.Characteristics.TotalConsumption)
+ .on("get", callback => {
+ accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData();
+ if (accessory.context.extraPersistedData !== undefined) {
+ accessory.context.totalEnergy = accessory.context.extraPersistedData.totalPower;
+ }
+ callback(null, accessory.context.totalEnergy);
+ });
+ accessory
+ .getService(Service.Outlet)
+ .getCharacteristic(EveService.Characteristics.ResetTotal)
+ .on("set", (value, callback) => {
+ accessory.context.totalEnergy = 0;
+ accessory.context.lastReset = value;
+ accessory.eveLogger.setExtraPersistedData({
+ totalPower: 0,
+ lastReset: value,
+ });
+ callback();
+ })
+ .on("get", callback => {
+ accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData();
+ if (accessory.context.extraPersistedData !== undefined) {
+ accessory.context.lastReset = accessory.context.extraPersistedData.lastReset;
+ }
+ callback(null, accessory.context.lastReset);
+ });
+ break;
+ case "usb":
+ accessory
+ .getService(Service.Outlet)
+ .getCharacteristic(Characteristic.On)
+ .on("set", (value, callback) => this.internalUSBUpdate(accessory, value, callback));
+ break;
+ case "scm":
+ accessory
+ .getService(Service.Switch)
+ .getCharacteristic(Characteristic.On)
+ .on("set", (value, callback) => this.internalSCMUpdate(accessory, value, callback));
+ break;
+ case "light":
+ accessory
+ .getService(Service.Lightbulb)
+ .getCharacteristic(Characteristic.On)
+ .on("set", (value, callback) => this.internalLightbulbUpdate(accessory, value, callback));
+ if (cns.devicesBrightable.includes(accessory.context.eweUIID)) {
+ accessory
+ .getService(Service.Lightbulb)
+ .getCharacteristic(Characteristic.Brightness)
+ .on("set", (value, callback) => {
+ if (value > 0) {
+ if (!accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value) {
+ this.internalLightbulbUpdate(accessory, true, function () {
+ return;
+ });
}
- }
- if (!isX) {
- for (let i = 1; i <= accessory.context.channelCount; i++) {
- if (this.devicesInHB.has(device.deviceid + "SW" + i)) {
- let oAccessory = this.devicesInHB.get(device.deviceid + "SW" + i);
- oAccessory.context.reachableWAN = device.params.online;
- this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory);
- }
+ this.internalBrightnessUpdate(accessory, value, callback);
+ } else {
+ this.internalLightbulbUpdate(accessory, false, callback);
+ }
+ });
+ } else if (cns.devicesColourable.includes(accessory.context.eweUIID)) {
+ accessory
+ .getService(Service.Lightbulb)
+ .getCharacteristic(Characteristic.Brightness)
+ .on("set", (value, callback) => {
+ if (value > 0) {
+ if (!accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value) {
+ this.internalLightbulbUpdate(accessory, true, function () {
+ return;
+ });
}
- }
- }
- break;
- case "update":
- if ((accessory = this.devicesInHB.get(device.deviceid + "SWX") || this.devicesInHB.get(device.deviceid + "SW0"))) {
- if (device.params.updateSource === "WS" && !accessory.context.reachableWAN) {
- accessory.context.reachableWAN = true;
- this.log("[%s] has been reported [online] via [WS].", accessory.displayName);
- }
- if (device.params.updateSource === "LAN" && !accessory.context.reachableLAN) {
- accessory.context.reachableLAN = true;
- this.log("[%s] has been reported [online] via [LAN].", accessory.displayName);
- }
- if (this.debug) {
- this.log("[%s] externally updated from above %s message and will be refreshed.", accessory.displayName, device.params.updateSource);
- }
- if (!this.refreshAccessory(accessory, device.params)) {
- this.log.warn("[%s] cannot be refreshed. Please try removing accessory from the Homebridge cache along with any secondary devices (SW1, SW2, etc.). [debug:%s:%s]", accessory.displayName, accessory.context.type, accessory.context.channelCount);
- }
+ this.internalHSBUpdate(accessory, "bri", value, callback);
+ } else {
+ this.internalLightbulbUpdate(accessory, false, callback);
+ }
+ });
+ accessory
+ .getService(Service.Lightbulb)
+ .getCharacteristic(Characteristic.Hue)
+ .on("set", (value, callback) => this.internalHSBUpdate(accessory, "hue", value, callback));
+ accessory
+ .getService(Service.Lightbulb)
+ .getCharacteristic(Characteristic.Saturation)
+ .on("set", (value, callback) => callback());
+ }
+ break;
+ case "switch":
+ accessory
+ .getService(Service.Switch)
+ .getCharacteristic(Characteristic.On)
+ .on("set", (value, callback) => this.internalSwitchUpdate(accessory, value, callback));
+ break;
+ case "rf_sub":
+ accessory.context.rfChls = accessory.context.rfChls || {};
+ if (accessory.context.sensorType === "button") {
+ Object.entries(accessory.context.rfChls).forEach(([k, v]) => {
+ accessory.getService(v).updateCharacteristic(Characteristic.On, false);
+ accessory
+ .getService(v)
+ .getCharacteristic(Characteristic.On)
+ .on("set", (value, callback) => {
+ value ? this.internalRFDeviceUpdate(accessory, k, callback) : callback();
+ });
+ });
+ }
+ break;
+ case "zb_sub":
+ if (accessory.context.eweUIID === 1770) {
+ accessory.log = this.log;
+ accessory.eveLogger = new EveHistoryService("weather", accessory, {
+ storage: "fs",
+ minutes: 5,
+ path: this.eveLogPath,
+ });
+ corrInterval.setCorrectingInterval(() => {
+ let dataToAdd = {
+ time: Date.now(),
+ temp: accessory
+ .getService(Service.TemperatureSensor)
+ .getCharacteristic(Characteristic.CurrentTemperature).value,
+ humidity: accessory
+ .getService(Service.HumiditySensor)
+ .getCharacteristic(Characteristic.CurrentRelativeHumidity).value,
+ };
+ accessory.eveLogger.addEntry(dataToAdd);
+ }, 300000);
+ }
+ break;
+ }
+ this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
+ } catch (err) {
+ this.log.warn("[%s] could not be refreshed as %s.", accessory.displayName, err);
+ }
+ }
+ refreshAccessory(accessory, newParams) {
+ switch (accessory.context.type) {
+ case "valve":
+ if (Object.keys(newParams).some(v => cns.devicesValveParams.includes(v)) && Array.isArray(newParams.switches)) {
+ this.externalValveUpdate(accessory, newParams);
+ }
+ return true;
+ case "blind":
+ if (Object.keys(newParams).some(v => cns.devicesBlindParams.includes(v)) && Array.isArray(newParams.switches)) {
+ this.externalBlindUpdate(accessory, newParams);
+ }
+ return true;
+ case "garage":
+ if (
+ Object.keys(newParams).some(v => cns.devicesGarageParams.includes(v)) &&
+ Array.isArray(newParams.switches)
+ ) {
+ this.externalGarageUpdate(accessory, newParams);
+ }
+ return true;
+ case "lock":
+ if (Object.keys(newParams).some(v => cns.devicesLockParams.includes(v))) {
+ this.externalLockUpdate(accessory, newParams);
+ }
+ return true;
+ case "sensor":
+ if (Object.keys(newParams).some(v => cns.devicesSensorParams.includes(v))) {
+ this.externalSensorUpdate(accessory, newParams);
+ }
+ return true;
+ case "fan":
+ if (Object.keys(newParams).some(v => cns.devicesFanParams.includes(v))) {
+ this.externalFanUpdate(accessory, newParams);
+ }
+ return true;
+ case "thermostat":
+ if (Object.keys(newParams).some(v => cns.devicesThermostatParams.includes(v))) {
+ this.externalThermostatUpdate(accessory, newParams);
+ }
+ return true;
+ case "outlet":
+ if (Object.keys(newParams).some(v => cns.devicesOutletParams.includes(v))) {
+ this.externalOutletUpdate(accessory, newParams);
+ }
+ return true;
+ case "usb":
+ if (Object.keys(newParams).some(v => cns.devicesUSBParams.includes(v)) && Array.isArray(newParams.switches)) {
+ this.externalUSBUpdate(accessory, newParams);
+ }
+ return true;
+ case "scm":
+ if (Object.keys(newParams).some(v => cns.devicesSCMParams.includes(v)) && Array.isArray(newParams.switches)) {
+ this.externalSCMUpdate(accessory, newParams);
+ }
+ return true;
+ case "light":
+ if (
+ cns.devicesSingleSwitch.includes(accessory.context.eweUIID) &&
+ cns.devicesSingleSwitchLight.includes(accessory.context.eweModel)
+ ) {
+ if (Object.keys(newParams).some(v => cns.devicesSingleSwitchLightParams.includes(v))) {
+ this.externalSingleLightUpdate(accessory, newParams);
+ }
+ } else if (
+ cns.devicesMultiSwitch.includes(accessory.context.eweUIID) &&
+ cns.devicesMultiSwitchLight.includes(accessory.context.eweModel)
+ ) {
+ if (
+ Object.keys(newParams).some(v => cns.devicesMultiSwitchLightParams.includes(v)) &&
+ Array.isArray(newParams.switches)
+ ) {
+ this.externalMultiLightUpdate(accessory, newParams);
+ }
+ }
+ return true;
+ case "switch":
+ if (cns.devicesSingleSwitch.includes(accessory.context.eweUIID)) {
+ if (Object.keys(newParams).some(v => cns.devicesSingleSwitchParams.includes(v))) {
+ this.externalSingleSwitchUpdate(accessory, newParams);
+ }
+ } else if (cns.devicesMultiSwitch.includes(accessory.context.eweUIID)) {
+ if (
+ Object.keys(newParams).some(v => cns.devicesMultiSwitchParams.includes(v)) &&
+ Array.isArray(newParams.switches)
+ ) {
+ this.externalMultiSwitchUpdate(accessory, newParams);
+ }
+ }
+ return true;
+ case "rf_pri":
+ if (Object.keys(newParams).some(v => cns.devicesRFBridgeParams.includes(v))) {
+ this.externalRFDeviceUpdate(accessory, newParams);
+ }
+ return true;
+ case "rf_sub":
+ case "zb_pri":
+ return true;
+ case "zb_sub":
+ if (Object.keys(newParams).some(v => cns.devicesZBBridgeParams.includes(v))) {
+ this.externalZBDeviceUpdate(accessory, newParams);
+ }
+ return true;
+ default:
+ return false;
+ }
+ }
+ removeAccessory(accessory) {
+ try {
+ this.devicesInHB.delete(accessory.context.hbDeviceId);
+ this.api.unregisterPlatformAccessories("homebridge-ewelink", "eWeLink", [accessory]);
+ this.log("[%s] has been removed from Homebridge.", accessory.displayName);
+ } catch (err) {
+ this.log.warn("[%s] needed to be removed but couldn't as %s.", accessory.displayName, err);
+ }
+ }
+ sendDeviceUpdate(accessory, params, callback) {
+ let payload = {
+ apikey: accessory.context.eweApiKey,
+ deviceid: accessory.context.eweDeviceId,
+ params,
+ };
+ let sendViaWS = () => {
+ if (accessory.context.reachableWAN) {
+ this.wsClient.sendUpdate(payload);
+ callback();
+ } else {
+ this.log.error("[%s] could not be updated as it appears to be offline.", accessory.displayName);
+ callback("Device has failed to update");
+ }
+ };
+ if (cns.devicesNonLAN.includes(accessory.context.eweUIID) || !accessory.context.reachableLAN) {
+ sendViaWS();
+ } else {
+ this.lanClient
+ .sendUpdate(payload)
+ .then(() => callback())
+ .catch(err => {
+ if (this.debug) {
+ this.log.warn("[%s] Reverting to web socket as %s.", accessory.displayName, err);
+ }
+ sendViaWS();
+ });
+ }
+ }
+ receiveDeviceUpdate(device) {
+ let accessory;
+ switch (device.action) {
+ case "sysmsg":
+ if (
+ (accessory = this.devicesInHB.get(device.deviceid + "SWX") || this.devicesInHB.get(device.deviceid + "SW0"))
+ ) {
+ let isX = accessory.context.hbDeviceId.substr(-1) === "X";
+ if (device.params.updateSource === "WS") {
+ if (accessory.context.reachableWAN !== device.params.online) {
+ accessory.context.reachableWAN = device.params.online;
+ this.log(
+ "[%s] has been reported [%s] via [WS].",
+ accessory.displayName,
+ accessory.context.reachableWAN ? "online" : "offline"
+ );
+ this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
+ if (accessory.context.reachableWAN) this.wsClient.requestUpdate(accessory);
} else {
- if (!(this.config.hideDevFromHB || "").includes(device.deviceid)) {
- this.log.warn("[%s] Accessory received via %s update does not exist in Homebridge. If it's a new accessory please restart Homebridge so it is added.", device.deviceid, device.params.updateSource);
- }
+ if (this.debug) {
+ this.log("[%s] Nothing to update from above WS message.", accessory.displayName);
+ }
}
- break;
+ }
+ if (!isX) {
+ for (let i = 1; i <= accessory.context.channelCount; i++) {
+ if (this.devicesInHB.has(device.deviceid + "SW" + i)) {
+ let oAccessory = this.devicesInHB.get(device.deviceid + "SW" + i);
+ oAccessory.context.reachableWAN = device.params.online;
+ this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory);
+ }
+ }
+ }
+ }
+ break;
+ case "update":
+ if (
+ (accessory = this.devicesInHB.get(device.deviceid + "SWX") || this.devicesInHB.get(device.deviceid + "SW0"))
+ ) {
+ if (device.params.updateSource === "WS" && !accessory.context.reachableWAN) {
+ accessory.context.reachableWAN = true;
+ this.log("[%s] has been reported [online] via [WS].", accessory.displayName);
+ }
+ if (device.params.updateSource === "LAN" && !accessory.context.reachableLAN) {
+ accessory.context.reachableLAN = true;
+ this.log("[%s] has been reported [online] via [LAN].", accessory.displayName);
+ }
+ if (this.debug) {
+ this.log(
+ "[%s] externally updated from above %s message and will be refreshed.",
+ accessory.displayName,
+ device.params.updateSource
+ );
+ }
+ if (!this.refreshAccessory(accessory, device.params)) {
+ this.log.warn(
+ "[%s] cannot be refreshed. Please try removing accessory from the Homebridge cache along with any secondary devices (SW1, SW2, etc.). [debug:%s:%s]",
+ accessory.displayName,
+ accessory.context.type,
+ accessory.context.channelCount
+ );
+ }
+ } else {
+ if (!(this.config.hideDevFromHB || "").includes(device.deviceid)) {
+ this.log.warn(
+ "[%s] Accessory received via %s update does not exist in Homebridge. If it's a new accessory please restart Homebridge so it is added.",
+ device.deviceid,
+ device.params.updateSource
+ );
+ }
+ }
+ break;
+ }
+ }
+ internalValveUpdate(accessory, valve, value, callback) {
+ try {
+ if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
+ throw "it is currently offline";
}
- }
- internalValveUpdate(accessory, valve, value, callback) {
- try {
- if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
- throw "it is currently offline";
- }
- let params = {};
- accessory.getService(valve)
- .updateCharacteristic(Characteristic.Active, value)
- .updateCharacteristic(Characteristic.InUse, value);
- switch (value) {
- case 0:
- accessory.getService(valve).updateCharacteristic(Characteristic.RemainingDuration, 0);
- clearTimeout(accessory.getService(valve).timer);
- break;
- case 1:
- let timer = accessory.getService(valve).getCharacteristic(Characteristic.SetDuration).value;
- accessory.getService(valve).updateCharacteristic(Characteristic.RemainingDuration, timer);
- accessory.getService(valve).timer = setTimeout(() => {
- accessory.getService(valve).setCharacteristic(Characteristic.Active, 0);
- }, (timer * 1000));
- break;
- }
- params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
- switch (valve) {
- case "Valve A":
- params.switches[0].switch = value ? "on" : "off";
- params.switches[1].switch = accessory.getService("Valve B").getCharacteristic(Characteristic.Active).value ? "on" : "off";
- break;
- case "Valve B":
- params.switches[0].switch = accessory.getService("Valve A").getCharacteristic(Characteristic.Active).value ? "on" : "off";
- params.switches[1].switch = value ? "on" : "off";
- break;
- default:
- throw "unknown valve [" + valve + "]";
- }
- params.switches[2].switch = "off";
- params.switches[3].switch = "off";
- this.sendDeviceUpdate(accessory, params, callback);
- } catch (err) {
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
- this.log.error(str);
- callback(str);
- }
- }
- internalBlindUpdate(accessory, value, callback) {
- try {
- if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
- throw "it is currently offline";
- }
- let blindConfig;
- if (!(blindConfig = this.cusG.get(accessory.context.hbDeviceId))) {
- throw "group config missing";
- }
- if (blindConfig.type !== "blind" || !["oneSwitch", "twoSwitch"].includes(blindConfig.setup)) {
- throw "improper configuration";
- }
- let oldPos, params = {};
- value = value >= 50 ? 100 : 0;
- oldPos = accessory.getService(Service.WindowCovering).getCharacteristic(Characteristic.PositionState).value;
- if (value === oldPos * 100) {
- accessory.getService(Service.WindowCovering)
- .updateCharacteristic(Characteristic.TargetPosition, value)
- .updateCharacteristic(Characteristic.PositionState, oldPos);
- callback();
- return;
- }
- switch (blindConfig.setup) {
+ let params = {};
+ accessory
+ .getService(valve)
+ .updateCharacteristic(Characteristic.Active, value)
+ .updateCharacteristic(Characteristic.InUse, value);
+ switch (value) {
+ case 0:
+ accessory.getService(valve).updateCharacteristic(Characteristic.RemainingDuration, 0);
+ clearTimeout(accessory.getService(valve).timer);
+ break;
+ case 1:
+ let timer = accessory.getService(valve).getCharacteristic(Characteristic.SetDuration).value;
+ accessory.getService(valve).updateCharacteristic(Characteristic.RemainingDuration, timer);
+ accessory.getService(valve).timer = setTimeout(() => {
+ accessory.getService(valve).setCharacteristic(Characteristic.Active, 0);
+ }, timer * 1000);
+ break;
+ }
+ params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
+ switch (valve) {
+ case "Valve A":
+ params.switches[0].switch = value ? "on" : "off";
+ params.switches[1].switch = accessory.getService("Valve B").getCharacteristic(Characteristic.Active).value
+ ? "on"
+ : "off";
+ break;
+ case "Valve B":
+ params.switches[0].switch = accessory.getService("Valve A").getCharacteristic(Characteristic.Active).value
+ ? "on"
+ : "off";
+ params.switches[1].switch = value ? "on" : "off";
+ break;
+ default:
+ throw "unknown valve [" + valve + "]";
+ }
+ params.switches[2].switch = "off";
+ params.switches[3].switch = "off";
+ this.sendDeviceUpdate(accessory, params, callback);
+ } catch (err) {
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ this.log.error(str);
+ callback(str);
+ }
+ }
+ internalBlindUpdate(accessory, value, callback) {
+ try {
+ if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
+ throw "it is currently offline";
+ }
+ let blindConfig;
+ if (!(blindConfig = this.cusG.get(accessory.context.hbDeviceId))) {
+ throw "group config missing";
+ }
+ if (blindConfig.type !== "blind" || !["oneSwitch", "twoSwitch"].includes(blindConfig.setup)) {
+ throw "improper configuration";
+ }
+ let oldPos,
+ params = {};
+ value = value >= 50 ? 100 : 0;
+ oldPos = accessory.getService(Service.WindowCovering).getCharacteristic(Characteristic.PositionState).value;
+ if (value === oldPos * 100) {
+ accessory
+ .getService(Service.WindowCovering)
+ .updateCharacteristic(Characteristic.TargetPosition, value)
+ .updateCharacteristic(Characteristic.PositionState, oldPos);
+ callback();
+ return;
+ }
+ switch (blindConfig.setup) {
+ case "oneSwitch":
+ params.switch = "on";
+ break;
+ case "twoSwitch":
+ params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
+ params.switches[0].switch = value === 100 ? "on" : "off";
+ params.switches[1].switch = value === 0 ? "on" : "off";
+ break;
+ }
+ this.sendDeviceUpdate(accessory, params, function () {
+ return;
+ });
+ accessory
+ .getService(Service.WindowCovering)
+ .updateCharacteristic(Characteristic.TargetPosition, value)
+ .updateCharacteristic(Characteristic.PositionState, value / 100);
+ setTimeout(() => {
+ accessory
+ .getService(Service.WindowCovering)
+ .updateCharacteristic(Characteristic.CurrentPosition, value)
+ .updateCharacteristic(Characteristic.PositionState, 2);
+ callback();
+ }, parseInt(blindConfig.operationTime) * 100);
+ } catch (err) {
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ this.log.error(str);
+ callback(str);
+ }
+ }
+ internalGarageUpdate(accessory, value, callback) {
+ try {
+ if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
+ throw "it is currently offline";
+ }
+ let garageConfig;
+ if (!(garageConfig = this.cusG.get(accessory.context.hbDeviceId))) {
+ throw "group config missing";
+ }
+ if (garageConfig.type !== "garage" || !["oneSwitch", "twoSwitch"].includes(garageConfig.setup)) {
+ throw "improper configuration";
+ }
+ accessory.context.inUse = true;
+ accessory.context.state = value;
+ let sensorDefinition = garageConfig.sensorId || false,
+ sAccessory = false,
+ oldPos,
+ newPos = value,
+ params = {},
+ delay = 0;
+ if (sensorDefinition && !(sAccessory = this.devicesInHB.get(garageConfig.sensorId + "SWX"))) {
+ throw "defined DW2 sensor doesn't exist";
+ }
+ if (sAccessory.context.type !== "sensor") {
+ throw "defined DW2 sensor isn't a sensor";
+ }
+ oldPos = sAccessory
+ ? sAccessory.getService(Service.ContactSensor).getCharacteristic(Characteristic.ContactSensorState).value === 0
+ ? 1
+ : 0
+ : accessory.getService(Service.GarageDoorOpener).getCharacteristic(Characteristic.CurrentDoorState).value;
+ if (newPos === oldPos % 2) {
+ accessory.context.inUse = false;
+ callback();
+ return;
+ }
+ if (garageConfig.setup === "oneSwitch" && [2, 3].includes(oldPos)) {
+ accessory
+ .getService(Service.GarageDoorOpener)
+ .updateCharacteristic(Characteristic.CurrentDoorState, ((oldPos * 2) % 3) + 2);
+ delay = 1500;
+ }
+ setTimeout(() => {
+ if (accessory.context.state === newPos) {
+ accessory
+ .getService(Service.GarageDoorOpener)
+ .updateCharacteristic(Characteristic.TargetDoorState, newPos)
+ .updateCharacteristic(Characteristic.CurrentDoorState, newPos + 2);
+ switch (garageConfig.setup) {
case "oneSwitch":
- params.switch = "on";
- break;
+ params.switch = "on";
+ break;
case "twoSwitch":
- params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
- params.switches[0].switch = value === 100 ? "on" : "off";
- params.switches[1].switch = value === 0 ? "on" : "off";
- break;
- }
- this.sendDeviceUpdate(accessory, params, function() {
- return;
- });
- accessory.getService(Service.WindowCovering)
- .updateCharacteristic(Characteristic.TargetPosition, value)
- .updateCharacteristic(Characteristic.PositionState, (value / 100));
- setTimeout(() => {
- accessory.getService(Service.WindowCovering)
- .updateCharacteristic(Characteristic.CurrentPosition, value)
- .updateCharacteristic(Characteristic.PositionState, 2);
- callback();
- }, parseInt(blindConfig.operationTime) * 100);
- } catch (err) {
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
- this.log.error(str);
- callback(str);
- }
- }
- internalGarageUpdate(accessory, value, callback) {
- try {
- if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
- throw "it is currently offline";
- }
- let garageConfig;
- if (!(garageConfig = this.cusG.get(accessory.context.hbDeviceId))) {
- throw "group config missing";
- }
- if (garageConfig.type !== "garage" || !["oneSwitch", "twoSwitch"].includes(garageConfig.setup)) {
- throw "improper configuration";
- }
- accessory.context.inUse = true;
- accessory.context.state = value;
- let sensorDefinition = garageConfig.sensorId || false,
- sAccessory = false,
- oldPos,
- newPos = value,
- params = {},
- delay = 0;
- if (sensorDefinition && !(sAccessory = this.devicesInHB.get(garageConfig.sensorId + "SWX"))) {
- throw "defined DW2 sensor doesn't exist";
- }
- if (sAccessory.context.type !== "sensor") {
- throw "defined DW2 sensor isn't a sensor";
- }
- oldPos = sAccessory ?
- sAccessory.getService(Service.ContactSensor).getCharacteristic(Characteristic.ContactSensorState).value === 0 ? 1 : 0 :
- accessory.getService(Service.GarageDoorOpener).getCharacteristic(Characteristic.CurrentDoorState).value;
- if (newPos === (oldPos % 2)) {
- accessory.context.inUse = false;
- callback();
+ params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
+ params.switches[0].switch = newPos === 0 ? "on" : "off";
+ params.switches[1].switch = newPos === 1 ? "on" : "off";
+ break;
+ }
+ this.sendDeviceUpdate(accessory, params, function () {
return;
- }
- if (garageConfig.setup === "oneSwitch" && [2, 3].includes(oldPos)) {
- accessory.getService(Service.GarageDoorOpener).updateCharacteristic(Characteristic.CurrentDoorState, oldPos * 2 % 3 + 2);
- delay = 1500;
- }
- setTimeout(() => {
- if (accessory.context.state === newPos) {
- accessory.getService(Service.GarageDoorOpener)
- .updateCharacteristic(Characteristic.TargetDoorState, newPos)
- .updateCharacteristic(Characteristic.CurrentDoorState, newPos + 2);
- switch (garageConfig.setup) {
- case "oneSwitch":
- params.switch = "on";
- break;
- case "twoSwitch":
- params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
- params.switches[0].switch = newPos === 0 ? "on" : "off";
- params.switches[1].switch = newPos === 1 ? "on" : "off";
- break;
- }
- this.sendDeviceUpdate(accessory, params, function() {
- return;
- });
- setTimeout(() => {
- if (!sAccessory) {
- accessory.getService(Service.GarageDoorOpener).updateCharacteristic(Characteristic.CurrentDoorState, newPos);
- }
- accessory.context.inUse = false;
- }, parseInt(garageConfig.operationTime) * 100);
+ });
+ setTimeout(() => {
+ if (!sAccessory) {
+ accessory
+ .getService(Service.GarageDoorOpener)
+ .updateCharacteristic(Characteristic.CurrentDoorState, newPos);
}
- }, delay);
- callback();
- } catch (err) {
- accessory.context.inUse = false;
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
- this.log.error(str);
- callback(str);
- }
- }
- internalLockUpdate(accessory, value, callback) {
- try {
- if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
- throw "it is currently offline";
- }
- let lockConfig, params = {};
- if (!(lockConfig = this.cusG.get(accessory.context.hbDeviceId))) {
- throw "group config missing";
- }
- if (lockConfig.type !== "lock") {
- throw "improper configuration";
- }
- accessory.context.inUse = true;
- this.log("[%s] has received request to unlock.", accessory.displayName);
- accessory.getService(Service.LockMechanism)
- .updateCharacteristic(Characteristic.LockTargetState, 0)
- .updateCharacteristic(Characteristic.LockCurrentState, 0);
- params.switch = "on";
- this.sendDeviceUpdate(accessory, params, callback);
- setTimeout(() => {
- accessory.getService(Service.LockMechanism)
- .updateCharacteristic(Characteristic.LockTargetState, 1)
- .updateCharacteristic(Characteristic.LockCurrentState, 1);
accessory.context.inUse = false;
- }, parseInt(lockConfig.operationTime) * 100);
- } catch (err) {
- accessory.context.inUse = false;
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
- this.log.error(str);
- callback(str);
- }
- }
- internalFanUpdate(accessory, type, value, callback) {
- try {
- if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
- throw "it is currently offline";
- }
- let newPower, newSpeed, newLight;
- switch (type) {
- case "power":
- newPower = value;
- newSpeed = value ? 33 : 0;
- newLight = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value;
- break;
- case "speed":
- newPower = value >= 33 ? 1 : 0;
- newSpeed = value;
- newLight = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value;
- break;
- case "light":
- newPower = accessory.getService(Service.Fanv2).getCharacteristic(Characteristic.Active).value;
- newSpeed = accessory.getService(Service.Fanv2).getCharacteristic(Characteristic.RotationSpeed).value;
- newLight = value;
- break;
- }
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, newLight);
- accessory.getService(Service.Fanv2)
- .updateCharacteristic(Characteristic.Active, newPower)
- .updateCharacteristic(Characteristic.RotationSpeed, newSpeed);
- let params = {
- switches: this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches
- };
- params.switches[0].switch = newLight ? "on" : "off";
- params.switches[1].switch = (newPower === 1 && newSpeed >= 33) ? "on" : "off";
- params.switches[2].switch = (newPower === 1 && newSpeed >= 66 && newSpeed < 99) ? "on" : "off";
- params.switches[3].switch = (newPower === 1 && newSpeed >= 99) ? "on" : "off";
- if (this.debug) {
- this.log.warn("Fan Update - setting " + type + " to " + value);
- this.log("[%s] new stats: power [%s], speed [%s%], light [%s].", accessory.displayName, newPower, newSpeed, newLight);
- }
- this.sendDeviceUpdate(accessory, params, callback);
- } catch (err) {
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
- this.log.error(str);
- callback(str);
- }
- }
- internalThermostatUpdate(accessory, value, callback) {
- try {
- if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
- throw "it is currently offline";
- }
- let params = {
- switch: value ? "on" : "off",
- mainSwitch: value ? "on" : "off"
- };
- if (this.debug) {
+ }, parseInt(garageConfig.operationTime) * 100);
+ }
+ }, delay);
+ callback();
+ } catch (err) {
+ accessory.context.inUse = false;
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ this.log.error(str);
+ callback(str);
+ }
+ }
+ internalLockUpdate(accessory, value, callback) {
+ try {
+ if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
+ throw "it is currently offline";
+ }
+ let lockConfig,
+ params = {};
+ if (!(lockConfig = this.cusG.get(accessory.context.hbDeviceId))) {
+ throw "group config missing";
+ }
+ if (lockConfig.type !== "lock") {
+ throw "improper configuration";
+ }
+ accessory.context.inUse = true;
+ this.log("[%s] has received request to unlock.", accessory.displayName);
+ accessory
+ .getService(Service.LockMechanism)
+ .updateCharacteristic(Characteristic.LockTargetState, 0)
+ .updateCharacteristic(Characteristic.LockCurrentState, 0);
+ params.switch = "on";
+ this.sendDeviceUpdate(accessory, params, callback);
+ setTimeout(() => {
+ accessory
+ .getService(Service.LockMechanism)
+ .updateCharacteristic(Characteristic.LockTargetState, 1)
+ .updateCharacteristic(Characteristic.LockCurrentState, 1);
+ accessory.context.inUse = false;
+ }, parseInt(lockConfig.operationTime) * 100);
+ } catch (err) {
+ accessory.context.inUse = false;
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ this.log.error(str);
+ callback(str);
+ }
+ }
+ internalFanUpdate(accessory, type, value, callback) {
+ try {
+ if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
+ throw "it is currently offline";
+ }
+ let newPower, newSpeed, newLight;
+ switch (type) {
+ case "power":
+ newPower = value;
+ newSpeed = value ? 33 : 0;
+ newLight = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value;
+ break;
+ case "speed":
+ newPower = value >= 33 ? 1 : 0;
+ newSpeed = value;
+ newLight = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value;
+ break;
+ case "light":
+ newPower = accessory.getService(Service.Fanv2).getCharacteristic(Characteristic.Active).value;
+ newSpeed = accessory.getService(Service.Fanv2).getCharacteristic(Characteristic.RotationSpeed).value;
+ newLight = value;
+ break;
+ }
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, newLight);
+ accessory
+ .getService(Service.Fanv2)
+ .updateCharacteristic(Characteristic.Active, newPower)
+ .updateCharacteristic(Characteristic.RotationSpeed, newSpeed);
+ let params = {
+ switches: this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches,
+ };
+ params.switches[0].switch = newLight ? "on" : "off";
+ params.switches[1].switch = newPower === 1 && newSpeed >= 33 ? "on" : "off";
+ params.switches[2].switch = newPower === 1 && newSpeed >= 66 && newSpeed < 99 ? "on" : "off";
+ params.switches[3].switch = newPower === 1 && newSpeed >= 99 ? "on" : "off";
+ if (this.debug) {
+ this.log.warn("Fan Update - setting " + type + " to " + value);
+ this.log(
+ "[%s] new stats: power [%s], speed [%s%], light [%s].",
+ accessory.displayName,
+ newPower,
+ newSpeed,
+ newLight
+ );
+ }
+ this.sendDeviceUpdate(accessory, params, callback);
+ } catch (err) {
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ this.log.error(str);
+ callback(str);
+ }
+ }
+ internalThermostatUpdate(accessory, value, callback) {
+ try {
+ if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
+ throw "it is currently offline";
+ }
+ let params = {
+ switch: value ? "on" : "off",
+ mainSwitch: value ? "on" : "off",
+ };
+ if (this.debug) {
+ this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
+ }
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
+ this.sendDeviceUpdate(accessory, params, callback);
+ } catch (err) {
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ this.log.error(str);
+ callback(str);
+ }
+ }
+ internalOutletUpdate(accessory, value, callback) {
+ try {
+ if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
+ throw "it is currently offline";
+ }
+ let params = {
+ switch: value ? "on" : "off",
+ };
+ if (this.debug) {
+ this.log("[%s] requesting to turn [%s].", accessory.displayName, value ? "on" : "off");
+ }
+ accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, value);
+ this.sendDeviceUpdate(accessory, params, callback);
+ } catch (err) {
+ callback("[" + accessory.displayName + "] " + err + ".");
+ }
+ }
+ internalUSBUpdate(accessory, value, callback) {
+ try {
+ if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
+ throw "it is currently offline";
+ }
+ let params = {
+ switches: this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches,
+ };
+ params.switches[0].switch = value ? "on" : "off";
+ if (this.debug) {
+ this.log("[%s] requesting to turn [%s].", accessory.displayName, value ? "on" : "off");
+ }
+ accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, value);
+ this.sendDeviceUpdate(accessory, params, callback);
+ } catch (err) {
+ callback("[" + accessory.displayName + "] " + err + ".");
+ }
+ }
+ internalSCMUpdate(accessory, value, callback) {
+ try {
+ if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
+ throw "it is currently offline";
+ }
+ let params = {
+ switches: this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches,
+ };
+ params.switches[0].switch = value ? "on" : "off";
+ if (this.debug) {
+ this.log("[%s] requesting to turn [%s].", accessory.displayName, value ? "on" : "off");
+ }
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
+ this.sendDeviceUpdate(accessory, params, callback);
+ } catch (err) {
+ callback("[" + accessory.displayName + "] " + err + ".");
+ }
+ }
+ internalLightbulbUpdate(accessory, value, callback) {
+ try {
+ if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
+ throw "it is currently offline";
+ }
+ let oAccessory,
+ params = {};
+ switch (accessory.context.switchNumber) {
+ case "X":
+ if (accessory.context.eweUIID === 22) {
+ //*** B1 ***\\
+ params.state = value ? "on" : "off";
+ } else {
+ params.switch = value ? "on" : "off";
+ }
+ if (this.debug) {
this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
- }
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
- this.sendDeviceUpdate(accessory, params, callback);
- } catch (err) {
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
- this.log.error(str);
- callback(str);
- }
- }
- internalOutletUpdate(accessory, value, callback) {
- try {
- if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
- throw "it is currently offline";
- }
- let params = {
- switch: value ? "on" : "off"
- };
- if (this.debug) {
- this.log("[%s] requesting to turn [%s].", accessory.displayName, value ? "on" : "off");
- }
- accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, value);
- this.sendDeviceUpdate(accessory, params, callback);
- } catch (err) {
- callback("[" + accessory.displayName + "] " + err + ".");
- }
- }
- internalUSBUpdate(accessory, value, callback) {
- try {
- if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
- throw "it is currently offline";
- }
- let params = {
- switches: this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches
- };
- params.switches[0].switch = value ? "on" : "off";
- if (this.debug) {
- this.log("[%s] requesting to turn [%s].", accessory.displayName, value ? "on" : "off");
- }
- accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, value);
- this.sendDeviceUpdate(accessory, params, callback);
- } catch (err) {
- callback("[" + accessory.displayName + "] " + err + ".");
- }
- }
- internalSCMUpdate(accessory, value, callback) {
- try {
- if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
- throw "it is currently offline";
- }
- let params = {
- switches: this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches
- };
- params.switches[0].switch = value ? "on" : "off";
- if (this.debug) {
- this.log("[%s] requesting to turn [%s].", accessory.displayName, value ? "on" : "off");
- }
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
- this.sendDeviceUpdate(accessory, params, callback);
- } catch (err) {
- callback("[" + accessory.displayName + "] " + err + ".");
- }
- }
- internalLightbulbUpdate(accessory, value, callback) {
- try {
- if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
- throw "it is currently offline";
- }
- let oAccessory, params = {};
- switch (accessory.context.switchNumber) {
- case "X":
- if (accessory.context.eweUIID === 22) { //*** B1 ***\\
- params.state = value ? "on" : "off";
- } else {
- params.switch = value ? "on" : "off";
- }
- if (this.debug) {
- this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
- }
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
- break;
- case "0":
- params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
- params.switches[0].switch = value ? "on" : "off";
- params.switches[1].switch = value ? "on" : "off";
- params.switches[2].switch = value ? "on" : "off";
- params.switches[3].switch = value ? "on" : "off";
- if (this.debug) {
- this.log("[%s] updating to turn group [%s].", accessory.displayName, value ? "on" : "off");
- }
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
- for (let i = 1; i <= 4; i++) {
- if (this.devicesInHB.has(accessory.context.eweDeviceId + "SW" + i)) {
- oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i);
- oAccessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
- }
- }
- break;
- case "1":
- case "2":
- case "3":
- case "4":
- if (this.debug) {
- this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
- }
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
- let tAccessory,
- masterState = "off";
- params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
- for (let i = 1; i <= 4; i++) {
- if ((tAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
- i === parseInt(accessory.context.switchNumber) ?
- params.switches[i - 1].switch = value ? "on" : "off" :
- params.switches[i - 1].switch = tAccessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value ? "on" : "off";
- if (tAccessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value) {
- masterState = "on";
- }
- } else {
- params.switches[i - 1].switch = "off";
- }
- }
- oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
- oAccessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, masterState === "on");
- break;
- default:
- throw "unknown switch number [" + accessory.context.switchNumber + "]";
- }
- this.sendDeviceUpdate(accessory, params, callback);
- } catch (err) {
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
- this.log.error(str);
- callback(str);
- }
- }
- internalBrightnessUpdate(accessory, value, callback) {
- try {
- if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
- throw "it is currently offline";
- }
- let params = {};
- if (value === 0) {
- params.switch = "off";
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, false);
- } else {
- if (!accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value) {
- params.switch = "on";
+ }
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
+ break;
+ case "0":
+ params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
+ params.switches[0].switch = value ? "on" : "off";
+ params.switches[1].switch = value ? "on" : "off";
+ params.switches[2].switch = value ? "on" : "off";
+ params.switches[3].switch = value ? "on" : "off";
+ if (this.debug) {
+ this.log("[%s] updating to turn group [%s].", accessory.displayName, value ? "on" : "off");
+ }
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
+ for (let i = 1; i <= 4; i++) {
+ if (this.devicesInHB.has(accessory.context.eweDeviceId + "SW" + i)) {
+ oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i);
+ oAccessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
}
- switch (accessory.context.eweUIID) {
- case 36: //*** KING-M4 ***\\
- params.bright = Math.round(value * 9 / 10 + 10);
- break;
- case 44: //*** D1 ***\\
- params.brightness = value;
- params.mode = 0;
- break;
- default:
- throw "unknown device UIID";
+ }
+ break;
+ case "1":
+ case "2":
+ case "3":
+ case "4":
+ if (this.debug) {
+ this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
+ }
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
+ let tAccessory,
+ masterState = "off";
+ params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
+ for (let i = 1; i <= 4; i++) {
+ if ((tAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
+ i === parseInt(accessory.context.switchNumber)
+ ? (params.switches[i - 1].switch = value ? "on" : "off")
+ : (params.switches[i - 1].switch = tAccessory
+ .getService(Service.Lightbulb)
+ .getCharacteristic(Characteristic.On).value
+ ? "on"
+ : "off");
+ if (tAccessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value) {
+ masterState = "on";
+ }
+ } else {
+ params.switches[i - 1].switch = "off";
}
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Brightness, value);
- }
- if (this.debug) {
- this.log("[%s] updating brightness to [%s%].", accessory.displayName, value);
- }
- setTimeout(() => this.sendDeviceUpdate(accessory, params, callback), 250);
- } catch (err) {
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
- this.log.error(str);
- callback(str);
- }
- }
- internalHSBUpdate(accessory, type, value, callback) {
- try {
- if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
- throw "it is currently offline";
- }
- let newRGB,
- params = {},
- curHue = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Hue).value,
- curSat = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Saturation).value;
- switch (type) {
- case "hue":
- newRGB = convert.hsv.rgb(value, curSat, 100);
- switch (accessory.context.eweUIID) {
- case 22: //*** B1 ***\\
- params = {
- zyx_mode: 2,
- type: "middle",
- channel0: "0",
- channel1: "0",
- channel2: newRGB[0].toString(),
- channel3: newRGB[1].toString(),
- channel4: newRGB[2].toString()
- };
- break;
- case 59: //*** L1 ***\\
- params = {
- mode: 1,
- colorR: newRGB[0],
- colorG: newRGB[1],
- colorB: newRGB[2]
- };
- break;
- default:
- throw "unknown device UIID";
- }
- if (this.debug) {
- this.log("[%s] updating hue to [%s°].", accessory.displayName, value);
- }
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Hue, value);
- break;
- case "bri":
- switch (accessory.context.eweUIID) {
- case 22: //*** B1 ***\\
- newRGB = convert.hsv.rgb(curHue, curSat, value);
- params = {
- zyx_mode: 2,
- type: "middle",
- channel0: "0",
- channel1: "0",
- channel2: newRGB[0].toString(),
- channel3: newRGB[1].toString(),
- channel4: newRGB[2].toString()
- };
- break;
- case 59: //*** L1 ***\\
- params = {
- mode: 1,
- bright: value
- };
- break;
- }
- if (this.debug) {
- this.log("[%s] updating brightness to [%s%].", accessory.displayName, value);
- }
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Brightness, value);
- break;
- default:
- throw "unknown device UIID";
- }
- setTimeout(() => this.sendDeviceUpdate(accessory, params, callback), 250);
- } catch (err) {
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
- this.log.error(str);
- callback(str);
- }
- }
- internalSwitchUpdate(accessory, value, callback) {
- try {
- if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
- throw "it is currently offline";
- }
- let oAccessory, params = {};
- switch (accessory.context.switchNumber) {
- case "X":
- params.switch = value ? "on" : "off";
- if (this.debug) {
- this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
- }
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
- break;
- case "0":
- params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
- params.switches[0].switch = value ? "on" : "off";
- params.switches[1].switch = value ? "on" : "off";
- params.switches[2].switch = value ? "on" : "off";
- params.switches[3].switch = value ? "on" : "off";
- if (this.debug) {
- this.log("[%s] updating to turn group [%s].", accessory.displayName, value ? "on" : "off");
- }
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
- for (let i = 1; i <= 4; i++) {
- if (this.devicesInHB.has(accessory.context.eweDeviceId + "SW" + i)) {
- oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i);
- oAccessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
- }
- }
- break;
- case "1":
- case "2":
- case "3":
- case "4":
- if (this.debug) {
- this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
- }
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
- let tAccessory,
- masterState = "off";
- params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
- for (let i = 1; i <= 4; i++) {
- if ((tAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
- i === parseInt(accessory.context.switchNumber) ?
- params.switches[i - 1].switch = value ? "on" : "off" :
- params.switches[i - 1].switch = tAccessory.getService(Service.Switch).getCharacteristic(Characteristic.On).value ? "on" : "off";
- if (tAccessory.getService(Service.Switch).getCharacteristic(Characteristic.On).value) {
- masterState = "on";
- }
- } else {
- params.switches[i - 1].switch = "off";
- }
- }
- oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
- oAccessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, masterState === "on");
- break;
+ }
+ oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
+ oAccessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, masterState === "on");
+ break;
+ default:
+ throw "unknown switch number [" + accessory.context.switchNumber + "]";
+ }
+ this.sendDeviceUpdate(accessory, params, callback);
+ } catch (err) {
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ this.log.error(str);
+ callback(str);
+ }
+ }
+ internalBrightnessUpdate(accessory, value, callback) {
+ try {
+ if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
+ throw "it is currently offline";
+ }
+ let params = {};
+ if (value === 0) {
+ params.switch = "off";
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, false);
+ } else {
+ if (!accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value) {
+ params.switch = "on";
+ }
+ switch (accessory.context.eweUIID) {
+ case 36: //*** KING-M4 ***\\
+ params.bright = Math.round((value * 9) / 10 + 10);
+ break;
+ case 44: //*** D1 ***\\
+ params.brightness = value;
+ params.mode = 0;
+ break;
+ default:
+ throw "unknown device UIID";
+ }
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Brightness, value);
+ }
+ if (this.debug) {
+ this.log("[%s] updating brightness to [%s%].", accessory.displayName, value);
+ }
+ setTimeout(() => this.sendDeviceUpdate(accessory, params, callback), 250);
+ } catch (err) {
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ this.log.error(str);
+ callback(str);
+ }
+ }
+ internalHSBUpdate(accessory, type, value, callback) {
+ try {
+ if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
+ throw "it is currently offline";
+ }
+ let newRGB,
+ params = {},
+ curHue = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Hue).value,
+ curSat = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Saturation).value;
+ switch (type) {
+ case "hue":
+ newRGB = convert.hsv.rgb(value, curSat, 100);
+ switch (accessory.context.eweUIID) {
+ case 22: //*** B1 ***\\
+ params = {
+ zyx_mode: 2,
+ type: "middle",
+ channel0: "0",
+ channel1: "0",
+ channel2: newRGB[0].toString(),
+ channel3: newRGB[1].toString(),
+ channel4: newRGB[2].toString(),
+ };
+ break;
+ case 59: //*** L1 ***\\
+ params = {
+ mode: 1,
+ colorR: newRGB[0],
+ colorG: newRGB[1],
+ colorB: newRGB[2],
+ };
+ break;
default:
- throw "unknown switch number [" + accessory.context.switchNumber + "]";
- }
- this.sendDeviceUpdate(accessory, params, callback);
- } catch (err) {
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
- this.log.error(str);
- callback(str);
- }
- }
- internalRFDeviceUpdate(accessory, rfChl, callback) {
- try {
- if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
- throw "it is currently offline";
- }
- rfChl = parseInt(rfChl);
- let params = {
- cmd: "transmit",
- rfChl
- };
- if (this.debug) {
- this.log("[%s %s] mimicking RF button press.", accessory.displayName, accessory.context.rfChls[rfChl]);
- }
- accessory.getService(accessory.context.rfChls[rfChl]).updateCharacteristic(Characteristic.On, true);
- this.sendDeviceUpdate(accessory, params, callback);
- setTimeout(() => accessory.getService(accessory.context.rfChls[rfChl]).updateCharacteristic(Characteristic.On, false), 3000);
- } catch (err) {
- let str = "[" + accessory.displayName + " " + name + "] could not be updated as " + err + ".";
- this.log.error(str);
- callback(str);
- }
- }
- externalValveUpdate(accessory, params) {
- try {
- ["A", "B"].forEach((v, k) => {
- accessory.getService("Valve " + v)
- .updateCharacteristic(Characteristic.Active, params.switches[k].switch === "on")
- .updateCharacteristic(Characteristic.InUse, params.switches[k].switch === "on");
- if (params.switches[k].switch === "on") {
- let timer = accessory.getService("Valve " + v).getCharacteristic(Characteristic.SetDuration).value;
- accessory.getService("Valve " + v).updateCharacteristic(Characteristic.RemainingDuration, timer);
- accessory.getService("Valve " + v).timer = setTimeout(() => {
- accessory.getService("Valve " + v).setCharacteristic(Characteristic.Active, 0);
- }, (timer * 1000));
+ throw "unknown device UIID";
+ }
+ if (this.debug) {
+ this.log("[%s] updating hue to [%s°].", accessory.displayName, value);
+ }
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Hue, value);
+ break;
+ case "bri":
+ switch (accessory.context.eweUIID) {
+ case 22: //*** B1 ***\\
+ newRGB = convert.hsv.rgb(curHue, curSat, value);
+ params = {
+ zyx_mode: 2,
+ type: "middle",
+ channel0: "0",
+ channel1: "0",
+ channel2: newRGB[0].toString(),
+ channel3: newRGB[1].toString(),
+ channel4: newRGB[2].toString(),
+ };
+ break;
+ case 59: //*** L1 ***\\
+ params = {
+ mode: 1,
+ bright: value,
+ };
+ break;
+ }
+ if (this.debug) {
+ this.log("[%s] updating brightness to [%s%].", accessory.displayName, value);
+ }
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Brightness, value);
+ break;
+ default:
+ throw "unknown device UIID";
+ }
+ setTimeout(() => this.sendDeviceUpdate(accessory, params, callback), 250);
+ } catch (err) {
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ this.log.error(str);
+ callback(str);
+ }
+ }
+ internalSwitchUpdate(accessory, value, callback) {
+ try {
+ if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
+ throw "it is currently offline";
+ }
+ let oAccessory,
+ params = {};
+ switch (accessory.context.switchNumber) {
+ case "X":
+ params.switch = value ? "on" : "off";
+ if (this.debug) {
+ this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
+ }
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
+ break;
+ case "0":
+ params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
+ params.switches[0].switch = value ? "on" : "off";
+ params.switches[1].switch = value ? "on" : "off";
+ params.switches[2].switch = value ? "on" : "off";
+ params.switches[3].switch = value ? "on" : "off";
+ if (this.debug) {
+ this.log("[%s] updating to turn group [%s].", accessory.displayName, value ? "on" : "off");
+ }
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
+ for (let i = 1; i <= 4; i++) {
+ if (this.devicesInHB.has(accessory.context.eweDeviceId + "SW" + i)) {
+ oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i);
+ oAccessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
+ }
+ }
+ break;
+ case "1":
+ case "2":
+ case "3":
+ case "4":
+ if (this.debug) {
+ this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
+ }
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
+ let tAccessory,
+ masterState = "off";
+ params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
+ for (let i = 1; i <= 4; i++) {
+ if ((tAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
+ i === parseInt(accessory.context.switchNumber)
+ ? (params.switches[i - 1].switch = value ? "on" : "off")
+ : (params.switches[i - 1].switch = tAccessory
+ .getService(Service.Switch)
+ .getCharacteristic(Characteristic.On).value
+ ? "on"
+ : "off");
+ if (tAccessory.getService(Service.Switch).getCharacteristic(Characteristic.On).value) {
+ masterState = "on";
+ }
} else {
- accessory.getService("Valve " + v).updateCharacteristic(Characteristic.RemainingDuration, 0);
- clearTimeout(accessory.getService("Valve " + v).timer);
+ params.switches[i - 1].switch = "off";
}
- });
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- externalBlindUpdate(accessory, params) {
- try {
- let blindConfig, nSte;
- if (!(blindConfig = this.cusG.get(accessory.context.hbDeviceId))) {
- throw "group config missing";
- }
- if (blindConfig.type !== "blind" || ["oneSwitch", "twoSwitch"].includes(blindConfig.setup)) {
- throw "improper configuration";
- }
- switch (blindConfig.setup) {
- case "oneSwitch":
- if (params.switch === "off") {
- return;
- }
- nSte = accessory.getService(Service.WindowCovering).getCharacteristic(Characteristic.PositionState).value === 0 ? 1 : 0;
- break;
- case "twoSwitch":
- if (params.switches[0].switch === "off" && params.switches[1].switch === "off") {
- return;
- }
- let switchUp = params.switches[0].switch === "on" ? -1 : 0, // matrix of numbers to get
- switchDown = params.switches[1].switch === "on" ? 0 : 2; // ... the correct HomeKit value
- nSte = switchUp + switchDown;
- break;
- }
- accessory.getService(Service.WindowCovering)
- .updateCharacteristic(Characteristic.PositionState, nSte)
- .updateCharacteristic(Characteristic.TargetPosition, nSte * 100);
- setTimeout(() => {
- accessory.getService(Service.WindowCovering)
- .updateCharacteristic(Characteristic.PositionState, 2)
- .updateCharacteristic(Characteristic.CurrentPosition, nSte * 100);
- }, parseInt(blindConfig.operationTime) * 100);
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- externalGarageUpdate(accessory, params) {
- try {
- let garageConfig,
- oldPos = accessory.getService(Service.GarageDoorOpener).getCharacteristic(Characteristic.CurrentDoorState).value,
- newPos = [0, 2].includes(oldPos) ? 3 : 2;
- if (!(garageConfig = this.cusG.get(accessory.context.hbDeviceId))) {
- throw "group config missing";
- }
- if (garageConfig.type !== "garage" || !["oneSwitch", "twoSwitch"].includes(garageConfig.setup)) {
- throw "improper configuration";
- }
- if (accessory.context.inUse || garageConfig.sensorId) {
+ }
+ oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
+ oAccessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, masterState === "on");
+ break;
+ default:
+ throw "unknown switch number [" + accessory.context.switchNumber + "]";
+ }
+ this.sendDeviceUpdate(accessory, params, callback);
+ } catch (err) {
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ this.log.error(str);
+ callback(str);
+ }
+ }
+ internalRFDeviceUpdate(accessory, rfChl, callback) {
+ try {
+ if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
+ throw "it is currently offline";
+ }
+ rfChl = parseInt(rfChl);
+ let params = {
+ cmd: "transmit",
+ rfChl,
+ };
+ if (this.debug) {
+ this.log("[%s %s] mimicking RF button press.", accessory.displayName, accessory.context.rfChls[rfChl]);
+ }
+ accessory.getService(accessory.context.rfChls[rfChl]).updateCharacteristic(Characteristic.On, true);
+ this.sendDeviceUpdate(accessory, params, callback);
+ setTimeout(
+ () => accessory.getService(accessory.context.rfChls[rfChl]).updateCharacteristic(Characteristic.On, false),
+ 3000
+ );
+ } catch (err) {
+ let str = "[" + accessory.displayName + " " + name + "] could not be updated as " + err + ".";
+ this.log.error(str);
+ callback(str);
+ }
+ }
+ externalValveUpdate(accessory, params) {
+ try {
+ ["A", "B"].forEach((v, k) => {
+ accessory
+ .getService("Valve " + v)
+ .updateCharacteristic(Characteristic.Active, params.switches[k].switch === "on")
+ .updateCharacteristic(Characteristic.InUse, params.switches[k].switch === "on");
+ if (params.switches[k].switch === "on") {
+ let timer = accessory.getService("Valve " + v).getCharacteristic(Characteristic.SetDuration).value;
+ accessory.getService("Valve " + v).updateCharacteristic(Characteristic.RemainingDuration, timer);
+ accessory.getService("Valve " + v).timer = setTimeout(() => {
+ accessory.getService("Valve " + v).setCharacteristic(Characteristic.Active, 0);
+ }, timer * 1000);
+ } else {
+ accessory.getService("Valve " + v).updateCharacteristic(Characteristic.RemainingDuration, 0);
+ clearTimeout(accessory.getService("Valve " + v).timer);
+ }
+ });
+ } catch (err) {
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
+ externalBlindUpdate(accessory, params) {
+ try {
+ let blindConfig, nSte;
+ if (!(blindConfig = this.cusG.get(accessory.context.hbDeviceId))) {
+ throw "group config missing";
+ }
+ if (blindConfig.type !== "blind" || ["oneSwitch", "twoSwitch"].includes(blindConfig.setup)) {
+ throw "improper configuration";
+ }
+ switch (blindConfig.setup) {
+ case "oneSwitch":
+ if (params.switch === "off") {
return;
- }
- switch (garageConfig.setup) {
- case "oneSwitch":
- if (params.switch === "off") {
- return;
- }
- break;
- case "twoSwitch":
- if (params.switches[0].switch === params.switches[1].switch || params.switches[oldPos % 2].switch === "on") {
- return;
- }
- break;
- }
- accessory.context.inUse = true;
- if (!garageConfig.sensorId) {
- accessory.getService(Service.GarageDoorOpener)
- .updateCharacteristic(Characteristic.CurrentDoorState, newPos)
- .updateCharacteristic(Characteristic.TargetDoorState, newPos - 2);
- setTimeout(() => {
- accessory.getService(Service.GarageDoorOpener).updateCharacteristic(Characteristic.CurrentDoorState, newPos - 2);
- }, parseInt(garageConfig.operationTime) * 100);
- }
- setTimeout(() => {
- accessory.context.inUse = false;
- }, parseInt(garageConfig.operationTime) * 100);
- } catch (err) {
- accessory.context.inUse = false;
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- externalLockUpdate(accessory, params) {
- try {
- let lockConfig;
- if (!(lockConfig = this.cusG.get(accessory.context.hbDeviceId))) {
- throw "group config missing";
- }
- if (lockConfig.type !== "lock") {
- throw "improper configuration";
- }
- if (params.switch === "off" || accessory.context.inUse) {
+ }
+ nSte =
+ accessory.getService(Service.WindowCovering).getCharacteristic(Characteristic.PositionState).value === 0
+ ? 1
+ : 0;
+ break;
+ case "twoSwitch":
+ if (params.switches[0].switch === "off" && params.switches[1].switch === "off") {
return;
- }
- accessory.context.inUse = true;
- accessory.getService(Service.LockMechanism)
- .updateCharacteristic(Characteristic.LockCurrentState, 0)
- .updateCharacteristic(Characteristic.LockTargetState, 0);
- setTimeout(() => {
- accessory.getService(Service.LockMechanism)
- .updateCharacteristic(Characteristic.LockCurrentState, 1)
- .updateCharacteristic(Characteristic.LockTargetState, 1);
- accessory.context.inUse = false;
- }, parseInt(lockConfig.operationTime) * 100);
- } catch (err) {
- accessory.context.inUse = false;
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- externalSensorUpdate(accessory, params) {
- try {
- let newState = params.switch === "on" ? 1 : 0,
- oAccessory = false;
- accessory.getService(Service.ContactSensor).updateCharacteristic(Characteristic.ContactSensorState, newState);
- if (params.hasOwnProperty("battery")) {
- let batteryService = accessory.getService(Service.BatteryService) || accessory.addService(Service.BatteryService);
- batteryService.updateCharacteristic(Characteristic.BatteryLevel, params.battery);
- batteryService.updateCharacteristic(Characteristic.StatusLowBattery, params.battery <= 25);
- }
- this.cusG.forEach(group => {
- if (group.sensorId === accessory.context.eweDeviceId && group.type === "garage") {
- if ((oAccessory = this.devicesInHB.get(group.deviceId + "SWX"))) {
- switch (newState) {
- case 0:
- oAccessory.getService(Service.GarageDoorOpener)
- .updateCharacteristic(Characteristic.TargetDoorState, 1)
- .updateCharacteristic(Characteristic.CurrentDoorState, 1);
- break;
- case 1:
- setTimeout(() => {
- oAccessory.getService(Service.GarageDoorOpener)
- .updateCharacteristic(Characteristic.TargetDoorState, 0)
- .updateCharacteristic(Characteristic.CurrentDoorState, 0);
- }, group.operationTime * 100);
- break;
- default:
- throw "unknown sensor status received [" + newState + "]";
- }
- }
+ }
+ let switchUp = params.switches[0].switch === "on" ? -1 : 0, // matrix of numbers to get
+ switchDown = params.switches[1].switch === "on" ? 0 : 2; // ... the correct HomeKit value
+ nSte = switchUp + switchDown;
+ break;
+ }
+ accessory
+ .getService(Service.WindowCovering)
+ .updateCharacteristic(Characteristic.PositionState, nSte)
+ .updateCharacteristic(Characteristic.TargetPosition, nSte * 100);
+ setTimeout(() => {
+ accessory
+ .getService(Service.WindowCovering)
+ .updateCharacteristic(Characteristic.PositionState, 2)
+ .updateCharacteristic(Characteristic.CurrentPosition, nSte * 100);
+ }, parseInt(blindConfig.operationTime) * 100);
+ } catch (err) {
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
+ externalGarageUpdate(accessory, params) {
+ try {
+ let garageConfig,
+ oldPos = accessory.getService(Service.GarageDoorOpener).getCharacteristic(Characteristic.CurrentDoorState)
+ .value,
+ newPos = [0, 2].includes(oldPos) ? 3 : 2;
+ if (!(garageConfig = this.cusG.get(accessory.context.hbDeviceId))) {
+ throw "group config missing";
+ }
+ if (garageConfig.type !== "garage" || !["oneSwitch", "twoSwitch"].includes(garageConfig.setup)) {
+ throw "improper configuration";
+ }
+ if (accessory.context.inUse || garageConfig.sensorId) {
+ return;
+ }
+ switch (garageConfig.setup) {
+ case "oneSwitch":
+ if (params.switch === "off") {
+ return;
+ }
+ break;
+ case "twoSwitch":
+ if (params.switches[0].switch === params.switches[1].switch || params.switches[oldPos % 2].switch === "on") {
+ return;
+ }
+ break;
+ }
+ accessory.context.inUse = true;
+ if (!garageConfig.sensorId) {
+ accessory
+ .getService(Service.GarageDoorOpener)
+ .updateCharacteristic(Characteristic.CurrentDoorState, newPos)
+ .updateCharacteristic(Characteristic.TargetDoorState, newPos - 2);
+ setTimeout(() => {
+ accessory
+ .getService(Service.GarageDoorOpener)
+ .updateCharacteristic(Characteristic.CurrentDoorState, newPos - 2);
+ }, parseInt(garageConfig.operationTime) * 100);
+ }
+ setTimeout(() => {
+ accessory.context.inUse = false;
+ }, parseInt(garageConfig.operationTime) * 100);
+ } catch (err) {
+ accessory.context.inUse = false;
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
+ externalLockUpdate(accessory, params) {
+ try {
+ let lockConfig;
+ if (!(lockConfig = this.cusG.get(accessory.context.hbDeviceId))) {
+ throw "group config missing";
+ }
+ if (lockConfig.type !== "lock") {
+ throw "improper configuration";
+ }
+ if (params.switch === "off" || accessory.context.inUse) {
+ return;
+ }
+ accessory.context.inUse = true;
+ accessory
+ .getService(Service.LockMechanism)
+ .updateCharacteristic(Characteristic.LockCurrentState, 0)
+ .updateCharacteristic(Characteristic.LockTargetState, 0);
+ setTimeout(() => {
+ accessory
+ .getService(Service.LockMechanism)
+ .updateCharacteristic(Characteristic.LockCurrentState, 1)
+ .updateCharacteristic(Characteristic.LockTargetState, 1);
+ accessory.context.inUse = false;
+ }, parseInt(lockConfig.operationTime) * 100);
+ } catch (err) {
+ accessory.context.inUse = false;
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
+ externalSensorUpdate(accessory, params) {
+ try {
+ let newState = params.switch === "on" ? 1 : 0,
+ oAccessory = false;
+ accessory.getService(Service.ContactSensor).updateCharacteristic(Characteristic.ContactSensorState, newState);
+ if (params.hasOwnProperty("battery")) {
+ let batteryService =
+ accessory.getService(Service.BatteryService) || accessory.addService(Service.BatteryService);
+ batteryService.updateCharacteristic(Characteristic.BatteryLevel, params.battery);
+ batteryService.updateCharacteristic(Characteristic.StatusLowBattery, params.battery <= 25);
+ }
+ this.cusG.forEach(group => {
+ if (group.sensorId === accessory.context.eweDeviceId && group.type === "garage") {
+ if ((oAccessory = this.devicesInHB.get(group.deviceId + "SWX"))) {
+ switch (newState) {
+ case 0:
+ oAccessory
+ .getService(Service.GarageDoorOpener)
+ .updateCharacteristic(Characteristic.TargetDoorState, 1)
+ .updateCharacteristic(Characteristic.CurrentDoorState, 1);
+ break;
+ case 1:
+ setTimeout(() => {
+ oAccessory
+ .getService(Service.GarageDoorOpener)
+ .updateCharacteristic(Characteristic.TargetDoorState, 0)
+ .updateCharacteristic(Characteristic.CurrentDoorState, 0);
+ }, group.operationTime * 100);
+ break;
+ default:
+ throw "unknown sensor status received [" + newState + "]";
}
- });
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- externalFanUpdate(accessory, params) {
- try {
- let light, status, speed;
- if (Array.isArray(params.switches)) {
- light = params.switches[0].switch === "on";
- switch (params.switches[1].switch+params.switches[2].switch+params.switches[3].switch) {
- default:
- status = 0;
- speed = 0;
- break;
- case "onoffoff":
- status = 1;
- speed = 33;
- break;
- case "ononoff":
- status = 1;
- speed = 66;
- break;
- case "onoffon":
- status = 1;
- speed = 99;
+ }
+ }
+ });
+ } catch (err) {
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
+ externalFanUpdate(accessory, params) {
+ try {
+ let light, status, speed;
+ if (Array.isArray(params.switches)) {
+ light = params.switches[0].switch === "on";
+ switch (params.switches[1].switch + params.switches[2].switch + params.switches[3].switch) {
+ default:
+ status = 0;
+ speed = 0;
+ break;
+ case "onoffoff":
+ status = 1;
+ speed = 33;
+ break;
+ case "ononoff":
+ status = 1;
+ speed = 66;
+ break;
+ case "onoffon":
+ status = 1;
+ speed = 99;
+ }
+ } else if (params.hasOwnProperty("light") && params.hasOwnProperty("fan") && params.hasOwnProperty("speed")) {
+ light = params.light === "on";
+ status = params.fan === "on" ? 1 : 0;
+ speed = params.speed * 33 * status;
+ } else {
+ throw "unknown parameters received";
+ }
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, light);
+ accessory
+ .getService(Service.Fanv2)
+ .updateCharacteristic(Characteristic.Active, status)
+ .updateCharacteristic(Characteristic.RotationSpeed, speed);
+ } catch (err) {
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
+ externalThermostatUpdate(accessory, params) {
+ try {
+ if (!this.config.hideTHSwitch && (params.hasOwnProperty("switch") || params.hasOwnProperty("mainSwitch"))) {
+ let newState = params.hasOwnProperty("switch") ? params.switch === "on" : params.mainSwitch === "on";
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, newState);
+ }
+ let eveLog = {
+ time: Date.now(),
+ };
+ if (params.hasOwnProperty("currentTemperature") && accessory.getService(Service.TemperatureSensor)) {
+ let currentTemp = params.currentTemperature !== "unavailable" ? params.currentTemperature : 0;
+ accessory
+ .getService(Service.TemperatureSensor)
+ .updateCharacteristic(Characteristic.CurrentTemperature, currentTemp);
+ eveLog.temp = parseFloat(currentTemp);
+ }
+ if (params.hasOwnProperty("currentHumidity") && accessory.getService(Service.HumiditySensor)) {
+ let currentHumi = params.currentHumidity !== "unavailable" ? params.currentHumidity : 0;
+ accessory
+ .getService(Service.HumiditySensor)
+ .updateCharacteristic(Characteristic.CurrentRelativeHumidity, currentHumi);
+ eveLog.humidity = parseFloat(currentHumi);
+ }
+ if (eveLog.hasOwnProperty("temp") || eveLog.hasOwnProperty("humidity")) {
+ accessory.eveLogger.addEntry(eveLog);
+ }
+ } catch (err) {
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
+ externalOutletUpdate(accessory, params) {
+ try {
+ if (params.hasOwnProperty("switch")) {
+ accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, params.switch === "on");
+ }
+ if (params.hasOwnProperty("power")) {
+ accessory
+ .getService(Service.Outlet)
+ .updateCharacteristic(EveService.Characteristics.CurrentConsumption, parseFloat(params.power));
+ accessory
+ .getService(Service.Outlet)
+ .updateCharacteristic(Characteristic.OutletInUse, parseFloat(params.power) > 0);
+ let isOn = accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On).value;
+ accessory.eveLogger.addEntry({
+ time: Date.now(),
+ power: isOn ? parseFloat(params.power) : 0,
+ });
+ }
+ if (params.hasOwnProperty("voltage")) {
+ accessory
+ .getService(Service.Outlet)
+ .updateCharacteristic(EveService.Characteristics.Voltage, parseFloat(params.voltage));
+ }
+ if (params.hasOwnProperty("current")) {
+ accessory
+ .getService(Service.Outlet)
+ .updateCharacteristic(EveService.Characteristics.ElectricCurrent, parseFloat(params.current));
+ }
+ } catch (err) {
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
+ externalUSBUpdate(accessory, params) {
+ try {
+ accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, params.switches[0].switch === "on");
+ } catch (err) {
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
+ externalSCMUpdate(accessory, params) {
+ try {
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, params.switches[0].switch === "on");
+ } catch (err) {
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
+ externalSingleLightUpdate(accessory, params) {
+ try {
+ let newColour,
+ mode,
+ isOn = false;
+ if (accessory.context.eweUIID === 22 && params.hasOwnProperty("state")) {
+ isOn = params.state === "on";
+ } else if (accessory.context.eweUIID !== 22 && params.hasOwnProperty("switch")) {
+ isOn = params.switch === "on";
+ } else {
+ isOn = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value;
+ }
+ if (isOn) {
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, true);
+ switch (accessory.context.eweUIID) {
+ case 36: // KING-M4
+ if (params.hasOwnProperty("bright")) {
+ let nb = Math.round(((params.bright - 10) * 10) / 9); // eWeLink scale is 10-100 and HomeKit scale is 0-100.
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Brightness, nb);
}
- } else if (params.hasOwnProperty("light") && params.hasOwnProperty("fan") && params.hasOwnProperty("speed")) {
- light = params.light === "on";
- status = params.fan === "on" ? 1 : 0;
- speed = params.speed * 33 * status;
- } else {
- throw "unknown parameters received";
- }
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, light);
- accessory.getService(Service.Fanv2)
- .updateCharacteristic(Characteristic.Active, status)
- .updateCharacteristic(Characteristic.RotationSpeed, speed);
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- externalThermostatUpdate(accessory, params) {
- try {
- if (!this.config.hideTHSwitch && (params.hasOwnProperty("switch") || params.hasOwnProperty("mainSwitch"))) {
- let newState = params.hasOwnProperty("switch") ? params.switch === "on" : params.mainSwitch === "on";
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, newState);
- }
- let eveLog = {
- time: Date.now()
- };
- if (params.hasOwnProperty("currentTemperature") && accessory.getService(Service.TemperatureSensor)) {
- let currentTemp = params.currentTemperature !== "unavailable" ? params.currentTemperature : 0;
- accessory.getService(Service.TemperatureSensor).updateCharacteristic(Characteristic.CurrentTemperature, currentTemp);
- eveLog.temp = parseFloat(currentTemp);
- }
- if (params.hasOwnProperty("currentHumidity") && accessory.getService(Service.HumiditySensor)) {
- let currentHumi = params.currentHumidity !== "unavailable" ? params.currentHumidity : 0;
- accessory.getService(Service.HumiditySensor).updateCharacteristic(Characteristic.CurrentRelativeHumidity, currentHumi);
- eveLog.humidity = parseFloat(currentHumi);
- }
- if (eveLog.hasOwnProperty("temp") || eveLog.hasOwnProperty("humidity")) {
- accessory.eveLogger.addEntry(eveLog);
- }
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- externalOutletUpdate(accessory, params) {
- try {
- if (params.hasOwnProperty("switch")) {
- accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, params.switch === "on");
- }
- if (params.hasOwnProperty("power")) {
- accessory.getService(Service.Outlet).updateCharacteristic(EveService.Characteristics.CurrentConsumption, parseFloat(params.power));
- accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.OutletInUse, parseFloat(params.power) > 0);
- let isOn = accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On).value;
- accessory.eveLogger.addEntry({
- time: Date.now(),
- power: isOn ? parseFloat(params.power) : 0
- });
- }
- if (params.hasOwnProperty("voltage")) {
- accessory.getService(Service.Outlet).updateCharacteristic(EveService.Characteristics.Voltage, parseFloat(params.voltage));
- }
- if (params.hasOwnProperty("current")) {
- accessory.getService(Service.Outlet).updateCharacteristic(EveService.Characteristics.ElectricCurrent, parseFloat(params.current));
- }
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- externalUSBUpdate(accessory, params) {
- try {
- accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, params.switches[0].switch === "on");
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- externalSCMUpdate(accessory, params) {
- try {
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, params.switches[0].switch === "on");
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- externalSingleLightUpdate(accessory, params) {
- try {
- let newColour, mode, isOn = false;
- if (accessory.context.eweUIID === 22 && params.hasOwnProperty("state")) {
- isOn = params.state === "on";
- } else if (accessory.context.eweUIID !== 22 && params.hasOwnProperty("switch")) {
- isOn = params.switch === "on";
- } else {
- isOn = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value;
- }
- if (isOn) {
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, true);
- switch (accessory.context.eweUIID) {
- case 36: // KING-M4
- if (params.hasOwnProperty("bright")) {
- let nb = Math.round((params.bright - 10) * 10 / 9); // eWeLink scale is 10-100 and HomeKit scale is 0-100.
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Brightness, nb);
- }
- break;
- case 44: // D1
- if (params.hasOwnProperty("brightness")) {
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Brightness, params.brightness);
- }
- break;
- case 22: // B1
- if (params.hasOwnProperty("zyx_mode")) {
- mode = parseInt(params.zyx_mode);
- } else if (params.hasOwnProperty("channel0") && (parseInt(params.channel0) + parseInt(params.channel1) > 0)) {
- mode = 1;
- } else {
- mode = 2;
- }
- if (mode === 2) {
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, true);
- newColour = convert.rgb.hsv(parseInt(params.channel2), parseInt(params.channel3), parseInt(params.channel4));
- accessory.getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.Hue, newColour[0])
- .updateCharacteristic(Characteristic.Saturation, 100)
- .updateCharacteristic(Characteristic.Brightness, 100);
- } else if (mode === 1) {
- throw "has been set to white mode which is not supported";
- }
- break;
- case 59: // L1
- if (params.hasOwnProperty("bright")) {
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Brightness, params.bright);
- }
- if (params.hasOwnProperty("colorR")) {
- newColour = convert.rgb.hsv(params.colorR, params.colorG, params.colorB);
- accessory.getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.Hue, newColour[0])
- .updateCharacteristic(Characteristic.Saturation, newColour[1]);
- }
- break;
- default:
- return;
+ break;
+ case 44: // D1
+ if (params.hasOwnProperty("brightness")) {
+ accessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.Brightness, params.brightness);
}
- } else {
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, false);
- }
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- externalMultiLightUpdate(accessory, params) {
- try {
- let idToCheck = accessory.context.hbDeviceId.slice(0, -1),
- primaryState = false;
- for (let i = 1; i <= accessory.context.channelCount; i++) {
- if (this.devicesInHB.has(idToCheck + i)) {
- let oAccessory = this.devicesInHB.get(idToCheck + i);
- oAccessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, params.switches[i - 1].switch === "on");
- if (params.switches[i - 1].switch === "on") {
- primaryState = true;
- }
+ break;
+ case 22: // B1
+ if (params.hasOwnProperty("zyx_mode")) {
+ mode = parseInt(params.zyx_mode);
+ } else if (params.hasOwnProperty("channel0") && parseInt(params.channel0) + parseInt(params.channel1) > 0) {
+ mode = 1;
+ } else {
+ mode = 2;
}
- }
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, primaryState);
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- externalSingleSwitchUpdate(accessory, params) {
- try {
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, params.switch === "on");
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- externalMultiSwitchUpdate(accessory, params) {
- try {
- let idToCheck = accessory.context.hbDeviceId.slice(0, -1),
- primaryState = false;
- for (let i = 1; i <= accessory.context.channelCount; i++) {
- if (this.devicesInHB.has(idToCheck + i)) {
- let oAccessory = this.devicesInHB.get(idToCheck + i);
- oAccessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, params.switches[i - 1].switch === "on");
- if (params.switches[i - 1].switch === "on") {
- primaryState = true;
- }
+ if (mode === 2) {
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, true);
+ newColour = convert.rgb.hsv(
+ parseInt(params.channel2),
+ parseInt(params.channel3),
+ parseInt(params.channel4)
+ );
+ accessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.Hue, newColour[0])
+ .updateCharacteristic(Characteristic.Saturation, 100)
+ .updateCharacteristic(Characteristic.Brightness, 100);
+ } else if (mode === 1) {
+ throw "has been set to white mode which is not supported";
}
- }
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, primaryState);
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- externalRFDeviceUpdate(accessory, params) {
- try {
- if (!params.hasOwnProperty("updateSource")) return;
- let idToCheck = accessory.context.hbDeviceId.slice(0, -1),
- timeNow = new Date();
- if (params.hasOwnProperty("cmd") && params.cmd === "transmit" && params.hasOwnProperty("rfChl")) { // RF Button
- let bAccessory;
- if ((bAccessory = this.devicesInHB.get(idToCheck + accessory.context.rfChlMap[params.rfChl]))) {
- bAccessory.getService(bAccessory.context.rfChls[params.rfChl]).updateCharacteristic(Characteristic.On, 1);
- setTimeout(() => bAccessory.getService(bAccessory.context.rfChls[params.rfChl]).updateCharacteristic(Characteristic.On, 0), 3000);
- } else {
- throw "rf button not found in Homebridge";
+ break;
+ case 59: // L1
+ if (params.hasOwnProperty("bright")) {
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Brightness, params.bright);
}
- } else if (params.hasOwnProperty("cmd") && params.cmd === "trigger") { // RF Sensor
- Object.keys(params)
- .filter(name => /rfTrig/.test(name))
- .forEach(chan => {
- let chanNum = chan.substr(-1).toString(),
- accessoryNum = accessory.context.rfChlMap[chanNum],
- oAccessory;
- if ((oAccessory = this.devicesInHB.get(idToCheck + accessoryNum))) {
- let timeOfMotion = new Date(params[chan]),
- timeDifference = (timeNow.getTime() - timeOfMotion.getTime()) / 1000;
- if (timeDifference < (this.config.sensorTimeDifference || 120)) {
- switch (oAccessory.context.sensorType) {
- case "button":
- break;
- case "water":
- oAccessory.getService(Service.LeakSensor).updateCharacteristic(Characteristic.LeakDetected, 1);
- setTimeout(() => {
- oAccessory.getService(Service.LeakSensor).updateCharacteristic(Characteristic.LeakDetected, 0);
- }, (this.config.sensorTimeLength || 2) * 1000);
- break;
- case "fire":
- case "smoke":
- oAccessory.getService(Service.SmokeSensor).updateCharacteristic(Characteristic.SmokeDetected, 1);
- setTimeout(() => {
- oAccessory.getService(Service.SmokeSensor).updateCharacteristic(Characteristic.SmokeDetected, 0);
- }, (this.config.sensorTimeLength || 2) * 1000);
- break;
- case "co":
- oAccessory.getService(Service.CarbonMonoxideSensor).updateCharacteristic(Characteristic.CarbonMonoxideDetected, 1);
- setTimeout(() => {
- oAccessory.getService(Service.CarbonMonoxideSensor).updateCharacteristic(Characteristic.CarbonMonoxideDetected, 0);
- }, (this.config.sensorTimeLength || 2) * 1000);
- break;
- case "co2":
- oAccessory.getService(Service.CarbonDioxideSensor).updateCharacteristic(Characteristic.CarbonDioxideDetected, 1);
- setTimeout(() => {
- oAccessory.getService(Service.CarbonDioxideSensor).updateCharacteristic(Characteristic.CarbonDioxideDetected, 0);
- }, (this.config.sensorTimeLength || 2) * 1000);
- break;
- case "contact":
- oAccessory.getService(Service.ContactSensor).updateCharacteristic(Characteristic.ContactSensorState, 1);
- setTimeout(() => {
- oAccessory.getService(Service.ContactSensor).updateCharacteristic(Characteristic.ContactSensorState, 0);
- }, (this.config.sensorTimeLength || 2) * 1000);
- break;
- case "occupancy":
- oAccessory.getService(Service.OccupancySensor).updateCharacteristic(Characteristic.OccupancyDetected, 1);
- setTimeout(() => {
- oAccessory.getService(Service.OccupancySensor).updateCharacteristic(Characteristic.OccupancyDetected, 0);
- }, (this.config.sensorTimeLength || 2) * 1000);
- break;
- default:
- oAccessory.getService(Service.MotionSensor).updateCharacteristic(Characteristic.MotionDetected, true);
- setTimeout(() => {
- oAccessory.getService(Service.MotionSensor).updateCharacteristic(Characteristic.MotionDetected, false);
- }, (this.config.sensorTimeLength || 2) * 1000);
- break;
- }
- if (this.debug) {
- this.log("[%s] has detected [%s].", oAccessory.displayName, oAccessory.context.sensorType);
- }
- }
- }
- });
- }
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- externalZBDeviceUpdate(accessory, params) {
- try { //*** credit @tasict ***\\
- if (params.hasOwnProperty("battery")) {
- let batteryService = accessory.getService(Service.BatteryService) || accessory.addService(Service.BatteryService);
- batteryService.updateCharacteristic(Characteristic.BatteryLevel, params.battery);
- batteryService.updateCharacteristic(Characteristic.StatusLowBattery, params.battery <= 25);
- }
- switch (accessory.context.eweUIID) {
- case 1000:
- if (params.hasOwnProperty("key") && [0, 1, 2].includes(params.key)) {
- accessory.getService(Service.StatelessProgrammableSwitch).updateCharacteristic(Characteristic.ProgrammableSwitchEvent, params.key);
- }
- break;
- case 1770:
- let eveLog = {
- time: Date.now()
- };
- if (params.hasOwnProperty("temperature")) {
- let currentTemp = parseInt(params.temperature) / 100;
- accessory.getService(Service.TemperatureSensor).updateCharacteristic(Characteristic.CurrentTemperature, currentTemp);
- eveLog.temp = parseFloat(currentTemp);
- }
- if (params.hasOwnProperty("humidity")) {
- let currentHumi = parseInt(params.humidity) / 100;
- accessory.getService(Service.HumiditySensor).updateCharacteristic(Characteristic.CurrentRelativeHumidity, currentHumi);
- eveLog.humidity = parseFloat(currentHumi);
- }
- if (eveLog.hasOwnProperty("temp") || eveLog.hasOwnProperty("humidity")) {
- accessory.eveLogger.addEntry(eveLog);
- }
- break;
- case 2026:
- if (params.hasOwnProperty("motion") && params.motion === 1 && params.hasOwnProperty("trigTime")) {
- let timeNow = new Date(),
- timeDifference = (timeNow.getTime() - params.trigTime) / 1000;
- if (timeDifference < (this.config.sensorTimeDifference || 120)) {
- accessory.getService(Service.MotionSensor).updateCharacteristic(Characteristic.MotionDetected, 1);
- setTimeout(() => {
- accessory.getService(Service.MotionSensor).updateCharacteristic(Characteristic.MotionDetected, 0);
- }, (this.config.sensorTimeLength || 2) * 1000);
- }
- break;
- }
- break;
- case 3026:
- if (params.hasOwnProperty("lock") && [0, 1].includes(params.lock)) {
- accessory.getService(Service.ContactSensor).updateCharacteristic(Characteristic.ContactSensorState, params.lock);
- }
- break;
- }
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
+ if (params.hasOwnProperty("colorR")) {
+ newColour = convert.rgb.hsv(params.colorR, params.colorG, params.colorB);
+ accessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.Hue, newColour[0])
+ .updateCharacteristic(Characteristic.Saturation, newColour[1]);
+ }
+ break;
+ default:
+ return;
+ }
+ } else {
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, false);
+ }
+ } catch (err) {
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
+ externalMultiLightUpdate(accessory, params) {
+ try {
+ let idToCheck = accessory.context.hbDeviceId.slice(0, -1),
+ primaryState = false;
+ for (let i = 1; i <= accessory.context.channelCount; i++) {
+ if (this.devicesInHB.has(idToCheck + i)) {
+ let oAccessory = this.devicesInHB.get(idToCheck + i);
+ oAccessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.On, params.switches[i - 1].switch === "on");
+ if (params.switches[i - 1].switch === "on") {
+ primaryState = true;
+ }
+ }
+ }
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, primaryState);
+ } catch (err) {
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
+ externalSingleSwitchUpdate(accessory, params) {
+ try {
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, params.switch === "on");
+ } catch (err) {
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
+ externalMultiSwitchUpdate(accessory, params) {
+ try {
+ let idToCheck = accessory.context.hbDeviceId.slice(0, -1),
+ primaryState = false;
+ for (let i = 1; i <= accessory.context.channelCount; i++) {
+ if (this.devicesInHB.has(idToCheck + i)) {
+ let oAccessory = this.devicesInHB.get(idToCheck + i);
+ oAccessory
+ .getService(Service.Switch)
+ .updateCharacteristic(Characteristic.On, params.switches[i - 1].switch === "on");
+ if (params.switches[i - 1].switch === "on") {
+ primaryState = true;
+ }
+ }
+ }
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, primaryState);
+ } catch (err) {
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
+ externalRFDeviceUpdate(accessory, params) {
+ try {
+ if (!params.hasOwnProperty("updateSource")) return;
+ let idToCheck = accessory.context.hbDeviceId.slice(0, -1),
+ timeNow = new Date();
+ if (params.hasOwnProperty("cmd") && params.cmd === "transmit" && params.hasOwnProperty("rfChl")) {
+ // RF Button
+ let bAccessory;
+ if ((bAccessory = this.devicesInHB.get(idToCheck + accessory.context.rfChlMap[params.rfChl]))) {
+ bAccessory.getService(bAccessory.context.rfChls[params.rfChl]).updateCharacteristic(Characteristic.On, 1);
+ setTimeout(
+ () =>
+ bAccessory.getService(bAccessory.context.rfChls[params.rfChl]).updateCharacteristic(Characteristic.On, 0),
+ 3000
+ );
+ } else {
+ throw "rf button not found in Homebridge";
+ }
+ } else if (params.hasOwnProperty("cmd") && params.cmd === "trigger") {
+ // RF Sensor
+ Object.keys(params)
+ .filter(name => /rfTrig/.test(name))
+ .forEach(chan => {
+ let chanNum = chan.substr(-1).toString(),
+ accessoryNum = accessory.context.rfChlMap[chanNum],
+ oAccessory;
+ if ((oAccessory = this.devicesInHB.get(idToCheck + accessoryNum))) {
+ let timeOfMotion = new Date(params[chan]),
+ diff = (timeNow.getTime() - timeOfMotion.getTime()) / 1000;
+ if (diff < (this.config.sensorTimeDifference || 120)) {
+ switch (oAccessory.context.sensorType) {
+ case "button":
+ break;
+ case "water":
+ oAccessory.getService(Service.LeakSensor).updateCharacteristic(Characteristic.LeakDetected, 1);
+ setTimeout(() => {
+ oAccessory.getService(Service.LeakSensor).updateCharacteristic(Characteristic.LeakDetected, 0);
+ }, (this.config.sensorTimeLength || 2) * 1000);
+ break;
+ case "fire":
+ case "smoke":
+ oAccessory.getService(Service.SmokeSensor).updateCharacteristic(Characteristic.SmokeDetected, 1);
+ setTimeout(() => {
+ oAccessory.getService(Service.SmokeSensor).updateCharacteristic(Characteristic.SmokeDetected, 0);
+ }, (this.config.sensorTimeLength || 2) * 1000);
+ break;
+ case "co":
+ oAccessory
+ .getService(Service.CarbonMonoxideSensor)
+ .updateCharacteristic(Characteristic.CarbonMonoxideDetected, 1);
+ setTimeout(() => {
+ oAccessory
+ .getService(Service.CarbonMonoxideSensor)
+ .updateCharacteristic(Characteristic.CarbonMonoxideDetected, 0);
+ }, (this.config.sensorTimeLength || 2) * 1000);
+ break;
+ case "co2":
+ oAccessory
+ .getService(Service.CarbonDioxideSensor)
+ .updateCharacteristic(Characteristic.CarbonDioxideDetected, 1);
+ setTimeout(() => {
+ oAccessory
+ .getService(Service.CarbonDioxideSensor)
+ .updateCharacteristic(Characteristic.CarbonDioxideDetected, 0);
+ }, (this.config.sensorTimeLength || 2) * 1000);
+ break;
+ case "contact":
+ oAccessory
+ .getService(Service.ContactSensor)
+ .updateCharacteristic(Characteristic.ContactSensorState, 1);
+ setTimeout(() => {
+ oAccessory
+ .getService(Service.ContactSensor)
+ .updateCharacteristic(Characteristic.ContactSensorState, 0);
+ }, (this.config.sensorTimeLength || 2) * 1000);
+ break;
+ case "occupancy":
+ oAccessory
+ .getService(Service.OccupancySensor)
+ .updateCharacteristic(Characteristic.OccupancyDetected, 1);
+ setTimeout(() => {
+ oAccessory
+ .getService(Service.OccupancySensor)
+ .updateCharacteristic(Characteristic.OccupancyDetected, 0);
+ }, (this.config.sensorTimeLength || 2) * 1000);
+ break;
+ default:
+ oAccessory
+ .getService(Service.MotionSensor)
+ .updateCharacteristic(Characteristic.MotionDetected, true);
+ setTimeout(() => {
+ oAccessory
+ .getService(Service.MotionSensor)
+ .updateCharacteristic(Characteristic.MotionDetected, false);
+ }, (this.config.sensorTimeLength || 2) * 1000);
+ break;
+ }
+ if (this.debug) {
+ this.log("[%s] has detected [%s].", oAccessory.displayName, oAccessory.context.sensorType);
+ }
+ }
+ }
+ });
+ }
+ } catch (err) {
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
+ externalZBDeviceUpdate(accessory, params) {
+ try {
+ //*** credit @tasict ***\\
+ if (params.hasOwnProperty("battery")) {
+ let batteryService =
+ accessory.getService(Service.BatteryService) || accessory.addService(Service.BatteryService);
+ batteryService.updateCharacteristic(Characteristic.BatteryLevel, params.battery);
+ batteryService.updateCharacteristic(Characteristic.StatusLowBattery, params.battery <= 25);
+ }
+ switch (accessory.context.eweUIID) {
+ case 1000:
+ if (params.hasOwnProperty("key") && [0, 1, 2].includes(params.key)) {
+ accessory
+ .getService(Service.StatelessProgrammableSwitch)
+ .updateCharacteristic(Characteristic.ProgrammableSwitchEvent, params.key);
+ }
+ break;
+ case 1770:
+ let eveLog = {
+ time: Date.now(),
+ };
+ if (params.hasOwnProperty("temperature")) {
+ let currentTemp = parseInt(params.temperature) / 100;
+ accessory
+ .getService(Service.TemperatureSensor)
+ .updateCharacteristic(Characteristic.CurrentTemperature, currentTemp);
+ eveLog.temp = parseFloat(currentTemp);
+ }
+ if (params.hasOwnProperty("humidity")) {
+ let currentHumi = parseInt(params.humidity) / 100;
+ accessory
+ .getService(Service.HumiditySensor)
+ .updateCharacteristic(Characteristic.CurrentRelativeHumidity, currentHumi);
+ eveLog.humidity = parseFloat(currentHumi);
+ }
+ if (eveLog.hasOwnProperty("temp") || eveLog.hasOwnProperty("humidity")) {
+ accessory.eveLogger.addEntry(eveLog);
+ }
+ break;
+ case 2026:
+ if (params.hasOwnProperty("motion") && params.hasOwnProperty("trigTime")) {
+ let timeNow = new Date(),
+ diff = (timeNow.getTime() - params.trigTime) / 1000;
+ accessory
+ .getService(Service.MotionSensor)
+ .updateCharacteristic(
+ Characteristic.MotionDetected,
+ params.hasOwnProperty("updateSource") &&
+ params.motion === 1 &&
+ diff < (this.config.sensortimeDifference || 120)
+ );
+ break;
+ }
+ break;
+ case 3026:
+ if (params.hasOwnProperty("lock") && [0, 1].includes(params.lock)) {
+ accessory
+ .getService(Service.ContactSensor)
+ .updateCharacteristic(Characteristic.ContactSensorState, params.lock);
+ }
+ break;
+ }
+ } catch (err) {
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
}
-module.exports = function(homebridge) {
- Accessory = homebridge.platformAccessory;
- Characteristic = homebridge.hap.Characteristic;
- EveService = new hbLib.EveHomeKitTypes(homebridge);
- EveHistoryService = fakegato(homebridge);
- Service = homebridge.hap.Service;
- UUIDGen = homebridge.hap.uuid;
- return eWeLink;
-};
\ No newline at end of file
+module.exports = function (homebridge) {
+ Accessory = homebridge.platformAccessory;
+ Characteristic = homebridge.hap.Characteristic;
+ EveService = new hbLib.EveHomeKitTypes(homebridge);
+ EveHistoryService = fakegato(homebridge);
+ Service = homebridge.hap.Service;
+ UUIDGen = homebridge.hap.uuid;
+ return eWeLink;
+};
diff --git a/lib/eWeLinkHTTP.js b/lib/eWeLinkHTTP.js
index 0382542b..57e12c2f 100644
--- a/lib/eWeLinkHTTP.js
+++ b/lib/eWeLinkHTTP.js
@@ -1,156 +1,176 @@
/* jshint esversion: 9, -W030, node: true */
"use strict";
const axios = require("axios"),
- constants = require("./constants"),
- crypto = require("crypto");
+ constants = require("./constants"),
+ crypto = require("crypto");
module.exports = class eWeLinkHTTP {
- constructor(config, log) {
- this.config = config;
- this.log = log;
- this.debug = this.config.debug || false;
- this.debugReqRes = this.config.debugReqRes || false;
- }
- login() {
- let data = {
- countryCode: "+" + this.config.countryCode.toString().replace("+", "").replace(" ", ""),
- password: this.config.password
- };
- this.config.username.includes("@") ?
- data.email = this.config.username :
- data.phoneNumber = this.config.username;
- if (this.debugReqRes) {
- let msg = JSON.stringify(data, null, 2).replace(this.config.password, "**hidden**").replace(this.config.username, "**hidden**");
- this.log.warn("Sending HTTP login request. This text is yellow for clarity.\n%s", msg);
- } else if (this.debug) {
- this.log("Sending HTTP login request.");
- }
- let dataToSign = crypto.createHmac("sha256", constants.appSecret).update(JSON.stringify(data)).digest("base64");
- return new Promise((resolve, reject) => {
- axios({
- url: "https://" + this.httpHost + "/v2/user/login",
- method: "post",
- headers: {
- Authorization: "Sign " + dataToSign,
- "Content-Type": "application/json",
- Host: this.httpHost,
- "X-CK-Appid": constants.appId,
- "X-CK-Nonce": Math.random().toString(36).substr(2, 8)
- },
- data
- }).then(res => {
- let body = res.data;
- if (body.hasOwnProperty("error") && body.error === 10004 && body.hasOwnProperty("data") && body.data.hasOwnProperty("region")) {
- switch (body.data.region) {
- case "eu":
- case "us":
- case "as":
- this.httpHost = body.data.region + "-apia.coolkit.cc";
- break;
- case "cn":
- this.httpHost = "cn-apia.coolkit.cn";
- break;
- default:
- throw "No valid region received - [" + body.data.region + "].";
- }
- if (this.debug) {
- this.log("New HTTP API host received [%s].", this.httpHost);
- }
- resolve(this.login());
- return;
- }
- if (!body.data.at) {
- throw "Server did not respond with an authentication token. Please double check your eWeLink username and password in the Homebridge configuration.\n" + JSON.stringify(body, null, 2);
- }
- this.aToken = body.data.at;
- this.apiKey = body.data.user.apikey;
- resolve({
- aToken: body.data.at,
- apiKey: body.data.user.apikey,
- httpHost: this.httpHost
- });
- }).catch(err => {
- reject(err);
- });
- });
- }
- getHost() {
- let data = {
- appid: constants.appId,
- country_code: this.config.countryCode.toString().replace("+", "").replace(" ", ""),
- nonce: Math.random().toString(36).substr(2, 8),
- ts: Math.floor(new Date().getTime() / 1000),
- version: 8
- },
- dataToSign = [];
- Object.keys(data).forEach(function(key) {
- dataToSign.push({
- key: key,
- value: data[key]
- });
- });
- dataToSign.sort(function(a, b) {
- return a.key < b.key ? -1 : 1;
- });
- dataToSign = dataToSign.map(function(kv) {
- return kv.key + "=" + kv.value;
- }).join("&");
- dataToSign = crypto.createHmac("sha256", "6Nz4n0xA8s8qdxQf2GqurZj2Fs55FUvM").update(dataToSign).digest("base64");
- return new Promise((resolve, reject) => {
- axios.get("https://api.coolkit.cc:8080/api/user/region", {
- headers: {
- Authorization: "Sign " + dataToSign,
- "Content-Type": "application/json"
- },
- params: data
- }).then(res => {
- let body = res.data;
- if (!body.region) {
- throw "Server did not respond with a region.\n" + JSON.stringify(body, null, 2);
- }
- switch (body.region) {
- case "eu":
- case "us":
- case "as":
- this.httpHost = body.region + "-apia.coolkit.cc";
- break;
- case "cn":
- this.httpHost = "cn-apia.coolkit.cn";
- break;
- default:
- throw "No valid region received - [" + body.region + "].";
+ constructor(config, log) {
+ this.config = config;
+ this.log = log;
+ this.debug = this.config.debug || false;
+ this.debugReqRes = this.config.debugReqRes || false;
+ }
+ login() {
+ let data = {
+ countryCode: "+" + this.config.countryCode.toString().replace("+", "").replace(" ", ""),
+ password: this.config.password,
+ };
+ this.config.username.includes("@")
+ ? (data.email = this.config.username)
+ : (data.phoneNumber = this.config.username);
+ if (this.debugReqRes) {
+ let msg = JSON.stringify(data, null, 2)
+ .replace(this.config.password, "**hidden**")
+ .replace(this.config.username, "**hidden**");
+ this.log.warn("Sending HTTP login request. This text is yellow for clarity.\n%s", msg);
+ } else if (this.debug) {
+ this.log("Sending HTTP login request.");
+ }
+ let dataToSign = crypto.createHmac("sha256", constants.appSecret).update(JSON.stringify(data)).digest("base64");
+ return new Promise((resolve, reject) => {
+ axios({
+ url: "https://" + this.httpHost + "/v2/user/login",
+ method: "post",
+ headers: {
+ Authorization: "Sign " + dataToSign,
+ "Content-Type": "application/json",
+ Host: this.httpHost,
+ "X-CK-Appid": constants.appId,
+ "X-CK-Nonce": Math.random().toString(36).substr(2, 8),
+ },
+ data,
+ })
+ .then(res => {
+ let body = res.data;
+ if (
+ body.hasOwnProperty("error") &&
+ body.error === 10004 &&
+ body.hasOwnProperty("data") &&
+ body.data.hasOwnProperty("region")
+ ) {
+ switch (body.data.region) {
+ case "eu":
+ case "us":
+ case "as":
+ this.httpHost = body.data.region + "-apia.coolkit.cc";
+ break;
+ case "cn":
+ this.httpHost = "cn-apia.coolkit.cn";
+ break;
+ default:
+ throw "No valid region received - [" + body.data.region + "].";
}
if (this.debug) {
- this.log("HTTP API host received [%s].", this.httpHost);
- }
- resolve(this.httpHost);
- }).catch(err => {
- reject(err);
- });
- });
- }
- getDevices() {
- return new Promise((resolve, reject) => {
- axios.get("https://" + this.httpHost + "/v2/device/thing", {
- headers: {
- Authorization: "Bearer " + this.aToken,
- "Content-Type": "application/json",
- Host: this.httpHost,
- "X-CK-Appid": constants.appId,
- "X-CK-Nonce": Math.random().toString(36).substr(2, 8)
- }
- }).then(res => {
- let body = res.data;
- if (!body.hasOwnProperty("error") || (body.hasOwnProperty("error") && body.error !== 0)) {
- throw JSON.stringify(body, null, 2);
- }
- let deviceList = [];
- if (body.data.thingList && body.data.thingList.length > 0) {
- body.data.thingList.forEach(device => deviceList.push(device.itemData));
+ this.log("New HTTP API host received [%s].", this.httpHost);
}
- resolve(deviceList);
- }).catch(err => {
- reject(err);
- });
+ resolve(this.login());
+ return;
+ }
+ if (!body.data.at) {
+ throw (
+ "Server did not respond with an authentication token. Please double check your eWeLink username and password in the Homebridge configuration.\n" +
+ JSON.stringify(body, null, 2)
+ );
+ }
+ this.aToken = body.data.at;
+ this.apiKey = body.data.user.apikey;
+ resolve({
+ aToken: body.data.at,
+ apiKey: body.data.user.apikey,
+ httpHost: this.httpHost,
+ });
+ })
+ .catch(err => {
+ reject(err);
+ });
+ });
+ }
+ getHost() {
+ let data = {
+ appid: constants.appId,
+ country_code: this.config.countryCode.toString().replace("+", "").replace(" ", ""),
+ nonce: Math.random().toString(36).substr(2, 8),
+ ts: Math.floor(new Date().getTime() / 1000),
+ version: 8,
+ },
+ dataToSign = [];
+ Object.keys(data).forEach(function (key) {
+ dataToSign.push({
+ key: key,
+ value: data[key],
});
- }
-};
\ No newline at end of file
+ });
+ dataToSign.sort(function (a, b) {
+ return a.key < b.key ? -1 : 1;
+ });
+ dataToSign = dataToSign
+ .map(function (kv) {
+ return kv.key + "=" + kv.value;
+ })
+ .join("&");
+ dataToSign = crypto.createHmac("sha256", "6Nz4n0xA8s8qdxQf2GqurZj2Fs55FUvM").update(dataToSign).digest("base64");
+ return new Promise((resolve, reject) => {
+ axios
+ .get("https://api.coolkit.cc:8080/api/user/region", {
+ headers: {
+ Authorization: "Sign " + dataToSign,
+ "Content-Type": "application/json",
+ },
+ params: data,
+ })
+ .then(res => {
+ let body = res.data;
+ if (!body.region) {
+ throw "Server did not respond with a region.\n" + JSON.stringify(body, null, 2);
+ }
+ switch (body.region) {
+ case "eu":
+ case "us":
+ case "as":
+ this.httpHost = body.region + "-apia.coolkit.cc";
+ break;
+ case "cn":
+ this.httpHost = "cn-apia.coolkit.cn";
+ break;
+ default:
+ throw "No valid region received - [" + body.region + "].";
+ }
+ if (this.debug) {
+ this.log("HTTP API host received [%s].", this.httpHost);
+ }
+ resolve(this.httpHost);
+ })
+ .catch(err => {
+ reject(err);
+ });
+ });
+ }
+ getDevices() {
+ return new Promise((resolve, reject) => {
+ axios
+ .get("https://" + this.httpHost + "/v2/device/thing", {
+ headers: {
+ Authorization: "Bearer " + this.aToken,
+ "Content-Type": "application/json",
+ Host: this.httpHost,
+ "X-CK-Appid": constants.appId,
+ "X-CK-Nonce": Math.random().toString(36).substr(2, 8),
+ },
+ })
+ .then(res => {
+ let body = res.data;
+ if (!body.hasOwnProperty("error") || (body.hasOwnProperty("error") && body.error !== 0)) {
+ throw JSON.stringify(body, null, 2);
+ }
+ let deviceList = [];
+ if (body.data.thingList && body.data.thingList.length > 0) {
+ body.data.thingList.forEach(device => deviceList.push(device.itemData));
+ }
+ resolve(deviceList);
+ })
+ .catch(err => {
+ reject(err);
+ });
+ });
+ }
+};
diff --git a/lib/eWeLinkLAN.js b/lib/eWeLinkLAN.js
index f6ff9188..2bbbf005 100644
--- a/lib/eWeLinkLAN.js
+++ b/lib/eWeLinkLAN.js
@@ -1,181 +1,196 @@
/* jshint esversion: 9, -W030, node: true */
"use strict";
const axios = require("axios"),
- constants = require("./constants"),
- crypto = require("crypto"),
- dns = require("node-dns-sd"),
- eventemitter = require("events");
+ constants = require("./constants"),
+ crypto = require("crypto"),
+ dns = require("node-dns-sd"),
+ eventemitter = require("events");
module.exports = class eWeLinkLAN {
- constructor(config, log, devices) {
- this.config = config;
- this.log = log;
- this.devices = devices;
- this.ipOverrides = this.config.ipOverride || {};
- let deviceMap = new Map();
- devices.forEach(device => {
- deviceMap.set(device.deviceid, {
- apiKey: device.devicekey,
- online: this.ipOverrides.hasOwnProperty(device.deviceid) ? true : false,
- ip: this.ipOverrides.hasOwnProperty(device.deviceid) ? this.ipOverrides[device.deviceid] : null
- });
+ constructor(config, log, devices) {
+ this.config = config;
+ this.log = log;
+ this.devices = devices;
+ this.ipOverrides = this.config.ipOverride || {};
+ let deviceMap = new Map();
+ devices.forEach(device => {
+ deviceMap.set(device.deviceid, {
+ apiKey: device.devicekey,
+ online: this.ipOverrides.hasOwnProperty(device.deviceid) ? true : false,
+ ip: this.ipOverrides.hasOwnProperty(device.deviceid) ? this.ipOverrides[device.deviceid] : null,
});
- this.deviceMap = deviceMap;
- this.debug = this.config.debug || false;
- this.debugReqRes = this.config.debugReqRes || false;
- this.emitter = new eventemitter();
- }
- getHosts() {
- return new Promise((resolve, reject) => {
- dns.discover({
- name: "_ewelink._tcp.local"
- }).then(res => {
- let onlineCount = 0;
- res.forEach(device => {
- let d, deviceId = device.fqdn.replace("._ewelink._tcp.local", "").replace("eWeLink_", "");
- if ((d = this.deviceMap.get(deviceId))) {
- if (!this.ipOverrides.hasOwnProperty(deviceId)) {
- this.deviceMap.set(deviceId, {
- apiKey: d.apiKey,
- online: true,
- ip: device.address
- });
- }
- onlineCount++;
- }
- });
- resolve({
- map: this.deviceMap,
- count: onlineCount
- });
- }).catch(err => {
- reject(err);
- });
- });
- }
- startMonitor() {
- dns.ondata = packet => {
- if (packet.answers) {
- packet.answers
- .filter(value => value.name.includes("_ewelink._tcp.local"))
- .filter(value => value.type === "TXT")
- .filter(value => this.deviceMap.has(value.rdata.id))
- .forEach(value => {
- let rdata = value.rdata,
- deviceInfo = this.deviceMap.get(rdata.id),
- data = rdata.data1 +
- (rdata.hasOwnProperty("data2") ? rdata.data2 : "") +
- (rdata.hasOwnProperty("data3") ? rdata.data3 : "") +
- (rdata.hasOwnProperty("data4") ? rdata.data4 : ""),
- key = crypto.createHash("md5").update(Buffer.from(deviceInfo.apiKey, "utf8")).digest(),
- dText = crypto.createDecipheriv("aes-128-cbc", key, Buffer.from(rdata.iv, "base64")),
- pText = Buffer.concat([dText.update(Buffer.from(data, "base64")), dText.final()]).toString("utf8"),
- params;
- if (packet.address !== deviceInfo.ip && !this.ipOverrides.hasOwnProperty(rdata.id)) {
- this.deviceMap.set(rdata.id, {
- apiKey: deviceInfo.apiKey,
- online: true,
- ip: packet.address
- });
- if (this.debug) {
- this.log.warn("[%s] updating IP address to [%s].", rdata.id, packet.address);
- }
- }
- try {
- params = JSON.parse(pText);
- } catch (e) {
- this.log.warn("[%s] An error occured reading the LAN message [%s]", rdata.id, e);
- return;
- }
- for (let param in params) {
- if (params.hasOwnProperty(param)) {
- if (!constants.paramsToKeep.includes(param.replace(/[0-9]/g, ""))) {
- delete params[param];
- }
- }
- }
- if (Object.keys(params).length > 0) {
- params.updateSource = "LAN";
- let returnTemplate = {
- deviceid: rdata.id,
- action: "update",
- params
- };
- if (this.debugReqRes) {
- let msg = JSON.stringify(returnTemplate, null, 2).replace(rdata.id, "**hidden**");
- this.log("LAN message received.\n%s", msg);
- } else if (this.debug) {
- this.log("LAN message received.");
- }
- this.emitter.emit("update", returnTemplate);
- }
- });
- }
- };
- return new Promise((resolve, reject) => {
- dns.startMonitoring().then(() => {
- resolve();
- }).catch(err => {
- reject(err);
- });
- });
- }
- sendUpdate(json) {
- return new Promise((resolve, reject) => {
- if (!this.deviceMap.get(json.deviceid).online) {
- throw "device does not support LAN mode";
- }
- let apiKey, suffix, params = {};
- if (json.params.hasOwnProperty("switches")) {
- params.switches = json.params.switches;
- suffix = "switches";
- } else if (json.params.hasOwnProperty("switch")) {
- params.switch = json.params.switch;
- suffix = "switch";
- } else {
- throw "plugin does not support lan mode for this device yet - feel free to create a github issue";
- }
- if ((apiKey = this.deviceMap.get(json.deviceid).apiKey)) {
- let key = crypto.createHash('md5').update(Buffer.from(apiKey, 'utf8')).digest(),
- iv = crypto.randomBytes(16),
- enc = crypto.createCipheriv('aes-128-cbc', key, iv),
- data = {
- data: Buffer.concat([enc.update(JSON.stringify(params)), enc.final()]).toString('base64'),
- deviceid: json.deviceid,
- encrypt: true,
- iv: iv.toString('base64'),
- selfApikey: "123",
- sequence: Date.now().toString()
- };
- if (this.debugReqRes) {
- let msg = JSON.stringify(json, null, 2).replace(json.apikey, "**hidden**").replace(json.apikey, "**hidden**").replace(json.deviceid, "**hidden**");
- this.log.warn("LAN message sent. This text is yellow for clarity.\n%s", msg);
- } else if (this.debug) {
- this.log("LAN message sent.");
+ });
+ this.deviceMap = deviceMap;
+ this.debug = this.config.debug || false;
+ this.debugReqRes = this.config.debugReqRes || false;
+ this.emitter = new eventemitter();
+ }
+ getHosts() {
+ return new Promise((resolve, reject) => {
+ dns
+ .discover({
+ name: "_ewelink._tcp.local",
+ })
+ .then(res => {
+ let onlineCount = 0;
+ res.forEach(device => {
+ let d,
+ deviceId = device.fqdn.replace("._ewelink._tcp.local", "").replace("eWeLink_", "");
+ if ((d = this.deviceMap.get(deviceId))) {
+ if (!this.ipOverrides.hasOwnProperty(deviceId)) {
+ this.deviceMap.set(deviceId, {
+ apiKey: d.apiKey,
+ online: true,
+ ip: device.address,
+ });
+ }
+ onlineCount++;
}
- axios({
- method: "post",
- url: "http://" + this.deviceMap.get(json.deviceid).ip + ":8081/zeroconf/" + suffix,
- headers: {
- Accept: "application/json",
- "Content-Type": "application/json"
- },
- data
- }).then(res => {
- if (res.data.hasOwnProperty("error") && res.data.error === 0) {
- resolve();
- }
- throw res.data;
- }).catch(err => {
- reject(err);
- });
- }
- });
- }
- receiveUpdate(f) {
- this.emitter.addListener("update", f);
- }
- closeConnection() {
- dns.stopMonitoring();
- this.log("LAN monitoring gracefully stopped.");
- }
-};
\ No newline at end of file
+ });
+ resolve({
+ map: this.deviceMap,
+ count: onlineCount,
+ });
+ })
+ .catch(err => {
+ reject(err);
+ });
+ });
+ }
+ startMonitor() {
+ dns.ondata = packet => {
+ if (packet.answers) {
+ packet.answers
+ .filter(value => value.name.includes("_ewelink._tcp.local"))
+ .filter(value => value.type === "TXT")
+ .filter(value => this.deviceMap.has(value.rdata.id))
+ .forEach(value => {
+ let rdata = value.rdata,
+ deviceInfo = this.deviceMap.get(rdata.id),
+ data =
+ rdata.data1 +
+ (rdata.hasOwnProperty("data2") ? rdata.data2 : "") +
+ (rdata.hasOwnProperty("data3") ? rdata.data3 : "") +
+ (rdata.hasOwnProperty("data4") ? rdata.data4 : ""),
+ key = crypto.createHash("md5").update(Buffer.from(deviceInfo.apiKey, "utf8")).digest(),
+ dText = crypto.createDecipheriv("aes-128-cbc", key, Buffer.from(rdata.iv, "base64")),
+ pText = Buffer.concat([dText.update(Buffer.from(data, "base64")), dText.final()]).toString("utf8"),
+ params;
+ if (packet.address !== deviceInfo.ip && !this.ipOverrides.hasOwnProperty(rdata.id)) {
+ this.deviceMap.set(rdata.id, {
+ apiKey: deviceInfo.apiKey,
+ online: true,
+ ip: packet.address,
+ });
+ if (this.debug) {
+ this.log.warn("[%s] updating IP address to [%s].", rdata.id, packet.address);
+ }
+ }
+ try {
+ params = JSON.parse(pText);
+ } catch (e) {
+ this.log.warn("[%s] An error occured reading the LAN message [%s]", rdata.id, e);
+ return;
+ }
+ for (let param in params) {
+ if (params.hasOwnProperty(param)) {
+ if (!constants.paramsToKeep.includes(param.replace(/[0-9]/g, ""))) {
+ delete params[param];
+ }
+ }
+ }
+ if (Object.keys(params).length > 0) {
+ params.updateSource = "LAN";
+ let returnTemplate = {
+ deviceid: rdata.id,
+ action: "update",
+ params,
+ };
+ if (this.debugReqRes) {
+ let msg = JSON.stringify(returnTemplate, null, 2).replace(rdata.id, "**hidden**");
+ this.log("LAN message received.\n%s", msg);
+ } else if (this.debug) {
+ this.log("LAN message received.");
+ }
+ this.emitter.emit("update", returnTemplate);
+ }
+ });
+ }
+ };
+ return new Promise((resolve, reject) => {
+ dns
+ .startMonitoring()
+ .then(() => {
+ resolve();
+ })
+ .catch(err => {
+ reject(err);
+ });
+ });
+ }
+ sendUpdate(json) {
+ return new Promise((resolve, reject) => {
+ if (!this.deviceMap.get(json.deviceid).online) {
+ throw "device does not support LAN mode";
+ }
+ let apiKey,
+ suffix,
+ params = {};
+ if (json.params.hasOwnProperty("switches")) {
+ params.switches = json.params.switches;
+ suffix = "switches";
+ } else if (json.params.hasOwnProperty("switch")) {
+ params.switch = json.params.switch;
+ suffix = "switch";
+ } else {
+ throw "plugin does not support lan mode for this device yet - feel free to create a github issue";
+ }
+ if ((apiKey = this.deviceMap.get(json.deviceid).apiKey)) {
+ let key = crypto.createHash("md5").update(Buffer.from(apiKey, "utf8")).digest(),
+ iv = crypto.randomBytes(16),
+ enc = crypto.createCipheriv("aes-128-cbc", key, iv),
+ data = {
+ data: Buffer.concat([enc.update(JSON.stringify(params)), enc.final()]).toString("base64"),
+ deviceid: json.deviceid,
+ encrypt: true,
+ iv: iv.toString("base64"),
+ selfApikey: "123",
+ sequence: Date.now().toString(),
+ };
+ if (this.debugReqRes) {
+ let msg = JSON.stringify(json, null, 2)
+ .replace(json.apikey, "**hidden**")
+ .replace(json.apikey, "**hidden**")
+ .replace(json.deviceid, "**hidden**");
+ this.log.warn("LAN message sent. This text is yellow for clarity.\n%s", msg);
+ } else if (this.debug) {
+ this.log("LAN message sent.");
+ }
+ axios({
+ method: "post",
+ url: "http://" + this.deviceMap.get(json.deviceid).ip + ":8081/zeroconf/" + suffix,
+ headers: {
+ Accept: "application/json",
+ "Content-Type": "application/json",
+ },
+ data,
+ })
+ .then(res => {
+ if (res.data.hasOwnProperty("error") && res.data.error === 0) {
+ resolve();
+ }
+ throw res.data;
+ })
+ .catch(err => {
+ reject(err);
+ });
+ }
+ });
+ }
+ receiveUpdate(f) {
+ this.emitter.addListener("update", f);
+ }
+ closeConnection() {
+ dns.stopMonitoring();
+ this.log("LAN monitoring gracefully stopped.");
+ }
+};
diff --git a/lib/eWeLinkWS.js b/lib/eWeLinkWS.js
index 9cb70c1c..86f08e3e 100644
--- a/lib/eWeLinkWS.js
+++ b/lib/eWeLinkWS.js
@@ -1,282 +1,299 @@
/* jshint esversion: 9, -W030, node: true */
"use strict";
const axios = require("axios"),
- constants = require("./constants"),
- eventemitter = require("events"),
- ws = require("ws");
+ constants = require("./constants"),
+ eventemitter = require("events"),
+ ws = require("ws");
module.exports = class eWeLinkWS {
- constructor(config, log, res) {
- this.config = config;
- this.log = log;
- this.debug = this.config.debug || false;
- this.debugReqRes = this.config.debugReqRes || false;
- this.httpHost = res.httpHost;
- this.aToken = res.aToken;
- this.apiKey = res.apiKey;
- this.wsIsOpen = false;
- this.emitter = new eventemitter();
- this.delaySend = 0;
- }
- getHost() {
- return new Promise((resolve, reject) => {
- axios({
- method: "post",
- url: "https://" + this.httpHost.replace("-api", "-disp") + "/dispatch/app",
- headers: {
- Authorization: "Bearer " + this.aToken,
- "Content-Type": "application/json"
- },
- data: {
- appid: constants.appId,
- nonce: Math.random().toString(36).substr(2, 8),
- ts: Math.floor(new Date().getTime() / 1000),
- version: 8
- }
- }).then(res => {
- let body = res.data;
- if (!body.domain) {
- throw "Server did not respond with a web socket host.";
- }
- if (this.debug) {
- this.log("Web socket host received [%s].", body.domain);
- }
- this.wsHost = body.domain;
- resolve(body.domain);
- }).catch(err => {
- reject(err);
- });
- });
- }
- login() {
- this.ws = new ws("wss://" + this.wsHost + ":8080/api/ws");
- this.ws.on("open", () => {
- this.wsIsOpen = true;
- let payload = {
- action: "userOnline",
- apikey: this.apiKey,
- appid: constants.appId,
- at: this.aToken,
- nonce: Math.random().toString(36).substr(2, 8),
- sequence: Math.floor(new Date()),
- ts: Math.floor(new Date() / 1000),
- userAgent: "app",
- version: 8
- };
- this.ws.send(JSON.stringify(payload));
- if (this.debugReqRes) {
- let msg = JSON.stringify(payload, null, 2).replace(this.aToken, "**hidden**").replace(this.apiKey, "**hidden**");
- this.log.warn("Sending WS login request. This text is yellow for clarity.\n%s", msg);
- } else if (this.debug) {
- this.log("Sending WS login request.");
- }
- });
- this.ws.on("message", m => {
- if (m === "pong") {
- return;
- }
- let device;
- try {
- device = JSON.parse(m);
- } catch (e) {
- this.log.warn("An error occured reading the web socket message [%s]", e);
- return;
- }
- // for requestUpdate response
- if (device.hasOwnProperty("deviceid") && device.hasOwnProperty("params") && device.hasOwnProperty("error") && device.error === 0) {
- device.action = "update";
- } else if (device.hasOwnProperty("deviceid") && device.hasOwnProperty("error") && device.error === 504) {
- device.action = "sysmsg";
- device.params = {
- online: false
+ constructor(config, log, res) {
+ this.config = config;
+ this.log = log;
+ this.debug = this.config.debug || false;
+ this.debugReqRes = this.config.debugReqRes || false;
+ this.httpHost = res.httpHost;
+ this.aToken = res.aToken;
+ this.apiKey = res.apiKey;
+ this.wsIsOpen = false;
+ this.emitter = new eventemitter();
+ this.delaySend = 0;
+ }
+ getHost() {
+ return new Promise((resolve, reject) => {
+ axios({
+ method: "post",
+ url: "https://" + this.httpHost.replace("-api", "-disp") + "/dispatch/app",
+ headers: {
+ Authorization: "Bearer " + this.aToken,
+ "Content-Type": "application/json",
+ },
+ data: {
+ appid: constants.appId,
+ nonce: Math.random().toString(36).substr(2, 8),
+ ts: Math.floor(new Date().getTime() / 1000),
+ version: 8,
+ },
+ })
+ .then(res => {
+ let body = res.data;
+ if (!body.domain) {
+ throw "Server did not respond with a web socket host.";
+ }
+ if (this.debug) {
+ this.log("Web socket host received [%s].", body.domain);
+ }
+ this.wsHost = body.domain;
+ resolve(body.domain);
+ })
+ .catch(err => {
+ reject(err);
+ });
+ });
+ }
+ login() {
+ this.ws = new ws("wss://" + this.wsHost + ":8080/api/ws");
+ this.ws.on("open", () => {
+ this.wsIsOpen = true;
+ let payload = {
+ action: "userOnline",
+ apikey: this.apiKey,
+ appid: constants.appId,
+ at: this.aToken,
+ nonce: Math.random().toString(36).substr(2, 8),
+ sequence: Math.floor(new Date()),
+ ts: Math.floor(new Date() / 1000),
+ userAgent: "app",
+ version: 8,
+ };
+ this.ws.send(JSON.stringify(payload));
+ if (this.debugReqRes) {
+ let msg = JSON.stringify(payload, null, 2)
+ .replace(this.aToken, "**hidden**")
+ .replace(this.apiKey, "**hidden**");
+ this.log.warn("Sending WS login request. This text is yellow for clarity.\n%s", msg);
+ } else if (this.debug) {
+ this.log("Sending WS login request.");
+ }
+ });
+ this.ws.on("message", m => {
+ if (m === "pong") {
+ return;
+ }
+ let device;
+ try {
+ device = JSON.parse(m);
+ } catch (e) {
+ this.log.warn("An error occured reading the web socket message [%s]", e);
+ return;
+ }
+ // for requestUpdate response
+ if (
+ device.hasOwnProperty("deviceid") &&
+ device.hasOwnProperty("params") &&
+ device.hasOwnProperty("error") &&
+ device.error === 0
+ ) {
+ device.action = "update";
+ } else if (device.hasOwnProperty("deviceid") && device.hasOwnProperty("error") && device.error === 504) {
+ device.action = "sysmsg";
+ device.params = {
+ online: false,
+ };
+ }
+ // for external updates
+ if (device.hasOwnProperty("config") && device.config.hb && device.config.hbInterval && !this.hbInterval) {
+ this.hbInterval = setInterval(() => {
+ this.ws.send("ping");
+ }, (device.config.hbInterval + 7) * 1000);
+ } else if (device.hasOwnProperty("action")) {
+ switch (device.action) {
+ case "sysmsg":
+ device.params.updateSource = "WS";
+ let returnTemplate = {
+ deviceid: device.deviceid,
+ action: "sysmsg",
+ params: device.params,
};
- }
- // for external updates
- if (device.hasOwnProperty("config") && device.config.hb && device.config.hbInterval && !this.hbInterval) {
- this.hbInterval = setInterval(() => {
- this.ws.send("ping");
- }, (device.config.hbInterval + 7) * 1000);
- } else if (device.hasOwnProperty("action")) {
- switch (device.action) {
- case "sysmsg":
- device.params.updateSource = "WS";
- let returnTemplate = {
- deviceid: device.deviceid,
- action: "sysmsg",
- params: device.params
- };
- if (this.debugReqRes) {
- let msg = JSON.stringify(returnTemplate, null, 2).replace(device.deviceid, "**hidden**");
- this.log("WS message received.\n%s", msg);
- } else if (this.debug) {
- this.log("WS message received.");
- }
- this.emitter.emit("update", returnTemplate);
- break;
- case "update":
- for (let param in device.params) {
- if (device.params.hasOwnProperty(param)) {
- if (!constants.paramsToKeep.includes(param.replace(/[0-9]/g, ""))) {
- delete device.params[param];
- }
- }
- }
- if (Object.keys(device.params).length > 0) {
- device.params.updateSource = "WS";
- let returnTemplate = {
- deviceid: device.deviceid,
- action: "update",
- params: device.params
- };
- if (this.debugReqRes) {
- let msg = JSON.stringify(returnTemplate, null, 2).replace(device.deviceid, "**hidden**");
- this.log("WS message received.\n%s", msg);
- } else if (this.debug) {
- this.log("WS message received.");
- }
- this.emitter.emit("update", returnTemplate);
- }
- break;
- default:
- this.log.warn("[%s] WS message has unknown action.\n" + JSON.stringify(device, null, 2), device.deviceid);
- return;
+ if (this.debugReqRes) {
+ let msg = JSON.stringify(returnTemplate, null, 2).replace(device.deviceid, "**hidden**");
+ this.log("WS message received.\n%s", msg);
+ } else if (this.debug) {
+ this.log("WS message received.");
}
- } else if (device.hasOwnProperty("error") && device.error === 0) {
- // *** Safe to ignore these messages *** \\
- } else {
- if (this.debug) {
- this.log.warn("WS unknown command received.\n" + JSON.stringify(device, null, 2));
+ this.emitter.emit("update", returnTemplate);
+ break;
+ case "update":
+ for (let param in device.params) {
+ if (device.params.hasOwnProperty(param)) {
+ if (!constants.paramsToKeep.includes(param.replace(/[0-9]/g, ""))) {
+ delete device.params[param];
+ }
+ }
}
- }
- });
- this.ws.on("close", (e, m) => {
- if (m === "Stopping Homebridge") {
- this.log("Web socket gracefully closed.");
- } else {
- this.log.warn("Web socket closed - [%s - %s].", e, m);
- if (e !== 1000) {
- this.log("Web socket will try to reconnect in five seconds.");
- setTimeout(() => {
- this.login();
- }, 5000);
- } else {
- this.log("Please try restarting Homebridge so that this plugin can work again.");
+ if (Object.keys(device.params).length > 0) {
+ device.params.updateSource = "WS";
+ let returnTemplate = {
+ deviceid: device.deviceid,
+ action: "update",
+ params: device.params,
+ };
+ if (this.debugReqRes) {
+ let msg = JSON.stringify(returnTemplate, null, 2).replace(device.deviceid, "**hidden**");
+ this.log("WS message received.\n%s", msg);
+ } else if (this.debug) {
+ this.log("WS message received.");
+ }
+ this.emitter.emit("update", returnTemplate);
}
- }
- this.wsIsOpen = false;
- if (this.hbInterval) {
- clearInterval(this.hbInterval);
- this.hbInterval = null;
- }
- this.ws.removeAllListeners();
- });
- this.ws.on("error", (e) => {
- this.log.error("Web socket error - [%s].", e);
- if (e.code === "ECONNREFUSED") {
- this.log.warn("Web socket will try to reconnect in five seconds then try the command again.");
- this.ws.removeAllListeners();
- setTimeout(() => {
- this.login();
- }, 5000);
- } else {
- this.log.warn("If this was unexpected then please try restarting Homebridge.");
- }
- });
- }
- sendUpdate(json) {
- json = {
- ...json,
- ...{
- action: "update",
- sequence: Math.floor(new Date()),
- userAgent: "app"
- }
- };
- let sendOperation = req => {
- if (!this.wsIsOpen) {
- setTimeout(() => {
- sendOperation(req);
- }, 280);
+ break;
+ case "reportSubDevice":
return;
- }
- if (this.ws) {
- this.ws.send(req);
- if (this.debugReqRes) {
- let msg = JSON.stringify(json, null, 2).replace(json.apikey, "**hidden**").replace(json.apiKey, "**hidden**").replace(json.deviceid, "**hidden**");
- this.log.warn("WS message sent. This text is yellow for clarity.\n%s", msg);
- } else if (this.debug) {
- this.log("WS message sent.");
- }
+ default:
+ this.log.warn("[%s] WS message has unknown action.\n" + JSON.stringify(device, null, 2), device.deviceid);
return;
- }
- this.delaySend = this.delaySend <= 0 ? 0 : this.delaySend -= 280;
- };
- let string = JSON.stringify(json);
- if (this.wsIsOpen) {
- setTimeout(sendOperation, this.delaySend, string);
- this.delaySend += 280;
+ }
+ } else if (device.hasOwnProperty("error") && device.error === 0) {
+ // *** Safe to ignore these messages *** \\
} else {
- this.log.warn("Web socket is currently reconnecting. Command will be resent.");
- let interval,
- waitToSend = req => {
- if (this.wsIsOpen) {
- clearInterval(interval);
- sendOperation(req);
- }
- };
- interval = setInterval(waitToSend, 2500, string);
+ if (this.debug) {
+ this.log.warn("WS unknown command received.\n" + JSON.stringify(device, null, 2));
+ }
}
- }
- requestUpdate(accessory) {
- let json = {
- action: "query",
- apikey: accessory.context.eweApiKey,
- deviceid: accessory.context.eweDeviceId,
- params: [],
- sequence: Math.floor(new Date()),
- ts: 0,
- userAgent: "app"
- },
- sendOperation = req => {
- if (!this.wsIsOpen) {
- setTimeout(() => {
- sendOperation(req);
- }, 280);
- return;
- }
- if (this.ws) {
- this.ws.send(req);
- if (this.debugReqRes) {
- let msg = JSON.stringify(json, null, 2).replace(json.apikey, "**hidden**").replace(json.apiKey, "**hidden**").replace(json.deviceid, "**hidden**");
- this.log.warn("WS message sent. This text is yellow for clarity.\n%s", msg);
- } else if (this.debug) {
- this.log("WS message sent.");
- }
- return;
- }
- this.delaySend = this.delaySend <= 0 ? 0 : this.delaySend -= 280;
- },
- string = JSON.stringify(json);
- if (this.wsIsOpen) {
- setTimeout(sendOperation, this.delaySend, string);
- this.delaySend += 280;
+ });
+ this.ws.on("close", (e, m) => {
+ if (m === "Stopping Homebridge") {
+ this.log("Web socket gracefully closed.");
} else {
- this.log.warn("Web socket is currently reconnecting. Command will be resent.");
- let interval,
- waitToSend = req => {
- if (this.wsIsOpen) {
- clearInterval(interval);
- sendOperation(req);
- }
- };
- interval = setInterval(waitToSend, 2500, string);
+ this.log.warn("Web socket closed - [%s - %s].", e, m);
+ if (e !== 1000) {
+ this.log("Web socket will try to reconnect in five seconds.");
+ setTimeout(() => {
+ this.login();
+ }, 5000);
+ } else {
+ this.log("Please try restarting Homebridge so that this plugin can work again.");
+ }
+ }
+ this.wsIsOpen = false;
+ if (this.hbInterval) {
+ clearInterval(this.hbInterval);
+ this.hbInterval = null;
+ }
+ this.ws.removeAllListeners();
+ });
+ this.ws.on("error", e => {
+ this.log.error("Web socket error - [%s].", e);
+ if (e.code === "ECONNREFUSED") {
+ this.log.warn("Web socket will try to reconnect in five seconds then try the command again.");
+ this.ws.removeAllListeners();
+ setTimeout(() => {
+ this.login();
+ }, 5000);
+ } else {
+ this.log.warn("If this was unexpected then please try restarting Homebridge.");
+ }
+ });
+ }
+ sendUpdate(json) {
+ json = {
+ ...json,
+ ...{
+ action: "update",
+ sequence: Math.floor(new Date()),
+ userAgent: "app",
+ },
+ };
+ let sendOperation = req => {
+ if (!this.wsIsOpen) {
+ setTimeout(() => {
+ sendOperation(req);
+ }, 280);
+ return;
}
- }
- receiveUpdate(f) {
- this.emitter.addListener("update", f);
- }
- closeConnection() {
- if (this.ws && this.wsIsOpen) {
- this.ws.close(1000, "Stopping Homebridge");
+ if (this.ws) {
+ this.ws.send(req);
+ if (this.debugReqRes) {
+ let msg = JSON.stringify(json, null, 2)
+ .replace(json.apikey, "**hidden**")
+ .replace(json.apiKey, "**hidden**")
+ .replace(json.deviceid, "**hidden**");
+ this.log.warn("WS message sent. This text is yellow for clarity.\n%s", msg);
+ } else if (this.debug) {
+ this.log("WS message sent.");
+ }
+ return;
}
- }
-};
\ No newline at end of file
+ this.delaySend = this.delaySend <= 0 ? 0 : (this.delaySend -= 280);
+ };
+ let string = JSON.stringify(json);
+ if (this.wsIsOpen) {
+ setTimeout(sendOperation, this.delaySend, string);
+ this.delaySend += 280;
+ } else {
+ this.log.warn("Web socket is currently reconnecting. Command will be resent.");
+ let interval,
+ waitToSend = req => {
+ if (this.wsIsOpen) {
+ clearInterval(interval);
+ sendOperation(req);
+ }
+ };
+ interval = setInterval(waitToSend, 2500, string);
+ }
+ }
+ requestUpdate(accessory) {
+ let json = {
+ action: "query",
+ apikey: accessory.context.eweApiKey,
+ deviceid: accessory.context.eweDeviceId,
+ params: [],
+ sequence: Math.floor(new Date()),
+ ts: 0,
+ userAgent: "app",
+ },
+ sendOperation = req => {
+ if (!this.wsIsOpen) {
+ setTimeout(() => {
+ sendOperation(req);
+ }, 280);
+ return;
+ }
+ if (this.ws) {
+ this.ws.send(req);
+ if (this.debugReqRes) {
+ let msg = JSON.stringify(json, null, 2)
+ .replace(json.apikey, "**hidden**")
+ .replace(json.apiKey, "**hidden**")
+ .replace(json.deviceid, "**hidden**");
+ this.log.warn("WS message sent. This text is yellow for clarity.\n%s", msg);
+ } else if (this.debug) {
+ this.log("WS message sent.");
+ }
+ return;
+ }
+ this.delaySend = this.delaySend <= 0 ? 0 : (this.delaySend -= 280);
+ },
+ string = JSON.stringify(json);
+ if (this.wsIsOpen) {
+ setTimeout(sendOperation, this.delaySend, string);
+ this.delaySend += 280;
+ } else {
+ this.log.warn("Web socket is currently reconnecting. Command will be resent.");
+ let interval,
+ waitToSend = req => {
+ if (this.wsIsOpen) {
+ clearInterval(interval);
+ sendOperation(req);
+ }
+ };
+ interval = setInterval(waitToSend, 2500, string);
+ }
+ }
+ receiveUpdate(f) {
+ this.emitter.addListener("update", f);
+ }
+ closeConnection() {
+ if (this.ws && this.wsIsOpen) {
+ this.ws.close(1000, "Stopping Homebridge");
+ }
+ }
+};
diff --git a/package-lock.json b/package-lock.json
index 89e609db..61a31ae5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,624 +1,630 @@
{
- "name": "homebridge-ewelink",
- "version": "2.26.2",
- "lockfileVersion": 1,
- "requires": true,
- "dependencies": {
- "@types/color-name": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
- "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ=="
- },
- "abort-controller": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
- "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
- "requires": {
- "event-target-shim": "^5.0.0"
- }
- },
- "agent-base": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.1.tgz",
- "integrity": "sha512-01q25QQDwLSsyfhrKbn8yuur+JNw0H+0Y4JiGIKd3z9aYk/w/2kxD/Upc+t2ZBBSUNff50VjPsSW2YxM8QYKVg==",
- "requires": {
- "debug": "4"
- },
- "dependencies": {
- "debug": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
- "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
- "requires": {
- "ms": "^2.1.1"
- }
- },
- "ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
- }
- }
- },
- "ansi-styles": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
- "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
- "requires": {
- "@types/color-name": "^1.1.1",
- "color-convert": "^2.0.1"
- }
- },
- "array-flatten": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz",
- "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ=="
- },
- "arrify": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz",
- "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug=="
- },
- "axios": {
- "version": "0.20.0",
- "resolved": "https://registry.npmjs.org/axios/-/axios-0.20.0.tgz",
- "integrity": "sha512-ANA4rr2BDcmmAQLOKft2fufrtuvlqR+cXNNinUmvfeSNCOF98PZL+7M/v1zIdGo7OLjEA9J2gXJL+j4zGsl0bA==",
- "requires": {
- "follow-redirects": "^1.10.0"
- }
- },
- "base64-js": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
- "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g=="
- },
- "bignumber.js": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz",
- "integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A=="
- },
- "bonjour": {
- "version": "3.5.0",
- "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz",
- "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=",
- "requires": {
- "array-flatten": "^2.1.0",
- "deep-equal": "^1.0.1",
- "dns-equal": "^1.0.0",
- "dns-txt": "^2.0.2",
- "multicast-dns": "^6.0.1",
- "multicast-dns-service-types": "^1.1.0"
- }
- },
- "buffer-equal-constant-time": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
- "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk="
- },
- "buffer-indexof": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz",
- "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g=="
- },
- "chalk": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
- "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
- },
- "correcting-interval": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/correcting-interval/-/correcting-interval-2.0.0.tgz",
- "integrity": "sha1-iTdklFcN+C7axTQRHV8n/z6gstM="
- },
- "debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "requires": {
- "ms": "2.0.0"
- }
- },
- "deep-equal": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz",
- "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==",
- "requires": {
- "is-arguments": "^1.0.4",
- "is-date-object": "^1.0.1",
- "is-regex": "^1.0.4",
- "object-is": "^1.0.1",
- "object-keys": "^1.1.1",
- "regexp.prototype.flags": "^1.2.0"
- }
- },
- "define-properties": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
- "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
- "requires": {
- "object-keys": "^1.0.12"
- }
- },
- "dns-equal": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz",
- "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0="
- },
- "dns-packet": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz",
- "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==",
- "requires": {
- "ip": "^1.1.0",
- "safe-buffer": "^5.0.1"
- }
- },
- "dns-txt": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz",
- "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=",
- "requires": {
- "buffer-indexof": "^1.0.0"
- }
- },
- "ecdsa-sig-formatter": {
- "version": "1.0.11",
- "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
- "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
- "requires": {
- "safe-buffer": "^5.0.1"
- }
- },
- "es-abstract": {
- "version": "1.17.6",
- "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz",
- "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==",
- "requires": {
- "es-to-primitive": "^1.2.1",
- "function-bind": "^1.1.1",
- "has": "^1.0.3",
- "has-symbols": "^1.0.1",
- "is-callable": "^1.2.0",
- "is-regex": "^1.1.0",
- "object-inspect": "^1.7.0",
- "object-keys": "^1.1.1",
- "object.assign": "^4.1.0",
- "string.prototype.trimend": "^1.0.1",
- "string.prototype.trimstart": "^1.0.1"
- }
- },
- "es-to-primitive": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
- "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
- "requires": {
- "is-callable": "^1.1.4",
- "is-date-object": "^1.0.1",
- "is-symbol": "^1.0.2"
- }
- },
- "event-target-shim": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
- "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="
- },
- "extend": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
- "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
- },
- "fakegato-history": {
- "version": "0.5.6",
- "resolved": "https://registry.npmjs.org/fakegato-history/-/fakegato-history-0.5.6.tgz",
- "integrity": "sha512-LlsOkiw9LntVlRlBkssD5ozhEkQzYuEJUlvXk5YAgBQcWzk19PQ5g+NoKfs6SRY1qAeC1onb65hes4mCvY+JmA==",
- "requires": {
- "debug": "^2.2.0",
- "googleapis": ">39.1.0",
- "moment": "*"
- }
- },
- "fast-text-encoding": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz",
- "integrity": "sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig=="
- },
- "follow-redirects": {
- "version": "1.13.0",
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz",
- "integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA=="
- },
- "function-bind": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
- "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
- },
- "gaxios": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-3.1.0.tgz",
- "integrity": "sha512-DDTn3KXVJJigtz+g0J3vhcfbDbKtAroSTxauWsdnP57sM5KZ3d2c/3D9RKFJ86s43hfw6WULg6TXYw/AYiBlpA==",
- "requires": {
- "abort-controller": "^3.0.0",
- "extend": "^3.0.2",
- "https-proxy-agent": "^5.0.0",
- "is-stream": "^2.0.0",
- "node-fetch": "^2.3.0"
- }
- },
- "gcp-metadata": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.1.4.tgz",
- "integrity": "sha512-5J/GIH0yWt/56R3dNaNWPGQ/zXsZOddYECfJaqxFWgrZ9HC2Kvc5vl9upOgUUHKzURjAVf2N+f6tEJiojqXUuA==",
- "requires": {
- "gaxios": "^3.0.0",
- "json-bigint": "^1.0.0"
- }
- },
- "google-auth-library": {
- "version": "6.0.6",
- "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-6.0.6.tgz",
- "integrity": "sha512-fWYdRdg55HSJoRq9k568jJA1lrhg9i2xgfhVIMJbskUmbDpJGHsbv9l41DGhCDXM21F9Kn4kUwdysgxSYBYJUw==",
- "requires": {
- "arrify": "^2.0.0",
- "base64-js": "^1.3.0",
- "ecdsa-sig-formatter": "^1.0.11",
- "fast-text-encoding": "^1.0.0",
- "gaxios": "^3.0.0",
- "gcp-metadata": "^4.1.0",
- "gtoken": "^5.0.0",
- "jws": "^4.0.0",
- "lru-cache": "^6.0.0"
- }
- },
- "google-p12-pem": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.0.3.tgz",
- "integrity": "sha512-wS0ek4ZtFx/ACKYF3JhyGe5kzH7pgiQ7J5otlumqR9psmWMYc+U9cErKlCYVYHoUaidXHdZ2xbo34kB+S+24hA==",
- "requires": {
- "node-forge": "^0.10.0"
- }
- },
- "googleapis": {
- "version": "59.0.0",
- "resolved": "https://registry.npmjs.org/googleapis/-/googleapis-59.0.0.tgz",
- "integrity": "sha512-GV/E4KRN89a4GxSk7D7cwUfRYgcJHR05sOgm/WGdwc/u8dxNXG5lWmz9gF5ZwFGk2yKtVxL4VZNn4zBuZ6rmGg==",
- "requires": {
- "google-auth-library": "^6.0.0",
- "googleapis-common": "^4.4.0"
- }
- },
- "googleapis-common": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/googleapis-common/-/googleapis-common-4.4.0.tgz",
- "integrity": "sha512-Bgrs8/1OZQFFIfVuX38L9t48rPAkVUXttZy6NzhhXxFOEMSHgfFIjxou7RIXOkBHxmx2pVwct9WjKkbnqMYImQ==",
- "requires": {
- "extend": "^3.0.2",
- "gaxios": "^3.0.0",
- "google-auth-library": "^6.0.0",
- "qs": "^6.7.0",
- "url-template": "^2.0.8",
- "uuid": "^8.0.0"
- }
- },
- "gtoken": {
- "version": "5.0.3",
- "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.0.3.tgz",
- "integrity": "sha512-Nyd1wZCMRc2dj/mAD0LlfQLcAO06uKdpKJXvK85SGrF5+5+Bpfil9u/2aw35ltvEHjvl0h5FMKN5knEU+9JrOg==",
- "requires": {
- "gaxios": "^3.0.0",
- "google-p12-pem": "^3.0.0",
- "jws": "^4.0.0",
- "mime": "^2.2.0"
- }
- },
- "has": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
- "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
- "requires": {
- "function-bind": "^1.1.1"
- }
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
- },
- "has-symbols": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
- "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg=="
- },
- "homebridge-lib": {
- "version": "4.7.14",
- "resolved": "https://registry.npmjs.org/homebridge-lib/-/homebridge-lib-4.7.14.tgz",
- "integrity": "sha512-8eUGTVrCRd7WHwEH49CgqYUu2q9WjeTVDnEA5WXL2ZvPevTMCck5GcVIXtvVWxr9we8Ay0ybFp0N5RRlrIzH/g==",
- "requires": {
- "bonjour": "^3.5.0",
- "chalk": "^4.1.0",
- "debug": "^4.1.1",
- "semver": "^7.3.2"
- },
- "dependencies": {
- "debug": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
- "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
- "requires": {
- "ms": "^2.1.1"
- }
- },
- "ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
- }
- }
- },
- "https-proxy-agent": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
- "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
- "requires": {
- "agent-base": "6",
- "debug": "4"
- },
- "dependencies": {
- "debug": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
- "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
- "requires": {
- "ms": "^2.1.1"
- }
- },
- "ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
- }
- }
- },
- "ip": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
- "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo="
- },
- "is-arguments": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz",
- "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA=="
- },
- "is-callable": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.1.tgz",
- "integrity": "sha512-wliAfSzx6V+6WfMOmus1xy0XvSgf/dlStkvTfq7F0g4bOIW0PSUbnyse3NhDwdyYS1ozfUtAAySqTws3z9Eqgg=="
- },
- "is-date-object": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz",
- "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g=="
- },
- "is-regex": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz",
- "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==",
- "requires": {
- "has-symbols": "^1.0.1"
- }
- },
- "is-stream": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
- "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw=="
- },
- "is-symbol": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz",
- "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==",
- "requires": {
- "has-symbols": "^1.0.1"
- }
- },
- "json-bigint": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz",
- "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==",
- "requires": {
- "bignumber.js": "^9.0.0"
- }
- },
- "jwa": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz",
- "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==",
- "requires": {
- "buffer-equal-constant-time": "1.0.1",
- "ecdsa-sig-formatter": "1.0.11",
- "safe-buffer": "^5.0.1"
- }
- },
- "jws": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz",
- "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==",
- "requires": {
- "jwa": "^2.0.0",
- "safe-buffer": "^5.0.1"
- }
- },
- "lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "requires": {
- "yallist": "^4.0.0"
- }
- },
- "mime": {
- "version": "2.4.6",
- "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz",
- "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA=="
- },
- "moment": {
- "version": "2.27.0",
- "resolved": "https://registry.npmjs.org/moment/-/moment-2.27.0.tgz",
- "integrity": "sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ=="
- },
- "ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
- },
- "multicast-dns": {
- "version": "6.2.3",
- "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz",
- "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==",
- "requires": {
- "dns-packet": "^1.3.1",
- "thunky": "^1.0.2"
- }
- },
- "multicast-dns-service-types": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz",
- "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE="
- },
- "node-dns-sd": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/node-dns-sd/-/node-dns-sd-0.4.1.tgz",
- "integrity": "sha512-x+WSuMgvDBQv24OCq75YHcZj1SOzvP5fU4Tz+PBUiVvVBsfc+9XAHAuIftaCpf2nPLl+ys71uZoGr/v9fVDa6A=="
- },
- "node-fetch": {
- "version": "2.6.1",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
- "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
- },
- "node-forge": {
- "version": "0.10.0",
- "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz",
- "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA=="
- },
- "object-inspect": {
- "version": "1.8.0",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz",
- "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA=="
- },
- "object-is": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.2.tgz",
- "integrity": "sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ==",
- "requires": {
- "define-properties": "^1.1.3",
- "es-abstract": "^1.17.5"
- }
- },
- "object-keys": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
- "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="
- },
- "object.assign": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
- "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
- "requires": {
- "define-properties": "^1.1.2",
- "function-bind": "^1.1.1",
- "has-symbols": "^1.0.0",
- "object-keys": "^1.0.11"
- }
- },
- "qs": {
- "version": "6.9.4",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz",
- "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ=="
- },
- "regexp.prototype.flags": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz",
- "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==",
- "requires": {
- "define-properties": "^1.1.3",
- "es-abstract": "^1.17.0-next.1"
- }
- },
- "safe-buffer": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
- "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
- },
- "semver": {
- "version": "7.3.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
- "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ=="
- },
- "string.prototype.trimend": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz",
- "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==",
- "requires": {
- "define-properties": "^1.1.3",
- "es-abstract": "^1.17.5"
- }
- },
- "string.prototype.trimstart": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz",
- "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==",
- "requires": {
- "define-properties": "^1.1.3",
- "es-abstract": "^1.17.5"
- }
- },
- "supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "requires": {
- "has-flag": "^4.0.0"
- }
- },
- "thunky": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz",
- "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA=="
- },
- "url-template": {
- "version": "2.0.8",
- "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz",
- "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE="
- },
- "uuid": {
- "version": "8.3.0",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.0.tgz",
- "integrity": "sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ=="
- },
- "ws": {
- "version": "7.3.1",
- "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz",
- "integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA=="
- },
- "yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+ "name": "homebridge-ewelink",
+ "version": "2.26.2",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "@types/color-name": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
+ "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ=="
+ },
+ "abort-controller": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
+ "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
+ "requires": {
+ "event-target-shim": "^5.0.0"
+ }
+ },
+ "agent-base": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.1.tgz",
+ "integrity": "sha512-01q25QQDwLSsyfhrKbn8yuur+JNw0H+0Y4JiGIKd3z9aYk/w/2kxD/Upc+t2ZBBSUNff50VjPsSW2YxM8QYKVg==",
+ "requires": {
+ "debug": "4"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ }
+ }
+ },
+ "ansi-styles": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+ "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+ "requires": {
+ "@types/color-name": "^1.1.1",
+ "color-convert": "^2.0.1"
+ }
+ },
+ "array-flatten": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz",
+ "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ=="
+ },
+ "arrify": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz",
+ "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug=="
+ },
+ "axios": {
+ "version": "0.20.0",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-0.20.0.tgz",
+ "integrity": "sha512-ANA4rr2BDcmmAQLOKft2fufrtuvlqR+cXNNinUmvfeSNCOF98PZL+7M/v1zIdGo7OLjEA9J2gXJL+j4zGsl0bA==",
+ "requires": {
+ "follow-redirects": "^1.10.0"
+ }
+ },
+ "base64-js": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
+ "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g=="
+ },
+ "bignumber.js": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz",
+ "integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A=="
+ },
+ "bonjour": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz",
+ "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=",
+ "requires": {
+ "array-flatten": "^2.1.0",
+ "deep-equal": "^1.0.1",
+ "dns-equal": "^1.0.0",
+ "dns-txt": "^2.0.2",
+ "multicast-dns": "^6.0.1",
+ "multicast-dns-service-types": "^1.1.0"
+ }
+ },
+ "buffer-equal-constant-time": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
+ "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk="
+ },
+ "buffer-indexof": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz",
+ "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g=="
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+ },
+ "correcting-interval": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/correcting-interval/-/correcting-interval-2.0.0.tgz",
+ "integrity": "sha1-iTdklFcN+C7axTQRHV8n/z6gstM="
+ },
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "deep-equal": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz",
+ "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==",
+ "requires": {
+ "is-arguments": "^1.0.4",
+ "is-date-object": "^1.0.1",
+ "is-regex": "^1.0.4",
+ "object-is": "^1.0.1",
+ "object-keys": "^1.1.1",
+ "regexp.prototype.flags": "^1.2.0"
+ }
+ },
+ "define-properties": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
+ "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
+ "requires": {
+ "object-keys": "^1.0.12"
+ }
+ },
+ "dns-equal": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz",
+ "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0="
+ },
+ "dns-packet": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz",
+ "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==",
+ "requires": {
+ "ip": "^1.1.0",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "dns-txt": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz",
+ "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=",
+ "requires": {
+ "buffer-indexof": "^1.0.0"
+ }
+ },
+ "ecdsa-sig-formatter": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
+ "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
+ "requires": {
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "es-abstract": {
+ "version": "1.17.6",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz",
+ "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==",
+ "requires": {
+ "es-to-primitive": "^1.2.1",
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1",
+ "is-callable": "^1.2.0",
+ "is-regex": "^1.1.0",
+ "object-inspect": "^1.7.0",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.0",
+ "string.prototype.trimend": "^1.0.1",
+ "string.prototype.trimstart": "^1.0.1"
+ }
+ },
+ "es-to-primitive": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
+ "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+ "requires": {
+ "is-callable": "^1.1.4",
+ "is-date-object": "^1.0.1",
+ "is-symbol": "^1.0.2"
+ }
+ },
+ "event-target-shim": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
+ "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="
+ },
+ "extend": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
+ },
+ "fakegato-history": {
+ "version": "0.5.6",
+ "resolved": "https://registry.npmjs.org/fakegato-history/-/fakegato-history-0.5.6.tgz",
+ "integrity": "sha512-LlsOkiw9LntVlRlBkssD5ozhEkQzYuEJUlvXk5YAgBQcWzk19PQ5g+NoKfs6SRY1qAeC1onb65hes4mCvY+JmA==",
+ "requires": {
+ "debug": "^2.2.0",
+ "googleapis": ">39.1.0",
+ "moment": "*"
+ }
+ },
+ "fast-text-encoding": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz",
+ "integrity": "sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig=="
+ },
+ "follow-redirects": {
+ "version": "1.13.0",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz",
+ "integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA=="
+ },
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+ },
+ "gaxios": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-3.1.0.tgz",
+ "integrity": "sha512-DDTn3KXVJJigtz+g0J3vhcfbDbKtAroSTxauWsdnP57sM5KZ3d2c/3D9RKFJ86s43hfw6WULg6TXYw/AYiBlpA==",
+ "requires": {
+ "abort-controller": "^3.0.0",
+ "extend": "^3.0.2",
+ "https-proxy-agent": "^5.0.0",
+ "is-stream": "^2.0.0",
+ "node-fetch": "^2.3.0"
+ }
+ },
+ "gcp-metadata": {
+ "version": "4.1.4",
+ "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.1.4.tgz",
+ "integrity": "sha512-5J/GIH0yWt/56R3dNaNWPGQ/zXsZOddYECfJaqxFWgrZ9HC2Kvc5vl9upOgUUHKzURjAVf2N+f6tEJiojqXUuA==",
+ "requires": {
+ "gaxios": "^3.0.0",
+ "json-bigint": "^1.0.0"
+ }
+ },
+ "google-auth-library": {
+ "version": "6.0.6",
+ "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-6.0.6.tgz",
+ "integrity": "sha512-fWYdRdg55HSJoRq9k568jJA1lrhg9i2xgfhVIMJbskUmbDpJGHsbv9l41DGhCDXM21F9Kn4kUwdysgxSYBYJUw==",
+ "requires": {
+ "arrify": "^2.0.0",
+ "base64-js": "^1.3.0",
+ "ecdsa-sig-formatter": "^1.0.11",
+ "fast-text-encoding": "^1.0.0",
+ "gaxios": "^3.0.0",
+ "gcp-metadata": "^4.1.0",
+ "gtoken": "^5.0.0",
+ "jws": "^4.0.0",
+ "lru-cache": "^6.0.0"
+ }
+ },
+ "google-p12-pem": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.0.3.tgz",
+ "integrity": "sha512-wS0ek4ZtFx/ACKYF3JhyGe5kzH7pgiQ7J5otlumqR9psmWMYc+U9cErKlCYVYHoUaidXHdZ2xbo34kB+S+24hA==",
+ "requires": {
+ "node-forge": "^0.10.0"
+ }
+ },
+ "googleapis": {
+ "version": "59.0.0",
+ "resolved": "https://registry.npmjs.org/googleapis/-/googleapis-59.0.0.tgz",
+ "integrity": "sha512-GV/E4KRN89a4GxSk7D7cwUfRYgcJHR05sOgm/WGdwc/u8dxNXG5lWmz9gF5ZwFGk2yKtVxL4VZNn4zBuZ6rmGg==",
+ "requires": {
+ "google-auth-library": "^6.0.0",
+ "googleapis-common": "^4.4.0"
+ }
+ },
+ "googleapis-common": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/googleapis-common/-/googleapis-common-4.4.0.tgz",
+ "integrity": "sha512-Bgrs8/1OZQFFIfVuX38L9t48rPAkVUXttZy6NzhhXxFOEMSHgfFIjxou7RIXOkBHxmx2pVwct9WjKkbnqMYImQ==",
+ "requires": {
+ "extend": "^3.0.2",
+ "gaxios": "^3.0.0",
+ "google-auth-library": "^6.0.0",
+ "qs": "^6.7.0",
+ "url-template": "^2.0.8",
+ "uuid": "^8.0.0"
+ }
+ },
+ "gtoken": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.0.3.tgz",
+ "integrity": "sha512-Nyd1wZCMRc2dj/mAD0LlfQLcAO06uKdpKJXvK85SGrF5+5+Bpfil9u/2aw35ltvEHjvl0h5FMKN5knEU+9JrOg==",
+ "requires": {
+ "gaxios": "^3.0.0",
+ "google-p12-pem": "^3.0.0",
+ "jws": "^4.0.0",
+ "mime": "^2.2.0"
+ }
+ },
+ "has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "requires": {
+ "function-bind": "^1.1.1"
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
+ },
+ "has-symbols": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
+ "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg=="
+ },
+ "homebridge-lib": {
+ "version": "4.7.14",
+ "resolved": "https://registry.npmjs.org/homebridge-lib/-/homebridge-lib-4.7.14.tgz",
+ "integrity": "sha512-8eUGTVrCRd7WHwEH49CgqYUu2q9WjeTVDnEA5WXL2ZvPevTMCck5GcVIXtvVWxr9we8Ay0ybFp0N5RRlrIzH/g==",
+ "requires": {
+ "bonjour": "^3.5.0",
+ "chalk": "^4.1.0",
+ "debug": "^4.1.1",
+ "semver": "^7.3.2"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ }
+ }
+ },
+ "https-proxy-agent": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
+ "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
+ "requires": {
+ "agent-base": "6",
+ "debug": "4"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ }
+ }
+ },
+ "ip": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
+ "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo="
+ },
+ "is-arguments": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz",
+ "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA=="
+ },
+ "is-callable": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.1.tgz",
+ "integrity": "sha512-wliAfSzx6V+6WfMOmus1xy0XvSgf/dlStkvTfq7F0g4bOIW0PSUbnyse3NhDwdyYS1ozfUtAAySqTws3z9Eqgg=="
+ },
+ "is-date-object": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz",
+ "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g=="
+ },
+ "is-regex": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz",
+ "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==",
+ "requires": {
+ "has-symbols": "^1.0.1"
+ }
+ },
+ "is-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
+ "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw=="
+ },
+ "is-symbol": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz",
+ "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==",
+ "requires": {
+ "has-symbols": "^1.0.1"
+ }
+ },
+ "json-bigint": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz",
+ "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==",
+ "requires": {
+ "bignumber.js": "^9.0.0"
+ }
+ },
+ "jwa": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz",
+ "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==",
+ "requires": {
+ "buffer-equal-constant-time": "1.0.1",
+ "ecdsa-sig-formatter": "1.0.11",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "jws": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz",
+ "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==",
+ "requires": {
+ "jwa": "^2.0.0",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "requires": {
+ "yallist": "^4.0.0"
+ }
+ },
+ "mime": {
+ "version": "2.4.6",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz",
+ "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA=="
+ },
+ "moment": {
+ "version": "2.27.0",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.27.0.tgz",
+ "integrity": "sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ=="
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ },
+ "multicast-dns": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz",
+ "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==",
+ "requires": {
+ "dns-packet": "^1.3.1",
+ "thunky": "^1.0.2"
+ }
+ },
+ "multicast-dns-service-types": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz",
+ "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE="
+ },
+ "node-dns-sd": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/node-dns-sd/-/node-dns-sd-0.4.1.tgz",
+ "integrity": "sha512-x+WSuMgvDBQv24OCq75YHcZj1SOzvP5fU4Tz+PBUiVvVBsfc+9XAHAuIftaCpf2nPLl+ys71uZoGr/v9fVDa6A=="
+ },
+ "node-fetch": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
+ "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
+ },
+ "node-forge": {
+ "version": "0.10.0",
+ "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz",
+ "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA=="
+ },
+ "object-inspect": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz",
+ "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA=="
+ },
+ "object-is": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.2.tgz",
+ "integrity": "sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ==",
+ "requires": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.5"
+ }
+ },
+ "object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="
+ },
+ "object.assign": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
+ "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
+ "requires": {
+ "define-properties": "^1.1.2",
+ "function-bind": "^1.1.1",
+ "has-symbols": "^1.0.0",
+ "object-keys": "^1.0.11"
+ }
+ },
+ "prettier": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.1.1.tgz",
+ "integrity": "sha512-9bY+5ZWCfqj3ghYBLxApy2zf6m+NJo5GzmLTpr9FsApsfjriNnS2dahWReHMi7qNPhhHl9SYHJs2cHZLgexNIw==",
+ "dev": true
+ },
+ "qs": {
+ "version": "6.9.4",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz",
+ "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ=="
+ },
+ "regexp.prototype.flags": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz",
+ "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==",
+ "requires": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.0-next.1"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
+ },
+ "semver": {
+ "version": "7.3.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
+ "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ=="
+ },
+ "string.prototype.trimend": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz",
+ "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==",
+ "requires": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.5"
+ }
+ },
+ "string.prototype.trimstart": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz",
+ "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==",
+ "requires": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.5"
+ }
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "requires": {
+ "has-flag": "^4.0.0"
}
- }
+ },
+ "thunky": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz",
+ "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA=="
+ },
+ "url-template": {
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz",
+ "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE="
+ },
+ "uuid": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.0.tgz",
+ "integrity": "sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ=="
+ },
+ "ws": {
+ "version": "7.3.1",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz",
+ "integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA=="
+ },
+ "yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+ }
+ }
}
diff --git a/package.json b/package.json
index 5e90fe89..06d38b28 100644
--- a/package.json
+++ b/package.json
@@ -1,68 +1,71 @@
{
- "name": "homebridge-ewelink",
- "version": "2.26.2",
- "author": "bwp91",
- "contributors": [
- "gbro115",
- "MrTomAsh",
- "howanghk",
- "LeJeko",
- "aremishevsky-chegg",
- "samkni",
- "robsonfj",
- "ramsesz",
- "metarutaiga",
- "janbuecker",
- "jacopofranza",
- "donavanbecker",
- "dhutchison",
- "danielk117",
- "bassrock",
- "VictorKrasnov",
- "JuniorGenius",
- "BobbySlope"
- ],
- "description": "Homebridge plugin to control eWeLink devices with original firmware.",
- "license": "MIT",
- "keywords": [
- "homebridge",
- "homebridge-plugin",
- "homekit",
- "sonoff",
- "ewelink"
- ],
- "engines": {
- "node": ">=6.0.0",
- "homebridge": ">=0.2.0"
- },
- "repository": {
- "type": "git",
- "url": "https://github.com/bwp91/homebridge-ewelink"
- },
- "bugs": {
- "url": "https://github.com/bwp91/homebridge-ewelink/issues"
- },
- "dependencies": {
- "axios": "0.20.0",
- "color-convert": "2.0.1",
- "correcting-interval": "2.0.0",
- "fakegato-history": "0.5.6",
- "homebridge-lib": "4.7.14",
- "node-dns-sd": "0.4.1",
- "ws": "7.3.1"
- },
- "funding": [
- {
- "type": "kofi",
- "url": "https://ko-fi.com/bwp91"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/bwp91"
- },
- {
- "type": "paypal",
- "url": "https://www.paypal.me/BenPotter"
- }
- ]
+ "name": "homebridge-ewelink",
+ "version": "2.26.2",
+ "author": "bwp91",
+ "contributors": [
+ "gbro115",
+ "MrTomAsh",
+ "howanghk",
+ "LeJeko",
+ "aremishevsky-chegg",
+ "samkni",
+ "robsonfj",
+ "ramsesz",
+ "metarutaiga",
+ "janbuecker",
+ "jacopofranza",
+ "donavanbecker",
+ "dhutchison",
+ "danielk117",
+ "bassrock",
+ "VictorKrasnov",
+ "JuniorGenius",
+ "BobbySlope"
+ ],
+ "description": "Homebridge plugin to control eWeLink devices with original firmware.",
+ "license": "MIT",
+ "keywords": [
+ "homebridge",
+ "homebridge-plugin",
+ "homekit",
+ "sonoff",
+ "ewelink"
+ ],
+ "engines": {
+ "node": ">=6.0.0",
+ "homebridge": ">=0.2.0"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/bwp91/homebridge-ewelink"
+ },
+ "bugs": {
+ "url": "https://github.com/bwp91/homebridge-ewelink/issues"
+ },
+ "funding": [
+ {
+ "type": "kofi",
+ "url": "https://ko-fi.com/bwp91"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/bwp91"
+ },
+ {
+ "type": "paypal",
+ "url": "https://www.paypal.me/BenPotter"
+ }
+ ],
+ "dependencies": {
+ "axios": "0.20.0",
+ "color-convert": "2.0.1",
+ "correcting-interval": "2.0.0",
+ "fakegato-history": "0.5.6",
+ "homebridge-lib": "4.7.14",
+ "node-dns-sd": "0.4.1",
+ "ws": "7.3.1"
+ },
+ "devDependencies": {
+ "prettier": "2.1.1"
+ }
}
From 42845071fa919551a64540ee964151f4498fa1e8 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 15 Sep 2020 18:09:07 +0100
Subject: [PATCH 0151/3183] prettier formatting
---
.prettierrc.json | 3 +-
lib/constants.js | 30 +-
lib/eWeLink.js | 1489 ++++++++++++++++++++++++++++++++++----------
lib/eWeLinkHTTP.js | 38 +-
lib/eWeLinkLAN.js | 71 ++-
lib/eWeLinkWS.js | 80 ++-
6 files changed, 1322 insertions(+), 389 deletions(-)
diff --git a/.prettierrc.json b/.prettierrc.json
index 163a0a7e..d68aa739 100644
--- a/.prettierrc.json
+++ b/.prettierrc.json
@@ -1,4 +1,3 @@
{
- "arrowParens": "avoid",
- "printWidth": 120
+ "arrowParens": "avoid"
}
diff --git a/lib/constants.js b/lib/constants.js
index c8a8f17f..34215ac6 100644
--- a/lib/constants.js
+++ b/lib/constants.js
@@ -11,7 +11,18 @@ module.exports = {
devicesSingleSwitchParams: ["switch"],
devicesMultiSwitch: [2, 3, 4, 7, 8, 9, 29, 30, 31, 34, 41],
devicesMultiSwitchParams: ["switches"],
- devicesSingleSwitchLight: ["T1 1C", "L1", "B1", "B1_R2", "TX1C", "D1", "D1R1", "KING-M4", "Slampher", "GTTA59"],
+ devicesSingleSwitchLight: [
+ "T1 1C",
+ "L1",
+ "B1",
+ "B1_R2",
+ "TX1C",
+ "D1",
+ "D1R1",
+ "KING-M4",
+ "Slampher",
+ "GTTA59",
+ ],
devicesSingleSwitchLightParams: [
"switch",
"state",
@@ -29,7 +40,12 @@ module.exports = {
devicesSensor: [102],
devicesSensorParams: ["switch", "battery", "type"],
devicesThermostat: [15],
- devicesThermostatParams: ["currentTemperature", "currentHumidity", "switch", "masterSwitch"],
+ devicesThermostatParams: [
+ "currentTemperature",
+ "currentHumidity",
+ "switch",
+ "masterSwitch",
+ ],
devicesFan: [34],
devicesFanParams: ["switches", "light", "fan", "speed"],
devicesOutlet: [32],
@@ -42,7 +58,15 @@ module.exports = {
devicesRFBridge: [28],
devicesRFBridgeParams: ["cmd"],
devicesZBBridge: [66],
- devicesZBBridgeParams: ["key", "temperature", "humidity", "motion", "lock", "trigTime", "battery"],
+ devicesZBBridgeParams: [
+ "key",
+ "temperature",
+ "humidity",
+ "motion",
+ "lock",
+ "trigTime",
+ "battery",
+ ],
devicesZB: [1000, 1770, 2026, 3026],
devicesValveParams: ["switches"],
devicesBlindParams: ["switch", "switches"],
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 5b87acf8..0869e08a 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -13,9 +13,15 @@ class eWeLink {
constructor(log, config, api) {
if (!log || !api || !config) return;
if (!config.username || !config.password || !config.countryCode) {
- log.error("**************** Cannot load homebridge-ewelink ****************");
- log.error("Your eWeLink credentials are missing from the Homebridge config.");
- log.error("****************************************************************");
+ log.error(
+ "**************** Cannot load homebridge-ewelink ****************"
+ );
+ log.error(
+ "Your eWeLink credentials are missing from the Homebridge config."
+ );
+ log.error(
+ "****************************************************************"
+ );
return;
}
this.log = log;
@@ -29,7 +35,9 @@ class eWeLink {
this.eveLogPath = this.api.user.storagePath() + "/homebridge-ewelink/";
this.api
.on("didFinishLaunching", () => {
- this.log("Plugin has finished initialising. Starting synchronisation with eWeLink account.");
+ this.log(
+ "Plugin has finished initialising. Starting synchronisation with eWeLink account."
+ );
//*** Set up HTTP client and get the user HTTP host ***\\
this.httpClient = new eWeLinkHTTP(this.config, this.log);
this.httpClient
@@ -48,10 +56,23 @@ class eWeLink {
.then(res => {
//*** Get device IP addresses for LAN mode ***\\
this.httpDevices = res
- .filter(device => device.hasOwnProperty("extra") && device.extra.hasOwnProperty("uiid"))
- .filter(device => !(this.config.hideDevFromHB || "").includes(device.deviceid));
- this.lanClient = new eWeLinkLAN(this.config, this.log, this.httpDevices);
- this.httpDevices.forEach(device => this.devicesInEwe.set(device.deviceid, device));
+ .filter(
+ device =>
+ device.hasOwnProperty("extra") &&
+ device.extra.hasOwnProperty("uiid")
+ )
+ .filter(
+ device =>
+ !(this.config.hideDevFromHB || "").includes(device.deviceid)
+ );
+ this.lanClient = new eWeLinkLAN(
+ this.config,
+ this.log,
+ this.httpDevices
+ );
+ this.httpDevices.forEach(device =>
+ this.devicesInEwe.set(device.deviceid, device)
+ );
return this.lanClient.getHosts();
})
.then(res => {
@@ -64,8 +85,13 @@ class eWeLink {
//*** Use the device list to refresh Homebridge accessories ***\\
(() => {
//*** Remove all Homebridge accessories if none found ***\\
- if (Object.keys(this.httpDevices).length === 0 && Object.keys(this.lanDevices).length === 0) {
- Array.from(this.devicesInHB.values()).forEach(a => this.removeAccessory(a));
+ if (
+ Object.keys(this.httpDevices).length === 0 &&
+ Object.keys(this.lanDevices).length === 0
+ ) {
+ Array.from(this.devicesInHB.values()).forEach(a =>
+ this.removeAccessory(a)
+ );
this.devicesInHB.clear();
this.log.warn("******* Not loading homebridge-ewelink *******");
this.log.warn("No devices were found in your eWeLink account.");
@@ -75,20 +101,41 @@ class eWeLink {
//*** Make a map of custom groups from Homebridge config ***\\
if (Object.keys(this.config.groups || []).length > 0) {
this.config.groups
- .filter(g => g.hasOwnProperty("type") && cns.allowedGroups.includes(g.type))
- .filter(g => g.hasOwnProperty("deviceId") && this.devicesInEwe.has(g.deviceId.toLowerCase()))
+ .filter(
+ g =>
+ g.hasOwnProperty("type") &&
+ cns.allowedGroups.includes(g.type)
+ )
+ .filter(
+ g =>
+ g.hasOwnProperty("deviceId") &&
+ this.devicesInEwe.has(g.deviceId.toLowerCase())
+ )
.forEach(g => this.cusG.set(g.deviceId + "SWX", g));
}
//*** Make a map of RF Bridge custom sensors from Homebridge config ***\\
if (Object.keys(this.config.bridgeSensors || []).length > 0) {
this.config.bridgeSensors
- .filter(s => s.hasOwnProperty("deviceId") && this.devicesInEwe.has(s.deviceId.toLowerCase()))
+ .filter(
+ s =>
+ s.hasOwnProperty("deviceId") &&
+ this.devicesInEwe.has(s.deviceId.toLowerCase())
+ )
.forEach(s => this.cusS.set(s.fullDeviceId, s));
}
//*** Logging always helps to see if everything is okay so far ***\\
- this.log("[%s] eWeLink devices were loaded from the Homebridge cache.", this.devicesInHB.size);
- this.log("[%s] primary devices were loaded from your eWeLink account.", this.devicesInEwe.size);
- this.log("[%s] primary devices were discovered on your local network.", this.lanDevicesOnline);
+ this.log(
+ "[%s] eWeLink devices were loaded from the Homebridge cache.",
+ this.devicesInHB.size
+ );
+ this.log(
+ "[%s] primary devices were loaded from your eWeLink account.",
+ this.devicesInEwe.size
+ );
+ this.log(
+ "[%s] primary devices were discovered on your local network.",
+ this.lanDevicesOnline
+ );
//*** Remove Homebridge accessories that don't appear in eWeLink ***\\
this.devicesInHB.forEach(a => {
if (!this.devicesInEwe.has(a.context.eweDeviceId)) {
@@ -99,7 +146,9 @@ class eWeLink {
this.devicesInEwe.forEach(d => this.initialiseDevice(d));
this.wsClient.receiveUpdate(d => this.receiveDeviceUpdate(d));
this.lanClient.receiveUpdate(d => this.receiveDeviceUpdate(d));
- this.log("eWeLink setup complete. If you're enjoying this package please consider a âī¸ on GitHub :).");
+ this.log(
+ "eWeLink setup complete. If you're enjoying this package please consider a âī¸ on GitHub :)."
+ );
if (this.config.debugReqRes || false) {
this.log.warn(
"You have 'Request & Response Logging' enabled. This setting is not recommended for long-term use."
@@ -108,9 +157,13 @@ class eWeLink {
})();
})
.catch(err => {
- this.log.error("************** Cannot load homebridge-ewelink **************");
+ this.log.error(
+ "************** Cannot load homebridge-ewelink **************"
+ );
this.log.error(err);
- this.log.error("************************************************************");
+ this.log.error(
+ "************************************************************"
+ );
if (this.lanClient) this.lanClient.closeConnection();
if (this.wsClient) this.wsClient.closeConnection();
});
@@ -122,16 +175,31 @@ class eWeLink {
}
initialiseDevice(device) {
let accessory;
- // if (device.extra.uiid === 102) this.log.warn(device);
//*** First add the device if it isn't already in Homebridge. Yeah this code looks a mess :| ***\\
- if (!this.devicesInHB.has(device.deviceid + "SWX") && !this.devicesInHB.has(device.deviceid + "SW0")) {
- if (device.extra.uiid === 2 && device.brandName === "coolkit" && device.productModel === "0285") {
+ if (
+ !this.devicesInHB.has(device.deviceid + "SWX") &&
+ !this.devicesInHB.has(device.deviceid + "SW0")
+ ) {
+ if (
+ device.extra.uiid === 2 &&
+ device.brandName === "coolkit" &&
+ device.productModel === "0285"
+ ) {
this.addAccessory(device, device.deviceid + "SWX", "valve");
- } else if (this.cusG.has(device.deviceid + "SWX") && this.cusG.get(device.deviceid + "SWX").type === "blind") {
+ } else if (
+ this.cusG.has(device.deviceid + "SWX") &&
+ this.cusG.get(device.deviceid + "SWX").type === "blind"
+ ) {
this.addAccessory(device, device.deviceid + "SWX", "blind");
- } else if (this.cusG.has(device.deviceid + "SWX") && this.cusG.get(device.deviceid + "SWX").type === "garage") {
+ } else if (
+ this.cusG.has(device.deviceid + "SWX") &&
+ this.cusG.get(device.deviceid + "SWX").type === "garage"
+ ) {
this.addAccessory(device, device.deviceid + "SWX", "garage");
- } else if (this.cusG.has(device.deviceid + "SWX") && this.cusG.get(device.deviceid + "SWX").type === "lock") {
+ } else if (
+ this.cusG.has(device.deviceid + "SWX") &&
+ this.cusG.get(device.deviceid + "SWX").type === "lock"
+ ) {
this.addAccessory(device, device.deviceid + "SWX", "lock");
} else if (cns.devicesSensor.includes(device.extra.uiid)) {
this.addAccessory(device, device.deviceid + "SWX", "sensor");
@@ -165,7 +233,9 @@ class eWeLink {
}
} else if (cns.devicesRFBridge.includes(device.extra.uiid)) {
this.addAccessory(device, device.deviceid + "SW0", "rf_pri");
- if (Object.keys((device.tags && device.tags.zyx_info) || []).length > 0) {
+ if (
+ Object.keys((device.tags && device.tags.zyx_info) || []).length > 0
+ ) {
for (let i = 1; i <= Object.keys(device.tags.zyx_info).length; i++) {
this.addAccessory(device, device.deviceid + "SW" + i, "rf_sub");
}
@@ -189,18 +259,29 @@ class eWeLink {
}
}
//*** Next refresh the device ***\\
- if ((accessory = this.devicesInHB.get(device.deviceid + "SWX") || this.devicesInHB.get(device.deviceid + "SW0"))) {
+ if (
+ (accessory =
+ this.devicesInHB.get(device.deviceid + "SWX") ||
+ this.devicesInHB.get(device.deviceid + "SW0"))
+ ) {
let isX = accessory.context.hbDeviceId.substr(-1) === "X",
isRfBridge = cns.devicesRFBridge.includes(accessory.context.eweUIID),
rfBridgeChange = false;
accessory
.getService(Service.AccessoryInformation)
- .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion);
- accessory.context.reachableWAN = accessory.context.eweUIID !== 102 ? device.online : true;
- accessory.context.reachableLAN = this.lanDevices.get(device.deviceid).online || false;
+ .setCharacteristic(
+ Characteristic.FirmwareRevision,
+ device.params.fwVersion
+ );
+ accessory.context.reachableWAN =
+ accessory.context.eweUIID !== 102 ? device.online : true;
+ accessory.context.reachableLAN =
+ this.lanDevices.get(device.deviceid).online || false;
accessory.context.inUse = false;
let str = accessory.context.reachableLAN
- ? "and locally with IP [" + this.lanDevices.get(device.deviceid).ip + "]"
+ ? "and locally with IP [" +
+ this.lanDevices.get(device.deviceid).ip +
+ "]"
: "but LAN mode unavailable as unsupported/shared device";
this.log("[%s] found in eWeLink %s.", accessory.displayName, str);
this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
@@ -208,7 +289,11 @@ class eWeLink {
for (let i = 1; i <= accessory.context.channelCount; i++) {
if (!this.devicesInHB.has(device.deviceid + "SW" + i)) {
if (cns.devicesHideable.includes(accessory.context.type)) {
- if ((this.config.hideFromHB || "").includes(device.deviceid + "SW" + i)) {
+ if (
+ (this.config.hideFromHB || "").includes(
+ device.deviceid + "SW" + i
+ )
+ ) {
continue;
} else {
this.addAccessory(device, device.deviceid + "SW" + i, "switch");
@@ -217,7 +302,9 @@ class eWeLink {
}
let oAccessory = this.devicesInHB.get(device.deviceid + "SW" + i);
if (
- (this.config.hideFromHB || "").includes(device.deviceid + "SW" + i) &&
+ (this.config.hideFromHB || "").includes(
+ device.deviceid + "SW" + i
+ ) &&
cns.devicesHideable.includes(accessory.context.type)
) {
this.removeAccessory(oAccessory);
@@ -231,9 +318,13 @@ class eWeLink {
}
oAccessory
.getService(Service.AccessoryInformation)
- .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion);
+ .setCharacteristic(
+ Characteristic.FirmwareRevision,
+ device.params.fwVersion
+ );
oAccessory.context.reachableWAN = device.online;
- oAccessory.context.reachableLAN = this.lanDevices.get(device.deviceid).online || false;
+ oAccessory.context.reachableLAN =
+ this.lanDevices.get(device.deviceid).online || false;
this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory);
}
}
@@ -258,19 +349,28 @@ class eWeLink {
);
}
} else {
- this.log.warn("[%s] cannot be initialised as it wasn't found in Homebridge.", device.name);
+ this.log.warn(
+ "[%s] cannot be initialised as it wasn't found in Homebridge.",
+ device.name
+ );
}
}
addAccessory(device, hbDeviceId, type) {
let switchNumber = hbDeviceId.substr(-1).toString(),
- newDeviceName = type === "rf_sub" ? device.tags.zyx_info[switchNumber - 1].name : device.name,
+ newDeviceName =
+ type === "rf_sub"
+ ? device.tags.zyx_info[switchNumber - 1].name
+ : device.name,
channelCount =
type === "rf_pri"
? Object.keys((device.tags && device.tags.zyx_info) || []).length
: cns.chansFromUiid[device.extra.uiid];
if (["1", "2", "3", "4"].includes(switchNumber) && type !== "rf_sub") {
newDeviceName += " SW" + switchNumber;
- if ((this.config.hideFromHB || "").includes(hbDeviceId) && cns.devicesHideable.includes(type)) {
+ if (
+ (this.config.hideFromHB || "").includes(hbDeviceId) &&
+ cns.devicesHideable.includes(type)
+ ) {
this.log("[%s] will not be added as per configuration.", newDeviceName);
return;
}
@@ -278,14 +378,23 @@ class eWeLink {
if ((this.config.nameOverride || {}).hasOwnProperty(hbDeviceId)) {
newDeviceName = this.config.nameOverride[hbDeviceId];
}
- const accessory = new Accessory(newDeviceName, UUIDGen.generate(hbDeviceId).toString());
+ const accessory = new Accessory(
+ newDeviceName,
+ UUIDGen.generate(hbDeviceId).toString()
+ );
try {
accessory
.getService(Service.AccessoryInformation)
.setCharacteristic(Characteristic.SerialNumber, hbDeviceId)
.setCharacteristic(Characteristic.Manufacturer, device.brandName)
- .setCharacteristic(Characteristic.Model, device.productModel + " (" + device.extra.model + ")")
- .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion)
+ .setCharacteristic(
+ Characteristic.Model,
+ device.productModel + " (" + device.extra.model + ")"
+ )
+ .setCharacteristic(
+ Characteristic.FirmwareRevision,
+ device.params.fwVersion
+ )
.setCharacteristic(Characteristic.Identify, false);
accessory.context = {
hbDeviceId,
@@ -301,11 +410,18 @@ class eWeLink {
case "valve":
["A", "B"].forEach(v => {
accessory
- .addService(Service.Valve, "Valve " + v, "valve" + v.toLowerCase())
+ .addService(
+ Service.Valve,
+ "Valve " + v,
+ "valve" + v.toLowerCase()
+ )
.setCharacteristic(Characteristic.Active, 0)
.setCharacteristic(Characteristic.InUse, 0)
.setCharacteristic(Characteristic.ValveType, 1)
- .setCharacteristic(Characteristic.SetDuration, this.config.valveTimeLength || 120)
+ .setCharacteristic(
+ Characteristic.SetDuration,
+ this.config.valveTimeLength || 120
+ )
.addCharacteristic(Characteristic.RemainingDuration);
});
break;
@@ -339,15 +455,26 @@ class eWeLink {
case "thermostat":
if (!this.config.hideTHSwitch) accessory.addService(Service.Switch);
accessory.addService(Service.TemperatureSensor);
- if (device.params.sensorType !== "DS18B20") accessory.addService(Service.HumiditySensor);
+ if (device.params.sensorType !== "DS18B20")
+ accessory.addService(Service.HumiditySensor);
break;
case "outlet":
accessory.addService(Service.Outlet);
- accessory.getService(Service.Outlet).addCharacteristic(EveService.Characteristics.Voltage);
- accessory.getService(Service.Outlet).addCharacteristic(EveService.Characteristics.CurrentConsumption);
- accessory.getService(Service.Outlet).addCharacteristic(EveService.Characteristics.ElectricCurrent);
- accessory.getService(Service.Outlet).addCharacteristic(EveService.Characteristics.TotalConsumption);
- accessory.getService(Service.Outlet).addCharacteristic(EveService.Characteristics.ResetTotal);
+ accessory
+ .getService(Service.Outlet)
+ .addCharacteristic(EveService.Characteristics.Voltage);
+ accessory
+ .getService(Service.Outlet)
+ .addCharacteristic(EveService.Characteristics.CurrentConsumption);
+ accessory
+ .getService(Service.Outlet)
+ .addCharacteristic(EveService.Characteristics.ElectricCurrent);
+ accessory
+ .getService(Service.Outlet)
+ .addCharacteristic(EveService.Characteristics.TotalConsumption);
+ accessory
+ .getService(Service.Outlet)
+ .addCharacteristic(EveService.Characteristics.ResetTotal);
accessory.context = {
...accessory.context,
...{
@@ -375,7 +502,9 @@ class eWeLink {
break;
case "rf_sub":
accessory.context.rfChls = {};
- switch (device.tags.zyx_info[parseInt(switchNumber) - 1].remote_type) {
+ switch (
+ device.tags.zyx_info[parseInt(switchNumber) - 1].remote_type
+ ) {
case "1":
case "2":
case "3":
@@ -383,7 +512,9 @@ class eWeLink {
accessory.context.sensorType = "button";
break;
case "6":
- accessory.context.sensorType = this.cusS.has(hbDeviceId) ? this.cusS.get(hbDeviceId).type : "motion";
+ accessory.context.sensorType = this.cusS.has(hbDeviceId)
+ ? this.cusS.get(hbDeviceId).type
+ : "motion";
break;
default:
throw (
@@ -393,46 +524,52 @@ class eWeLink {
);
}
let mAccessory = this.devicesInHB.get(device.deviceid + "SW0");
- device.tags.zyx_info[parseInt(switchNumber) - 1].buttonName.forEach(button => {
- let rfData;
- Object.entries(button).forEach(
- ([k, v]) =>
- (rfData = {
- rfChan: k,
- name: v,
- })
- );
- accessory.context.rfChls[rfData.rfChan] = rfData.name;
- mAccessory.context.rfChlMap[rfData.rfChan] = switchNumber;
- switch (accessory.context.sensorType) {
- case "button":
- accessory.addService(Service.Switch, rfData.name, "switch" + rfData.rfChan);
- break;
- case "water":
- accessory.addService(Service.LeakSensor);
- break;
- case "fire":
- case "smoke":
- accessory.addService(Service.SmokeSensor);
- break;
- case "co":
- accessory.addService(Service.CarbonMonoxideSensor);
- break;
- case "co2":
- accessory.addService(Service.CarbonDioxideSensor);
- break;
- case "contact":
- accessory.addService(Service.ContactSensor);
- break;
- case "occupancy":
- accessory.addService(Service.OccupancySensor);
- break;
- default:
- accessory.addService(Service.MotionSensor);
- break;
+ device.tags.zyx_info[parseInt(switchNumber) - 1].buttonName.forEach(
+ button => {
+ let rfData;
+ Object.entries(button).forEach(
+ ([k, v]) =>
+ (rfData = {
+ rfChan: k,
+ name: v,
+ })
+ );
+ accessory.context.rfChls[rfData.rfChan] = rfData.name;
+ mAccessory.context.rfChlMap[rfData.rfChan] = switchNumber;
+ switch (accessory.context.sensorType) {
+ case "button":
+ accessory.addService(
+ Service.Switch,
+ rfData.name,
+ "switch" + rfData.rfChan
+ );
+ break;
+ case "water":
+ accessory.addService(Service.LeakSensor);
+ break;
+ case "fire":
+ case "smoke":
+ accessory.addService(Service.SmokeSensor);
+ break;
+ case "co":
+ accessory.addService(Service.CarbonMonoxideSensor);
+ break;
+ case "co2":
+ accessory.addService(Service.CarbonDioxideSensor);
+ break;
+ case "contact":
+ accessory.addService(Service.ContactSensor);
+ break;
+ case "occupancy":
+ accessory.addService(Service.OccupancySensor);
+ break;
+ default:
+ accessory.addService(Service.MotionSensor);
+ break;
+ }
+ this.devicesInHB.set(mAccessory.context.hbDeviceId, mAccessory);
}
- this.devicesInHB.set(mAccessory.context.hbDeviceId, mAccessory);
- });
+ );
break;
case "zb_sub": //*** credit @tasict ***\\
accessory.addService(Service.BatteryService);
@@ -459,14 +596,20 @@ class eWeLink {
accessory.addService(Service.ContactSensor);
break;
default:
- throw "unsupported zigbee device type [" + device.extra.uiid + "]. Please create an issue on GitHub";
+ throw (
+ "unsupported zigbee device type [" +
+ device.extra.uiid +
+ "]. Please create an issue on GitHub"
+ );
}
break;
default:
throw "device is not supported by this plugin. Please create an issue on GitHub";
}
this.devicesInHB.set(hbDeviceId, accessory);
- this.api.registerPlatformAccessories("homebridge-ewelink", "eWeLink", [accessory]);
+ this.api.registerPlatformAccessories("homebridge-ewelink", "eWeLink", [
+ accessory,
+ ]);
this.configureAccessory(accessory);
this.log("[%s] has been added to Homebridge.", newDeviceName);
} catch (err) {
@@ -484,16 +627,34 @@ class eWeLink {
accessory
.getService("Valve " + v)
.getCharacteristic(Characteristic.Active)
- .on("set", (value, callback) => this.internalValveUpdate(accessory, "Valve " + v, value, callback));
+ .on("set", (value, callback) =>
+ this.internalValveUpdate(
+ accessory,
+ "Valve " + v,
+ value,
+ callback
+ )
+ );
accessory
.getService("Valve " + v)
.getCharacteristic(Characteristic.SetDuration)
.on("set", (value, callback) => {
- if (accessory.getService("Valve " + v).getCharacteristic(Characteristic.InUse).value) {
- accessory.getService("Valve " + v).updateCharacteristic(Characteristic.RemainingDuration, value);
+ if (
+ accessory
+ .getService("Valve " + v)
+ .getCharacteristic(Characteristic.InUse).value
+ ) {
+ accessory
+ .getService("Valve " + v)
+ .updateCharacteristic(
+ Characteristic.RemainingDuration,
+ value
+ );
clearTimeout(accessory.getService("Valve " + v).timer);
accessory.getService("Valve " + v).timer = setTimeout(() => {
- accessory.getService("Valve " + v).setCharacteristic(Characteristic.Active, 0);
+ accessory
+ .getService("Valve " + v)
+ .setCharacteristic(Characteristic.Active, 0);
}, value * 1000);
}
callback();
@@ -504,7 +665,9 @@ class eWeLink {
accessory
.getService(Service.WindowCovering)
.getCharacteristic(Characteristic.TargetPosition)
- .on("set", (value, callback) => this.internalBlindUpdate(accessory, value, callback))
+ .on("set", (value, callback) =>
+ this.internalBlindUpdate(accessory, value, callback)
+ )
.setProps({
minStep: 100,
});
@@ -513,37 +676,49 @@ class eWeLink {
accessory
.getService(Service.GarageDoorOpener)
.getCharacteristic(Characteristic.TargetDoorState)
- .on("set", (value, callback) => this.internalGarageUpdate(accessory, value, callback));
+ .on("set", (value, callback) =>
+ this.internalGarageUpdate(accessory, value, callback)
+ );
break;
case "lock":
accessory
.getService(Service.LockMechanism)
.getCharacteristic(Characteristic.LockTargetState)
- .on("set", (value, callback) => this.internalLockUpdate(accessory, value, callback));
+ .on("set", (value, callback) =>
+ this.internalLockUpdate(accessory, value, callback)
+ );
break;
case "fan":
accessory
.getService(Service.Fanv2)
.getCharacteristic(Characteristic.Active)
- .on("set", (value, callback) => this.internalFanUpdate(accessory, "power", value, callback));
+ .on("set", (value, callback) =>
+ this.internalFanUpdate(accessory, "power", value, callback)
+ );
accessory
.getService(Service.Fanv2)
.getCharacteristic(Characteristic.RotationSpeed)
- .on("set", (value, callback) => this.internalFanUpdate(accessory, "speed", value, callback))
+ .on("set", (value, callback) =>
+ this.internalFanUpdate(accessory, "speed", value, callback)
+ )
.setProps({
minStep: 33,
});
accessory
.getService(Service.Lightbulb)
.getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => this.internalFanUpdate(accessory, "light", value, callback));
+ .on("set", (value, callback) =>
+ this.internalFanUpdate(accessory, "light", value, callback)
+ );
break;
case "thermostat":
if (!this.config.hideTHSwitch) {
accessory
.getService(Service.Switch)
.getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => this.internalThermostatUpdate(accessory, value, callback));
+ .on("set", (value, callback) =>
+ this.internalThermostatUpdate(accessory, value, callback)
+ );
}
accessory.log = this.log;
accessory.eveLogger = new EveHistoryService("weather", accessory, {
@@ -554,13 +729,16 @@ class eWeLink {
corrInterval.setCorrectingInterval(() => {
let dataToAdd = {
time: Date.now(),
- temp: accessory.getService(Service.TemperatureSensor).getCharacteristic(Characteristic.CurrentTemperature)
- .value,
+ temp: accessory
+ .getService(Service.TemperatureSensor)
+ .getCharacteristic(Characteristic.CurrentTemperature).value,
};
if (accessory.getService(Service.HumiditySensor)) {
dataToAdd.humidity = accessory
.getService(Service.HumiditySensor)
- .getCharacteristic(Characteristic.CurrentRelativeHumidity).value;
+ .getCharacteristic(
+ Characteristic.CurrentRelativeHumidity
+ ).value;
}
accessory.eveLogger.addEntry(dataToAdd);
}, 300000);
@@ -569,7 +747,9 @@ class eWeLink {
accessory
.getService(Service.Outlet)
.getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => this.internalOutletUpdate(accessory, value, callback));
+ .on("set", (value, callback) =>
+ this.internalOutletUpdate(accessory, value, callback)
+ );
accessory.log = this.log;
accessory.eveLogger = new EveHistoryService("energy", accessory, {
storage: "fs",
@@ -588,10 +768,15 @@ class eWeLink {
};
}
corrInterval.setCorrectingInterval(() => {
- let isOn = accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On).value,
+ let isOn = accessory
+ .getService(Service.Outlet)
+ .getCharacteristic(Characteristic.On).value,
currentWatt = isOn
- ? accessory.getService(Service.Outlet).getCharacteristic(EveService.Characteristics.CurrentConsumption)
- .value
+ ? accessory
+ .getService(Service.Outlet)
+ .getCharacteristic(
+ EveService.Characteristics.CurrentConsumption
+ ).value
: 0;
if (accessory.eveLogger.isHistoryLoaded()) {
accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData();
@@ -605,7 +790,9 @@ class eWeLink {
lastReset: accessory.context.extraPersistedData.lastReset,
});
} else {
- accessory.context.totalEnergy = accessory.context.totalEnergyTemp + (currentWatt * 10) / 3600 / 1000;
+ accessory.context.totalEnergy =
+ accessory.context.totalEnergyTemp +
+ (currentWatt * 10) / 3600 / 1000;
accessory.eveLogger.setExtraPersistedData({
totalenergy: accessory.context.totalEnergy,
lastReset: 0,
@@ -613,7 +800,8 @@ class eWeLink {
}
accessory.context.totalEnergytemp = 0;
} else {
- accessory.context.totalEnergyTemp += (currentWatt * 10) / 3600 / 1000;
+ accessory.context.totalEnergyTemp +=
+ (currentWatt * 10) / 3600 / 1000;
accessory.context.totalEnergy = accessory.context.totalEnergyTemp;
}
accessory.eveLogger.addEntry({
@@ -627,7 +815,8 @@ class eWeLink {
.on("get", callback => {
accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData();
if (accessory.context.extraPersistedData !== undefined) {
- accessory.context.totalEnergy = accessory.context.extraPersistedData.totalPower;
+ accessory.context.totalEnergy =
+ accessory.context.extraPersistedData.totalPower;
}
callback(null, accessory.context.totalEnergy);
});
@@ -646,7 +835,8 @@ class eWeLink {
.on("get", callback => {
accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData();
if (accessory.context.extraPersistedData !== undefined) {
- accessory.context.lastReset = accessory.context.extraPersistedData.lastReset;
+ accessory.context.lastReset =
+ accessory.context.extraPersistedData.lastReset;
}
callback(null, accessory.context.lastReset);
});
@@ -655,26 +845,36 @@ class eWeLink {
accessory
.getService(Service.Outlet)
.getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => this.internalUSBUpdate(accessory, value, callback));
+ .on("set", (value, callback) =>
+ this.internalUSBUpdate(accessory, value, callback)
+ );
break;
case "scm":
accessory
.getService(Service.Switch)
.getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => this.internalSCMUpdate(accessory, value, callback));
+ .on("set", (value, callback) =>
+ this.internalSCMUpdate(accessory, value, callback)
+ );
break;
case "light":
accessory
.getService(Service.Lightbulb)
.getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => this.internalLightbulbUpdate(accessory, value, callback));
+ .on("set", (value, callback) =>
+ this.internalLightbulbUpdate(accessory, value, callback)
+ );
if (cns.devicesBrightable.includes(accessory.context.eweUIID)) {
accessory
.getService(Service.Lightbulb)
.getCharacteristic(Characteristic.Brightness)
.on("set", (value, callback) => {
if (value > 0) {
- if (!accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value) {
+ if (
+ !accessory
+ .getService(Service.Lightbulb)
+ .getCharacteristic(Characteristic.On).value
+ ) {
this.internalLightbulbUpdate(accessory, true, function () {
return;
});
@@ -684,13 +884,19 @@ class eWeLink {
this.internalLightbulbUpdate(accessory, false, callback);
}
});
- } else if (cns.devicesColourable.includes(accessory.context.eweUIID)) {
+ } else if (
+ cns.devicesColourable.includes(accessory.context.eweUIID)
+ ) {
accessory
.getService(Service.Lightbulb)
.getCharacteristic(Characteristic.Brightness)
.on("set", (value, callback) => {
if (value > 0) {
- if (!accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value) {
+ if (
+ !accessory
+ .getService(Service.Lightbulb)
+ .getCharacteristic(Characteristic.On).value
+ ) {
this.internalLightbulbUpdate(accessory, true, function () {
return;
});
@@ -703,7 +909,9 @@ class eWeLink {
accessory
.getService(Service.Lightbulb)
.getCharacteristic(Characteristic.Hue)
- .on("set", (value, callback) => this.internalHSBUpdate(accessory, "hue", value, callback));
+ .on("set", (value, callback) =>
+ this.internalHSBUpdate(accessory, "hue", value, callback)
+ );
accessory
.getService(Service.Lightbulb)
.getCharacteristic(Characteristic.Saturation)
@@ -714,18 +922,24 @@ class eWeLink {
accessory
.getService(Service.Switch)
.getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => this.internalSwitchUpdate(accessory, value, callback));
+ .on("set", (value, callback) =>
+ this.internalSwitchUpdate(accessory, value, callback)
+ );
break;
case "rf_sub":
accessory.context.rfChls = accessory.context.rfChls || {};
if (accessory.context.sensorType === "button") {
Object.entries(accessory.context.rfChls).forEach(([k, v]) => {
- accessory.getService(v).updateCharacteristic(Characteristic.On, false);
+ accessory
+ .getService(v)
+ .updateCharacteristic(Characteristic.On, false);
accessory
.getService(v)
.getCharacteristic(Characteristic.On)
.on("set", (value, callback) => {
- value ? this.internalRFDeviceUpdate(accessory, k, callback) : callback();
+ value
+ ? this.internalRFDeviceUpdate(accessory, k, callback)
+ : callback();
});
});
}
@@ -746,7 +960,8 @@ class eWeLink {
.getCharacteristic(Characteristic.CurrentTemperature).value,
humidity: accessory
.getService(Service.HumiditySensor)
- .getCharacteristic(Characteristic.CurrentRelativeHumidity).value,
+ .getCharacteristic(Characteristic.CurrentRelativeHumidity)
+ .value,
};
accessory.eveLogger.addEntry(dataToAdd);
}, 300000);
@@ -755,61 +970,95 @@ class eWeLink {
}
this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
} catch (err) {
- this.log.warn("[%s] could not be refreshed as %s.", accessory.displayName, err);
+ this.log.warn(
+ "[%s] could not be refreshed as %s.",
+ accessory.displayName,
+ err
+ );
}
}
refreshAccessory(accessory, newParams) {
switch (accessory.context.type) {
case "valve":
- if (Object.keys(newParams).some(v => cns.devicesValveParams.includes(v)) && Array.isArray(newParams.switches)) {
+ if (
+ Object.keys(newParams).some(v =>
+ cns.devicesValveParams.includes(v)
+ ) &&
+ Array.isArray(newParams.switches)
+ ) {
this.externalValveUpdate(accessory, newParams);
}
return true;
case "blind":
- if (Object.keys(newParams).some(v => cns.devicesBlindParams.includes(v)) && Array.isArray(newParams.switches)) {
+ if (
+ Object.keys(newParams).some(v =>
+ cns.devicesBlindParams.includes(v)
+ ) &&
+ Array.isArray(newParams.switches)
+ ) {
this.externalBlindUpdate(accessory, newParams);
}
return true;
case "garage":
if (
- Object.keys(newParams).some(v => cns.devicesGarageParams.includes(v)) &&
+ Object.keys(newParams).some(v =>
+ cns.devicesGarageParams.includes(v)
+ ) &&
Array.isArray(newParams.switches)
) {
this.externalGarageUpdate(accessory, newParams);
}
return true;
case "lock":
- if (Object.keys(newParams).some(v => cns.devicesLockParams.includes(v))) {
+ if (
+ Object.keys(newParams).some(v => cns.devicesLockParams.includes(v))
+ ) {
this.externalLockUpdate(accessory, newParams);
}
return true;
case "sensor":
- if (Object.keys(newParams).some(v => cns.devicesSensorParams.includes(v))) {
+ if (
+ Object.keys(newParams).some(v => cns.devicesSensorParams.includes(v))
+ ) {
this.externalSensorUpdate(accessory, newParams);
}
return true;
case "fan":
- if (Object.keys(newParams).some(v => cns.devicesFanParams.includes(v))) {
+ if (
+ Object.keys(newParams).some(v => cns.devicesFanParams.includes(v))
+ ) {
this.externalFanUpdate(accessory, newParams);
}
return true;
case "thermostat":
- if (Object.keys(newParams).some(v => cns.devicesThermostatParams.includes(v))) {
+ if (
+ Object.keys(newParams).some(v =>
+ cns.devicesThermostatParams.includes(v)
+ )
+ ) {
this.externalThermostatUpdate(accessory, newParams);
}
return true;
case "outlet":
- if (Object.keys(newParams).some(v => cns.devicesOutletParams.includes(v))) {
+ if (
+ Object.keys(newParams).some(v => cns.devicesOutletParams.includes(v))
+ ) {
this.externalOutletUpdate(accessory, newParams);
}
return true;
case "usb":
- if (Object.keys(newParams).some(v => cns.devicesUSBParams.includes(v)) && Array.isArray(newParams.switches)) {
+ if (
+ Object.keys(newParams).some(v => cns.devicesUSBParams.includes(v)) &&
+ Array.isArray(newParams.switches)
+ ) {
this.externalUSBUpdate(accessory, newParams);
}
return true;
case "scm":
- if (Object.keys(newParams).some(v => cns.devicesSCMParams.includes(v)) && Array.isArray(newParams.switches)) {
+ if (
+ Object.keys(newParams).some(v => cns.devicesSCMParams.includes(v)) &&
+ Array.isArray(newParams.switches)
+ ) {
this.externalSCMUpdate(accessory, newParams);
}
return true;
@@ -818,7 +1067,11 @@ class eWeLink {
cns.devicesSingleSwitch.includes(accessory.context.eweUIID) &&
cns.devicesSingleSwitchLight.includes(accessory.context.eweModel)
) {
- if (Object.keys(newParams).some(v => cns.devicesSingleSwitchLightParams.includes(v))) {
+ if (
+ Object.keys(newParams).some(v =>
+ cns.devicesSingleSwitchLightParams.includes(v)
+ )
+ ) {
this.externalSingleLightUpdate(accessory, newParams);
}
} else if (
@@ -826,7 +1079,9 @@ class eWeLink {
cns.devicesMultiSwitchLight.includes(accessory.context.eweModel)
) {
if (
- Object.keys(newParams).some(v => cns.devicesMultiSwitchLightParams.includes(v)) &&
+ Object.keys(newParams).some(v =>
+ cns.devicesMultiSwitchLightParams.includes(v)
+ ) &&
Array.isArray(newParams.switches)
) {
this.externalMultiLightUpdate(accessory, newParams);
@@ -835,12 +1090,18 @@ class eWeLink {
return true;
case "switch":
if (cns.devicesSingleSwitch.includes(accessory.context.eweUIID)) {
- if (Object.keys(newParams).some(v => cns.devicesSingleSwitchParams.includes(v))) {
+ if (
+ Object.keys(newParams).some(v =>
+ cns.devicesSingleSwitchParams.includes(v)
+ )
+ ) {
this.externalSingleSwitchUpdate(accessory, newParams);
}
} else if (cns.devicesMultiSwitch.includes(accessory.context.eweUIID)) {
if (
- Object.keys(newParams).some(v => cns.devicesMultiSwitchParams.includes(v)) &&
+ Object.keys(newParams).some(v =>
+ cns.devicesMultiSwitchParams.includes(v)
+ ) &&
Array.isArray(newParams.switches)
) {
this.externalMultiSwitchUpdate(accessory, newParams);
@@ -848,7 +1109,11 @@ class eWeLink {
}
return true;
case "rf_pri":
- if (Object.keys(newParams).some(v => cns.devicesRFBridgeParams.includes(v))) {
+ if (
+ Object.keys(newParams).some(v =>
+ cns.devicesRFBridgeParams.includes(v)
+ )
+ ) {
this.externalRFDeviceUpdate(accessory, newParams);
}
return true;
@@ -856,7 +1121,11 @@ class eWeLink {
case "zb_pri":
return true;
case "zb_sub":
- if (Object.keys(newParams).some(v => cns.devicesZBBridgeParams.includes(v))) {
+ if (
+ Object.keys(newParams).some(v =>
+ cns.devicesZBBridgeParams.includes(v)
+ )
+ ) {
this.externalZBDeviceUpdate(accessory, newParams);
}
return true;
@@ -867,10 +1136,16 @@ class eWeLink {
removeAccessory(accessory) {
try {
this.devicesInHB.delete(accessory.context.hbDeviceId);
- this.api.unregisterPlatformAccessories("homebridge-ewelink", "eWeLink", [accessory]);
+ this.api.unregisterPlatformAccessories("homebridge-ewelink", "eWeLink", [
+ accessory,
+ ]);
this.log("[%s] has been removed from Homebridge.", accessory.displayName);
} catch (err) {
- this.log.warn("[%s] needed to be removed but couldn't as %s.", accessory.displayName, err);
+ this.log.warn(
+ "[%s] needed to be removed but couldn't as %s.",
+ accessory.displayName,
+ err
+ );
}
}
sendDeviceUpdate(accessory, params, callback) {
@@ -884,11 +1159,17 @@ class eWeLink {
this.wsClient.sendUpdate(payload);
callback();
} else {
- this.log.error("[%s] could not be updated as it appears to be offline.", accessory.displayName);
+ this.log.error(
+ "[%s] could not be updated as it appears to be offline.",
+ accessory.displayName
+ );
callback("Device has failed to update");
}
};
- if (cns.devicesNonLAN.includes(accessory.context.eweUIID) || !accessory.context.reachableLAN) {
+ if (
+ cns.devicesNonLAN.includes(accessory.context.eweUIID) ||
+ !accessory.context.reachableLAN
+ ) {
sendViaWS();
} else {
this.lanClient
@@ -896,7 +1177,11 @@ class eWeLink {
.then(() => callback())
.catch(err => {
if (this.debug) {
- this.log.warn("[%s] Reverting to web socket as %s.", accessory.displayName, err);
+ this.log.warn(
+ "[%s] Reverting to web socket as %s.",
+ accessory.displayName,
+ err
+ );
}
sendViaWS();
});
@@ -907,7 +1192,9 @@ class eWeLink {
switch (device.action) {
case "sysmsg":
if (
- (accessory = this.devicesInHB.get(device.deviceid + "SWX") || this.devicesInHB.get(device.deviceid + "SW0"))
+ (accessory =
+ this.devicesInHB.get(device.deviceid + "SWX") ||
+ this.devicesInHB.get(device.deviceid + "SW0"))
) {
let isX = accessory.context.hbDeviceId.substr(-1) === "X";
if (device.params.updateSource === "WS") {
@@ -919,17 +1206,23 @@ class eWeLink {
accessory.context.reachableWAN ? "online" : "offline"
);
this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
- if (accessory.context.reachableWAN) this.wsClient.requestUpdate(accessory);
+ if (accessory.context.reachableWAN)
+ this.wsClient.requestUpdate(accessory);
} else {
if (this.debug) {
- this.log("[%s] Nothing to update from above WS message.", accessory.displayName);
+ this.log(
+ "[%s] Nothing to update from above WS message.",
+ accessory.displayName
+ );
}
}
}
if (!isX) {
for (let i = 1; i <= accessory.context.channelCount; i++) {
if (this.devicesInHB.has(device.deviceid + "SW" + i)) {
- let oAccessory = this.devicesInHB.get(device.deviceid + "SW" + i);
+ let oAccessory = this.devicesInHB.get(
+ device.deviceid + "SW" + i
+ );
oAccessory.context.reachableWAN = device.params.online;
this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory);
}
@@ -939,15 +1232,29 @@ class eWeLink {
break;
case "update":
if (
- (accessory = this.devicesInHB.get(device.deviceid + "SWX") || this.devicesInHB.get(device.deviceid + "SW0"))
+ (accessory =
+ this.devicesInHB.get(device.deviceid + "SWX") ||
+ this.devicesInHB.get(device.deviceid + "SW0"))
) {
- if (device.params.updateSource === "WS" && !accessory.context.reachableWAN) {
+ if (
+ device.params.updateSource === "WS" &&
+ !accessory.context.reachableWAN
+ ) {
accessory.context.reachableWAN = true;
- this.log("[%s] has been reported [online] via [WS].", accessory.displayName);
+ this.log(
+ "[%s] has been reported [online] via [WS].",
+ accessory.displayName
+ );
}
- if (device.params.updateSource === "LAN" && !accessory.context.reachableLAN) {
+ if (
+ device.params.updateSource === "LAN" &&
+ !accessory.context.reachableLAN
+ ) {
accessory.context.reachableLAN = true;
- this.log("[%s] has been reported [online] via [LAN].", accessory.displayName);
+ this.log(
+ "[%s] has been reported [online] via [LAN].",
+ accessory.displayName
+ );
}
if (this.debug) {
this.log(
@@ -988,27 +1295,41 @@ class eWeLink {
.updateCharacteristic(Characteristic.InUse, value);
switch (value) {
case 0:
- accessory.getService(valve).updateCharacteristic(Characteristic.RemainingDuration, 0);
+ accessory
+ .getService(valve)
+ .updateCharacteristic(Characteristic.RemainingDuration, 0);
clearTimeout(accessory.getService(valve).timer);
break;
case 1:
- let timer = accessory.getService(valve).getCharacteristic(Characteristic.SetDuration).value;
- accessory.getService(valve).updateCharacteristic(Characteristic.RemainingDuration, timer);
+ let timer = accessory
+ .getService(valve)
+ .getCharacteristic(Characteristic.SetDuration).value;
+ accessory
+ .getService(valve)
+ .updateCharacteristic(Characteristic.RemainingDuration, timer);
accessory.getService(valve).timer = setTimeout(() => {
- accessory.getService(valve).setCharacteristic(Characteristic.Active, 0);
+ accessory
+ .getService(valve)
+ .setCharacteristic(Characteristic.Active, 0);
}, timer * 1000);
break;
}
- params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
+ params.switches = this.devicesInEwe.get(
+ accessory.context.eweDeviceId
+ ).params.switches;
switch (valve) {
case "Valve A":
params.switches[0].switch = value ? "on" : "off";
- params.switches[1].switch = accessory.getService("Valve B").getCharacteristic(Characteristic.Active).value
+ params.switches[1].switch = accessory
+ .getService("Valve B")
+ .getCharacteristic(Characteristic.Active).value
? "on"
: "off";
break;
case "Valve B":
- params.switches[0].switch = accessory.getService("Valve A").getCharacteristic(Characteristic.Active).value
+ params.switches[0].switch = accessory
+ .getService("Valve A")
+ .getCharacteristic(Characteristic.Active).value
? "on"
: "off";
params.switches[1].switch = value ? "on" : "off";
@@ -1020,7 +1341,8 @@ class eWeLink {
params.switches[3].switch = "off";
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str =
+ "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -1034,13 +1356,18 @@ class eWeLink {
if (!(blindConfig = this.cusG.get(accessory.context.hbDeviceId))) {
throw "group config missing";
}
- if (blindConfig.type !== "blind" || !["oneSwitch", "twoSwitch"].includes(blindConfig.setup)) {
+ if (
+ blindConfig.type !== "blind" ||
+ !["oneSwitch", "twoSwitch"].includes(blindConfig.setup)
+ ) {
throw "improper configuration";
}
let oldPos,
params = {};
value = value >= 50 ? 100 : 0;
- oldPos = accessory.getService(Service.WindowCovering).getCharacteristic(Characteristic.PositionState).value;
+ oldPos = accessory
+ .getService(Service.WindowCovering)
+ .getCharacteristic(Characteristic.PositionState).value;
if (value === oldPos * 100) {
accessory
.getService(Service.WindowCovering)
@@ -1054,7 +1381,9 @@ class eWeLink {
params.switch = "on";
break;
case "twoSwitch":
- params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
+ params.switches = this.devicesInEwe.get(
+ accessory.context.eweDeviceId
+ ).params.switches;
params.switches[0].switch = value === 100 ? "on" : "off";
params.switches[1].switch = value === 0 ? "on" : "off";
break;
@@ -1074,7 +1403,8 @@ class eWeLink {
callback();
}, parseInt(blindConfig.operationTime) * 100);
} catch (err) {
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str =
+ "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -1088,7 +1418,10 @@ class eWeLink {
if (!(garageConfig = this.cusG.get(accessory.context.hbDeviceId))) {
throw "group config missing";
}
- if (garageConfig.type !== "garage" || !["oneSwitch", "twoSwitch"].includes(garageConfig.setup)) {
+ if (
+ garageConfig.type !== "garage" ||
+ !["oneSwitch", "twoSwitch"].includes(garageConfig.setup)
+ ) {
throw "improper configuration";
}
accessory.context.inUse = true;
@@ -1099,17 +1432,24 @@ class eWeLink {
newPos = value,
params = {},
delay = 0;
- if (sensorDefinition && !(sAccessory = this.devicesInHB.get(garageConfig.sensorId + "SWX"))) {
+ if (
+ sensorDefinition &&
+ !(sAccessory = this.devicesInHB.get(garageConfig.sensorId + "SWX"))
+ ) {
throw "defined DW2 sensor doesn't exist";
}
if (sAccessory.context.type !== "sensor") {
throw "defined DW2 sensor isn't a sensor";
}
oldPos = sAccessory
- ? sAccessory.getService(Service.ContactSensor).getCharacteristic(Characteristic.ContactSensorState).value === 0
+ ? sAccessory
+ .getService(Service.ContactSensor)
+ .getCharacteristic(Characteristic.ContactSensorState).value === 0
? 1
: 0
- : accessory.getService(Service.GarageDoorOpener).getCharacteristic(Characteristic.CurrentDoorState).value;
+ : accessory
+ .getService(Service.GarageDoorOpener)
+ .getCharacteristic(Characteristic.CurrentDoorState).value;
if (newPos === oldPos % 2) {
accessory.context.inUse = false;
callback();
@@ -1118,7 +1458,10 @@ class eWeLink {
if (garageConfig.setup === "oneSwitch" && [2, 3].includes(oldPos)) {
accessory
.getService(Service.GarageDoorOpener)
- .updateCharacteristic(Characteristic.CurrentDoorState, ((oldPos * 2) % 3) + 2);
+ .updateCharacteristic(
+ Characteristic.CurrentDoorState,
+ ((oldPos * 2) % 3) + 2
+ );
delay = 1500;
}
setTimeout(() => {
@@ -1132,7 +1475,9 @@ class eWeLink {
params.switch = "on";
break;
case "twoSwitch":
- params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
+ params.switches = this.devicesInEwe.get(
+ accessory.context.eweDeviceId
+ ).params.switches;
params.switches[0].switch = newPos === 0 ? "on" : "off";
params.switches[1].switch = newPos === 1 ? "on" : "off";
break;
@@ -1153,7 +1498,8 @@ class eWeLink {
callback();
} catch (err) {
accessory.context.inUse = false;
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str =
+ "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -1188,7 +1534,8 @@ class eWeLink {
}, parseInt(lockConfig.operationTime) * 100);
} catch (err) {
accessory.context.inUse = false;
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str =
+ "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -1203,31 +1550,45 @@ class eWeLink {
case "power":
newPower = value;
newSpeed = value ? 33 : 0;
- newLight = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value;
+ newLight = accessory
+ .getService(Service.Lightbulb)
+ .getCharacteristic(Characteristic.On).value;
break;
case "speed":
newPower = value >= 33 ? 1 : 0;
newSpeed = value;
- newLight = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value;
+ newLight = accessory
+ .getService(Service.Lightbulb)
+ .getCharacteristic(Characteristic.On).value;
break;
case "light":
- newPower = accessory.getService(Service.Fanv2).getCharacteristic(Characteristic.Active).value;
- newSpeed = accessory.getService(Service.Fanv2).getCharacteristic(Characteristic.RotationSpeed).value;
+ newPower = accessory
+ .getService(Service.Fanv2)
+ .getCharacteristic(Characteristic.Active).value;
+ newSpeed = accessory
+ .getService(Service.Fanv2)
+ .getCharacteristic(Characteristic.RotationSpeed).value;
newLight = value;
break;
}
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, newLight);
+ accessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.On, newLight);
accessory
.getService(Service.Fanv2)
.updateCharacteristic(Characteristic.Active, newPower)
.updateCharacteristic(Characteristic.RotationSpeed, newSpeed);
let params = {
- switches: this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches,
+ switches: this.devicesInEwe.get(accessory.context.eweDeviceId).params
+ .switches,
};
params.switches[0].switch = newLight ? "on" : "off";
- params.switches[1].switch = newPower === 1 && newSpeed >= 33 ? "on" : "off";
- params.switches[2].switch = newPower === 1 && newSpeed >= 66 && newSpeed < 99 ? "on" : "off";
- params.switches[3].switch = newPower === 1 && newSpeed >= 99 ? "on" : "off";
+ params.switches[1].switch =
+ newPower === 1 && newSpeed >= 33 ? "on" : "off";
+ params.switches[2].switch =
+ newPower === 1 && newSpeed >= 66 && newSpeed < 99 ? "on" : "off";
+ params.switches[3].switch =
+ newPower === 1 && newSpeed >= 99 ? "on" : "off";
if (this.debug) {
this.log.warn("Fan Update - setting " + type + " to " + value);
this.log(
@@ -1240,7 +1601,8 @@ class eWeLink {
}
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str =
+ "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -1255,12 +1617,19 @@ class eWeLink {
mainSwitch: value ? "on" : "off",
};
if (this.debug) {
- this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
+ this.log(
+ "[%s] updating to turn [%s].",
+ accessory.displayName,
+ value ? "on" : "off"
+ );
}
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
+ accessory
+ .getService(Service.Switch)
+ .updateCharacteristic(Characteristic.On, value);
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str =
+ "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -1274,9 +1643,15 @@ class eWeLink {
switch: value ? "on" : "off",
};
if (this.debug) {
- this.log("[%s] requesting to turn [%s].", accessory.displayName, value ? "on" : "off");
+ this.log(
+ "[%s] requesting to turn [%s].",
+ accessory.displayName,
+ value ? "on" : "off"
+ );
}
- accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, value);
+ accessory
+ .getService(Service.Outlet)
+ .updateCharacteristic(Characteristic.On, value);
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
callback("[" + accessory.displayName + "] " + err + ".");
@@ -1288,13 +1663,20 @@ class eWeLink {
throw "it is currently offline";
}
let params = {
- switches: this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches,
+ switches: this.devicesInEwe.get(accessory.context.eweDeviceId).params
+ .switches,
};
params.switches[0].switch = value ? "on" : "off";
if (this.debug) {
- this.log("[%s] requesting to turn [%s].", accessory.displayName, value ? "on" : "off");
+ this.log(
+ "[%s] requesting to turn [%s].",
+ accessory.displayName,
+ value ? "on" : "off"
+ );
}
- accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, value);
+ accessory
+ .getService(Service.Outlet)
+ .updateCharacteristic(Characteristic.On, value);
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
callback("[" + accessory.displayName + "] " + err + ".");
@@ -1306,13 +1688,20 @@ class eWeLink {
throw "it is currently offline";
}
let params = {
- switches: this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches,
+ switches: this.devicesInEwe.get(accessory.context.eweDeviceId).params
+ .switches,
};
params.switches[0].switch = value ? "on" : "off";
if (this.debug) {
- this.log("[%s] requesting to turn [%s].", accessory.displayName, value ? "on" : "off");
+ this.log(
+ "[%s] requesting to turn [%s].",
+ accessory.displayName,
+ value ? "on" : "off"
+ );
}
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
+ accessory
+ .getService(Service.Switch)
+ .updateCharacteristic(Characteristic.On, value);
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
callback("[" + accessory.displayName + "] " + err + ".");
@@ -1334,24 +1723,44 @@ class eWeLink {
params.switch = value ? "on" : "off";
}
if (this.debug) {
- this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
+ this.log(
+ "[%s] updating to turn [%s].",
+ accessory.displayName,
+ value ? "on" : "off"
+ );
}
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
+ accessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.On, value);
break;
case "0":
- params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
+ params.switches = this.devicesInEwe.get(
+ accessory.context.eweDeviceId
+ ).params.switches;
params.switches[0].switch = value ? "on" : "off";
params.switches[1].switch = value ? "on" : "off";
params.switches[2].switch = value ? "on" : "off";
params.switches[3].switch = value ? "on" : "off";
if (this.debug) {
- this.log("[%s] updating to turn group [%s].", accessory.displayName, value ? "on" : "off");
+ this.log(
+ "[%s] updating to turn group [%s].",
+ accessory.displayName,
+ value ? "on" : "off"
+ );
}
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
+ accessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.On, value);
for (let i = 1; i <= 4; i++) {
- if (this.devicesInHB.has(accessory.context.eweDeviceId + "SW" + i)) {
- oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i);
- oAccessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
+ if (
+ this.devicesInHB.has(accessory.context.eweDeviceId + "SW" + i)
+ ) {
+ oAccessory = this.devicesInHB.get(
+ accessory.context.eweDeviceId + "SW" + i
+ );
+ oAccessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.On, value);
}
}
break;
@@ -1360,14 +1769,26 @@ class eWeLink {
case "3":
case "4":
if (this.debug) {
- this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
+ this.log(
+ "[%s] updating to turn [%s].",
+ accessory.displayName,
+ value ? "on" : "off"
+ );
}
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
+ accessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.On, value);
let tAccessory,
masterState = "off";
- params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
+ params.switches = this.devicesInEwe.get(
+ accessory.context.eweDeviceId
+ ).params.switches;
for (let i = 1; i <= 4; i++) {
- if ((tAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
+ if (
+ (tAccessory = this.devicesInHB.get(
+ accessory.context.eweDeviceId + "SW" + i
+ ))
+ ) {
i === parseInt(accessory.context.switchNumber)
? (params.switches[i - 1].switch = value ? "on" : "off")
: (params.switches[i - 1].switch = tAccessory
@@ -1375,22 +1796,33 @@ class eWeLink {
.getCharacteristic(Characteristic.On).value
? "on"
: "off");
- if (tAccessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value) {
+ if (
+ tAccessory
+ .getService(Service.Lightbulb)
+ .getCharacteristic(Characteristic.On).value
+ ) {
masterState = "on";
}
} else {
params.switches[i - 1].switch = "off";
}
}
- oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
- oAccessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, masterState === "on");
+ oAccessory = this.devicesInHB.get(
+ accessory.context.eweDeviceId + "SW0"
+ );
+ oAccessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.On, masterState === "on");
break;
default:
- throw "unknown switch number [" + accessory.context.switchNumber + "]";
+ throw (
+ "unknown switch number [" + accessory.context.switchNumber + "]"
+ );
}
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str =
+ "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -1403,9 +1835,15 @@ class eWeLink {
let params = {};
if (value === 0) {
params.switch = "off";
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, false);
+ accessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.On, false);
} else {
- if (!accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value) {
+ if (
+ !accessory
+ .getService(Service.Lightbulb)
+ .getCharacteristic(Characteristic.On).value
+ ) {
params.switch = "on";
}
switch (accessory.context.eweUIID) {
@@ -1419,14 +1857,21 @@ class eWeLink {
default:
throw "unknown device UIID";
}
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Brightness, value);
+ accessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.Brightness, value);
}
if (this.debug) {
- this.log("[%s] updating brightness to [%s%].", accessory.displayName, value);
+ this.log(
+ "[%s] updating brightness to [%s%].",
+ accessory.displayName,
+ value
+ );
}
setTimeout(() => this.sendDeviceUpdate(accessory, params, callback), 250);
} catch (err) {
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str =
+ "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -1438,8 +1883,12 @@ class eWeLink {
}
let newRGB,
params = {},
- curHue = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Hue).value,
- curSat = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Saturation).value;
+ curHue = accessory
+ .getService(Service.Lightbulb)
+ .getCharacteristic(Characteristic.Hue).value,
+ curSat = accessory
+ .getService(Service.Lightbulb)
+ .getCharacteristic(Characteristic.Saturation).value;
switch (type) {
case "hue":
newRGB = convert.hsv.rgb(value, curSat, 100);
@@ -1467,9 +1916,15 @@ class eWeLink {
throw "unknown device UIID";
}
if (this.debug) {
- this.log("[%s] updating hue to [%s°].", accessory.displayName, value);
+ this.log(
+ "[%s] updating hue to [%s°].",
+ accessory.displayName,
+ value
+ );
}
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Hue, value);
+ accessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.Hue, value);
break;
case "bri":
switch (accessory.context.eweUIID) {
@@ -1493,16 +1948,23 @@ class eWeLink {
break;
}
if (this.debug) {
- this.log("[%s] updating brightness to [%s%].", accessory.displayName, value);
+ this.log(
+ "[%s] updating brightness to [%s%].",
+ accessory.displayName,
+ value
+ );
}
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Brightness, value);
+ accessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.Brightness, value);
break;
default:
throw "unknown device UIID";
}
setTimeout(() => this.sendDeviceUpdate(accessory, params, callback), 250);
} catch (err) {
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str =
+ "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -1518,24 +1980,44 @@ class eWeLink {
case "X":
params.switch = value ? "on" : "off";
if (this.debug) {
- this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
+ this.log(
+ "[%s] updating to turn [%s].",
+ accessory.displayName,
+ value ? "on" : "off"
+ );
}
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
+ accessory
+ .getService(Service.Switch)
+ .updateCharacteristic(Characteristic.On, value);
break;
case "0":
- params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
+ params.switches = this.devicesInEwe.get(
+ accessory.context.eweDeviceId
+ ).params.switches;
params.switches[0].switch = value ? "on" : "off";
params.switches[1].switch = value ? "on" : "off";
params.switches[2].switch = value ? "on" : "off";
params.switches[3].switch = value ? "on" : "off";
if (this.debug) {
- this.log("[%s] updating to turn group [%s].", accessory.displayName, value ? "on" : "off");
+ this.log(
+ "[%s] updating to turn group [%s].",
+ accessory.displayName,
+ value ? "on" : "off"
+ );
}
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
+ accessory
+ .getService(Service.Switch)
+ .updateCharacteristic(Characteristic.On, value);
for (let i = 1; i <= 4; i++) {
- if (this.devicesInHB.has(accessory.context.eweDeviceId + "SW" + i)) {
- oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i);
- oAccessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
+ if (
+ this.devicesInHB.has(accessory.context.eweDeviceId + "SW" + i)
+ ) {
+ oAccessory = this.devicesInHB.get(
+ accessory.context.eweDeviceId + "SW" + i
+ );
+ oAccessory
+ .getService(Service.Switch)
+ .updateCharacteristic(Characteristic.On, value);
}
}
break;
@@ -1544,14 +2026,26 @@ class eWeLink {
case "3":
case "4":
if (this.debug) {
- this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
+ this.log(
+ "[%s] updating to turn [%s].",
+ accessory.displayName,
+ value ? "on" : "off"
+ );
}
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
+ accessory
+ .getService(Service.Switch)
+ .updateCharacteristic(Characteristic.On, value);
let tAccessory,
masterState = "off";
- params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
+ params.switches = this.devicesInEwe.get(
+ accessory.context.eweDeviceId
+ ).params.switches;
for (let i = 1; i <= 4; i++) {
- if ((tAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
+ if (
+ (tAccessory = this.devicesInHB.get(
+ accessory.context.eweDeviceId + "SW" + i
+ ))
+ ) {
i === parseInt(accessory.context.switchNumber)
? (params.switches[i - 1].switch = value ? "on" : "off")
: (params.switches[i - 1].switch = tAccessory
@@ -1559,22 +2053,33 @@ class eWeLink {
.getCharacteristic(Characteristic.On).value
? "on"
: "off");
- if (tAccessory.getService(Service.Switch).getCharacteristic(Characteristic.On).value) {
+ if (
+ tAccessory
+ .getService(Service.Switch)
+ .getCharacteristic(Characteristic.On).value
+ ) {
masterState = "on";
}
} else {
params.switches[i - 1].switch = "off";
}
}
- oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
- oAccessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, masterState === "on");
+ oAccessory = this.devicesInHB.get(
+ accessory.context.eweDeviceId + "SW0"
+ );
+ oAccessory
+ .getService(Service.Switch)
+ .updateCharacteristic(Characteristic.On, masterState === "on");
break;
default:
- throw "unknown switch number [" + accessory.context.switchNumber + "]";
+ throw (
+ "unknown switch number [" + accessory.context.switchNumber + "]"
+ );
}
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str =
+ "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -1590,16 +2095,32 @@ class eWeLink {
rfChl,
};
if (this.debug) {
- this.log("[%s %s] mimicking RF button press.", accessory.displayName, accessory.context.rfChls[rfChl]);
+ this.log(
+ "[%s %s] mimicking RF button press.",
+ accessory.displayName,
+ accessory.context.rfChls[rfChl]
+ );
}
- accessory.getService(accessory.context.rfChls[rfChl]).updateCharacteristic(Characteristic.On, true);
+ accessory
+ .getService(accessory.context.rfChls[rfChl])
+ .updateCharacteristic(Characteristic.On, true);
this.sendDeviceUpdate(accessory, params, callback);
setTimeout(
- () => accessory.getService(accessory.context.rfChls[rfChl]).updateCharacteristic(Characteristic.On, false),
+ () =>
+ accessory
+ .getService(accessory.context.rfChls[rfChl])
+ .updateCharacteristic(Characteristic.On, false),
3000
);
} catch (err) {
- let str = "[" + accessory.displayName + " " + name + "] could not be updated as " + err + ".";
+ let str =
+ "[" +
+ accessory.displayName +
+ " " +
+ name +
+ "] could not be updated as " +
+ err +
+ ".";
this.log.error(str);
callback(str);
}
@@ -1609,21 +2130,39 @@ class eWeLink {
["A", "B"].forEach((v, k) => {
accessory
.getService("Valve " + v)
- .updateCharacteristic(Characteristic.Active, params.switches[k].switch === "on")
- .updateCharacteristic(Characteristic.InUse, params.switches[k].switch === "on");
+ .updateCharacteristic(
+ Characteristic.Active,
+ params.switches[k].switch === "on"
+ )
+ .updateCharacteristic(
+ Characteristic.InUse,
+ params.switches[k].switch === "on"
+ );
if (params.switches[k].switch === "on") {
- let timer = accessory.getService("Valve " + v).getCharacteristic(Characteristic.SetDuration).value;
- accessory.getService("Valve " + v).updateCharacteristic(Characteristic.RemainingDuration, timer);
+ let timer = accessory
+ .getService("Valve " + v)
+ .getCharacteristic(Characteristic.SetDuration).value;
+ accessory
+ .getService("Valve " + v)
+ .updateCharacteristic(Characteristic.RemainingDuration, timer);
accessory.getService("Valve " + v).timer = setTimeout(() => {
- accessory.getService("Valve " + v).setCharacteristic(Characteristic.Active, 0);
+ accessory
+ .getService("Valve " + v)
+ .setCharacteristic(Characteristic.Active, 0);
}, timer * 1000);
} else {
- accessory.getService("Valve " + v).updateCharacteristic(Characteristic.RemainingDuration, 0);
+ accessory
+ .getService("Valve " + v)
+ .updateCharacteristic(Characteristic.RemainingDuration, 0);
clearTimeout(accessory.getService("Valve " + v).timer);
}
});
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.log.warn(
+ "[%s] could not be updated as %s.",
+ accessory.displayName,
+ err
+ );
}
}
externalBlindUpdate(accessory, params) {
@@ -1632,7 +2171,10 @@ class eWeLink {
if (!(blindConfig = this.cusG.get(accessory.context.hbDeviceId))) {
throw "group config missing";
}
- if (blindConfig.type !== "blind" || ["oneSwitch", "twoSwitch"].includes(blindConfig.setup)) {
+ if (
+ blindConfig.type !== "blind" ||
+ ["oneSwitch", "twoSwitch"].includes(blindConfig.setup)
+ ) {
throw "improper configuration";
}
switch (blindConfig.setup) {
@@ -1641,12 +2183,17 @@ class eWeLink {
return;
}
nSte =
- accessory.getService(Service.WindowCovering).getCharacteristic(Characteristic.PositionState).value === 0
+ accessory
+ .getService(Service.WindowCovering)
+ .getCharacteristic(Characteristic.PositionState).value === 0
? 1
: 0;
break;
case "twoSwitch":
- if (params.switches[0].switch === "off" && params.switches[1].switch === "off") {
+ if (
+ params.switches[0].switch === "off" &&
+ params.switches[1].switch === "off"
+ ) {
return;
}
let switchUp = params.switches[0].switch === "on" ? -1 : 0, // matrix of numbers to get
@@ -1665,19 +2212,27 @@ class eWeLink {
.updateCharacteristic(Characteristic.CurrentPosition, nSte * 100);
}, parseInt(blindConfig.operationTime) * 100);
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.log.warn(
+ "[%s] could not be updated as %s.",
+ accessory.displayName,
+ err
+ );
}
}
externalGarageUpdate(accessory, params) {
try {
let garageConfig,
- oldPos = accessory.getService(Service.GarageDoorOpener).getCharacteristic(Characteristic.CurrentDoorState)
- .value,
+ oldPos = accessory
+ .getService(Service.GarageDoorOpener)
+ .getCharacteristic(Characteristic.CurrentDoorState).value,
newPos = [0, 2].includes(oldPos) ? 3 : 2;
if (!(garageConfig = this.cusG.get(accessory.context.hbDeviceId))) {
throw "group config missing";
}
- if (garageConfig.type !== "garage" || !["oneSwitch", "twoSwitch"].includes(garageConfig.setup)) {
+ if (
+ garageConfig.type !== "garage" ||
+ !["oneSwitch", "twoSwitch"].includes(garageConfig.setup)
+ ) {
throw "improper configuration";
}
if (accessory.context.inUse || garageConfig.sensorId) {
@@ -1690,7 +2245,10 @@ class eWeLink {
}
break;
case "twoSwitch":
- if (params.switches[0].switch === params.switches[1].switch || params.switches[oldPos % 2].switch === "on") {
+ if (
+ params.switches[0].switch === params.switches[1].switch ||
+ params.switches[oldPos % 2].switch === "on"
+ ) {
return;
}
break;
@@ -1712,7 +2270,11 @@ class eWeLink {
}, parseInt(garageConfig.operationTime) * 100);
} catch (err) {
accessory.context.inUse = false;
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.log.warn(
+ "[%s] could not be updated as %s.",
+ accessory.displayName,
+ err
+ );
}
}
externalLockUpdate(accessory, params) {
@@ -1741,22 +2303,39 @@ class eWeLink {
}, parseInt(lockConfig.operationTime) * 100);
} catch (err) {
accessory.context.inUse = false;
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.log.warn(
+ "[%s] could not be updated as %s.",
+ accessory.displayName,
+ err
+ );
}
}
externalSensorUpdate(accessory, params) {
try {
- let newState = params.switch === "on" ? 1 : 0,
- oAccessory = false;
- accessory.getService(Service.ContactSensor).updateCharacteristic(Characteristic.ContactSensorState, newState);
if (params.hasOwnProperty("battery")) {
let batteryService =
- accessory.getService(Service.BatteryService) || accessory.addService(Service.BatteryService);
- batteryService.updateCharacteristic(Characteristic.BatteryLevel, params.battery);
- batteryService.updateCharacteristic(Characteristic.StatusLowBattery, params.battery <= 25);
+ accessory.getService(Service.BatteryService) ||
+ accessory.addService(Service.BatteryService),
+ scaledBattery = Math.round(params.battery * 33.3);
+ batteryService.updateCharacteristic(
+ Characteristic.BatteryLevel,
+ scaledBattery
+ );
+ batteryService.updateCharacteristic(
+ Characteristic.StatusLowBattery,
+ scaledBattery < 25
+ );
}
+ let newState = params.switch === "on" ? 1 : 0,
+ oAccessory = false;
+ accessory
+ .getService(Service.ContactSensor)
+ .updateCharacteristic(Characteristic.ContactSensorState, newState);
this.cusG.forEach(group => {
- if (group.sensorId === accessory.context.eweDeviceId && group.type === "garage") {
+ if (
+ group.sensorId === accessory.context.eweDeviceId &&
+ group.type === "garage"
+ ) {
if ((oAccessory = this.devicesInHB.get(group.deviceId + "SWX"))) {
switch (newState) {
case 0:
@@ -1780,7 +2359,11 @@ class eWeLink {
}
});
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.log.warn(
+ "[%s] could not be updated as %s.",
+ accessory.displayName,
+ err
+ );
}
}
externalFanUpdate(accessory, params) {
@@ -1788,7 +2371,11 @@ class eWeLink {
let light, status, speed;
if (Array.isArray(params.switches)) {
light = params.switches[0].switch === "on";
- switch (params.switches[1].switch + params.switches[2].switch + params.switches[3].switch) {
+ switch (
+ params.switches[1].switch +
+ params.switches[2].switch +
+ params.switches[3].switch
+ ) {
default:
status = 0;
speed = 0;
@@ -1805,65 +2392,109 @@ class eWeLink {
status = 1;
speed = 99;
}
- } else if (params.hasOwnProperty("light") && params.hasOwnProperty("fan") && params.hasOwnProperty("speed")) {
+ } else if (
+ params.hasOwnProperty("light") &&
+ params.hasOwnProperty("fan") &&
+ params.hasOwnProperty("speed")
+ ) {
light = params.light === "on";
status = params.fan === "on" ? 1 : 0;
speed = params.speed * 33 * status;
} else {
throw "unknown parameters received";
}
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, light);
+ accessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.On, light);
accessory
.getService(Service.Fanv2)
.updateCharacteristic(Characteristic.Active, status)
.updateCharacteristic(Characteristic.RotationSpeed, speed);
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.log.warn(
+ "[%s] could not be updated as %s.",
+ accessory.displayName,
+ err
+ );
}
}
externalThermostatUpdate(accessory, params) {
try {
- if (!this.config.hideTHSwitch && (params.hasOwnProperty("switch") || params.hasOwnProperty("mainSwitch"))) {
- let newState = params.hasOwnProperty("switch") ? params.switch === "on" : params.mainSwitch === "on";
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, newState);
+ if (
+ !this.config.hideTHSwitch &&
+ (params.hasOwnProperty("switch") || params.hasOwnProperty("mainSwitch"))
+ ) {
+ let newState = params.hasOwnProperty("switch")
+ ? params.switch === "on"
+ : params.mainSwitch === "on";
+ accessory
+ .getService(Service.Switch)
+ .updateCharacteristic(Characteristic.On, newState);
}
let eveLog = {
time: Date.now(),
};
- if (params.hasOwnProperty("currentTemperature") && accessory.getService(Service.TemperatureSensor)) {
- let currentTemp = params.currentTemperature !== "unavailable" ? params.currentTemperature : 0;
+ if (
+ params.hasOwnProperty("currentTemperature") &&
+ accessory.getService(Service.TemperatureSensor)
+ ) {
+ let currentTemp =
+ params.currentTemperature !== "unavailable"
+ ? params.currentTemperature
+ : 0;
accessory
.getService(Service.TemperatureSensor)
.updateCharacteristic(Characteristic.CurrentTemperature, currentTemp);
eveLog.temp = parseFloat(currentTemp);
}
- if (params.hasOwnProperty("currentHumidity") && accessory.getService(Service.HumiditySensor)) {
- let currentHumi = params.currentHumidity !== "unavailable" ? params.currentHumidity : 0;
+ if (
+ params.hasOwnProperty("currentHumidity") &&
+ accessory.getService(Service.HumiditySensor)
+ ) {
+ let currentHumi =
+ params.currentHumidity !== "unavailable" ? params.currentHumidity : 0;
accessory
.getService(Service.HumiditySensor)
- .updateCharacteristic(Characteristic.CurrentRelativeHumidity, currentHumi);
+ .updateCharacteristic(
+ Characteristic.CurrentRelativeHumidity,
+ currentHumi
+ );
eveLog.humidity = parseFloat(currentHumi);
}
if (eveLog.hasOwnProperty("temp") || eveLog.hasOwnProperty("humidity")) {
accessory.eveLogger.addEntry(eveLog);
}
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.log.warn(
+ "[%s] could not be updated as %s.",
+ accessory.displayName,
+ err
+ );
}
}
externalOutletUpdate(accessory, params) {
try {
if (params.hasOwnProperty("switch")) {
- accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, params.switch === "on");
+ accessory
+ .getService(Service.Outlet)
+ .updateCharacteristic(Characteristic.On, params.switch === "on");
}
if (params.hasOwnProperty("power")) {
accessory
.getService(Service.Outlet)
- .updateCharacteristic(EveService.Characteristics.CurrentConsumption, parseFloat(params.power));
+ .updateCharacteristic(
+ EveService.Characteristics.CurrentConsumption,
+ parseFloat(params.power)
+ );
accessory
.getService(Service.Outlet)
- .updateCharacteristic(Characteristic.OutletInUse, parseFloat(params.power) > 0);
- let isOn = accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On).value;
+ .updateCharacteristic(
+ Characteristic.OutletInUse,
+ parseFloat(params.power) > 0
+ );
+ let isOn = accessory
+ .getService(Service.Outlet)
+ .getCharacteristic(Characteristic.On).value;
accessory.eveLogger.addEntry({
time: Date.now(),
power: isOn ? parseFloat(params.power) : 0,
@@ -1872,29 +2503,57 @@ class eWeLink {
if (params.hasOwnProperty("voltage")) {
accessory
.getService(Service.Outlet)
- .updateCharacteristic(EveService.Characteristics.Voltage, parseFloat(params.voltage));
+ .updateCharacteristic(
+ EveService.Characteristics.Voltage,
+ parseFloat(params.voltage)
+ );
}
if (params.hasOwnProperty("current")) {
accessory
.getService(Service.Outlet)
- .updateCharacteristic(EveService.Characteristics.ElectricCurrent, parseFloat(params.current));
+ .updateCharacteristic(
+ EveService.Characteristics.ElectricCurrent,
+ parseFloat(params.current)
+ );
}
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.log.warn(
+ "[%s] could not be updated as %s.",
+ accessory.displayName,
+ err
+ );
}
}
externalUSBUpdate(accessory, params) {
try {
- accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, params.switches[0].switch === "on");
+ accessory
+ .getService(Service.Outlet)
+ .updateCharacteristic(
+ Characteristic.On,
+ params.switches[0].switch === "on"
+ );
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.log.warn(
+ "[%s] could not be updated as %s.",
+ accessory.displayName,
+ err
+ );
}
}
externalSCMUpdate(accessory, params) {
try {
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, params.switches[0].switch === "on");
+ accessory
+ .getService(Service.Switch)
+ .updateCharacteristic(
+ Characteristic.On,
+ params.switches[0].switch === "on"
+ );
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.log.warn(
+ "[%s] could not be updated as %s.",
+ accessory.displayName,
+ err
+ );
}
}
externalSingleLightUpdate(accessory, params) {
@@ -1904,37 +2563,54 @@ class eWeLink {
isOn = false;
if (accessory.context.eweUIID === 22 && params.hasOwnProperty("state")) {
isOn = params.state === "on";
- } else if (accessory.context.eweUIID !== 22 && params.hasOwnProperty("switch")) {
+ } else if (
+ accessory.context.eweUIID !== 22 &&
+ params.hasOwnProperty("switch")
+ ) {
isOn = params.switch === "on";
} else {
- isOn = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value;
+ isOn = accessory
+ .getService(Service.Lightbulb)
+ .getCharacteristic(Characteristic.On).value;
}
if (isOn) {
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, true);
+ accessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.On, true);
switch (accessory.context.eweUIID) {
case 36: // KING-M4
if (params.hasOwnProperty("bright")) {
let nb = Math.round(((params.bright - 10) * 10) / 9); // eWeLink scale is 10-100 and HomeKit scale is 0-100.
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Brightness, nb);
+ accessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.Brightness, nb);
}
break;
case 44: // D1
if (params.hasOwnProperty("brightness")) {
accessory
.getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.Brightness, params.brightness);
+ .updateCharacteristic(
+ Characteristic.Brightness,
+ params.brightness
+ );
}
break;
case 22: // B1
if (params.hasOwnProperty("zyx_mode")) {
mode = parseInt(params.zyx_mode);
- } else if (params.hasOwnProperty("channel0") && parseInt(params.channel0) + parseInt(params.channel1) > 0) {
+ } else if (
+ params.hasOwnProperty("channel0") &&
+ parseInt(params.channel0) + parseInt(params.channel1) > 0
+ ) {
mode = 1;
} else {
mode = 2;
}
if (mode === 2) {
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, true);
+ accessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.On, true);
newColour = convert.rgb.hsv(
parseInt(params.channel2),
parseInt(params.channel3),
@@ -1951,10 +2627,16 @@ class eWeLink {
break;
case 59: // L1
if (params.hasOwnProperty("bright")) {
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Brightness, params.bright);
+ accessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.Brightness, params.bright);
}
if (params.hasOwnProperty("colorR")) {
- newColour = convert.rgb.hsv(params.colorR, params.colorG, params.colorB);
+ newColour = convert.rgb.hsv(
+ params.colorR,
+ params.colorG,
+ params.colorB
+ );
accessory
.getService(Service.Lightbulb)
.updateCharacteristic(Characteristic.Hue, newColour[0])
@@ -1965,10 +2647,16 @@ class eWeLink {
return;
}
} else {
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, false);
+ accessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.On, false);
}
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.log.warn(
+ "[%s] could not be updated as %s.",
+ accessory.displayName,
+ err
+ );
}
}
externalMultiLightUpdate(accessory, params) {
@@ -1980,22 +2668,37 @@ class eWeLink {
let oAccessory = this.devicesInHB.get(idToCheck + i);
oAccessory
.getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.On, params.switches[i - 1].switch === "on");
+ .updateCharacteristic(
+ Characteristic.On,
+ params.switches[i - 1].switch === "on"
+ );
if (params.switches[i - 1].switch === "on") {
primaryState = true;
}
}
}
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, primaryState);
+ accessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.On, primaryState);
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.log.warn(
+ "[%s] could not be updated as %s.",
+ accessory.displayName,
+ err
+ );
}
}
externalSingleSwitchUpdate(accessory, params) {
try {
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, params.switch === "on");
+ accessory
+ .getService(Service.Switch)
+ .updateCharacteristic(Characteristic.On, params.switch === "on");
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.log.warn(
+ "[%s] could not be updated as %s.",
+ accessory.displayName,
+ err
+ );
}
}
externalMultiSwitchUpdate(accessory, params) {
@@ -2007,15 +2710,24 @@ class eWeLink {
let oAccessory = this.devicesInHB.get(idToCheck + i);
oAccessory
.getService(Service.Switch)
- .updateCharacteristic(Characteristic.On, params.switches[i - 1].switch === "on");
+ .updateCharacteristic(
+ Characteristic.On,
+ params.switches[i - 1].switch === "on"
+ );
if (params.switches[i - 1].switch === "on") {
primaryState = true;
}
}
}
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, primaryState);
+ accessory
+ .getService(Service.Switch)
+ .updateCharacteristic(Characteristic.On, primaryState);
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.log.warn(
+ "[%s] could not be updated as %s.",
+ accessory.displayName,
+ err
+ );
}
}
externalRFDeviceUpdate(accessory, params) {
@@ -2023,14 +2735,26 @@ class eWeLink {
if (!params.hasOwnProperty("updateSource")) return;
let idToCheck = accessory.context.hbDeviceId.slice(0, -1),
timeNow = new Date();
- if (params.hasOwnProperty("cmd") && params.cmd === "transmit" && params.hasOwnProperty("rfChl")) {
+ if (
+ params.hasOwnProperty("cmd") &&
+ params.cmd === "transmit" &&
+ params.hasOwnProperty("rfChl")
+ ) {
// RF Button
let bAccessory;
- if ((bAccessory = this.devicesInHB.get(idToCheck + accessory.context.rfChlMap[params.rfChl]))) {
- bAccessory.getService(bAccessory.context.rfChls[params.rfChl]).updateCharacteristic(Characteristic.On, 1);
+ if (
+ (bAccessory = this.devicesInHB.get(
+ idToCheck + accessory.context.rfChlMap[params.rfChl]
+ ))
+ ) {
+ bAccessory
+ .getService(bAccessory.context.rfChls[params.rfChl])
+ .updateCharacteristic(Characteristic.On, 1);
setTimeout(
() =>
- bAccessory.getService(bAccessory.context.rfChls[params.rfChl]).updateCharacteristic(Characteristic.On, 0),
+ bAccessory
+ .getService(bAccessory.context.rfChls[params.rfChl])
+ .updateCharacteristic(Characteristic.On, 0),
3000
);
} else {
@@ -2052,78 +2776,124 @@ class eWeLink {
case "button":
break;
case "water":
- oAccessory.getService(Service.LeakSensor).updateCharacteristic(Characteristic.LeakDetected, 1);
+ oAccessory
+ .getService(Service.LeakSensor)
+ .updateCharacteristic(Characteristic.LeakDetected, 1);
setTimeout(() => {
- oAccessory.getService(Service.LeakSensor).updateCharacteristic(Characteristic.LeakDetected, 0);
+ oAccessory
+ .getService(Service.LeakSensor)
+ .updateCharacteristic(Characteristic.LeakDetected, 0);
}, (this.config.sensorTimeLength || 2) * 1000);
break;
case "fire":
case "smoke":
- oAccessory.getService(Service.SmokeSensor).updateCharacteristic(Characteristic.SmokeDetected, 1);
+ oAccessory
+ .getService(Service.SmokeSensor)
+ .updateCharacteristic(Characteristic.SmokeDetected, 1);
setTimeout(() => {
- oAccessory.getService(Service.SmokeSensor).updateCharacteristic(Characteristic.SmokeDetected, 0);
+ oAccessory
+ .getService(Service.SmokeSensor)
+ .updateCharacteristic(Characteristic.SmokeDetected, 0);
}, (this.config.sensorTimeLength || 2) * 1000);
break;
case "co":
oAccessory
.getService(Service.CarbonMonoxideSensor)
- .updateCharacteristic(Characteristic.CarbonMonoxideDetected, 1);
+ .updateCharacteristic(
+ Characteristic.CarbonMonoxideDetected,
+ 1
+ );
setTimeout(() => {
oAccessory
.getService(Service.CarbonMonoxideSensor)
- .updateCharacteristic(Characteristic.CarbonMonoxideDetected, 0);
+ .updateCharacteristic(
+ Characteristic.CarbonMonoxideDetected,
+ 0
+ );
}, (this.config.sensorTimeLength || 2) * 1000);
break;
case "co2":
oAccessory
.getService(Service.CarbonDioxideSensor)
- .updateCharacteristic(Characteristic.CarbonDioxideDetected, 1);
+ .updateCharacteristic(
+ Characteristic.CarbonDioxideDetected,
+ 1
+ );
setTimeout(() => {
oAccessory
.getService(Service.CarbonDioxideSensor)
- .updateCharacteristic(Characteristic.CarbonDioxideDetected, 0);
+ .updateCharacteristic(
+ Characteristic.CarbonDioxideDetected,
+ 0
+ );
}, (this.config.sensorTimeLength || 2) * 1000);
break;
case "contact":
oAccessory
.getService(Service.ContactSensor)
- .updateCharacteristic(Characteristic.ContactSensorState, 1);
+ .updateCharacteristic(
+ Characteristic.ContactSensorState,
+ 1
+ );
setTimeout(() => {
oAccessory
.getService(Service.ContactSensor)
- .updateCharacteristic(Characteristic.ContactSensorState, 0);
+ .updateCharacteristic(
+ Characteristic.ContactSensorState,
+ 0
+ );
}, (this.config.sensorTimeLength || 2) * 1000);
break;
case "occupancy":
oAccessory
.getService(Service.OccupancySensor)
- .updateCharacteristic(Characteristic.OccupancyDetected, 1);
+ .updateCharacteristic(
+ Characteristic.OccupancyDetected,
+ 1
+ );
setTimeout(() => {
oAccessory
.getService(Service.OccupancySensor)
- .updateCharacteristic(Characteristic.OccupancyDetected, 0);
+ .updateCharacteristic(
+ Characteristic.OccupancyDetected,
+ 0
+ );
}, (this.config.sensorTimeLength || 2) * 1000);
break;
default:
oAccessory
.getService(Service.MotionSensor)
- .updateCharacteristic(Characteristic.MotionDetected, true);
+ .updateCharacteristic(
+ Characteristic.MotionDetected,
+ true
+ );
setTimeout(() => {
oAccessory
.getService(Service.MotionSensor)
- .updateCharacteristic(Characteristic.MotionDetected, false);
+ .updateCharacteristic(
+ Characteristic.MotionDetected,
+ false
+ );
}, (this.config.sensorTimeLength || 2) * 1000);
break;
}
if (this.debug) {
- this.log("[%s] has detected [%s].", oAccessory.displayName, oAccessory.context.sensorType);
+ this.log(
+ "[%s] has detected [%s].",
+ oAccessory.displayName,
+ oAccessory.context.sensorType
+ );
}
}
}
});
}
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.log.warn(
+ "[%s] could not be updated as %s.",
+ accessory.displayName,
+ err
+ );
}
}
externalZBDeviceUpdate(accessory, params) {
@@ -2131,16 +2901,26 @@ class eWeLink {
//*** credit @tasict ***\\
if (params.hasOwnProperty("battery")) {
let batteryService =
- accessory.getService(Service.BatteryService) || accessory.addService(Service.BatteryService);
- batteryService.updateCharacteristic(Characteristic.BatteryLevel, params.battery);
- batteryService.updateCharacteristic(Characteristic.StatusLowBattery, params.battery <= 25);
+ accessory.getService(Service.BatteryService) ||
+ accessory.addService(Service.BatteryService);
+ batteryService.updateCharacteristic(
+ Characteristic.BatteryLevel,
+ params.battery
+ );
+ batteryService.updateCharacteristic(
+ Characteristic.StatusLowBattery,
+ params.battery < 25
+ );
}
switch (accessory.context.eweUIID) {
case 1000:
if (params.hasOwnProperty("key") && [0, 1, 2].includes(params.key)) {
accessory
.getService(Service.StatelessProgrammableSwitch)
- .updateCharacteristic(Characteristic.ProgrammableSwitchEvent, params.key);
+ .updateCharacteristic(
+ Characteristic.ProgrammableSwitchEvent,
+ params.key
+ );
}
break;
case 1770:
@@ -2151,22 +2931,34 @@ class eWeLink {
let currentTemp = parseInt(params.temperature) / 100;
accessory
.getService(Service.TemperatureSensor)
- .updateCharacteristic(Characteristic.CurrentTemperature, currentTemp);
+ .updateCharacteristic(
+ Characteristic.CurrentTemperature,
+ currentTemp
+ );
eveLog.temp = parseFloat(currentTemp);
}
if (params.hasOwnProperty("humidity")) {
let currentHumi = parseInt(params.humidity) / 100;
accessory
.getService(Service.HumiditySensor)
- .updateCharacteristic(Characteristic.CurrentRelativeHumidity, currentHumi);
+ .updateCharacteristic(
+ Characteristic.CurrentRelativeHumidity,
+ currentHumi
+ );
eveLog.humidity = parseFloat(currentHumi);
}
- if (eveLog.hasOwnProperty("temp") || eveLog.hasOwnProperty("humidity")) {
+ if (
+ eveLog.hasOwnProperty("temp") ||
+ eveLog.hasOwnProperty("humidity")
+ ) {
accessory.eveLogger.addEntry(eveLog);
}
break;
case 2026:
- if (params.hasOwnProperty("motion") && params.hasOwnProperty("trigTime")) {
+ if (
+ params.hasOwnProperty("motion") &&
+ params.hasOwnProperty("trigTime")
+ ) {
let timeNow = new Date(),
diff = (timeNow.getTime() - params.trigTime) / 1000;
accessory
@@ -2184,12 +2976,19 @@ class eWeLink {
if (params.hasOwnProperty("lock") && [0, 1].includes(params.lock)) {
accessory
.getService(Service.ContactSensor)
- .updateCharacteristic(Characteristic.ContactSensorState, params.lock);
+ .updateCharacteristic(
+ Characteristic.ContactSensorState,
+ params.lock
+ );
}
break;
}
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.log.warn(
+ "[%s] could not be updated as %s.",
+ accessory.displayName,
+ err
+ );
}
}
}
diff --git a/lib/eWeLinkHTTP.js b/lib/eWeLinkHTTP.js
index 57e12c2f..093bd0f2 100644
--- a/lib/eWeLinkHTTP.js
+++ b/lib/eWeLinkHTTP.js
@@ -12,7 +12,9 @@ module.exports = class eWeLinkHTTP {
}
login() {
let data = {
- countryCode: "+" + this.config.countryCode.toString().replace("+", "").replace(" ", ""),
+ countryCode:
+ "+" +
+ this.config.countryCode.toString().replace("+", "").replace(" ", ""),
password: this.config.password,
};
this.config.username.includes("@")
@@ -22,11 +24,17 @@ module.exports = class eWeLinkHTTP {
let msg = JSON.stringify(data, null, 2)
.replace(this.config.password, "**hidden**")
.replace(this.config.username, "**hidden**");
- this.log.warn("Sending HTTP login request. This text is yellow for clarity.\n%s", msg);
+ this.log.warn(
+ "Sending HTTP login request. This text is yellow for clarity.\n%s",
+ msg
+ );
} else if (this.debug) {
this.log("Sending HTTP login request.");
}
- let dataToSign = crypto.createHmac("sha256", constants.appSecret).update(JSON.stringify(data)).digest("base64");
+ let dataToSign = crypto
+ .createHmac("sha256", constants.appSecret)
+ .update(JSON.stringify(data))
+ .digest("base64");
return new Promise((resolve, reject) => {
axios({
url: "https://" + this.httpHost + "/v2/user/login",
@@ -88,7 +96,10 @@ module.exports = class eWeLinkHTTP {
getHost() {
let data = {
appid: constants.appId,
- country_code: this.config.countryCode.toString().replace("+", "").replace(" ", ""),
+ country_code: this.config.countryCode
+ .toString()
+ .replace("+", "")
+ .replace(" ", ""),
nonce: Math.random().toString(36).substr(2, 8),
ts: Math.floor(new Date().getTime() / 1000),
version: 8,
@@ -108,7 +119,10 @@ module.exports = class eWeLinkHTTP {
return kv.key + "=" + kv.value;
})
.join("&");
- dataToSign = crypto.createHmac("sha256", "6Nz4n0xA8s8qdxQf2GqurZj2Fs55FUvM").update(dataToSign).digest("base64");
+ dataToSign = crypto
+ .createHmac("sha256", "6Nz4n0xA8s8qdxQf2GqurZj2Fs55FUvM")
+ .update(dataToSign)
+ .digest("base64");
return new Promise((resolve, reject) => {
axios
.get("https://api.coolkit.cc:8080/api/user/region", {
@@ -121,7 +135,10 @@ module.exports = class eWeLinkHTTP {
.then(res => {
let body = res.data;
if (!body.region) {
- throw "Server did not respond with a region.\n" + JSON.stringify(body, null, 2);
+ throw (
+ "Server did not respond with a region.\n" +
+ JSON.stringify(body, null, 2)
+ );
}
switch (body.region) {
case "eu":
@@ -159,12 +176,17 @@ module.exports = class eWeLinkHTTP {
})
.then(res => {
let body = res.data;
- if (!body.hasOwnProperty("error") || (body.hasOwnProperty("error") && body.error !== 0)) {
+ if (
+ !body.hasOwnProperty("error") ||
+ (body.hasOwnProperty("error") && body.error !== 0)
+ ) {
throw JSON.stringify(body, null, 2);
}
let deviceList = [];
if (body.data.thingList && body.data.thingList.length > 0) {
- body.data.thingList.forEach(device => deviceList.push(device.itemData));
+ body.data.thingList.forEach(device =>
+ deviceList.push(device.itemData)
+ );
}
resolve(deviceList);
})
diff --git a/lib/eWeLinkLAN.js b/lib/eWeLinkLAN.js
index 2bbbf005..25baee53 100644
--- a/lib/eWeLinkLAN.js
+++ b/lib/eWeLinkLAN.js
@@ -16,7 +16,9 @@ module.exports = class eWeLinkLAN {
deviceMap.set(device.deviceid, {
apiKey: device.devicekey,
online: this.ipOverrides.hasOwnProperty(device.deviceid) ? true : false,
- ip: this.ipOverrides.hasOwnProperty(device.deviceid) ? this.ipOverrides[device.deviceid] : null,
+ ip: this.ipOverrides.hasOwnProperty(device.deviceid)
+ ? this.ipOverrides[device.deviceid]
+ : null,
});
});
this.deviceMap = deviceMap;
@@ -34,7 +36,9 @@ module.exports = class eWeLinkLAN {
let onlineCount = 0;
res.forEach(device => {
let d,
- deviceId = device.fqdn.replace("._ewelink._tcp.local", "").replace("eWeLink_", "");
+ deviceId = device.fqdn
+ .replace("._ewelink._tcp.local", "")
+ .replace("eWeLink_", "");
if ((d = this.deviceMap.get(deviceId))) {
if (!this.ipOverrides.hasOwnProperty(deviceId)) {
this.deviceMap.set(deviceId, {
@@ -71,29 +75,52 @@ module.exports = class eWeLinkLAN {
(rdata.hasOwnProperty("data2") ? rdata.data2 : "") +
(rdata.hasOwnProperty("data3") ? rdata.data3 : "") +
(rdata.hasOwnProperty("data4") ? rdata.data4 : ""),
- key = crypto.createHash("md5").update(Buffer.from(deviceInfo.apiKey, "utf8")).digest(),
- dText = crypto.createDecipheriv("aes-128-cbc", key, Buffer.from(rdata.iv, "base64")),
- pText = Buffer.concat([dText.update(Buffer.from(data, "base64")), dText.final()]).toString("utf8"),
+ key = crypto
+ .createHash("md5")
+ .update(Buffer.from(deviceInfo.apiKey, "utf8"))
+ .digest(),
+ dText = crypto.createDecipheriv(
+ "aes-128-cbc",
+ key,
+ Buffer.from(rdata.iv, "base64")
+ ),
+ pText = Buffer.concat([
+ dText.update(Buffer.from(data, "base64")),
+ dText.final(),
+ ]).toString("utf8"),
params;
- if (packet.address !== deviceInfo.ip && !this.ipOverrides.hasOwnProperty(rdata.id)) {
+ if (
+ packet.address !== deviceInfo.ip &&
+ !this.ipOverrides.hasOwnProperty(rdata.id)
+ ) {
this.deviceMap.set(rdata.id, {
apiKey: deviceInfo.apiKey,
online: true,
ip: packet.address,
});
if (this.debug) {
- this.log.warn("[%s] updating IP address to [%s].", rdata.id, packet.address);
+ this.log.warn(
+ "[%s] updating IP address to [%s].",
+ rdata.id,
+ packet.address
+ );
}
}
try {
params = JSON.parse(pText);
} catch (e) {
- this.log.warn("[%s] An error occured reading the LAN message [%s]", rdata.id, e);
+ this.log.warn(
+ "[%s] An error occured reading the LAN message [%s]",
+ rdata.id,
+ e
+ );
return;
}
for (let param in params) {
if (params.hasOwnProperty(param)) {
- if (!constants.paramsToKeep.includes(param.replace(/[0-9]/g, ""))) {
+ if (
+ !constants.paramsToKeep.includes(param.replace(/[0-9]/g, ""))
+ ) {
delete params[param];
}
}
@@ -106,7 +133,10 @@ module.exports = class eWeLinkLAN {
params,
};
if (this.debugReqRes) {
- let msg = JSON.stringify(returnTemplate, null, 2).replace(rdata.id, "**hidden**");
+ let msg = JSON.stringify(returnTemplate, null, 2).replace(
+ rdata.id,
+ "**hidden**"
+ );
this.log("LAN message received.\n%s", msg);
} else if (this.debug) {
this.log("LAN message received.");
@@ -145,11 +175,17 @@ module.exports = class eWeLinkLAN {
throw "plugin does not support lan mode for this device yet - feel free to create a github issue";
}
if ((apiKey = this.deviceMap.get(json.deviceid).apiKey)) {
- let key = crypto.createHash("md5").update(Buffer.from(apiKey, "utf8")).digest(),
+ let key = crypto
+ .createHash("md5")
+ .update(Buffer.from(apiKey, "utf8"))
+ .digest(),
iv = crypto.randomBytes(16),
enc = crypto.createCipheriv("aes-128-cbc", key, iv),
data = {
- data: Buffer.concat([enc.update(JSON.stringify(params)), enc.final()]).toString("base64"),
+ data: Buffer.concat([
+ enc.update(JSON.stringify(params)),
+ enc.final(),
+ ]).toString("base64"),
deviceid: json.deviceid,
encrypt: true,
iv: iv.toString("base64"),
@@ -161,13 +197,20 @@ module.exports = class eWeLinkLAN {
.replace(json.apikey, "**hidden**")
.replace(json.apikey, "**hidden**")
.replace(json.deviceid, "**hidden**");
- this.log.warn("LAN message sent. This text is yellow for clarity.\n%s", msg);
+ this.log.warn(
+ "LAN message sent. This text is yellow for clarity.\n%s",
+ msg
+ );
} else if (this.debug) {
this.log("LAN message sent.");
}
axios({
method: "post",
- url: "http://" + this.deviceMap.get(json.deviceid).ip + ":8081/zeroconf/" + suffix,
+ url:
+ "http://" +
+ this.deviceMap.get(json.deviceid).ip +
+ ":8081/zeroconf/" +
+ suffix,
headers: {
Accept: "application/json",
"Content-Type": "application/json",
diff --git a/lib/eWeLinkWS.js b/lib/eWeLinkWS.js
index 86f08e3e..56fbeb64 100644
--- a/lib/eWeLinkWS.js
+++ b/lib/eWeLinkWS.js
@@ -21,7 +21,8 @@ module.exports = class eWeLinkWS {
return new Promise((resolve, reject) => {
axios({
method: "post",
- url: "https://" + this.httpHost.replace("-api", "-disp") + "/dispatch/app",
+ url:
+ "https://" + this.httpHost.replace("-api", "-disp") + "/dispatch/app",
headers: {
Authorization: "Bearer " + this.aToken,
"Content-Type": "application/json",
@@ -69,7 +70,10 @@ module.exports = class eWeLinkWS {
let msg = JSON.stringify(payload, null, 2)
.replace(this.aToken, "**hidden**")
.replace(this.apiKey, "**hidden**");
- this.log.warn("Sending WS login request. This text is yellow for clarity.\n%s", msg);
+ this.log.warn(
+ "Sending WS login request. This text is yellow for clarity.\n%s",
+ msg
+ );
} else if (this.debug) {
this.log("Sending WS login request.");
}
@@ -82,7 +86,10 @@ module.exports = class eWeLinkWS {
try {
device = JSON.parse(m);
} catch (e) {
- this.log.warn("An error occured reading the web socket message [%s]", e);
+ this.log.warn(
+ "An error occured reading the web socket message [%s]",
+ e
+ );
return;
}
// for requestUpdate response
@@ -93,14 +100,23 @@ module.exports = class eWeLinkWS {
device.error === 0
) {
device.action = "update";
- } else if (device.hasOwnProperty("deviceid") && device.hasOwnProperty("error") && device.error === 504) {
+ } else if (
+ device.hasOwnProperty("deviceid") &&
+ device.hasOwnProperty("error") &&
+ device.error === 504
+ ) {
device.action = "sysmsg";
device.params = {
online: false,
};
}
// for external updates
- if (device.hasOwnProperty("config") && device.config.hb && device.config.hbInterval && !this.hbInterval) {
+ if (
+ device.hasOwnProperty("config") &&
+ device.config.hb &&
+ device.config.hbInterval &&
+ !this.hbInterval
+ ) {
this.hbInterval = setInterval(() => {
this.ws.send("ping");
}, (device.config.hbInterval + 7) * 1000);
@@ -114,7 +130,10 @@ module.exports = class eWeLinkWS {
params: device.params,
};
if (this.debugReqRes) {
- let msg = JSON.stringify(returnTemplate, null, 2).replace(device.deviceid, "**hidden**");
+ let msg = JSON.stringify(returnTemplate, null, 2).replace(
+ device.deviceid,
+ "**hidden**"
+ );
this.log("WS message received.\n%s", msg);
} else if (this.debug) {
this.log("WS message received.");
@@ -124,7 +143,9 @@ module.exports = class eWeLinkWS {
case "update":
for (let param in device.params) {
if (device.params.hasOwnProperty(param)) {
- if (!constants.paramsToKeep.includes(param.replace(/[0-9]/g, ""))) {
+ if (
+ !constants.paramsToKeep.includes(param.replace(/[0-9]/g, ""))
+ ) {
delete device.params[param];
}
}
@@ -137,7 +158,10 @@ module.exports = class eWeLinkWS {
params: device.params,
};
if (this.debugReqRes) {
- let msg = JSON.stringify(returnTemplate, null, 2).replace(device.deviceid, "**hidden**");
+ let msg = JSON.stringify(returnTemplate, null, 2).replace(
+ device.deviceid,
+ "**hidden**"
+ );
this.log("WS message received.\n%s", msg);
} else if (this.debug) {
this.log("WS message received.");
@@ -148,14 +172,20 @@ module.exports = class eWeLinkWS {
case "reportSubDevice":
return;
default:
- this.log.warn("[%s] WS message has unknown action.\n" + JSON.stringify(device, null, 2), device.deviceid);
+ this.log.warn(
+ "[%s] WS message has unknown action.\n" +
+ JSON.stringify(device, null, 2),
+ device.deviceid
+ );
return;
}
} else if (device.hasOwnProperty("error") && device.error === 0) {
// *** Safe to ignore these messages *** \\
} else {
if (this.debug) {
- this.log.warn("WS unknown command received.\n" + JSON.stringify(device, null, 2));
+ this.log.warn(
+ "WS unknown command received.\n" + JSON.stringify(device, null, 2)
+ );
}
}
});
@@ -170,7 +200,9 @@ module.exports = class eWeLinkWS {
this.login();
}, 5000);
} else {
- this.log("Please try restarting Homebridge so that this plugin can work again.");
+ this.log(
+ "Please try restarting Homebridge so that this plugin can work again."
+ );
}
}
this.wsIsOpen = false;
@@ -183,13 +215,17 @@ module.exports = class eWeLinkWS {
this.ws.on("error", e => {
this.log.error("Web socket error - [%s].", e);
if (e.code === "ECONNREFUSED") {
- this.log.warn("Web socket will try to reconnect in five seconds then try the command again.");
+ this.log.warn(
+ "Web socket will try to reconnect in five seconds then try the command again."
+ );
this.ws.removeAllListeners();
setTimeout(() => {
this.login();
}, 5000);
} else {
- this.log.warn("If this was unexpected then please try restarting Homebridge.");
+ this.log.warn(
+ "If this was unexpected then please try restarting Homebridge."
+ );
}
});
}
@@ -216,7 +252,10 @@ module.exports = class eWeLinkWS {
.replace(json.apikey, "**hidden**")
.replace(json.apiKey, "**hidden**")
.replace(json.deviceid, "**hidden**");
- this.log.warn("WS message sent. This text is yellow for clarity.\n%s", msg);
+ this.log.warn(
+ "WS message sent. This text is yellow for clarity.\n%s",
+ msg
+ );
} else if (this.debug) {
this.log("WS message sent.");
}
@@ -229,7 +268,9 @@ module.exports = class eWeLinkWS {
setTimeout(sendOperation, this.delaySend, string);
this.delaySend += 280;
} else {
- this.log.warn("Web socket is currently reconnecting. Command will be resent.");
+ this.log.warn(
+ "Web socket is currently reconnecting. Command will be resent."
+ );
let interval,
waitToSend = req => {
if (this.wsIsOpen) {
@@ -264,7 +305,10 @@ module.exports = class eWeLinkWS {
.replace(json.apikey, "**hidden**")
.replace(json.apiKey, "**hidden**")
.replace(json.deviceid, "**hidden**");
- this.log.warn("WS message sent. This text is yellow for clarity.\n%s", msg);
+ this.log.warn(
+ "WS message sent. This text is yellow for clarity.\n%s",
+ msg
+ );
} else if (this.debug) {
this.log("WS message sent.");
}
@@ -277,7 +321,9 @@ module.exports = class eWeLinkWS {
setTimeout(sendOperation, this.delaySend, string);
this.delaySend += 280;
} else {
- this.log.warn("Web socket is currently reconnecting. Command will be resent.");
+ this.log.warn(
+ "Web socket is currently reconnecting. Command will be resent."
+ );
let interval,
waitToSend = req => {
if (this.wsIsOpen) {
From f176305ab47bd3824c8f02a94c4abb4329756d85 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 15 Sep 2020 18:20:19 +0100
Subject: [PATCH 0152/3183] Update eWeLinkHTTP.js
---
lib/eWeLinkHTTP.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/eWeLinkHTTP.js b/lib/eWeLinkHTTP.js
index 093bd0f2..1aafd1e4 100644
--- a/lib/eWeLinkHTTP.js
+++ b/lib/eWeLinkHTTP.js
@@ -120,7 +120,7 @@ module.exports = class eWeLinkHTTP {
})
.join("&");
dataToSign = crypto
- .createHmac("sha256", "6Nz4n0xA8s8qdxQf2GqurZj2Fs55FUvM")
+ .createHmac("sha256", constants.appSecret)
.update(dataToSign)
.digest("base64");
return new Promise((resolve, reject) => {
From fb71abd9869024b0fb01d4d1a93c763d1e5e6bd5 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 15 Sep 2020 18:26:32 +0100
Subject: [PATCH 0153/3183] dw2 add battery
---
lib/eWeLink.js | 1 +
1 file changed, 1 insertion(+)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 0869e08a..13c6d210 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -447,6 +447,7 @@ class eWeLink {
break;
case "sensor":
accessory.addService(Service.ContactSensor);
+ accessory.addService(Service.BatteryService);
break;
case "fan":
accessory.addService(Service.Fanv2);
From fb75298a74a77458152ccf99a7b9041cc6f32bb6 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 15 Sep 2020 18:26:45 +0100
Subject: [PATCH 0154/3183] remove "type" from sensor params
---
lib/constants.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/constants.js b/lib/constants.js
index 34215ac6..d8892025 100644
--- a/lib/constants.js
+++ b/lib/constants.js
@@ -38,7 +38,7 @@ module.exports = {
devicesBrightable: [36, 44],
devicesColourable: [22, 59],
devicesSensor: [102],
- devicesSensorParams: ["switch", "battery", "type"],
+ devicesSensorParams: ["switch", "battery"],
devicesThermostat: [15],
devicesThermostatParams: [
"currentTemperature",
From 175a4e119a9526394b18e8db33f575c55da75365 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 15 Sep 2020 19:04:03 +0100
Subject: [PATCH 0155/3183] 2.27.0
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 61a31ae5..71955065 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.26.2",
+ "version": "2.27.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 06d38b28..90ba8792 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.26.2",
+ "version": "2.27.0",
"author": "bwp91",
"contributors": [
"gbro115",
From a8725d0b82686f25fafa5e3c4337bb6b5d8cade3 Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Tue, 15 Sep 2020 23:05:51 +0100
Subject: [PATCH 0156/3183] Update README.md
---
README.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 60323284..f85ca40c 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,8 @@
[![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/prettier/prettier)
[![npm](https://img.shields.io/npm/dt/homebridge-ewelink)](https://www.npmjs.com/package/homebridge-ewelink)
[![npm](https://img.shields.io/npm/v/homebridge-ewelink/latest?label=release)](https://www.npmjs.com/package/homebridge-ewelink)
- [![npm](https://img.shields.io/npm/v/homebridge-ewelink/beta?label=beta)](https://www.npmjs.com/package/homebridge-ewelink)
+ [![npm](https://img.shields.io/npm/v/homebridge-ewelink/beta?label=beta)](https://www.npmjs.com/package/homebridge-ewelink)
+ [![Contribute](https://img.shields.io/badge/contribute-a%20drink-yellow)](https://ko-fi.com/bwp91)
From 7232c7dca41bdcc4699c804844ad79a17d8f05ca Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Tue, 15 Sep 2020 23:07:37 +0100
Subject: [PATCH 0157/3183] Update README.md
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index f85ca40c..79d92ff6 100644
--- a/README.md
+++ b/README.md
@@ -10,9 +10,9 @@
[![verified-by-homebridge](https://badgen.net/badge/homebridge/verified/purple)](https://github.com/homebridge/homebridge/wiki/Verified-Plugins)
[![Discord](https://img.shields.io/discord/432663330281226270?color=728ED5&logo=discord&label=discord)](https://discord.com/channels/432663330281226270/742733745743855627)
[![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/prettier/prettier)
- [![npm](https://img.shields.io/npm/dt/homebridge-ewelink)](https://www.npmjs.com/package/homebridge-ewelink)
[![npm](https://img.shields.io/npm/v/homebridge-ewelink/latest?label=release)](https://www.npmjs.com/package/homebridge-ewelink)
[![npm](https://img.shields.io/npm/v/homebridge-ewelink/beta?label=beta)](https://www.npmjs.com/package/homebridge-ewelink)
+ [![npm](https://img.shields.io/npm/dt/homebridge-ewelink)](https://www.npmjs.com/package/homebridge-ewelink)
[![Contribute](https://img.shields.io/badge/contribute-a%20drink-yellow)](https://ko-fi.com/bwp91)
From 4c24c9f3bbe93bddfd333db580defdc116d150e5 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Wed, 16 Sep 2020 05:47:00 +0000
Subject: [PATCH 0158/3183] Bump prettier from 2.1.1 to 2.1.2
Bumps [prettier](https://github.com/prettier/prettier) from 2.1.1 to 2.1.2.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/master/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/2.1.1...2.1.2)
Signed-off-by: dependabot[bot]
---
package-lock.json | 6 +++---
package.json | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 71955065..3e66d828 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -546,9 +546,9 @@
}
},
"prettier": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.1.1.tgz",
- "integrity": "sha512-9bY+5ZWCfqj3ghYBLxApy2zf6m+NJo5GzmLTpr9FsApsfjriNnS2dahWReHMi7qNPhhHl9SYHJs2cHZLgexNIw==",
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.1.2.tgz",
+ "integrity": "sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg==",
"dev": true
},
"qs": {
diff --git a/package.json b/package.json
index 90ba8792..015ed59c 100644
--- a/package.json
+++ b/package.json
@@ -66,6 +66,6 @@
"ws": "7.3.1"
},
"devDependencies": {
- "prettier": "2.1.1"
+ "prettier": "2.1.2"
}
}
From 556a0e048249a7e8c423f052a6b8283318389b73 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Wed, 16 Sep 2020 13:57:48 +0100
Subject: [PATCH 0159/3183] 3.0 initial changes
---
.prettierrc.json | 3 +-
lib/constants.js | 7 +-
lib/eWeLink.js | 1389 +++++++++++++-------------------------------
lib/eWeLinkHTTP.js | 241 ++++----
lib/eWeLinkLAN.js | 91 +--
lib/eWeLinkWS.js | 156 ++---
6 files changed, 624 insertions(+), 1263 deletions(-)
diff --git a/.prettierrc.json b/.prettierrc.json
index d68aa739..87f5e5e8 100644
--- a/.prettierrc.json
+++ b/.prettierrc.json
@@ -1,3 +1,4 @@
{
- "arrowParens": "avoid"
+ "arrowParens": "avoid",
+ "printWidth": 100
}
diff --git a/lib/constants.js b/lib/constants.js
index d8892025..fe7fcb40 100644
--- a/lib/constants.js
+++ b/lib/constants.js
@@ -40,12 +40,7 @@ module.exports = {
devicesSensor: [102],
devicesSensorParams: ["switch", "battery"],
devicesThermostat: [15],
- devicesThermostatParams: [
- "currentTemperature",
- "currentHumidity",
- "switch",
- "masterSwitch",
- ],
+ devicesThermostatParams: ["currentTemperature", "currentHumidity", "switch", "masterSwitch"],
devicesFan: [34],
devicesFanParams: ["switches", "light", "fan", "speed"],
devicesOutlet: [32],
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 13c6d210..855a0402 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -13,15 +13,9 @@ class eWeLink {
constructor(log, config, api) {
if (!log || !api || !config) return;
if (!config.username || !config.password || !config.countryCode) {
- log.error(
- "**************** Cannot load homebridge-ewelink ****************"
- );
- log.error(
- "Your eWeLink credentials are missing from the Homebridge config."
- );
- log.error(
- "****************************************************************"
- );
+ log.error("*********** Cannot load homebridge-ewelink ***********");
+ log.error("eWeLink credentials missing from the Homebridge config.");
+ log.error("*******************************************************");
return;
}
this.log = log;
@@ -29,153 +23,103 @@ class eWeLink {
this.api = api;
this.debug = this.config.debug || false;
this.devicesInHB = new Map();
- this.devicesInEwe = new Map();
+ this.devicesInEW = new Map();
this.cusG = new Map();
this.cusS = new Map();
this.eveLogPath = this.api.user.storagePath() + "/homebridge-ewelink/";
this.api
- .on("didFinishLaunching", () => {
- this.log(
- "Plugin has finished initialising. Starting synchronisation with eWeLink account."
- );
- //*** Set up HTTP client and get the user HTTP host ***\\
- this.httpClient = new eWeLinkHTTP(this.config, this.log);
- this.httpClient
- .getHost()
- .then(() => this.httpClient.login())
- .then(res => {
- //*** Set up the web socket client ***\\
- this.wsClient = new eWeLinkWS(this.config, this.log, res);
- return this.wsClient.getHost();
- })
- .then(() => {
- //*** Open web socket connection and get device list via HTTP ***\\
- this.wsClient.login();
- return this.httpClient.getDevices();
- })
- .then(res => {
- //*** Get device IP addresses for LAN mode ***\\
- this.httpDevices = res
- .filter(
- device =>
- device.hasOwnProperty("extra") &&
- device.extra.hasOwnProperty("uiid")
- )
- .filter(
- device =>
- !(this.config.hideDevFromHB || "").includes(device.deviceid)
- );
- this.lanClient = new eWeLinkLAN(
- this.config,
- this.log,
- this.httpDevices
- );
- this.httpDevices.forEach(device =>
- this.devicesInEwe.set(device.deviceid, device)
- );
- return this.lanClient.getHosts();
- })
- .then(res => {
- //*** Set up the LAN mode listener ***\\
- this.lanDevices = res.map;
- this.lanDevicesOnline = res.count;
- return this.lanClient.startMonitor();
- })
- .then(() => {
- //*** Use the device list to refresh Homebridge accessories ***\\
- (() => {
- //*** Remove all Homebridge accessories if none found ***\\
- if (
- Object.keys(this.httpDevices).length === 0 &&
- Object.keys(this.lanDevices).length === 0
- ) {
- Array.from(this.devicesInHB.values()).forEach(a =>
- this.removeAccessory(a)
- );
- this.devicesInHB.clear();
- this.log.warn("******* Not loading homebridge-ewelink *******");
- this.log.warn("No devices were found in your eWeLink account.");
- this.log.warn("**********************************************");
- return;
- }
- //*** Make a map of custom groups from Homebridge config ***\\
- if (Object.keys(this.config.groups || []).length > 0) {
- this.config.groups
- .filter(
- g =>
- g.hasOwnProperty("type") &&
- cns.allowedGroups.includes(g.type)
- )
- .filter(
- g =>
- g.hasOwnProperty("deviceId") &&
- this.devicesInEwe.has(g.deviceId.toLowerCase())
- )
- .forEach(g => this.cusG.set(g.deviceId + "SWX", g));
- }
- //*** Make a map of RF Bridge custom sensors from Homebridge config ***\\
- if (Object.keys(this.config.bridgeSensors || []).length > 0) {
- this.config.bridgeSensors
- .filter(
- s =>
- s.hasOwnProperty("deviceId") &&
- this.devicesInEwe.has(s.deviceId.toLowerCase())
- )
- .forEach(s => this.cusS.set(s.fullDeviceId, s));
- }
- //*** Logging always helps to see if everything is okay so far ***\\
- this.log(
- "[%s] eWeLink devices were loaded from the Homebridge cache.",
- this.devicesInHB.size
- );
- this.log(
- "[%s] primary devices were loaded from your eWeLink account.",
- this.devicesInEwe.size
- );
- this.log(
- "[%s] primary devices were discovered on your local network.",
- this.lanDevicesOnline
- );
- //*** Remove Homebridge accessories that don't appear in eWeLink ***\\
- this.devicesInHB.forEach(a => {
- if (!this.devicesInEwe.has(a.context.eweDeviceId)) {
- this.removeAccessory(a);
- }
- });
- //*** Synchronise devices between eWeLink and Homebridge and set up ws/lan listeners ***\\
- this.devicesInEwe.forEach(d => this.initialiseDevice(d));
- this.wsClient.receiveUpdate(d => this.receiveDeviceUpdate(d));
- this.lanClient.receiveUpdate(d => this.receiveDeviceUpdate(d));
- this.log(
- "eWeLink setup complete. If you're enjoying this package please consider a âī¸ on GitHub :)."
- );
- if (this.config.debugReqRes || false) {
- this.log.warn(
- "You have 'Request & Response Logging' enabled. This setting is not recommended for long-term use."
- );
- }
- })();
- })
- .catch(err => {
- this.log.error(
- "************** Cannot load homebridge-ewelink **************"
- );
- this.log.error(err);
- this.log.error(
- "************************************************************"
- );
- if (this.lanClient) this.lanClient.closeConnection();
- if (this.wsClient) this.wsClient.closeConnection();
+ .on("didFinishLaunching", () => this.eWeLinkSync())
+ .on("shutdown", () => {
+ if (this.lanClient) this.lanClient.closeConnection();
+ if (this.wsClient) this.wsClient.closeConnection();
+ });
+ }
+ eWeLinkSync() {
+ this.log("Plugin has finished initialising. Synching with eWeLink.");
+ this.httpClient = new eWeLinkHTTP(this.config, this.log);
+ this.httpClient
+ .getHost()
+ .then(() => this.httpClient.login())
+ .then(res => {
+ this.authData = res;
+ return this.httpClient.getDevices();
+ })
+ .then(res => {
+ this.httpDevices = res
+ .filter(d => d.hasOwnProperty("extra") && d.extra.hasOwnProperty("uiid"))
+ .filter(d => !(this.config.hideDevFromHB || "").includes(d.deviceid));
+ this.httpDevices.forEach(device => this.devicesInEW.set(device.deviceid, device));
+ this.wsClient = new eWeLinkWS(this.config, this.log, this.authData);
+ return this.wsClient.getHost();
+ })
+ .then(() => {
+ this.wsClient.login();
+ this.lanClient = new eWeLinkLAN(this.config, this.log, this.httpDevices);
+ return this.lanClient.getHosts();
+ })
+ .then(res => {
+ this.lanDevices = res.map;
+ this.lanCount = res.count;
+ return this.lanClient.startMonitor();
+ })
+ .then(() => {
+ (() => {
+ //*** Remove all Homebridge accessories if none found ***\\
+ if (
+ Object.keys(this.httpDevices).length === 0 &&
+ Object.keys(this.lanDevices).length === 0
+ ) {
+ Array.from(this.devicesInHB.values()).forEach(a => this.removeAccessory(a));
+ this.devicesInHB.clear();
+ this.log.warn("******* Not loading homebridge-ewelink *******");
+ this.log.warn("No devices were found in your eWeLink account.");
+ this.log.warn("**********************************************");
+ return;
+ }
+ //*** Make a map of custom groups from Homebridge config ***\\
+ if (Object.keys(this.config.groups || []).length > 0) {
+ this.config.groups
+ .filter(g => g.hasOwnProperty("type") && cns.allowedGroups.includes(g.type))
+ .filter(g => g.hasOwnProperty("deviceId") && this.devicesInEW.has(g.deviceId))
+ .forEach(g => this.cusG.set(g.deviceId + "SWX", g));
+ }
+ //*** Make a map of RF Bridge custom sensors from Homebridge config ***\\
+ if (Object.keys(this.config.bridgeSensors || []).length > 0) {
+ this.config.bridgeSensors
+ .filter(s => s.hasOwnProperty("deviceId") && this.devicesInEW.has(s.deviceId))
+ .forEach(s => this.cusS.set(s.fullDeviceId, s));
+ }
+ //*** Logging always helps to see if everything is okay so far ***\\
+ this.log("[%s] eWeLink devices loaded from the Homebridge cache.", this.devicesInHB.size);
+ this.log("[%s] primary devices loaded from your eWeLink account.", this.devicesInEW.size);
+ this.log("[%s] primary devices were discovered on your local network.", this.lanCount);
+ //*** Remove Homebridge accessories that don't appear in eWeLink ***\\
+ this.devicesInHB.forEach(a => {
+ if (!this.devicesInEW.has(a.context.eweDeviceId)) {
+ this.removeAccessory(a);
+ }
});
+ //*** Synchronise devices between eWeLink and Homebridge and set up ws/lan listeners ***\\
+ this.devicesInEW.forEach(d => this.initialiseDevice(d));
+ this.wsClient.receiveUpdate(d => this.receiveDeviceUpdate(d));
+ this.lanClient.receiveUpdate(d => this.receiveDeviceUpdate(d));
+ this.log("eWeLink sync complete. Don't forget to âī¸ this plugin on GitHub!");
+ if (this.config.debugReqRes || false) {
+ this.log.warn("Note: 'Request & Response Logging' is not advised for long-term use.");
+ }
+ })();
})
- .on("shutdown", () => {
+ .catch(err => {
+ this.log.error("************** Cannot load homebridge-ewelink **************");
+ this.log.error(err);
+ this.log.error("************************************************************");
if (this.lanClient) this.lanClient.closeConnection();
if (this.wsClient) this.wsClient.closeConnection();
});
}
initialiseDevice(device) {
let accessory;
- //*** First add the device if it isn't already in Homebridge. Yeah this code looks a mess :| ***\\
+ //*** First add the device if it isn't already in Homebridge ***\\
if (
!this.devicesInHB.has(device.deviceid + "SWX") &&
!this.devicesInHB.has(device.deviceid + "SW0")
@@ -233,9 +177,7 @@ class eWeLink {
}
} else if (cns.devicesRFBridge.includes(device.extra.uiid)) {
this.addAccessory(device, device.deviceid + "SW0", "rf_pri");
- if (
- Object.keys((device.tags && device.tags.zyx_info) || []).length > 0
- ) {
+ if (Object.keys((device.tags && device.tags.zyx_info) || []).length > 0) {
for (let i = 1; i <= Object.keys(device.tags.zyx_info).length; i++) {
this.addAccessory(device, device.deviceid + "SW" + i, "rf_sub");
}
@@ -269,31 +211,20 @@ class eWeLink {
rfBridgeChange = false;
accessory
.getService(Service.AccessoryInformation)
- .setCharacteristic(
- Characteristic.FirmwareRevision,
- device.params.fwVersion
- );
- accessory.context.reachableWAN =
- accessory.context.eweUIID !== 102 ? device.online : true;
- accessory.context.reachableLAN =
- this.lanDevices.get(device.deviceid).online || false;
+ .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion);
+ accessory.context.reachableWAN = accessory.context.eweUIID !== 102 ? device.online : true;
+ accessory.context.reachableLAN = this.lanDevices.get(device.deviceid).online || false;
accessory.context.inUse = false;
let str = accessory.context.reachableLAN
- ? "and locally with IP [" +
- this.lanDevices.get(device.deviceid).ip +
- "]"
- : "but LAN mode unavailable as unsupported/shared device";
+ ? "and locally with IP [" + this.lanDevices.get(device.deviceid).ip + "]"
+ : "but LAN mode unavailable as offline/unsupported/shared device";
this.log("[%s] found in eWeLink %s.", accessory.displayName, str);
this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
if (!isX) {
for (let i = 1; i <= accessory.context.channelCount; i++) {
if (!this.devicesInHB.has(device.deviceid + "SW" + i)) {
if (cns.devicesHideable.includes(accessory.context.type)) {
- if (
- (this.config.hideFromHB || "").includes(
- device.deviceid + "SW" + i
- )
- ) {
+ if ((this.config.hideFromHB || "").includes(device.deviceid + "SW" + i)) {
continue;
} else {
this.addAccessory(device, device.deviceid + "SW" + i, "switch");
@@ -302,9 +233,7 @@ class eWeLink {
}
let oAccessory = this.devicesInHB.get(device.deviceid + "SW" + i);
if (
- (this.config.hideFromHB || "").includes(
- device.deviceid + "SW" + i
- ) &&
+ (this.config.hideFromHB || "").includes(device.deviceid + "SW" + i) &&
cns.devicesHideable.includes(accessory.context.type)
) {
this.removeAccessory(oAccessory);
@@ -318,13 +247,9 @@ class eWeLink {
}
oAccessory
.getService(Service.AccessoryInformation)
- .setCharacteristic(
- Characteristic.FirmwareRevision,
- device.params.fwVersion
- );
+ .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion);
oAccessory.context.reachableWAN = device.online;
- oAccessory.context.reachableLAN =
- this.lanDevices.get(device.deviceid).online || false;
+ oAccessory.context.reachableLAN = this.lanDevices.get(device.deviceid).online || false;
this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory);
}
}
@@ -349,18 +274,12 @@ class eWeLink {
);
}
} else {
- this.log.warn(
- "[%s] cannot be initialised as it wasn't found in Homebridge.",
- device.name
- );
+ this.log.warn("[%s] cannot be initialised as it wasn't found in Homebridge.", device.name);
}
}
addAccessory(device, hbDeviceId, type) {
let switchNumber = hbDeviceId.substr(-1).toString(),
- newDeviceName =
- type === "rf_sub"
- ? device.tags.zyx_info[switchNumber - 1].name
- : device.name,
+ newDeviceName = type === "rf_sub" ? device.tags.zyx_info[switchNumber - 1].name : device.name,
channelCount =
type === "rf_pri"
? Object.keys((device.tags && device.tags.zyx_info) || []).length
@@ -378,10 +297,7 @@ class eWeLink {
if ((this.config.nameOverride || {}).hasOwnProperty(hbDeviceId)) {
newDeviceName = this.config.nameOverride[hbDeviceId];
}
- const accessory = new Accessory(
- newDeviceName,
- UUIDGen.generate(hbDeviceId).toString()
- );
+ const accessory = new Accessory(newDeviceName, UUIDGen.generate(hbDeviceId).toString());
try {
accessory
.getService(Service.AccessoryInformation)
@@ -391,10 +307,7 @@ class eWeLink {
Characteristic.Model,
device.productModel + " (" + device.extra.model + ")"
)
- .setCharacteristic(
- Characteristic.FirmwareRevision,
- device.params.fwVersion
- )
+ .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion)
.setCharacteristic(Characteristic.Identify, false);
accessory.context = {
hbDeviceId,
@@ -410,18 +323,11 @@ class eWeLink {
case "valve":
["A", "B"].forEach(v => {
accessory
- .addService(
- Service.Valve,
- "Valve " + v,
- "valve" + v.toLowerCase()
- )
+ .addService(Service.Valve, "Valve " + v, "valve" + v.toLowerCase())
.setCharacteristic(Characteristic.Active, 0)
.setCharacteristic(Characteristic.InUse, 0)
.setCharacteristic(Characteristic.ValveType, 1)
- .setCharacteristic(
- Characteristic.SetDuration,
- this.config.valveTimeLength || 120
- )
+ .setCharacteristic(Characteristic.SetDuration, this.config.valveTimeLength || 120)
.addCharacteristic(Characteristic.RemainingDuration);
});
break;
@@ -456,8 +362,7 @@ class eWeLink {
case "thermostat":
if (!this.config.hideTHSwitch) accessory.addService(Service.Switch);
accessory.addService(Service.TemperatureSensor);
- if (device.params.sensorType !== "DS18B20")
- accessory.addService(Service.HumiditySensor);
+ if (device.params.sensorType !== "DS18B20") accessory.addService(Service.HumiditySensor);
break;
case "outlet":
accessory.addService(Service.Outlet);
@@ -503,9 +408,7 @@ class eWeLink {
break;
case "rf_sub":
accessory.context.rfChls = {};
- switch (
- device.tags.zyx_info[parseInt(switchNumber) - 1].remote_type
- ) {
+ switch (device.tags.zyx_info[parseInt(switchNumber) - 1].remote_type) {
case "1":
case "2":
case "3":
@@ -525,52 +428,46 @@ class eWeLink {
);
}
let mAccessory = this.devicesInHB.get(device.deviceid + "SW0");
- device.tags.zyx_info[parseInt(switchNumber) - 1].buttonName.forEach(
- button => {
- let rfData;
- Object.entries(button).forEach(
- ([k, v]) =>
- (rfData = {
- rfChan: k,
- name: v,
- })
- );
- accessory.context.rfChls[rfData.rfChan] = rfData.name;
- mAccessory.context.rfChlMap[rfData.rfChan] = switchNumber;
- switch (accessory.context.sensorType) {
- case "button":
- accessory.addService(
- Service.Switch,
- rfData.name,
- "switch" + rfData.rfChan
- );
- break;
- case "water":
- accessory.addService(Service.LeakSensor);
- break;
- case "fire":
- case "smoke":
- accessory.addService(Service.SmokeSensor);
- break;
- case "co":
- accessory.addService(Service.CarbonMonoxideSensor);
- break;
- case "co2":
- accessory.addService(Service.CarbonDioxideSensor);
- break;
- case "contact":
- accessory.addService(Service.ContactSensor);
- break;
- case "occupancy":
- accessory.addService(Service.OccupancySensor);
- break;
- default:
- accessory.addService(Service.MotionSensor);
- break;
- }
- this.devicesInHB.set(mAccessory.context.hbDeviceId, mAccessory);
+ device.tags.zyx_info[parseInt(switchNumber) - 1].buttonName.forEach(button => {
+ let rfData;
+ Object.entries(button).forEach(
+ ([k, v]) =>
+ (rfData = {
+ rfChan: k,
+ name: v,
+ })
+ );
+ accessory.context.rfChls[rfData.rfChan] = rfData.name;
+ mAccessory.context.rfChlMap[rfData.rfChan] = switchNumber;
+ switch (accessory.context.sensorType) {
+ case "button":
+ accessory.addService(Service.Switch, rfData.name, "switch" + rfData.rfChan);
+ break;
+ case "water":
+ accessory.addService(Service.LeakSensor);
+ break;
+ case "fire":
+ case "smoke":
+ accessory.addService(Service.SmokeSensor);
+ break;
+ case "co":
+ accessory.addService(Service.CarbonMonoxideSensor);
+ break;
+ case "co2":
+ accessory.addService(Service.CarbonDioxideSensor);
+ break;
+ case "contact":
+ accessory.addService(Service.ContactSensor);
+ break;
+ case "occupancy":
+ accessory.addService(Service.OccupancySensor);
+ break;
+ default:
+ accessory.addService(Service.MotionSensor);
+ break;
}
- );
+ this.devicesInHB.set(mAccessory.context.hbDeviceId, mAccessory);
+ });
break;
case "zb_sub": //*** credit @tasict ***\\
accessory.addService(Service.BatteryService);
@@ -608,9 +505,7 @@ class eWeLink {
throw "device is not supported by this plugin. Please create an issue on GitHub";
}
this.devicesInHB.set(hbDeviceId, accessory);
- this.api.registerPlatformAccessories("homebridge-ewelink", "eWeLink", [
- accessory,
- ]);
+ this.api.registerPlatformAccessories("homebridge-ewelink", "eWeLink", [accessory]);
this.configureAccessory(accessory);
this.log("[%s] has been added to Homebridge.", newDeviceName);
} catch (err) {
@@ -629,33 +524,21 @@ class eWeLink {
.getService("Valve " + v)
.getCharacteristic(Characteristic.Active)
.on("set", (value, callback) =>
- this.internalValveUpdate(
- accessory,
- "Valve " + v,
- value,
- callback
- )
+ this.internalValveUpdate(accessory, "Valve " + v, value, callback)
);
accessory
.getService("Valve " + v)
.getCharacteristic(Characteristic.SetDuration)
.on("set", (value, callback) => {
if (
- accessory
- .getService("Valve " + v)
- .getCharacteristic(Characteristic.InUse).value
+ accessory.getService("Valve " + v).getCharacteristic(Characteristic.InUse).value
) {
accessory
.getService("Valve " + v)
- .updateCharacteristic(
- Characteristic.RemainingDuration,
- value
- );
+ .updateCharacteristic(Characteristic.RemainingDuration, value);
clearTimeout(accessory.getService("Valve " + v).timer);
accessory.getService("Valve " + v).timer = setTimeout(() => {
- accessory
- .getService("Valve " + v)
- .setCharacteristic(Characteristic.Active, 0);
+ accessory.getService("Valve " + v).setCharacteristic(Characteristic.Active, 0);
}, value * 1000);
}
callback();
@@ -666,9 +549,7 @@ class eWeLink {
accessory
.getService(Service.WindowCovering)
.getCharacteristic(Characteristic.TargetPosition)
- .on("set", (value, callback) =>
- this.internalBlindUpdate(accessory, value, callback)
- )
+ .on("set", (value, callback) => this.internalBlindUpdate(accessory, value, callback))
.setProps({
minStep: 100,
});
@@ -677,17 +558,13 @@ class eWeLink {
accessory
.getService(Service.GarageDoorOpener)
.getCharacteristic(Characteristic.TargetDoorState)
- .on("set", (value, callback) =>
- this.internalGarageUpdate(accessory, value, callback)
- );
+ .on("set", (value, callback) => this.internalGarageUpdate(accessory, value, callback));
break;
case "lock":
accessory
.getService(Service.LockMechanism)
.getCharacteristic(Characteristic.LockTargetState)
- .on("set", (value, callback) =>
- this.internalLockUpdate(accessory, value, callback)
- );
+ .on("set", (value, callback) => this.internalLockUpdate(accessory, value, callback));
break;
case "fan":
accessory
@@ -737,9 +614,7 @@ class eWeLink {
if (accessory.getService(Service.HumiditySensor)) {
dataToAdd.humidity = accessory
.getService(Service.HumiditySensor)
- .getCharacteristic(
- Characteristic.CurrentRelativeHumidity
- ).value;
+ .getCharacteristic(Characteristic.CurrentRelativeHumidity).value;
}
accessory.eveLogger.addEntry(dataToAdd);
}, 300000);
@@ -748,9 +623,7 @@ class eWeLink {
accessory
.getService(Service.Outlet)
.getCharacteristic(Characteristic.On)
- .on("set", (value, callback) =>
- this.internalOutletUpdate(accessory, value, callback)
- );
+ .on("set", (value, callback) => this.internalOutletUpdate(accessory, value, callback));
accessory.log = this.log;
accessory.eveLogger = new EveHistoryService("energy", accessory, {
storage: "fs",
@@ -769,15 +642,12 @@ class eWeLink {
};
}
corrInterval.setCorrectingInterval(() => {
- let isOn = accessory
- .getService(Service.Outlet)
- .getCharacteristic(Characteristic.On).value,
+ let isOn = accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On)
+ .value,
currentWatt = isOn
? accessory
.getService(Service.Outlet)
- .getCharacteristic(
- EveService.Characteristics.CurrentConsumption
- ).value
+ .getCharacteristic(EveService.Characteristics.CurrentConsumption).value
: 0;
if (accessory.eveLogger.isHistoryLoaded()) {
accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData();
@@ -792,8 +662,7 @@ class eWeLink {
});
} else {
accessory.context.totalEnergy =
- accessory.context.totalEnergyTemp +
- (currentWatt * 10) / 3600 / 1000;
+ accessory.context.totalEnergyTemp + (currentWatt * 10) / 3600 / 1000;
accessory.eveLogger.setExtraPersistedData({
totalenergy: accessory.context.totalEnergy,
lastReset: 0,
@@ -801,8 +670,7 @@ class eWeLink {
}
accessory.context.totalEnergytemp = 0;
} else {
- accessory.context.totalEnergyTemp +=
- (currentWatt * 10) / 3600 / 1000;
+ accessory.context.totalEnergyTemp += (currentWatt * 10) / 3600 / 1000;
accessory.context.totalEnergy = accessory.context.totalEnergyTemp;
}
accessory.eveLogger.addEntry({
@@ -816,8 +684,7 @@ class eWeLink {
.on("get", callback => {
accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData();
if (accessory.context.extraPersistedData !== undefined) {
- accessory.context.totalEnergy =
- accessory.context.extraPersistedData.totalPower;
+ accessory.context.totalEnergy = accessory.context.extraPersistedData.totalPower;
}
callback(null, accessory.context.totalEnergy);
});
@@ -836,8 +703,7 @@ class eWeLink {
.on("get", callback => {
accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData();
if (accessory.context.extraPersistedData !== undefined) {
- accessory.context.lastReset =
- accessory.context.extraPersistedData.lastReset;
+ accessory.context.lastReset = accessory.context.extraPersistedData.lastReset;
}
callback(null, accessory.context.lastReset);
});
@@ -846,17 +712,13 @@ class eWeLink {
accessory
.getService(Service.Outlet)
.getCharacteristic(Characteristic.On)
- .on("set", (value, callback) =>
- this.internalUSBUpdate(accessory, value, callback)
- );
+ .on("set", (value, callback) => this.internalUSBUpdate(accessory, value, callback));
break;
case "scm":
accessory
.getService(Service.Switch)
.getCharacteristic(Characteristic.On)
- .on("set", (value, callback) =>
- this.internalSCMUpdate(accessory, value, callback)
- );
+ .on("set", (value, callback) => this.internalSCMUpdate(accessory, value, callback));
break;
case "light":
accessory
@@ -872,9 +734,8 @@ class eWeLink {
.on("set", (value, callback) => {
if (value > 0) {
if (
- !accessory
- .getService(Service.Lightbulb)
- .getCharacteristic(Characteristic.On).value
+ !accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On)
+ .value
) {
this.internalLightbulbUpdate(accessory, true, function () {
return;
@@ -885,18 +746,15 @@ class eWeLink {
this.internalLightbulbUpdate(accessory, false, callback);
}
});
- } else if (
- cns.devicesColourable.includes(accessory.context.eweUIID)
- ) {
+ } else if (cns.devicesColourable.includes(accessory.context.eweUIID)) {
accessory
.getService(Service.Lightbulb)
.getCharacteristic(Characteristic.Brightness)
.on("set", (value, callback) => {
if (value > 0) {
if (
- !accessory
- .getService(Service.Lightbulb)
- .getCharacteristic(Characteristic.On).value
+ !accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On)
+ .value
) {
this.internalLightbulbUpdate(accessory, true, function () {
return;
@@ -923,24 +781,18 @@ class eWeLink {
accessory
.getService(Service.Switch)
.getCharacteristic(Characteristic.On)
- .on("set", (value, callback) =>
- this.internalSwitchUpdate(accessory, value, callback)
- );
+ .on("set", (value, callback) => this.internalSwitchUpdate(accessory, value, callback));
break;
case "rf_sub":
accessory.context.rfChls = accessory.context.rfChls || {};
if (accessory.context.sensorType === "button") {
Object.entries(accessory.context.rfChls).forEach(([k, v]) => {
- accessory
- .getService(v)
- .updateCharacteristic(Characteristic.On, false);
+ accessory.getService(v).updateCharacteristic(Characteristic.On, false);
accessory
.getService(v)
.getCharacteristic(Characteristic.On)
.on("set", (value, callback) => {
- value
- ? this.internalRFDeviceUpdate(accessory, k, callback)
- : callback();
+ value ? this.internalRFDeviceUpdate(accessory, k, callback) : callback();
});
});
}
@@ -961,8 +813,7 @@ class eWeLink {
.getCharacteristic(Characteristic.CurrentTemperature).value,
humidity: accessory
.getService(Service.HumiditySensor)
- .getCharacteristic(Characteristic.CurrentRelativeHumidity)
- .value,
+ .getCharacteristic(Characteristic.CurrentRelativeHumidity).value,
};
accessory.eveLogger.addEntry(dataToAdd);
}, 300000);
@@ -971,20 +822,14 @@ class eWeLink {
}
this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
} catch (err) {
- this.log.warn(
- "[%s] could not be refreshed as %s.",
- accessory.displayName,
- err
- );
+ this.log.warn("[%s] could not be refreshed as %s.", accessory.displayName, err);
}
}
refreshAccessory(accessory, newParams) {
switch (accessory.context.type) {
case "valve":
if (
- Object.keys(newParams).some(v =>
- cns.devicesValveParams.includes(v)
- ) &&
+ Object.keys(newParams).some(v => cns.devicesValveParams.includes(v)) &&
Array.isArray(newParams.switches)
) {
this.externalValveUpdate(accessory, newParams);
@@ -992,9 +837,7 @@ class eWeLink {
return true;
case "blind":
if (
- Object.keys(newParams).some(v =>
- cns.devicesBlindParams.includes(v)
- ) &&
+ Object.keys(newParams).some(v => cns.devicesBlindParams.includes(v)) &&
Array.isArray(newParams.switches)
) {
this.externalBlindUpdate(accessory, newParams);
@@ -1002,48 +845,34 @@ class eWeLink {
return true;
case "garage":
if (
- Object.keys(newParams).some(v =>
- cns.devicesGarageParams.includes(v)
- ) &&
+ Object.keys(newParams).some(v => cns.devicesGarageParams.includes(v)) &&
Array.isArray(newParams.switches)
) {
this.externalGarageUpdate(accessory, newParams);
}
return true;
case "lock":
- if (
- Object.keys(newParams).some(v => cns.devicesLockParams.includes(v))
- ) {
+ if (Object.keys(newParams).some(v => cns.devicesLockParams.includes(v))) {
this.externalLockUpdate(accessory, newParams);
}
return true;
case "sensor":
- if (
- Object.keys(newParams).some(v => cns.devicesSensorParams.includes(v))
- ) {
+ if (Object.keys(newParams).some(v => cns.devicesSensorParams.includes(v))) {
this.externalSensorUpdate(accessory, newParams);
}
return true;
case "fan":
- if (
- Object.keys(newParams).some(v => cns.devicesFanParams.includes(v))
- ) {
+ if (Object.keys(newParams).some(v => cns.devicesFanParams.includes(v))) {
this.externalFanUpdate(accessory, newParams);
}
return true;
case "thermostat":
- if (
- Object.keys(newParams).some(v =>
- cns.devicesThermostatParams.includes(v)
- )
- ) {
+ if (Object.keys(newParams).some(v => cns.devicesThermostatParams.includes(v))) {
this.externalThermostatUpdate(accessory, newParams);
}
return true;
case "outlet":
- if (
- Object.keys(newParams).some(v => cns.devicesOutletParams.includes(v))
- ) {
+ if (Object.keys(newParams).some(v => cns.devicesOutletParams.includes(v))) {
this.externalOutletUpdate(accessory, newParams);
}
return true;
@@ -1068,11 +897,7 @@ class eWeLink {
cns.devicesSingleSwitch.includes(accessory.context.eweUIID) &&
cns.devicesSingleSwitchLight.includes(accessory.context.eweModel)
) {
- if (
- Object.keys(newParams).some(v =>
- cns.devicesSingleSwitchLightParams.includes(v)
- )
- ) {
+ if (Object.keys(newParams).some(v => cns.devicesSingleSwitchLightParams.includes(v))) {
this.externalSingleLightUpdate(accessory, newParams);
}
} else if (
@@ -1080,9 +905,7 @@ class eWeLink {
cns.devicesMultiSwitchLight.includes(accessory.context.eweModel)
) {
if (
- Object.keys(newParams).some(v =>
- cns.devicesMultiSwitchLightParams.includes(v)
- ) &&
+ Object.keys(newParams).some(v => cns.devicesMultiSwitchLightParams.includes(v)) &&
Array.isArray(newParams.switches)
) {
this.externalMultiLightUpdate(accessory, newParams);
@@ -1091,18 +914,12 @@ class eWeLink {
return true;
case "switch":
if (cns.devicesSingleSwitch.includes(accessory.context.eweUIID)) {
- if (
- Object.keys(newParams).some(v =>
- cns.devicesSingleSwitchParams.includes(v)
- )
- ) {
+ if (Object.keys(newParams).some(v => cns.devicesSingleSwitchParams.includes(v))) {
this.externalSingleSwitchUpdate(accessory, newParams);
}
} else if (cns.devicesMultiSwitch.includes(accessory.context.eweUIID)) {
if (
- Object.keys(newParams).some(v =>
- cns.devicesMultiSwitchParams.includes(v)
- ) &&
+ Object.keys(newParams).some(v => cns.devicesMultiSwitchParams.includes(v)) &&
Array.isArray(newParams.switches)
) {
this.externalMultiSwitchUpdate(accessory, newParams);
@@ -1110,11 +927,7 @@ class eWeLink {
}
return true;
case "rf_pri":
- if (
- Object.keys(newParams).some(v =>
- cns.devicesRFBridgeParams.includes(v)
- )
- ) {
+ if (Object.keys(newParams).some(v => cns.devicesRFBridgeParams.includes(v))) {
this.externalRFDeviceUpdate(accessory, newParams);
}
return true;
@@ -1122,11 +935,7 @@ class eWeLink {
case "zb_pri":
return true;
case "zb_sub":
- if (
- Object.keys(newParams).some(v =>
- cns.devicesZBBridgeParams.includes(v)
- )
- ) {
+ if (Object.keys(newParams).some(v => cns.devicesZBBridgeParams.includes(v))) {
this.externalZBDeviceUpdate(accessory, newParams);
}
return true;
@@ -1137,16 +946,10 @@ class eWeLink {
removeAccessory(accessory) {
try {
this.devicesInHB.delete(accessory.context.hbDeviceId);
- this.api.unregisterPlatformAccessories("homebridge-ewelink", "eWeLink", [
- accessory,
- ]);
+ this.api.unregisterPlatformAccessories("homebridge-ewelink", "eWeLink", [accessory]);
this.log("[%s] has been removed from Homebridge.", accessory.displayName);
} catch (err) {
- this.log.warn(
- "[%s] needed to be removed but couldn't as %s.",
- accessory.displayName,
- err
- );
+ this.log.warn("[%s] needed to be removed but couldn't as %s.", accessory.displayName, err);
}
}
sendDeviceUpdate(accessory, params, callback) {
@@ -1167,10 +970,7 @@ class eWeLink {
callback("Device has failed to update");
}
};
- if (
- cns.devicesNonLAN.includes(accessory.context.eweUIID) ||
- !accessory.context.reachableLAN
- ) {
+ if (cns.devicesNonLAN.includes(accessory.context.eweUIID) || !accessory.context.reachableLAN) {
sendViaWS();
} else {
this.lanClient
@@ -1178,110 +978,81 @@ class eWeLink {
.then(() => callback())
.catch(err => {
if (this.debug) {
- this.log.warn(
- "[%s] Reverting to web socket as %s.",
- accessory.displayName,
- err
- );
+ this.log.warn("[%s] Reverting to web socket as %s.", accessory.displayName, err);
}
sendViaWS();
});
}
}
receiveDeviceUpdate(device) {
- let accessory;
- switch (device.action) {
- case "sysmsg":
- if (
- (accessory =
- this.devicesInHB.get(device.deviceid + "SWX") ||
- this.devicesInHB.get(device.deviceid + "SW0"))
- ) {
- let isX = accessory.context.hbDeviceId.substr(-1) === "X";
- if (device.params.updateSource === "WS") {
- if (accessory.context.reachableWAN !== device.params.online) {
- accessory.context.reachableWAN = device.params.online;
- this.log(
- "[%s] has been reported [%s] via [WS].",
- accessory.displayName,
- accessory.context.reachableWAN ? "online" : "offline"
- );
- this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
- if (accessory.context.reachableWAN)
- this.wsClient.requestUpdate(accessory);
- } else {
- if (this.debug) {
- this.log(
- "[%s] Nothing to update from above WS message.",
- accessory.displayName
- );
- }
- }
- }
- if (!isX) {
- for (let i = 1; i <= accessory.context.channelCount; i++) {
- if (this.devicesInHB.has(device.deviceid + "SW" + i)) {
- let oAccessory = this.devicesInHB.get(
- device.deviceid + "SW" + i
- );
- oAccessory.context.reachableWAN = device.params.online;
- this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory);
- }
- }
- }
+ let accessory,
+ deviceId = device.deviceid,
+ statusChange = false;
+ if (
+ (accessory = this.devicesInHB.get(deviceId + "SWX") || this.devicesInHB.get(deviceId + "SW0"))
+ ) {
+ let isX = accessory.context.hbDeviceId.substr(-1) === "X";
+
+ if (device.params.updateSource === "WS") {
+ if (device.params.online != accessory.context.reachableWAN) {
+ accessory.context.reachableWAN = device.params.online;
+ this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
+ if (accessory.context.reachableWAN) this.wsClient.requestUpdate(accessory);
+ statusChange = true;
+ this.log.warn(
+ "[%s] has been reported [%s] via [WS].",
+ accessory.displayName,
+ accessory.context.reachableWAN ? "online" : "offline"
+ );
}
- break;
- case "update":
- if (
- (accessory =
- this.devicesInHB.get(device.deviceid + "SWX") ||
- this.devicesInHB.get(device.deviceid + "SW0"))
- ) {
- if (
- device.params.updateSource === "WS" &&
- !accessory.context.reachableWAN
- ) {
- accessory.context.reachableWAN = true;
- this.log(
- "[%s] has been reported [online] via [WS].",
- accessory.displayName
- );
- }
- if (
- device.params.updateSource === "LAN" &&
- !accessory.context.reachableLAN
- ) {
- accessory.context.reachableLAN = true;
- this.log(
- "[%s] has been reported [online] via [LAN].",
- accessory.displayName
- );
- }
- if (this.debug) {
- this.log(
- "[%s] externally updated from above %s message and will be refreshed.",
- accessory.displayName,
- device.params.updateSource
- );
- }
- if (!this.refreshAccessory(accessory, device.params)) {
- this.log.warn(
- "[%s] cannot be refreshed. Please try removing accessory from the Homebridge cache along with any secondary devices (SW1, SW2, etc.). [debug:%s:%s]",
- accessory.displayName,
- accessory.context.type,
- accessory.context.channelCount
- );
- }
- } else {
- if (!(this.config.hideDevFromHB || "").includes(device.deviceid)) {
- this.log.warn(
- "[%s] Accessory received via %s update does not exist in Homebridge. If it's a new accessory please restart Homebridge so it is added.",
- device.deviceid,
- device.params.updateSource
- );
+ }
+
+ if (device.params.updateSource === "LAN") {
+ if (!accessory.context.reachableLAN) {
+ accessory.context.reachableLAN = true;
+ this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
+ this.wsClient.requestUpdate(accessory);
+ statusChange = true;
+ this.log.warn("[%s] has been reported [online] via [LAN].", accessory.displayName);
+ }
+ if (statusChange && !isX) {
+ for (let i = 1; i <= accessory.context.channelCount; i++) {
+ if (this.devicesInHB.has(deviceId + "SW" + i)) {
+ let oAccessory = this.devicesInHB.get(deviceId + "SW" + i);
+ oAccessory.context.reachableWAN = device.params.online;
+ oAccessory.context.reachableLAN = true;
+ this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory);
+ }
}
}
- break;
+ }
+ if (this.debug) {
+ this.log(
+ "[%s] externally updated from above %s message and will be refreshed.",
+ accessory.displayName,
+ device.params.updateSource
+ );
+ }
+ if (!this.refreshAccessory(accessory, device.params)) {
+ this.log.warn(
+ "[%s] cannot be refreshed. Please try removing accessory from the Homebridge cache along with any secondary devices (SW1, SW2, etc.). [debug:%s:%s]",
+ accessory.displayName,
+ accessory.context.type,
+ accessory.context.channelCount
+ );
+ }
+ } else {
+ if (!(this.config.hideDevFromHB || "").includes(deviceId)) {
+ this.log.warn(
+ "[%s] update received via %s does not exist in Homebridge so device will be added.",
+ deviceId,
+ device.params.updateSource
+ );
+ this.httpClient
+ .getDevice(deviceId)
+ .then(res => this.initialiseDevice(res))
+ .catch(err => this.log.error("[%s] error getting info [%s]", deviceId, err));
+ }
}
}
internalValveUpdate(accessory, valve, value, callback) {
@@ -1296,28 +1067,19 @@ class eWeLink {
.updateCharacteristic(Characteristic.InUse, value);
switch (value) {
case 0:
- accessory
- .getService(valve)
- .updateCharacteristic(Characteristic.RemainingDuration, 0);
+ accessory.getService(valve).updateCharacteristic(Characteristic.RemainingDuration, 0);
clearTimeout(accessory.getService(valve).timer);
break;
case 1:
- let timer = accessory
- .getService(valve)
- .getCharacteristic(Characteristic.SetDuration).value;
- accessory
- .getService(valve)
- .updateCharacteristic(Characteristic.RemainingDuration, timer);
+ let timer = accessory.getService(valve).getCharacteristic(Characteristic.SetDuration)
+ .value;
+ accessory.getService(valve).updateCharacteristic(Characteristic.RemainingDuration, timer);
accessory.getService(valve).timer = setTimeout(() => {
- accessory
- .getService(valve)
- .setCharacteristic(Characteristic.Active, 0);
+ accessory.getService(valve).setCharacteristic(Characteristic.Active, 0);
}, timer * 1000);
break;
}
- params.switches = this.devicesInEwe.get(
- accessory.context.eweDeviceId
- ).params.switches;
+ params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
switch (valve) {
case "Valve A":
params.switches[0].switch = value ? "on" : "off";
@@ -1342,8 +1104,7 @@ class eWeLink {
params.switches[3].switch = "off";
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
- let str =
- "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -1357,10 +1118,7 @@ class eWeLink {
if (!(blindConfig = this.cusG.get(accessory.context.hbDeviceId))) {
throw "group config missing";
}
- if (
- blindConfig.type !== "blind" ||
- !["oneSwitch", "twoSwitch"].includes(blindConfig.setup)
- ) {
+ if (blindConfig.type !== "blind" || !["oneSwitch", "twoSwitch"].includes(blindConfig.setup)) {
throw "improper configuration";
}
let oldPos,
@@ -1382,9 +1140,7 @@ class eWeLink {
params.switch = "on";
break;
case "twoSwitch":
- params.switches = this.devicesInEwe.get(
- accessory.context.eweDeviceId
- ).params.switches;
+ params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
params.switches[0].switch = value === 100 ? "on" : "off";
params.switches[1].switch = value === 0 ? "on" : "off";
break;
@@ -1404,8 +1160,7 @@ class eWeLink {
callback();
}, parseInt(blindConfig.operationTime) * 100);
} catch (err) {
- let str =
- "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -1433,10 +1188,7 @@ class eWeLink {
newPos = value,
params = {},
delay = 0;
- if (
- sensorDefinition &&
- !(sAccessory = this.devicesInHB.get(garageConfig.sensorId + "SWX"))
- ) {
+ if (sensorDefinition && !(sAccessory = this.devicesInHB.get(garageConfig.sensorId + "SWX"))) {
throw "defined DW2 sensor doesn't exist";
}
if (sAccessory.context.type !== "sensor") {
@@ -1459,10 +1211,7 @@ class eWeLink {
if (garageConfig.setup === "oneSwitch" && [2, 3].includes(oldPos)) {
accessory
.getService(Service.GarageDoorOpener)
- .updateCharacteristic(
- Characteristic.CurrentDoorState,
- ((oldPos * 2) % 3) + 2
- );
+ .updateCharacteristic(Characteristic.CurrentDoorState, ((oldPos * 2) % 3) + 2);
delay = 1500;
}
setTimeout(() => {
@@ -1476,9 +1225,7 @@ class eWeLink {
params.switch = "on";
break;
case "twoSwitch":
- params.switches = this.devicesInEwe.get(
- accessory.context.eweDeviceId
- ).params.switches;
+ params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
params.switches[0].switch = newPos === 0 ? "on" : "off";
params.switches[1].switch = newPos === 1 ? "on" : "off";
break;
@@ -1499,8 +1246,7 @@ class eWeLink {
callback();
} catch (err) {
accessory.context.inUse = false;
- let str =
- "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -1535,8 +1281,7 @@ class eWeLink {
}, parseInt(lockConfig.operationTime) * 100);
} catch (err) {
accessory.context.inUse = false;
- let str =
- "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -1551,45 +1296,36 @@ class eWeLink {
case "power":
newPower = value;
newSpeed = value ? 33 : 0;
- newLight = accessory
- .getService(Service.Lightbulb)
- .getCharacteristic(Characteristic.On).value;
+ newLight = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On)
+ .value;
break;
case "speed":
newPower = value >= 33 ? 1 : 0;
newSpeed = value;
- newLight = accessory
- .getService(Service.Lightbulb)
- .getCharacteristic(Characteristic.On).value;
+ newLight = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On)
+ .value;
break;
case "light":
- newPower = accessory
- .getService(Service.Fanv2)
- .getCharacteristic(Characteristic.Active).value;
+ newPower = accessory.getService(Service.Fanv2).getCharacteristic(Characteristic.Active)
+ .value;
newSpeed = accessory
.getService(Service.Fanv2)
.getCharacteristic(Characteristic.RotationSpeed).value;
newLight = value;
break;
}
- accessory
- .getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.On, newLight);
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, newLight);
accessory
.getService(Service.Fanv2)
.updateCharacteristic(Characteristic.Active, newPower)
.updateCharacteristic(Characteristic.RotationSpeed, newSpeed);
let params = {
- switches: this.devicesInEwe.get(accessory.context.eweDeviceId).params
- .switches,
+ switches: this.devicesInEW.get(accessory.context.eweDeviceId).params.switches,
};
params.switches[0].switch = newLight ? "on" : "off";
- params.switches[1].switch =
- newPower === 1 && newSpeed >= 33 ? "on" : "off";
- params.switches[2].switch =
- newPower === 1 && newSpeed >= 66 && newSpeed < 99 ? "on" : "off";
- params.switches[3].switch =
- newPower === 1 && newSpeed >= 99 ? "on" : "off";
+ params.switches[1].switch = newPower === 1 && newSpeed >= 33 ? "on" : "off";
+ params.switches[2].switch = newPower === 1 && newSpeed >= 66 && newSpeed < 99 ? "on" : "off";
+ params.switches[3].switch = newPower === 1 && newSpeed >= 99 ? "on" : "off";
if (this.debug) {
this.log.warn("Fan Update - setting " + type + " to " + value);
this.log(
@@ -1602,8 +1338,7 @@ class eWeLink {
}
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
- let str =
- "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -1618,19 +1353,12 @@ class eWeLink {
mainSwitch: value ? "on" : "off",
};
if (this.debug) {
- this.log(
- "[%s] updating to turn [%s].",
- accessory.displayName,
- value ? "on" : "off"
- );
+ this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
}
- accessory
- .getService(Service.Switch)
- .updateCharacteristic(Characteristic.On, value);
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
- let str =
- "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -1644,15 +1372,9 @@ class eWeLink {
switch: value ? "on" : "off",
};
if (this.debug) {
- this.log(
- "[%s] requesting to turn [%s].",
- accessory.displayName,
- value ? "on" : "off"
- );
+ this.log("[%s] requesting to turn [%s].", accessory.displayName, value ? "on" : "off");
}
- accessory
- .getService(Service.Outlet)
- .updateCharacteristic(Characteristic.On, value);
+ accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, value);
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
callback("[" + accessory.displayName + "] " + err + ".");
@@ -1664,20 +1386,13 @@ class eWeLink {
throw "it is currently offline";
}
let params = {
- switches: this.devicesInEwe.get(accessory.context.eweDeviceId).params
- .switches,
+ switches: this.devicesInEW.get(accessory.context.eweDeviceId).params.switches,
};
params.switches[0].switch = value ? "on" : "off";
if (this.debug) {
- this.log(
- "[%s] requesting to turn [%s].",
- accessory.displayName,
- value ? "on" : "off"
- );
+ this.log("[%s] requesting to turn [%s].", accessory.displayName, value ? "on" : "off");
}
- accessory
- .getService(Service.Outlet)
- .updateCharacteristic(Characteristic.On, value);
+ accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, value);
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
callback("[" + accessory.displayName + "] " + err + ".");
@@ -1689,20 +1404,13 @@ class eWeLink {
throw "it is currently offline";
}
let params = {
- switches: this.devicesInEwe.get(accessory.context.eweDeviceId).params
- .switches,
+ switches: this.devicesInEW.get(accessory.context.eweDeviceId).params.switches,
};
params.switches[0].switch = value ? "on" : "off";
if (this.debug) {
- this.log(
- "[%s] requesting to turn [%s].",
- accessory.displayName,
- value ? "on" : "off"
- );
+ this.log("[%s] requesting to turn [%s].", accessory.displayName, value ? "on" : "off");
}
- accessory
- .getService(Service.Switch)
- .updateCharacteristic(Characteristic.On, value);
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
callback("[" + accessory.displayName + "] " + err + ".");
@@ -1724,20 +1432,12 @@ class eWeLink {
params.switch = value ? "on" : "off";
}
if (this.debug) {
- this.log(
- "[%s] updating to turn [%s].",
- accessory.displayName,
- value ? "on" : "off"
- );
+ this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
}
- accessory
- .getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.On, value);
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
break;
case "0":
- params.switches = this.devicesInEwe.get(
- accessory.context.eweDeviceId
- ).params.switches;
+ params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
params.switches[0].switch = value ? "on" : "off";
params.switches[1].switch = value ? "on" : "off";
params.switches[2].switch = value ? "on" : "off";
@@ -1749,16 +1449,10 @@ class eWeLink {
value ? "on" : "off"
);
}
- accessory
- .getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.On, value);
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
for (let i = 1; i <= 4; i++) {
- if (
- this.devicesInHB.has(accessory.context.eweDeviceId + "SW" + i)
- ) {
- oAccessory = this.devicesInHB.get(
- accessory.context.eweDeviceId + "SW" + i
- );
+ if (this.devicesInHB.has(accessory.context.eweDeviceId + "SW" + i)) {
+ oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i);
oAccessory
.getService(Service.Lightbulb)
.updateCharacteristic(Characteristic.On, value);
@@ -1770,26 +1464,14 @@ class eWeLink {
case "3":
case "4":
if (this.debug) {
- this.log(
- "[%s] updating to turn [%s].",
- accessory.displayName,
- value ? "on" : "off"
- );
+ this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
}
- accessory
- .getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.On, value);
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
let tAccessory,
masterState = "off";
- params.switches = this.devicesInEwe.get(
- accessory.context.eweDeviceId
- ).params.switches;
+ params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
for (let i = 1; i <= 4; i++) {
- if (
- (tAccessory = this.devicesInHB.get(
- accessory.context.eweDeviceId + "SW" + i
- ))
- ) {
+ if ((tAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
i === parseInt(accessory.context.switchNumber)
? (params.switches[i - 1].switch = value ? "on" : "off")
: (params.switches[i - 1].switch = tAccessory
@@ -1798,9 +1480,7 @@ class eWeLink {
? "on"
: "off");
if (
- tAccessory
- .getService(Service.Lightbulb)
- .getCharacteristic(Characteristic.On).value
+ tAccessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value
) {
masterState = "on";
}
@@ -1808,22 +1488,17 @@ class eWeLink {
params.switches[i - 1].switch = "off";
}
}
- oAccessory = this.devicesInHB.get(
- accessory.context.eweDeviceId + "SW0"
- );
+ oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
oAccessory
.getService(Service.Lightbulb)
.updateCharacteristic(Characteristic.On, masterState === "on");
break;
default:
- throw (
- "unknown switch number [" + accessory.context.switchNumber + "]"
- );
+ throw "unknown switch number [" + accessory.context.switchNumber + "]";
}
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
- let str =
- "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -1836,15 +1511,9 @@ class eWeLink {
let params = {};
if (value === 0) {
params.switch = "off";
- accessory
- .getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.On, false);
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, false);
} else {
- if (
- !accessory
- .getService(Service.Lightbulb)
- .getCharacteristic(Characteristic.On).value
- ) {
+ if (!accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value) {
params.switch = "on";
}
switch (accessory.context.eweUIID) {
@@ -1863,16 +1532,11 @@ class eWeLink {
.updateCharacteristic(Characteristic.Brightness, value);
}
if (this.debug) {
- this.log(
- "[%s] updating brightness to [%s%].",
- accessory.displayName,
- value
- );
+ this.log("[%s] updating brightness to [%s%].", accessory.displayName, value);
}
setTimeout(() => this.sendDeviceUpdate(accessory, params, callback), 250);
} catch (err) {
- let str =
- "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -1884,9 +1548,8 @@ class eWeLink {
}
let newRGB,
params = {},
- curHue = accessory
- .getService(Service.Lightbulb)
- .getCharacteristic(Characteristic.Hue).value,
+ curHue = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Hue)
+ .value,
curSat = accessory
.getService(Service.Lightbulb)
.getCharacteristic(Characteristic.Saturation).value;
@@ -1917,15 +1580,9 @@ class eWeLink {
throw "unknown device UIID";
}
if (this.debug) {
- this.log(
- "[%s] updating hue to [%s°].",
- accessory.displayName,
- value
- );
+ this.log("[%s] updating hue to [%s°].", accessory.displayName, value);
}
- accessory
- .getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.Hue, value);
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Hue, value);
break;
case "bri":
switch (accessory.context.eweUIID) {
@@ -1949,11 +1606,7 @@ class eWeLink {
break;
}
if (this.debug) {
- this.log(
- "[%s] updating brightness to [%s%].",
- accessory.displayName,
- value
- );
+ this.log("[%s] updating brightness to [%s%].", accessory.displayName, value);
}
accessory
.getService(Service.Lightbulb)
@@ -1964,8 +1617,7 @@ class eWeLink {
}
setTimeout(() => this.sendDeviceUpdate(accessory, params, callback), 250);
} catch (err) {
- let str =
- "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -1981,20 +1633,12 @@ class eWeLink {
case "X":
params.switch = value ? "on" : "off";
if (this.debug) {
- this.log(
- "[%s] updating to turn [%s].",
- accessory.displayName,
- value ? "on" : "off"
- );
+ this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
}
- accessory
- .getService(Service.Switch)
- .updateCharacteristic(Characteristic.On, value);
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
break;
case "0":
- params.switches = this.devicesInEwe.get(
- accessory.context.eweDeviceId
- ).params.switches;
+ params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
params.switches[0].switch = value ? "on" : "off";
params.switches[1].switch = value ? "on" : "off";
params.switches[2].switch = value ? "on" : "off";
@@ -2006,19 +1650,11 @@ class eWeLink {
value ? "on" : "off"
);
}
- accessory
- .getService(Service.Switch)
- .updateCharacteristic(Characteristic.On, value);
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
for (let i = 1; i <= 4; i++) {
- if (
- this.devicesInHB.has(accessory.context.eweDeviceId + "SW" + i)
- ) {
- oAccessory = this.devicesInHB.get(
- accessory.context.eweDeviceId + "SW" + i
- );
- oAccessory
- .getService(Service.Switch)
- .updateCharacteristic(Characteristic.On, value);
+ if (this.devicesInHB.has(accessory.context.eweDeviceId + "SW" + i)) {
+ oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i);
+ oAccessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
}
}
break;
@@ -2027,26 +1663,14 @@ class eWeLink {
case "3":
case "4":
if (this.debug) {
- this.log(
- "[%s] updating to turn [%s].",
- accessory.displayName,
- value ? "on" : "off"
- );
+ this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
}
- accessory
- .getService(Service.Switch)
- .updateCharacteristic(Characteristic.On, value);
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
let tAccessory,
masterState = "off";
- params.switches = this.devicesInEwe.get(
- accessory.context.eweDeviceId
- ).params.switches;
+ params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
for (let i = 1; i <= 4; i++) {
- if (
- (tAccessory = this.devicesInHB.get(
- accessory.context.eweDeviceId + "SW" + i
- ))
- ) {
+ if ((tAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
i === parseInt(accessory.context.switchNumber)
? (params.switches[i - 1].switch = value ? "on" : "off")
: (params.switches[i - 1].switch = tAccessory
@@ -2055,9 +1679,7 @@ class eWeLink {
? "on"
: "off");
if (
- tAccessory
- .getService(Service.Switch)
- .getCharacteristic(Characteristic.On).value
+ tAccessory.getService(Service.Switch).getCharacteristic(Characteristic.On).value
) {
masterState = "on";
}
@@ -2065,22 +1687,17 @@ class eWeLink {
params.switches[i - 1].switch = "off";
}
}
- oAccessory = this.devicesInHB.get(
- accessory.context.eweDeviceId + "SW0"
- );
+ oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
oAccessory
.getService(Service.Switch)
.updateCharacteristic(Characteristic.On, masterState === "on");
break;
default:
- throw (
- "unknown switch number [" + accessory.context.switchNumber + "]"
- );
+ throw "unknown switch number [" + accessory.context.switchNumber + "]";
}
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
- let str =
- "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -2114,14 +1731,7 @@ class eWeLink {
3000
);
} catch (err) {
- let str =
- "[" +
- accessory.displayName +
- " " +
- name +
- "] could not be updated as " +
- err +
- ".";
+ let str = "[" + accessory.displayName + " " + name + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -2131,14 +1741,8 @@ class eWeLink {
["A", "B"].forEach((v, k) => {
accessory
.getService("Valve " + v)
- .updateCharacteristic(
- Characteristic.Active,
- params.switches[k].switch === "on"
- )
- .updateCharacteristic(
- Characteristic.InUse,
- params.switches[k].switch === "on"
- );
+ .updateCharacteristic(Characteristic.Active, params.switches[k].switch === "on")
+ .updateCharacteristic(Characteristic.InUse, params.switches[k].switch === "on");
if (params.switches[k].switch === "on") {
let timer = accessory
.getService("Valve " + v)
@@ -2147,9 +1751,7 @@ class eWeLink {
.getService("Valve " + v)
.updateCharacteristic(Characteristic.RemainingDuration, timer);
accessory.getService("Valve " + v).timer = setTimeout(() => {
- accessory
- .getService("Valve " + v)
- .setCharacteristic(Characteristic.Active, 0);
+ accessory.getService("Valve " + v).setCharacteristic(Characteristic.Active, 0);
}, timer * 1000);
} else {
accessory
@@ -2159,11 +1761,7 @@ class eWeLink {
}
});
} catch (err) {
- this.log.warn(
- "[%s] could not be updated as %s.",
- accessory.displayName,
- err
- );
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalBlindUpdate(accessory, params) {
@@ -2172,10 +1770,7 @@ class eWeLink {
if (!(blindConfig = this.cusG.get(accessory.context.hbDeviceId))) {
throw "group config missing";
}
- if (
- blindConfig.type !== "blind" ||
- ["oneSwitch", "twoSwitch"].includes(blindConfig.setup)
- ) {
+ if (blindConfig.type !== "blind" || ["oneSwitch", "twoSwitch"].includes(blindConfig.setup)) {
throw "improper configuration";
}
switch (blindConfig.setup) {
@@ -2191,10 +1786,7 @@ class eWeLink {
: 0;
break;
case "twoSwitch":
- if (
- params.switches[0].switch === "off" &&
- params.switches[1].switch === "off"
- ) {
+ if (params.switches[0].switch === "off" && params.switches[1].switch === "off") {
return;
}
let switchUp = params.switches[0].switch === "on" ? -1 : 0, // matrix of numbers to get
@@ -2213,11 +1805,7 @@ class eWeLink {
.updateCharacteristic(Characteristic.CurrentPosition, nSte * 100);
}, parseInt(blindConfig.operationTime) * 100);
} catch (err) {
- this.log.warn(
- "[%s] could not be updated as %s.",
- accessory.displayName,
- err
- );
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalGarageUpdate(accessory, params) {
@@ -2271,11 +1859,7 @@ class eWeLink {
}, parseInt(garageConfig.operationTime) * 100);
} catch (err) {
accessory.context.inUse = false;
- this.log.warn(
- "[%s] could not be updated as %s.",
- accessory.displayName,
- err
- );
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalLockUpdate(accessory, params) {
@@ -2304,11 +1888,7 @@ class eWeLink {
}, parseInt(lockConfig.operationTime) * 100);
} catch (err) {
accessory.context.inUse = false;
- this.log.warn(
- "[%s] could not be updated as %s.",
- accessory.displayName,
- err
- );
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalSensorUpdate(accessory, params) {
@@ -2318,14 +1898,8 @@ class eWeLink {
accessory.getService(Service.BatteryService) ||
accessory.addService(Service.BatteryService),
scaledBattery = Math.round(params.battery * 33.3);
- batteryService.updateCharacteristic(
- Characteristic.BatteryLevel,
- scaledBattery
- );
- batteryService.updateCharacteristic(
- Characteristic.StatusLowBattery,
- scaledBattery < 25
- );
+ batteryService.updateCharacteristic(Characteristic.BatteryLevel, scaledBattery);
+ batteryService.updateCharacteristic(Characteristic.StatusLowBattery, scaledBattery < 25);
}
let newState = params.switch === "on" ? 1 : 0,
oAccessory = false;
@@ -2333,10 +1907,7 @@ class eWeLink {
.getService(Service.ContactSensor)
.updateCharacteristic(Characteristic.ContactSensorState, newState);
this.cusG.forEach(group => {
- if (
- group.sensorId === accessory.context.eweDeviceId &&
- group.type === "garage"
- ) {
+ if (group.sensorId === accessory.context.eweDeviceId && group.type === "garage") {
if ((oAccessory = this.devicesInHB.get(group.deviceId + "SWX"))) {
switch (newState) {
case 0:
@@ -2360,11 +1931,7 @@ class eWeLink {
}
});
} catch (err) {
- this.log.warn(
- "[%s] could not be updated as %s.",
- accessory.displayName,
- err
- );
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalFanUpdate(accessory, params) {
@@ -2372,11 +1939,7 @@ class eWeLink {
let light, status, speed;
if (Array.isArray(params.switches)) {
light = params.switches[0].switch === "on";
- switch (
- params.switches[1].switch +
- params.switches[2].switch +
- params.switches[3].switch
- ) {
+ switch (params.switches[1].switch + params.switches[2].switch + params.switches[3].switch) {
default:
status = 0;
speed = 0;
@@ -2404,19 +1967,13 @@ class eWeLink {
} else {
throw "unknown parameters received";
}
- accessory
- .getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.On, light);
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, light);
accessory
.getService(Service.Fanv2)
.updateCharacteristic(Characteristic.Active, status)
.updateCharacteristic(Characteristic.RotationSpeed, speed);
} catch (err) {
- this.log.warn(
- "[%s] could not be updated as %s.",
- accessory.displayName,
- err
- );
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalThermostatUpdate(accessory, params) {
@@ -2428,9 +1985,7 @@ class eWeLink {
let newState = params.hasOwnProperty("switch")
? params.switch === "on"
: params.mainSwitch === "on";
- accessory
- .getService(Service.Switch)
- .updateCharacteristic(Characteristic.On, newState);
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, newState);
}
let eveLog = {
time: Date.now(),
@@ -2440,9 +1995,7 @@ class eWeLink {
accessory.getService(Service.TemperatureSensor)
) {
let currentTemp =
- params.currentTemperature !== "unavailable"
- ? params.currentTemperature
- : 0;
+ params.currentTemperature !== "unavailable" ? params.currentTemperature : 0;
accessory
.getService(Service.TemperatureSensor)
.updateCharacteristic(Characteristic.CurrentTemperature, currentTemp);
@@ -2452,25 +2005,17 @@ class eWeLink {
params.hasOwnProperty("currentHumidity") &&
accessory.getService(Service.HumiditySensor)
) {
- let currentHumi =
- params.currentHumidity !== "unavailable" ? params.currentHumidity : 0;
+ let currentHumi = params.currentHumidity !== "unavailable" ? params.currentHumidity : 0;
accessory
.getService(Service.HumiditySensor)
- .updateCharacteristic(
- Characteristic.CurrentRelativeHumidity,
- currentHumi
- );
+ .updateCharacteristic(Characteristic.CurrentRelativeHumidity, currentHumi);
eveLog.humidity = parseFloat(currentHumi);
}
if (eveLog.hasOwnProperty("temp") || eveLog.hasOwnProperty("humidity")) {
accessory.eveLogger.addEntry(eveLog);
}
} catch (err) {
- this.log.warn(
- "[%s] could not be updated as %s.",
- accessory.displayName,
- err
- );
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalOutletUpdate(accessory, params) {
@@ -2489,13 +2034,8 @@ class eWeLink {
);
accessory
.getService(Service.Outlet)
- .updateCharacteristic(
- Characteristic.OutletInUse,
- parseFloat(params.power) > 0
- );
- let isOn = accessory
- .getService(Service.Outlet)
- .getCharacteristic(Characteristic.On).value;
+ .updateCharacteristic(Characteristic.OutletInUse, parseFloat(params.power) > 0);
+ let isOn = accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On).value;
accessory.eveLogger.addEntry({
time: Date.now(),
power: isOn ? parseFloat(params.power) : 0,
@@ -2504,10 +2044,7 @@ class eWeLink {
if (params.hasOwnProperty("voltage")) {
accessory
.getService(Service.Outlet)
- .updateCharacteristic(
- EveService.Characteristics.Voltage,
- parseFloat(params.voltage)
- );
+ .updateCharacteristic(EveService.Characteristics.Voltage, parseFloat(params.voltage));
}
if (params.hasOwnProperty("current")) {
accessory
@@ -2518,43 +2055,25 @@ class eWeLink {
);
}
} catch (err) {
- this.log.warn(
- "[%s] could not be updated as %s.",
- accessory.displayName,
- err
- );
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalUSBUpdate(accessory, params) {
try {
accessory
.getService(Service.Outlet)
- .updateCharacteristic(
- Characteristic.On,
- params.switches[0].switch === "on"
- );
+ .updateCharacteristic(Characteristic.On, params.switches[0].switch === "on");
} catch (err) {
- this.log.warn(
- "[%s] could not be updated as %s.",
- accessory.displayName,
- err
- );
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalSCMUpdate(accessory, params) {
try {
accessory
.getService(Service.Switch)
- .updateCharacteristic(
- Characteristic.On,
- params.switches[0].switch === "on"
- );
+ .updateCharacteristic(Characteristic.On, params.switches[0].switch === "on");
} catch (err) {
- this.log.warn(
- "[%s] could not be updated as %s.",
- accessory.displayName,
- err
- );
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalSingleLightUpdate(accessory, params) {
@@ -2564,20 +2083,13 @@ class eWeLink {
isOn = false;
if (accessory.context.eweUIID === 22 && params.hasOwnProperty("state")) {
isOn = params.state === "on";
- } else if (
- accessory.context.eweUIID !== 22 &&
- params.hasOwnProperty("switch")
- ) {
+ } else if (accessory.context.eweUIID !== 22 && params.hasOwnProperty("switch")) {
isOn = params.switch === "on";
} else {
- isOn = accessory
- .getService(Service.Lightbulb)
- .getCharacteristic(Characteristic.On).value;
+ isOn = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value;
}
if (isOn) {
- accessory
- .getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.On, true);
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, true);
switch (accessory.context.eweUIID) {
case 36: // KING-M4
if (params.hasOwnProperty("bright")) {
@@ -2591,10 +2103,7 @@ class eWeLink {
if (params.hasOwnProperty("brightness")) {
accessory
.getService(Service.Lightbulb)
- .updateCharacteristic(
- Characteristic.Brightness,
- params.brightness
- );
+ .updateCharacteristic(Characteristic.Brightness, params.brightness);
}
break;
case 22: // B1
@@ -2609,9 +2118,7 @@ class eWeLink {
mode = 2;
}
if (mode === 2) {
- accessory
- .getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.On, true);
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, true);
newColour = convert.rgb.hsv(
parseInt(params.channel2),
parseInt(params.channel3),
@@ -2633,11 +2140,7 @@ class eWeLink {
.updateCharacteristic(Characteristic.Brightness, params.bright);
}
if (params.hasOwnProperty("colorR")) {
- newColour = convert.rgb.hsv(
- params.colorR,
- params.colorG,
- params.colorB
- );
+ newColour = convert.rgb.hsv(params.colorR, params.colorG, params.colorB);
accessory
.getService(Service.Lightbulb)
.updateCharacteristic(Characteristic.Hue, newColour[0])
@@ -2648,16 +2151,10 @@ class eWeLink {
return;
}
} else {
- accessory
- .getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.On, false);
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, false);
}
} catch (err) {
- this.log.warn(
- "[%s] could not be updated as %s.",
- accessory.displayName,
- err
- );
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalMultiLightUpdate(accessory, params) {
@@ -2669,24 +2166,15 @@ class eWeLink {
let oAccessory = this.devicesInHB.get(idToCheck + i);
oAccessory
.getService(Service.Lightbulb)
- .updateCharacteristic(
- Characteristic.On,
- params.switches[i - 1].switch === "on"
- );
+ .updateCharacteristic(Characteristic.On, params.switches[i - 1].switch === "on");
if (params.switches[i - 1].switch === "on") {
primaryState = true;
}
}
}
- accessory
- .getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.On, primaryState);
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, primaryState);
} catch (err) {
- this.log.warn(
- "[%s] could not be updated as %s.",
- accessory.displayName,
- err
- );
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalSingleSwitchUpdate(accessory, params) {
@@ -2695,11 +2183,7 @@ class eWeLink {
.getService(Service.Switch)
.updateCharacteristic(Characteristic.On, params.switch === "on");
} catch (err) {
- this.log.warn(
- "[%s] could not be updated as %s.",
- accessory.displayName,
- err
- );
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalMultiSwitchUpdate(accessory, params) {
@@ -2711,24 +2195,15 @@ class eWeLink {
let oAccessory = this.devicesInHB.get(idToCheck + i);
oAccessory
.getService(Service.Switch)
- .updateCharacteristic(
- Characteristic.On,
- params.switches[i - 1].switch === "on"
- );
+ .updateCharacteristic(Characteristic.On, params.switches[i - 1].switch === "on");
if (params.switches[i - 1].switch === "on") {
primaryState = true;
}
}
}
- accessory
- .getService(Service.Switch)
- .updateCharacteristic(Characteristic.On, primaryState);
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, primaryState);
} catch (err) {
- this.log.warn(
- "[%s] could not be updated as %s.",
- accessory.displayName,
- err
- );
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalRFDeviceUpdate(accessory, params) {
@@ -2744,9 +2219,7 @@ class eWeLink {
// RF Button
let bAccessory;
if (
- (bAccessory = this.devicesInHB.get(
- idToCheck + accessory.context.rfChlMap[params.rfChl]
- ))
+ (bAccessory = this.devicesInHB.get(idToCheck + accessory.context.rfChlMap[params.rfChl]))
) {
bAccessory
.getService(bAccessory.context.rfChls[params.rfChl])
@@ -2800,81 +2273,51 @@ class eWeLink {
case "co":
oAccessory
.getService(Service.CarbonMonoxideSensor)
- .updateCharacteristic(
- Characteristic.CarbonMonoxideDetected,
- 1
- );
+ .updateCharacteristic(Characteristic.CarbonMonoxideDetected, 1);
setTimeout(() => {
oAccessory
.getService(Service.CarbonMonoxideSensor)
- .updateCharacteristic(
- Characteristic.CarbonMonoxideDetected,
- 0
- );
+ .updateCharacteristic(Characteristic.CarbonMonoxideDetected, 0);
}, (this.config.sensorTimeLength || 2) * 1000);
break;
case "co2":
oAccessory
.getService(Service.CarbonDioxideSensor)
- .updateCharacteristic(
- Characteristic.CarbonDioxideDetected,
- 1
- );
+ .updateCharacteristic(Characteristic.CarbonDioxideDetected, 1);
setTimeout(() => {
oAccessory
.getService(Service.CarbonDioxideSensor)
- .updateCharacteristic(
- Characteristic.CarbonDioxideDetected,
- 0
- );
+ .updateCharacteristic(Characteristic.CarbonDioxideDetected, 0);
}, (this.config.sensorTimeLength || 2) * 1000);
break;
case "contact":
oAccessory
.getService(Service.ContactSensor)
- .updateCharacteristic(
- Characteristic.ContactSensorState,
- 1
- );
+ .updateCharacteristic(Characteristic.ContactSensorState, 1);
setTimeout(() => {
oAccessory
.getService(Service.ContactSensor)
- .updateCharacteristic(
- Characteristic.ContactSensorState,
- 0
- );
+ .updateCharacteristic(Characteristic.ContactSensorState, 0);
}, (this.config.sensorTimeLength || 2) * 1000);
break;
case "occupancy":
oAccessory
.getService(Service.OccupancySensor)
- .updateCharacteristic(
- Characteristic.OccupancyDetected,
- 1
- );
+ .updateCharacteristic(Characteristic.OccupancyDetected, 1);
setTimeout(() => {
oAccessory
.getService(Service.OccupancySensor)
- .updateCharacteristic(
- Characteristic.OccupancyDetected,
- 0
- );
+ .updateCharacteristic(Characteristic.OccupancyDetected, 0);
}, (this.config.sensorTimeLength || 2) * 1000);
break;
default:
oAccessory
.getService(Service.MotionSensor)
- .updateCharacteristic(
- Characteristic.MotionDetected,
- true
- );
+ .updateCharacteristic(Characteristic.MotionDetected, true);
setTimeout(() => {
oAccessory
.getService(Service.MotionSensor)
- .updateCharacteristic(
- Characteristic.MotionDetected,
- false
- );
+ .updateCharacteristic(Characteristic.MotionDetected, false);
}, (this.config.sensorTimeLength || 2) * 1000);
break;
}
@@ -2890,11 +2333,7 @@ class eWeLink {
});
}
} catch (err) {
- this.log.warn(
- "[%s] could not be updated as %s.",
- accessory.displayName,
- err
- );
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalZBDeviceUpdate(accessory, params) {
@@ -2904,24 +2343,15 @@ class eWeLink {
let batteryService =
accessory.getService(Service.BatteryService) ||
accessory.addService(Service.BatteryService);
- batteryService.updateCharacteristic(
- Characteristic.BatteryLevel,
- params.battery
- );
- batteryService.updateCharacteristic(
- Characteristic.StatusLowBattery,
- params.battery < 25
- );
+ batteryService.updateCharacteristic(Characteristic.BatteryLevel, params.battery);
+ batteryService.updateCharacteristic(Characteristic.StatusLowBattery, params.battery < 25);
}
switch (accessory.context.eweUIID) {
case 1000:
if (params.hasOwnProperty("key") && [0, 1, 2].includes(params.key)) {
accessory
.getService(Service.StatelessProgrammableSwitch)
- .updateCharacteristic(
- Characteristic.ProgrammableSwitchEvent,
- params.key
- );
+ .updateCharacteristic(Characteristic.ProgrammableSwitchEvent, params.key);
}
break;
case 1770:
@@ -2932,34 +2362,22 @@ class eWeLink {
let currentTemp = parseInt(params.temperature) / 100;
accessory
.getService(Service.TemperatureSensor)
- .updateCharacteristic(
- Characteristic.CurrentTemperature,
- currentTemp
- );
+ .updateCharacteristic(Characteristic.CurrentTemperature, currentTemp);
eveLog.temp = parseFloat(currentTemp);
}
if (params.hasOwnProperty("humidity")) {
let currentHumi = parseInt(params.humidity) / 100;
accessory
.getService(Service.HumiditySensor)
- .updateCharacteristic(
- Characteristic.CurrentRelativeHumidity,
- currentHumi
- );
+ .updateCharacteristic(Characteristic.CurrentRelativeHumidity, currentHumi);
eveLog.humidity = parseFloat(currentHumi);
}
- if (
- eveLog.hasOwnProperty("temp") ||
- eveLog.hasOwnProperty("humidity")
- ) {
+ if (eveLog.hasOwnProperty("temp") || eveLog.hasOwnProperty("humidity")) {
accessory.eveLogger.addEntry(eveLog);
}
break;
case 2026:
- if (
- params.hasOwnProperty("motion") &&
- params.hasOwnProperty("trigTime")
- ) {
+ if (params.hasOwnProperty("motion") && params.hasOwnProperty("trigTime")) {
let timeNow = new Date(),
diff = (timeNow.getTime() - params.trigTime) / 1000;
accessory
@@ -2977,19 +2395,12 @@ class eWeLink {
if (params.hasOwnProperty("lock") && [0, 1].includes(params.lock)) {
accessory
.getService(Service.ContactSensor)
- .updateCharacteristic(
- Characteristic.ContactSensorState,
- params.lock
- );
+ .updateCharacteristic(Characteristic.ContactSensorState, params.lock);
}
break;
}
} catch (err) {
- this.log.warn(
- "[%s] could not be updated as %s.",
- accessory.displayName,
- err
- );
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
}
diff --git a/lib/eWeLinkHTTP.js b/lib/eWeLinkHTTP.js
index 1aafd1e4..24b1a69d 100644
--- a/lib/eWeLinkHTTP.js
+++ b/lib/eWeLinkHTTP.js
@@ -5,29 +5,92 @@ const axios = require("axios"),
crypto = require("crypto");
module.exports = class eWeLinkHTTP {
constructor(config, log) {
- this.config = config;
this.log = log;
- this.debug = this.config.debug || false;
- this.debugReqRes = this.config.debugReqRes || false;
+ this.debug = config.debug || false;
+ this.debugReqRes = config.debugReqRes || false;
+ this.username = config.username.toString();
+ this.password = config.password.toString();
+ this.cCode = "+" + config.countryCode.toString().replace("+", "").replace(" ", "");
+ }
+ getHost() {
+ let data = {
+ appid: constants.appId,
+ country_code: this.cCode,
+ nonce: Math.random().toString(36).substr(2, 8),
+ ts: Math.floor(new Date().getTime() / 1000),
+ version: 8,
+ },
+ dataToSign = [];
+ Object.keys(data).forEach(k => {
+ dataToSign.push({
+ key: k,
+ value: data.k,
+ });
+ });
+ dataToSign.sort((a, b) => (a.key < b.key ? -1 : 1));
+ dataToSign = dataToSign.map(k => k.key + "=" + k.value).join("&");
+ dataToSign = crypto
+ .createHmac("sha256", constants.appSecret)
+ .update(dataToSign)
+ .digest("base64");
+ if (this.debugReqRes) {
+ let msg = JSON.stringify(data, null, 2);
+ this.log.warn("Sending HTTP getHost request. This text is yellow for clarity.\n%s", msg);
+ } else if (this.debug) {
+ this.log("Sending HTTP getHost request.");
+ }
+ return new Promise((resolve, reject) => {
+ axios
+ .get("https://api.coolkit.cc:8080/api/user/region", {
+ headers: {
+ Authorization: "Sign " + dataToSign,
+ "Content-Type": "application/json",
+ },
+ params: data,
+ })
+ .then(res => {
+ let body = res.data;
+ if (!body.region) {
+ throw "Server did not respond with a region.\n" + JSON.stringify(body, null, 2);
+ }
+ switch (body.region) {
+ case "eu":
+ case "us":
+ case "as":
+ this.httpHost = body.region + "-apia.coolkit.cc";
+ break;
+ case "cn":
+ this.httpHost = "cn-apia.coolkit.cn";
+ break;
+ default:
+ throw "No valid region received - [" + body.region + "].";
+ }
+ if (this.debug) {
+ this.log("HTTP API host received [%s].", this.httpHost);
+ }
+ resolve(this.httpHost);
+ })
+ .catch(err => {
+ if (err.hasOwnProperty("code") && ["ENOTFOUND", "ETIMEDOUT"].includes(err.code)) {
+ this.log.warn("Unable to reach eWeLink. Retrying in 30 seconds.");
+ this.delay().then(() => resolve(this.getHost()));
+ } else {
+ reject(err.message || err);
+ }
+ });
+ });
}
login() {
let data = {
- countryCode:
- "+" +
- this.config.countryCode.toString().replace("+", "").replace(" ", ""),
- password: this.config.password,
+ countryCode: this.cCode,
+ password: this.password,
};
- this.config.username.includes("@")
- ? (data.email = this.config.username)
- : (data.phoneNumber = this.config.username);
+ this.username.includes("@") ? (data.email = this.username) : (data.phoneNumber = this.username);
if (this.debugReqRes) {
let msg = JSON.stringify(data, null, 2)
- .replace(this.config.password, "**hidden**")
- .replace(this.config.username, "**hidden**");
- this.log.warn(
- "Sending HTTP login request. This text is yellow for clarity.\n%s",
- msg
- );
+ .replace(this.password, "**hidden**")
+ .replace(this.username, "**hidden**");
+ this.log.warn("Sending HTTP login request. This text is yellow for clarity.\n%s", msg);
} else if (this.debug) {
this.log("Sending HTTP login request.");
}
@@ -56,17 +119,18 @@ module.exports = class eWeLinkHTTP {
body.hasOwnProperty("data") &&
body.data.hasOwnProperty("region")
) {
- switch (body.data.region) {
+ let givenRegion = body.data.region;
+ switch (givenRegion) {
case "eu":
case "us":
case "as":
- this.httpHost = body.data.region + "-apia.coolkit.cc";
+ this.httpHost = givenRegion + "-apia.coolkit.cc";
break;
case "cn":
this.httpHost = "cn-apia.coolkit.cn";
break;
default:
- throw "No valid region received - [" + body.data.region + "].";
+ throw "No valid region received - [" + givenRegion + "].";
}
if (this.debug) {
this.log("New HTTP API host received [%s].", this.httpHost);
@@ -75,10 +139,7 @@ module.exports = class eWeLinkHTTP {
return;
}
if (!body.data.at) {
- throw (
- "Server did not respond with an authentication token. Please double check your eWeLink username and password in the Homebridge configuration.\n" +
- JSON.stringify(body, null, 2)
- );
+ throw "No auth token received.\n" + JSON.stringify(body, null, 2);
}
this.aToken = body.data.at;
this.apiKey = body.data.user.apikey;
@@ -88,111 +149,95 @@ module.exports = class eWeLinkHTTP {
httpHost: this.httpHost,
});
})
- .catch(err => {
- reject(err);
- });
+ .catch(err => reject(err.message || err));
});
}
- getHost() {
- let data = {
- appid: constants.appId,
- country_code: this.config.countryCode
- .toString()
- .replace("+", "")
- .replace(" ", ""),
- nonce: Math.random().toString(36).substr(2, 8),
- ts: Math.floor(new Date().getTime() / 1000),
- version: 8,
- },
- dataToSign = [];
- Object.keys(data).forEach(function (key) {
- dataToSign.push({
- key: key,
- value: data[key],
- });
- });
- dataToSign.sort(function (a, b) {
- return a.key < b.key ? -1 : 1;
- });
- dataToSign = dataToSign
- .map(function (kv) {
- return kv.key + "=" + kv.value;
- })
- .join("&");
- dataToSign = crypto
- .createHmac("sha256", constants.appSecret)
- .update(dataToSign)
- .digest("base64");
+ getDevices() {
return new Promise((resolve, reject) => {
axios
- .get("https://api.coolkit.cc:8080/api/user/region", {
+ .get("https://" + this.httpHost + "/v2/device/thing", {
headers: {
- Authorization: "Sign " + dataToSign,
+ Authorization: "Bearer " + this.aToken,
"Content-Type": "application/json",
+ Host: this.httpHost,
+ "X-CK-Appid": constants.appId,
+ "X-CK-Nonce": Math.random().toString(36).substr(2, 8),
},
- params: data,
})
.then(res => {
let body = res.data;
- if (!body.region) {
- throw (
- "Server did not respond with a region.\n" +
- JSON.stringify(body, null, 2)
- );
- }
- switch (body.region) {
- case "eu":
- case "us":
- case "as":
- this.httpHost = body.region + "-apia.coolkit.cc";
- break;
- case "cn":
- this.httpHost = "cn-apia.coolkit.cn";
- break;
- default:
- throw "No valid region received - [" + body.region + "].";
+ if (
+ !body.hasOwnProperty("data") ||
+ !body.hasOwnProperty("error") ||
+ (body.hasOwnProperty("error") && body.error !== 0)
+ ) {
+ throw JSON.stringify(body, null, 2);
}
- if (this.debug) {
- this.log("HTTP API host received [%s].", this.httpHost);
+ let deviceList = [];
+ if (body.data.thingList && body.data.thingList.length > 0) {
+ body.data.thingList.forEach(device => deviceList.push(device.itemData));
}
- resolve(this.httpHost);
+ resolve(deviceList);
})
.catch(err => {
- reject(err);
+ if (err.hasOwnProperty("code") && ["ENOTFOUND", "ETIMEDOUT"].includes(err.code)) {
+ this.log.warn("Unable to reach eWeLink. Retrying in 30 seconds.");
+ this.delay().then(() => resolve(this.getDevices()));
+ } else {
+ reject(err.message || err);
+ }
});
});
}
- getDevices() {
+
+ getDevice(deviceId) {
return new Promise((resolve, reject) => {
- axios
- .get("https://" + this.httpHost + "/v2/device/thing", {
- headers: {
- Authorization: "Bearer " + this.aToken,
- "Content-Type": "application/json",
- Host: this.httpHost,
- "X-CK-Appid": constants.appId,
- "X-CK-Nonce": Math.random().toString(36).substr(2, 8),
- },
- })
+ axios({
+ url: "https://" + this.httpHost + "/v2/device/thing",
+ method: "post",
+ headers: {
+ Authorization: "Bearer " + this.aToken,
+ "Content-Type": "application/json",
+ Host: this.httpHost,
+ "X-CK-Appid": constants.appId,
+ "X-CK-Nonce": Math.random().toString(36).substr(2, 8),
+ },
+ data: {
+ thingList: [
+ {
+ itemType: 1,
+ id: deviceId,
+ },
+ ],
+ },
+ })
.then(res => {
let body = res.data;
if (
+ !body.hasOwnProperty("data") ||
!body.hasOwnProperty("error") ||
(body.hasOwnProperty("error") && body.error !== 0)
) {
throw JSON.stringify(body, null, 2);
}
- let deviceList = [];
- if (body.data.thingList && body.data.thingList.length > 0) {
- body.data.thingList.forEach(device =>
- deviceList.push(device.itemData)
- );
+ if (body.data.thingList && body.data.thingList.length === 1) {
+ resolve(body.data.thingList[0].itemData);
+ } else {
+ throw "device not found in eWeLink";
}
- resolve(deviceList);
})
.catch(err => {
- reject(err);
+ if (err.hasOwnProperty("code") && ["ENOTFOUND", "ETIMEDOUT"].includes(err.code)) {
+ this.log.warn("Unable to reach eWeLink. Retrying in 30 seconds.");
+ this.delay().then(() => resolve(this.getDevice(deviceId)));
+ } else {
+ reject(err.message || err);
+ }
});
});
}
+
+ delay() {
+ return new Promise(resolve => setTimeout(resolve, 30000));
+ }
};
diff --git a/lib/eWeLinkLAN.js b/lib/eWeLinkLAN.js
index 25baee53..567c372d 100644
--- a/lib/eWeLinkLAN.js
+++ b/lib/eWeLinkLAN.js
@@ -1,19 +1,18 @@
/* jshint esversion: 9, -W030, node: true */
"use strict";
const axios = require("axios"),
- constants = require("./constants"),
+ cns = require("./constants"),
crypto = require("crypto"),
dns = require("node-dns-sd"),
eventemitter = require("events");
module.exports = class eWeLinkLAN {
constructor(config, log, devices) {
- this.config = config;
this.log = log;
this.devices = devices;
- this.ipOverrides = this.config.ipOverride || {};
- let deviceMap = new Map();
+ this.ipOverrides = config.ipOverride || {};
+ this.deviceMap = new Map();
devices.forEach(device => {
- deviceMap.set(device.deviceid, {
+ this.deviceMap.set(device.deviceid, {
apiKey: device.devicekey,
online: this.ipOverrides.hasOwnProperty(device.deviceid) ? true : false,
ip: this.ipOverrides.hasOwnProperty(device.deviceid)
@@ -21,9 +20,8 @@ module.exports = class eWeLinkLAN {
: null,
});
});
- this.deviceMap = deviceMap;
- this.debug = this.config.debug || false;
- this.debugReqRes = this.config.debugReqRes || false;
+ this.debug = config.debug || false;
+ this.debugReqRes = config.debugReqRes || false;
this.emitter = new eventemitter();
}
getHosts() {
@@ -36,9 +34,7 @@ module.exports = class eWeLinkLAN {
let onlineCount = 0;
res.forEach(device => {
let d,
- deviceId = device.fqdn
- .replace("._ewelink._tcp.local", "")
- .replace("eWeLink_", "");
+ deviceId = device.fqdn.replace("._ewelink._tcp.local", "").replace("eWeLink_", "");
if ((d = this.deviceMap.get(deviceId))) {
if (!this.ipOverrides.hasOwnProperty(deviceId)) {
this.deviceMap.set(deviceId, {
@@ -55,9 +51,7 @@ module.exports = class eWeLinkLAN {
count: onlineCount,
});
})
- .catch(err => {
- reject(err);
- });
+ .catch(err => reject(err));
});
}
startMonitor() {
@@ -79,64 +73,44 @@ module.exports = class eWeLinkLAN {
.createHash("md5")
.update(Buffer.from(deviceInfo.apiKey, "utf8"))
.digest(),
- dText = crypto.createDecipheriv(
- "aes-128-cbc",
- key,
- Buffer.from(rdata.iv, "base64")
- ),
+ dText = crypto.createDecipheriv("aes-128-cbc", key, Buffer.from(rdata.iv, "base64")),
pText = Buffer.concat([
dText.update(Buffer.from(data, "base64")),
dText.final(),
]).toString("utf8"),
params;
- if (
- packet.address !== deviceInfo.ip &&
- !this.ipOverrides.hasOwnProperty(rdata.id)
- ) {
+ if (packet.address !== deviceInfo.ip && !this.ipOverrides.hasOwnProperty(rdata.id)) {
this.deviceMap.set(rdata.id, {
apiKey: deviceInfo.apiKey,
online: true,
ip: packet.address,
});
if (this.debug) {
- this.log.warn(
- "[%s] updating IP address to [%s].",
- rdata.id,
- packet.address
- );
+ this.log.warn("[%s] updating IP address to [%s].", rdata.id, packet.address);
}
}
try {
params = JSON.parse(pText);
} catch (e) {
- this.log.warn(
- "[%s] An error occured reading the LAN message [%s]",
- rdata.id,
- e
- );
+ this.log.warn("[%s] An error occured reading the LAN message [%s]", rdata.id, e);
return;
}
for (let param in params) {
if (params.hasOwnProperty(param)) {
- if (
- !constants.paramsToKeep.includes(param.replace(/[0-9]/g, ""))
- ) {
+ if (!cns.paramsToKeep.includes(param.replace(/[0-9]/g, ""))) {
delete params[param];
}
}
}
if (Object.keys(params).length > 0) {
params.updateSource = "LAN";
+ params.online = true;
let returnTemplate = {
deviceid: rdata.id,
- action: "update",
params,
};
if (this.debugReqRes) {
- let msg = JSON.stringify(returnTemplate, null, 2).replace(
- rdata.id,
- "**hidden**"
- );
+ let msg = JSON.stringify(returnTemplate, null, 2).replace(rdata.id, "**hidden**");
this.log("LAN message received.\n%s", msg);
} else if (this.debug) {
this.log("LAN message received.");
@@ -149,12 +123,8 @@ module.exports = class eWeLinkLAN {
return new Promise((resolve, reject) => {
dns
.startMonitoring()
- .then(() => {
- resolve();
- })
- .catch(err => {
- reject(err);
- });
+ .then(() => resolve())
+ .catch(err => reject(err));
});
}
sendUpdate(json) {
@@ -175,17 +145,13 @@ module.exports = class eWeLinkLAN {
throw "plugin does not support lan mode for this device yet - feel free to create a github issue";
}
if ((apiKey = this.deviceMap.get(json.deviceid).apiKey)) {
- let key = crypto
- .createHash("md5")
- .update(Buffer.from(apiKey, "utf8"))
- .digest(),
+ let key = crypto.createHash("md5").update(Buffer.from(apiKey, "utf8")).digest(),
iv = crypto.randomBytes(16),
enc = crypto.createCipheriv("aes-128-cbc", key, iv),
data = {
- data: Buffer.concat([
- enc.update(JSON.stringify(params)),
- enc.final(),
- ]).toString("base64"),
+ data: Buffer.concat([enc.update(JSON.stringify(params)), enc.final()]).toString(
+ "base64"
+ ),
deviceid: json.deviceid,
encrypt: true,
iv: iv.toString("base64"),
@@ -197,20 +163,13 @@ module.exports = class eWeLinkLAN {
.replace(json.apikey, "**hidden**")
.replace(json.apikey, "**hidden**")
.replace(json.deviceid, "**hidden**");
- this.log.warn(
- "LAN message sent. This text is yellow for clarity.\n%s",
- msg
- );
+ this.log.warn("LAN message sent. This text is yellow for clarity.\n%s", msg);
} else if (this.debug) {
this.log("LAN message sent.");
}
axios({
method: "post",
- url:
- "http://" +
- this.deviceMap.get(json.deviceid).ip +
- ":8081/zeroconf/" +
- suffix,
+ url: "http://" + this.deviceMap.get(json.deviceid).ip + ":8081/zeroconf/" + suffix,
headers: {
Accept: "application/json",
"Content-Type": "application/json",
@@ -223,9 +182,7 @@ module.exports = class eWeLinkLAN {
}
throw res.data;
})
- .catch(err => {
- reject(err);
- });
+ .catch(err => reject(err));
}
});
}
diff --git a/lib/eWeLinkWS.js b/lib/eWeLinkWS.js
index 56fbeb64..29d265cc 100644
--- a/lib/eWeLinkWS.js
+++ b/lib/eWeLinkWS.js
@@ -1,7 +1,7 @@
/* jshint esversion: 9, -W030, node: true */
"use strict";
const axios = require("axios"),
- constants = require("./constants"),
+ cns = require("./constants"),
eventemitter = require("events"),
ws = require("ws");
module.exports = class eWeLinkWS {
@@ -21,14 +21,13 @@ module.exports = class eWeLinkWS {
return new Promise((resolve, reject) => {
axios({
method: "post",
- url:
- "https://" + this.httpHost.replace("-api", "-disp") + "/dispatch/app",
+ url: "https://" + this.httpHost.replace("-api", "-disp") + "/dispatch/app",
headers: {
Authorization: "Bearer " + this.aToken,
"Content-Type": "application/json",
},
data: {
- appid: constants.appId,
+ appid: cns.appId,
nonce: Math.random().toString(36).substr(2, 8),
ts: Math.floor(new Date().getTime() / 1000),
version: 8,
@@ -46,7 +45,12 @@ module.exports = class eWeLinkWS {
resolve(body.domain);
})
.catch(err => {
- reject(err);
+ if (err.hasOwnProperty("code") && ["ENOTFOUND", "ETIMEDOUT"].includes(err.code)) {
+ this.log.warn("Unable to reach eWeLink. Retrying in 30 seconds.");
+ this.delay().then(() => resolve(this.getDevices()));
+ } else {
+ reject(err.message || err);
+ }
});
});
}
@@ -57,7 +61,7 @@ module.exports = class eWeLinkWS {
let payload = {
action: "userOnline",
apikey: this.apiKey,
- appid: constants.appId,
+ appid: cns.appId,
at: this.aToken,
nonce: Math.random().toString(36).substr(2, 8),
sequence: Math.floor(new Date()),
@@ -70,91 +74,60 @@ module.exports = class eWeLinkWS {
let msg = JSON.stringify(payload, null, 2)
.replace(this.aToken, "**hidden**")
.replace(this.apiKey, "**hidden**");
- this.log.warn(
- "Sending WS login request. This text is yellow for clarity.\n%s",
- msg
- );
+ this.log.warn("Sending WS login request. This text is yellow for clarity.\n%s", msg);
} else if (this.debug) {
this.log("Sending WS login request.");
}
});
this.ws.on("message", m => {
- if (m === "pong") {
- return;
- }
- let device;
+ if (m === "pong") return;
+ let device,
+ onlineStatus = true;
try {
device = JSON.parse(m);
- } catch (e) {
- this.log.warn(
- "An error occured reading the web socket message [%s]",
- e
- );
+ } catch (err) {
+ this.log.warn("An error occured reading the WS message [%s]", err);
return;
}
- // for requestUpdate response
- if (
- device.hasOwnProperty("deviceid") &&
- device.hasOwnProperty("params") &&
- device.hasOwnProperty("error") &&
- device.error === 0
- ) {
- device.action = "update";
- } else if (
- device.hasOwnProperty("deviceid") &&
- device.hasOwnProperty("error") &&
- device.error === 504
- ) {
- device.action = "sysmsg";
- device.params = {
- online: false,
- };
- }
- // for external updates
+ //*** for heartbeat response ***\\
if (
device.hasOwnProperty("config") &&
device.config.hb &&
device.config.hbInterval &&
!this.hbInterval
) {
- this.hbInterval = setInterval(() => {
- this.ws.send("ping");
- }, (device.config.hbInterval + 7) * 1000);
- } else if (device.hasOwnProperty("action")) {
+ this.hbInterval = setInterval(
+ () => this.ws.send("ping"),
+ (device.config.hbInterval + 7) * 1000
+ );
+ return;
+ }
+ if (!device.hasOwnProperty("params")) device.params = {};
+ //*** for requestUpdate response ***\\
+ if (device.hasOwnProperty("deviceid") && device.hasOwnProperty("error")) {
+ device.action = "update";
+ onlineStatus = device.error === 0;
+ }
+ //*** for all updates including above ***\\
+ if (device.hasOwnProperty("action")) {
switch (device.action) {
+ case "update":
case "sysmsg":
- device.params.updateSource = "WS";
- let returnTemplate = {
- deviceid: device.deviceid,
- action: "sysmsg",
- params: device.params,
- };
- if (this.debugReqRes) {
- let msg = JSON.stringify(returnTemplate, null, 2).replace(
- device.deviceid,
- "**hidden**"
- );
- this.log("WS message received.\n%s", msg);
- } else if (this.debug) {
- this.log("WS message received.");
+ if (device.action === "sysmsg" && device.params.hasOwnProperty("online")) {
+ onlineStatus = device.params.online;
}
- this.emitter.emit("update", returnTemplate);
- break;
- case "update":
for (let param in device.params) {
if (device.params.hasOwnProperty(param)) {
- if (
- !constants.paramsToKeep.includes(param.replace(/[0-9]/g, ""))
- ) {
+ if (!cns.paramsToKeep.includes(param.replace(/[0-9]/g, ""))) {
delete device.params[param];
}
}
}
+ device.params.online = onlineStatus;
+ device.params.updateSource = "WS";
if (Object.keys(device.params).length > 0) {
- device.params.updateSource = "WS";
let returnTemplate = {
deviceid: device.deviceid,
- action: "update",
params: device.params,
};
if (this.debugReqRes) {
@@ -173,8 +146,7 @@ module.exports = class eWeLinkWS {
return;
default:
this.log.warn(
- "[%s] WS message has unknown action.\n" +
- JSON.stringify(device, null, 2),
+ "[%s] WS message has unknown action.\n" + JSON.stringify(device, null, 2),
device.deviceid
);
return;
@@ -183,9 +155,7 @@ module.exports = class eWeLinkWS {
// *** Safe to ignore these messages *** \\
} else {
if (this.debug) {
- this.log.warn(
- "WS unknown command received.\n" + JSON.stringify(device, null, 2)
- );
+ this.log.warn("WS unknown command received.\n" + JSON.stringify(device, null, 2));
}
}
});
@@ -193,16 +163,13 @@ module.exports = class eWeLinkWS {
if (m === "Stopping Homebridge") {
this.log("Web socket gracefully closed.");
} else {
- this.log.warn("Web socket closed - [%s - %s].", e, m);
+ this.log.warn("Web socket closed - [%s%s].", e, m ? " - " + m : "");
if (e !== 1000) {
this.log("Web socket will try to reconnect in five seconds.");
- setTimeout(() => {
- this.login();
- }, 5000);
+ this.ws.removeAllListeners();
+ setTimeout(() => this.login(), 5000);
} else {
- this.log(
- "Please try restarting Homebridge so that this plugin can work again."
- );
+ this.log("Please try restarting Homebridge so that this plugin can work again.");
}
}
this.wsIsOpen = false;
@@ -219,13 +186,9 @@ module.exports = class eWeLinkWS {
"Web socket will try to reconnect in five seconds then try the command again."
);
this.ws.removeAllListeners();
- setTimeout(() => {
- this.login();
- }, 5000);
+ setTimeout(() => this.login(), 5000);
} else {
- this.log.warn(
- "If this was unexpected then please try restarting Homebridge."
- );
+ this.log.warn("If this was unexpected then please try restarting Homebridge.");
}
});
}
@@ -240,9 +203,7 @@ module.exports = class eWeLinkWS {
};
let sendOperation = req => {
if (!this.wsIsOpen) {
- setTimeout(() => {
- sendOperation(req);
- }, 280);
+ setTimeout(() => sendOperation(req), 280);
return;
}
if (this.ws) {
@@ -252,10 +213,7 @@ module.exports = class eWeLinkWS {
.replace(json.apikey, "**hidden**")
.replace(json.apiKey, "**hidden**")
.replace(json.deviceid, "**hidden**");
- this.log.warn(
- "WS message sent. This text is yellow for clarity.\n%s",
- msg
- );
+ this.log.warn("WS message sent. This text is yellow for clarity.\n%s", msg);
} else if (this.debug) {
this.log("WS message sent.");
}
@@ -268,9 +226,7 @@ module.exports = class eWeLinkWS {
setTimeout(sendOperation, this.delaySend, string);
this.delaySend += 280;
} else {
- this.log.warn(
- "Web socket is currently reconnecting. Command will be resent."
- );
+ this.log.warn("Web socket is currently reconnecting. Command will be resent.");
let interval,
waitToSend = req => {
if (this.wsIsOpen) {
@@ -293,9 +249,7 @@ module.exports = class eWeLinkWS {
},
sendOperation = req => {
if (!this.wsIsOpen) {
- setTimeout(() => {
- sendOperation(req);
- }, 280);
+ setTimeout(() => sendOperation(req), 280);
return;
}
if (this.ws) {
@@ -305,10 +259,7 @@ module.exports = class eWeLinkWS {
.replace(json.apikey, "**hidden**")
.replace(json.apiKey, "**hidden**")
.replace(json.deviceid, "**hidden**");
- this.log.warn(
- "WS message sent. This text is yellow for clarity.\n%s",
- msg
- );
+ this.log.warn("WS message sent. This text is yellow for clarity.\n%s", msg);
} else if (this.debug) {
this.log("WS message sent.");
}
@@ -321,9 +272,7 @@ module.exports = class eWeLinkWS {
setTimeout(sendOperation, this.delaySend, string);
this.delaySend += 280;
} else {
- this.log.warn(
- "Web socket is currently reconnecting. Command will be resent."
- );
+ this.log.warn("Web socket is currently reconnecting. Command will be resent.");
let interval,
waitToSend = req => {
if (this.wsIsOpen) {
@@ -342,4 +291,7 @@ module.exports = class eWeLinkWS {
this.ws.close(1000, "Stopping Homebridge");
}
}
+ delay() {
+ return new Promise(resolve => setTimeout(resolve, 30000));
+ }
};
From 37ad909a3b4104b217af6396f08ac39fd4f14b05 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Wed, 16 Sep 2020 14:01:01 +0100
Subject: [PATCH 0160/3183] syntax error
---
lib/eWeLink.js | 32 ++++++++++++++------------------
1 file changed, 14 insertions(+), 18 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 855a0402..b1735aef 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -992,7 +992,6 @@ class eWeLink {
(accessory = this.devicesInHB.get(deviceId + "SWX") || this.devicesInHB.get(deviceId + "SW0"))
) {
let isX = accessory.context.hbDeviceId.substr(-1) === "X";
-
if (device.params.updateSource === "WS") {
if (device.params.online != accessory.context.reachableWAN) {
accessory.context.reachableWAN = device.params.online;
@@ -1006,23 +1005,20 @@ class eWeLink {
);
}
}
-
- if (device.params.updateSource === "LAN") {
- if (!accessory.context.reachableLAN) {
- accessory.context.reachableLAN = true;
- this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
- this.wsClient.requestUpdate(accessory);
- statusChange = true;
- this.log.warn("[%s] has been reported [online] via [LAN].", accessory.displayName);
- }
- if (statusChange && !isX) {
- for (let i = 1; i <= accessory.context.channelCount; i++) {
- if (this.devicesInHB.has(deviceId + "SW" + i)) {
- let oAccessory = this.devicesInHB.get(deviceId + "SW" + i);
- oAccessory.context.reachableWAN = device.params.online;
- oAccessory.context.reachableLAN = true;
- this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory);
- }
+ if (device.params.updateSource === "LAN" && !accessory.context.reachableLAN) {
+ accessory.context.reachableLAN = true;
+ this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
+ this.wsClient.requestUpdate(accessory);
+ statusChange = true;
+ this.log.warn("[%s] has been reported [online] via [LAN].", accessory.displayName);
+ }
+ if (statusChange && !isX) {
+ for (let i = 1; i <= accessory.context.channelCount; i++) {
+ if (this.devicesInHB.has(deviceId + "SW" + i)) {
+ let oAccessory = this.devicesInHB.get(deviceId + "SW" + i);
+ oAccessory.context.reachableWAN = device.params.online;
+ oAccessory.context.reachableLAN = true;
+ this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory);
}
}
}
From 02f84ed46fb5a002c2df06fc203ebf5c74f1faff Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Wed, 16 Sep 2020 14:04:31 +0100
Subject: [PATCH 0161/3183] lan check
---
lib/eWeLink.js | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index b1735aef..23a75865 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -1017,7 +1017,9 @@ class eWeLink {
if (this.devicesInHB.has(deviceId + "SW" + i)) {
let oAccessory = this.devicesInHB.get(deviceId + "SW" + i);
oAccessory.context.reachableWAN = device.params.online;
- oAccessory.context.reachableLAN = true;
+ if (device.params.updateSource === "LAN") {
+ oAccessory.context.reachableLAN = true;
+ }
this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory);
}
}
From 3a9962f6f2f7f2893b4d4aa1fa89c0a105018764 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Wed, 16 Sep 2020 16:49:39 +0100
Subject: [PATCH 0162/3183] Revert "lan check"
This reverts commit 02f84ed46fb5a002c2df06fc203ebf5c74f1faff.
---
lib/eWeLink.js | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 23a75865..b1735aef 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -1017,9 +1017,7 @@ class eWeLink {
if (this.devicesInHB.has(deviceId + "SW" + i)) {
let oAccessory = this.devicesInHB.get(deviceId + "SW" + i);
oAccessory.context.reachableWAN = device.params.online;
- if (device.params.updateSource === "LAN") {
- oAccessory.context.reachableLAN = true;
- }
+ oAccessory.context.reachableLAN = true;
this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory);
}
}
From e098bd63228b87a003ff8539908260d6fdf4cffa Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Wed, 16 Sep 2020 16:49:42 +0100
Subject: [PATCH 0163/3183] Revert "syntax error"
This reverts commit 37ad909a3b4104b217af6396f08ac39fd4f14b05.
---
lib/eWeLink.js | 32 ++++++++++++++++++--------------
1 file changed, 18 insertions(+), 14 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index b1735aef..855a0402 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -992,6 +992,7 @@ class eWeLink {
(accessory = this.devicesInHB.get(deviceId + "SWX") || this.devicesInHB.get(deviceId + "SW0"))
) {
let isX = accessory.context.hbDeviceId.substr(-1) === "X";
+
if (device.params.updateSource === "WS") {
if (device.params.online != accessory.context.reachableWAN) {
accessory.context.reachableWAN = device.params.online;
@@ -1005,20 +1006,23 @@ class eWeLink {
);
}
}
- if (device.params.updateSource === "LAN" && !accessory.context.reachableLAN) {
- accessory.context.reachableLAN = true;
- this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
- this.wsClient.requestUpdate(accessory);
- statusChange = true;
- this.log.warn("[%s] has been reported [online] via [LAN].", accessory.displayName);
- }
- if (statusChange && !isX) {
- for (let i = 1; i <= accessory.context.channelCount; i++) {
- if (this.devicesInHB.has(deviceId + "SW" + i)) {
- let oAccessory = this.devicesInHB.get(deviceId + "SW" + i);
- oAccessory.context.reachableWAN = device.params.online;
- oAccessory.context.reachableLAN = true;
- this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory);
+
+ if (device.params.updateSource === "LAN") {
+ if (!accessory.context.reachableLAN) {
+ accessory.context.reachableLAN = true;
+ this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
+ this.wsClient.requestUpdate(accessory);
+ statusChange = true;
+ this.log.warn("[%s] has been reported [online] via [LAN].", accessory.displayName);
+ }
+ if (statusChange && !isX) {
+ for (let i = 1; i <= accessory.context.channelCount; i++) {
+ if (this.devicesInHB.has(deviceId + "SW" + i)) {
+ let oAccessory = this.devicesInHB.get(deviceId + "SW" + i);
+ oAccessory.context.reachableWAN = device.params.online;
+ oAccessory.context.reachableLAN = true;
+ this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory);
+ }
}
}
}
From 9507b0bed4f99ab07fd69d404fefc6663bbedd84 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Wed, 16 Sep 2020 16:49:45 +0100
Subject: [PATCH 0164/3183] Revert "3.0 initial changes"
This reverts commit 556a0e048249a7e8c423f052a6b8283318389b73.
---
.prettierrc.json | 3 +-
lib/constants.js | 7 +-
lib/eWeLink.js | 1389 +++++++++++++++++++++++++++++++-------------
lib/eWeLinkHTTP.js | 241 ++++----
lib/eWeLinkLAN.js | 91 ++-
lib/eWeLinkWS.js | 156 +++--
6 files changed, 1263 insertions(+), 624 deletions(-)
diff --git a/.prettierrc.json b/.prettierrc.json
index 87f5e5e8..d68aa739 100644
--- a/.prettierrc.json
+++ b/.prettierrc.json
@@ -1,4 +1,3 @@
{
- "arrowParens": "avoid",
- "printWidth": 100
+ "arrowParens": "avoid"
}
diff --git a/lib/constants.js b/lib/constants.js
index fe7fcb40..d8892025 100644
--- a/lib/constants.js
+++ b/lib/constants.js
@@ -40,7 +40,12 @@ module.exports = {
devicesSensor: [102],
devicesSensorParams: ["switch", "battery"],
devicesThermostat: [15],
- devicesThermostatParams: ["currentTemperature", "currentHumidity", "switch", "masterSwitch"],
+ devicesThermostatParams: [
+ "currentTemperature",
+ "currentHumidity",
+ "switch",
+ "masterSwitch",
+ ],
devicesFan: [34],
devicesFanParams: ["switches", "light", "fan", "speed"],
devicesOutlet: [32],
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 855a0402..13c6d210 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -13,9 +13,15 @@ class eWeLink {
constructor(log, config, api) {
if (!log || !api || !config) return;
if (!config.username || !config.password || !config.countryCode) {
- log.error("*********** Cannot load homebridge-ewelink ***********");
- log.error("eWeLink credentials missing from the Homebridge config.");
- log.error("*******************************************************");
+ log.error(
+ "**************** Cannot load homebridge-ewelink ****************"
+ );
+ log.error(
+ "Your eWeLink credentials are missing from the Homebridge config."
+ );
+ log.error(
+ "****************************************************************"
+ );
return;
}
this.log = log;
@@ -23,103 +29,153 @@ class eWeLink {
this.api = api;
this.debug = this.config.debug || false;
this.devicesInHB = new Map();
- this.devicesInEW = new Map();
+ this.devicesInEwe = new Map();
this.cusG = new Map();
this.cusS = new Map();
this.eveLogPath = this.api.user.storagePath() + "/homebridge-ewelink/";
this.api
- .on("didFinishLaunching", () => this.eWeLinkSync())
- .on("shutdown", () => {
- if (this.lanClient) this.lanClient.closeConnection();
- if (this.wsClient) this.wsClient.closeConnection();
- });
- }
- eWeLinkSync() {
- this.log("Plugin has finished initialising. Synching with eWeLink.");
- this.httpClient = new eWeLinkHTTP(this.config, this.log);
- this.httpClient
- .getHost()
- .then(() => this.httpClient.login())
- .then(res => {
- this.authData = res;
- return this.httpClient.getDevices();
- })
- .then(res => {
- this.httpDevices = res
- .filter(d => d.hasOwnProperty("extra") && d.extra.hasOwnProperty("uiid"))
- .filter(d => !(this.config.hideDevFromHB || "").includes(d.deviceid));
- this.httpDevices.forEach(device => this.devicesInEW.set(device.deviceid, device));
- this.wsClient = new eWeLinkWS(this.config, this.log, this.authData);
- return this.wsClient.getHost();
- })
- .then(() => {
- this.wsClient.login();
- this.lanClient = new eWeLinkLAN(this.config, this.log, this.httpDevices);
- return this.lanClient.getHosts();
- })
- .then(res => {
- this.lanDevices = res.map;
- this.lanCount = res.count;
- return this.lanClient.startMonitor();
- })
- .then(() => {
- (() => {
- //*** Remove all Homebridge accessories if none found ***\\
- if (
- Object.keys(this.httpDevices).length === 0 &&
- Object.keys(this.lanDevices).length === 0
- ) {
- Array.from(this.devicesInHB.values()).forEach(a => this.removeAccessory(a));
- this.devicesInHB.clear();
- this.log.warn("******* Not loading homebridge-ewelink *******");
- this.log.warn("No devices were found in your eWeLink account.");
- this.log.warn("**********************************************");
- return;
- }
- //*** Make a map of custom groups from Homebridge config ***\\
- if (Object.keys(this.config.groups || []).length > 0) {
- this.config.groups
- .filter(g => g.hasOwnProperty("type") && cns.allowedGroups.includes(g.type))
- .filter(g => g.hasOwnProperty("deviceId") && this.devicesInEW.has(g.deviceId))
- .forEach(g => this.cusG.set(g.deviceId + "SWX", g));
- }
- //*** Make a map of RF Bridge custom sensors from Homebridge config ***\\
- if (Object.keys(this.config.bridgeSensors || []).length > 0) {
- this.config.bridgeSensors
- .filter(s => s.hasOwnProperty("deviceId") && this.devicesInEW.has(s.deviceId))
- .forEach(s => this.cusS.set(s.fullDeviceId, s));
- }
- //*** Logging always helps to see if everything is okay so far ***\\
- this.log("[%s] eWeLink devices loaded from the Homebridge cache.", this.devicesInHB.size);
- this.log("[%s] primary devices loaded from your eWeLink account.", this.devicesInEW.size);
- this.log("[%s] primary devices were discovered on your local network.", this.lanCount);
- //*** Remove Homebridge accessories that don't appear in eWeLink ***\\
- this.devicesInHB.forEach(a => {
- if (!this.devicesInEW.has(a.context.eweDeviceId)) {
- this.removeAccessory(a);
- }
+ .on("didFinishLaunching", () => {
+ this.log(
+ "Plugin has finished initialising. Starting synchronisation with eWeLink account."
+ );
+ //*** Set up HTTP client and get the user HTTP host ***\\
+ this.httpClient = new eWeLinkHTTP(this.config, this.log);
+ this.httpClient
+ .getHost()
+ .then(() => this.httpClient.login())
+ .then(res => {
+ //*** Set up the web socket client ***\\
+ this.wsClient = new eWeLinkWS(this.config, this.log, res);
+ return this.wsClient.getHost();
+ })
+ .then(() => {
+ //*** Open web socket connection and get device list via HTTP ***\\
+ this.wsClient.login();
+ return this.httpClient.getDevices();
+ })
+ .then(res => {
+ //*** Get device IP addresses for LAN mode ***\\
+ this.httpDevices = res
+ .filter(
+ device =>
+ device.hasOwnProperty("extra") &&
+ device.extra.hasOwnProperty("uiid")
+ )
+ .filter(
+ device =>
+ !(this.config.hideDevFromHB || "").includes(device.deviceid)
+ );
+ this.lanClient = new eWeLinkLAN(
+ this.config,
+ this.log,
+ this.httpDevices
+ );
+ this.httpDevices.forEach(device =>
+ this.devicesInEwe.set(device.deviceid, device)
+ );
+ return this.lanClient.getHosts();
+ })
+ .then(res => {
+ //*** Set up the LAN mode listener ***\\
+ this.lanDevices = res.map;
+ this.lanDevicesOnline = res.count;
+ return this.lanClient.startMonitor();
+ })
+ .then(() => {
+ //*** Use the device list to refresh Homebridge accessories ***\\
+ (() => {
+ //*** Remove all Homebridge accessories if none found ***\\
+ if (
+ Object.keys(this.httpDevices).length === 0 &&
+ Object.keys(this.lanDevices).length === 0
+ ) {
+ Array.from(this.devicesInHB.values()).forEach(a =>
+ this.removeAccessory(a)
+ );
+ this.devicesInHB.clear();
+ this.log.warn("******* Not loading homebridge-ewelink *******");
+ this.log.warn("No devices were found in your eWeLink account.");
+ this.log.warn("**********************************************");
+ return;
+ }
+ //*** Make a map of custom groups from Homebridge config ***\\
+ if (Object.keys(this.config.groups || []).length > 0) {
+ this.config.groups
+ .filter(
+ g =>
+ g.hasOwnProperty("type") &&
+ cns.allowedGroups.includes(g.type)
+ )
+ .filter(
+ g =>
+ g.hasOwnProperty("deviceId") &&
+ this.devicesInEwe.has(g.deviceId.toLowerCase())
+ )
+ .forEach(g => this.cusG.set(g.deviceId + "SWX", g));
+ }
+ //*** Make a map of RF Bridge custom sensors from Homebridge config ***\\
+ if (Object.keys(this.config.bridgeSensors || []).length > 0) {
+ this.config.bridgeSensors
+ .filter(
+ s =>
+ s.hasOwnProperty("deviceId") &&
+ this.devicesInEwe.has(s.deviceId.toLowerCase())
+ )
+ .forEach(s => this.cusS.set(s.fullDeviceId, s));
+ }
+ //*** Logging always helps to see if everything is okay so far ***\\
+ this.log(
+ "[%s] eWeLink devices were loaded from the Homebridge cache.",
+ this.devicesInHB.size
+ );
+ this.log(
+ "[%s] primary devices were loaded from your eWeLink account.",
+ this.devicesInEwe.size
+ );
+ this.log(
+ "[%s] primary devices were discovered on your local network.",
+ this.lanDevicesOnline
+ );
+ //*** Remove Homebridge accessories that don't appear in eWeLink ***\\
+ this.devicesInHB.forEach(a => {
+ if (!this.devicesInEwe.has(a.context.eweDeviceId)) {
+ this.removeAccessory(a);
+ }
+ });
+ //*** Synchronise devices between eWeLink and Homebridge and set up ws/lan listeners ***\\
+ this.devicesInEwe.forEach(d => this.initialiseDevice(d));
+ this.wsClient.receiveUpdate(d => this.receiveDeviceUpdate(d));
+ this.lanClient.receiveUpdate(d => this.receiveDeviceUpdate(d));
+ this.log(
+ "eWeLink setup complete. If you're enjoying this package please consider a âī¸ on GitHub :)."
+ );
+ if (this.config.debugReqRes || false) {
+ this.log.warn(
+ "You have 'Request & Response Logging' enabled. This setting is not recommended for long-term use."
+ );
+ }
+ })();
+ })
+ .catch(err => {
+ this.log.error(
+ "************** Cannot load homebridge-ewelink **************"
+ );
+ this.log.error(err);
+ this.log.error(
+ "************************************************************"
+ );
+ if (this.lanClient) this.lanClient.closeConnection();
+ if (this.wsClient) this.wsClient.closeConnection();
});
- //*** Synchronise devices between eWeLink and Homebridge and set up ws/lan listeners ***\\
- this.devicesInEW.forEach(d => this.initialiseDevice(d));
- this.wsClient.receiveUpdate(d => this.receiveDeviceUpdate(d));
- this.lanClient.receiveUpdate(d => this.receiveDeviceUpdate(d));
- this.log("eWeLink sync complete. Don't forget to âī¸ this plugin on GitHub!");
- if (this.config.debugReqRes || false) {
- this.log.warn("Note: 'Request & Response Logging' is not advised for long-term use.");
- }
- })();
})
- .catch(err => {
- this.log.error("************** Cannot load homebridge-ewelink **************");
- this.log.error(err);
- this.log.error("************************************************************");
+ .on("shutdown", () => {
if (this.lanClient) this.lanClient.closeConnection();
if (this.wsClient) this.wsClient.closeConnection();
});
}
initialiseDevice(device) {
let accessory;
- //*** First add the device if it isn't already in Homebridge ***\\
+ //*** First add the device if it isn't already in Homebridge. Yeah this code looks a mess :| ***\\
if (
!this.devicesInHB.has(device.deviceid + "SWX") &&
!this.devicesInHB.has(device.deviceid + "SW0")
@@ -177,7 +233,9 @@ class eWeLink {
}
} else if (cns.devicesRFBridge.includes(device.extra.uiid)) {
this.addAccessory(device, device.deviceid + "SW0", "rf_pri");
- if (Object.keys((device.tags && device.tags.zyx_info) || []).length > 0) {
+ if (
+ Object.keys((device.tags && device.tags.zyx_info) || []).length > 0
+ ) {
for (let i = 1; i <= Object.keys(device.tags.zyx_info).length; i++) {
this.addAccessory(device, device.deviceid + "SW" + i, "rf_sub");
}
@@ -211,20 +269,31 @@ class eWeLink {
rfBridgeChange = false;
accessory
.getService(Service.AccessoryInformation)
- .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion);
- accessory.context.reachableWAN = accessory.context.eweUIID !== 102 ? device.online : true;
- accessory.context.reachableLAN = this.lanDevices.get(device.deviceid).online || false;
+ .setCharacteristic(
+ Characteristic.FirmwareRevision,
+ device.params.fwVersion
+ );
+ accessory.context.reachableWAN =
+ accessory.context.eweUIID !== 102 ? device.online : true;
+ accessory.context.reachableLAN =
+ this.lanDevices.get(device.deviceid).online || false;
accessory.context.inUse = false;
let str = accessory.context.reachableLAN
- ? "and locally with IP [" + this.lanDevices.get(device.deviceid).ip + "]"
- : "but LAN mode unavailable as offline/unsupported/shared device";
+ ? "and locally with IP [" +
+ this.lanDevices.get(device.deviceid).ip +
+ "]"
+ : "but LAN mode unavailable as unsupported/shared device";
this.log("[%s] found in eWeLink %s.", accessory.displayName, str);
this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
if (!isX) {
for (let i = 1; i <= accessory.context.channelCount; i++) {
if (!this.devicesInHB.has(device.deviceid + "SW" + i)) {
if (cns.devicesHideable.includes(accessory.context.type)) {
- if ((this.config.hideFromHB || "").includes(device.deviceid + "SW" + i)) {
+ if (
+ (this.config.hideFromHB || "").includes(
+ device.deviceid + "SW" + i
+ )
+ ) {
continue;
} else {
this.addAccessory(device, device.deviceid + "SW" + i, "switch");
@@ -233,7 +302,9 @@ class eWeLink {
}
let oAccessory = this.devicesInHB.get(device.deviceid + "SW" + i);
if (
- (this.config.hideFromHB || "").includes(device.deviceid + "SW" + i) &&
+ (this.config.hideFromHB || "").includes(
+ device.deviceid + "SW" + i
+ ) &&
cns.devicesHideable.includes(accessory.context.type)
) {
this.removeAccessory(oAccessory);
@@ -247,9 +318,13 @@ class eWeLink {
}
oAccessory
.getService(Service.AccessoryInformation)
- .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion);
+ .setCharacteristic(
+ Characteristic.FirmwareRevision,
+ device.params.fwVersion
+ );
oAccessory.context.reachableWAN = device.online;
- oAccessory.context.reachableLAN = this.lanDevices.get(device.deviceid).online || false;
+ oAccessory.context.reachableLAN =
+ this.lanDevices.get(device.deviceid).online || false;
this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory);
}
}
@@ -274,12 +349,18 @@ class eWeLink {
);
}
} else {
- this.log.warn("[%s] cannot be initialised as it wasn't found in Homebridge.", device.name);
+ this.log.warn(
+ "[%s] cannot be initialised as it wasn't found in Homebridge.",
+ device.name
+ );
}
}
addAccessory(device, hbDeviceId, type) {
let switchNumber = hbDeviceId.substr(-1).toString(),
- newDeviceName = type === "rf_sub" ? device.tags.zyx_info[switchNumber - 1].name : device.name,
+ newDeviceName =
+ type === "rf_sub"
+ ? device.tags.zyx_info[switchNumber - 1].name
+ : device.name,
channelCount =
type === "rf_pri"
? Object.keys((device.tags && device.tags.zyx_info) || []).length
@@ -297,7 +378,10 @@ class eWeLink {
if ((this.config.nameOverride || {}).hasOwnProperty(hbDeviceId)) {
newDeviceName = this.config.nameOverride[hbDeviceId];
}
- const accessory = new Accessory(newDeviceName, UUIDGen.generate(hbDeviceId).toString());
+ const accessory = new Accessory(
+ newDeviceName,
+ UUIDGen.generate(hbDeviceId).toString()
+ );
try {
accessory
.getService(Service.AccessoryInformation)
@@ -307,7 +391,10 @@ class eWeLink {
Characteristic.Model,
device.productModel + " (" + device.extra.model + ")"
)
- .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion)
+ .setCharacteristic(
+ Characteristic.FirmwareRevision,
+ device.params.fwVersion
+ )
.setCharacteristic(Characteristic.Identify, false);
accessory.context = {
hbDeviceId,
@@ -323,11 +410,18 @@ class eWeLink {
case "valve":
["A", "B"].forEach(v => {
accessory
- .addService(Service.Valve, "Valve " + v, "valve" + v.toLowerCase())
+ .addService(
+ Service.Valve,
+ "Valve " + v,
+ "valve" + v.toLowerCase()
+ )
.setCharacteristic(Characteristic.Active, 0)
.setCharacteristic(Characteristic.InUse, 0)
.setCharacteristic(Characteristic.ValveType, 1)
- .setCharacteristic(Characteristic.SetDuration, this.config.valveTimeLength || 120)
+ .setCharacteristic(
+ Characteristic.SetDuration,
+ this.config.valveTimeLength || 120
+ )
.addCharacteristic(Characteristic.RemainingDuration);
});
break;
@@ -362,7 +456,8 @@ class eWeLink {
case "thermostat":
if (!this.config.hideTHSwitch) accessory.addService(Service.Switch);
accessory.addService(Service.TemperatureSensor);
- if (device.params.sensorType !== "DS18B20") accessory.addService(Service.HumiditySensor);
+ if (device.params.sensorType !== "DS18B20")
+ accessory.addService(Service.HumiditySensor);
break;
case "outlet":
accessory.addService(Service.Outlet);
@@ -408,7 +503,9 @@ class eWeLink {
break;
case "rf_sub":
accessory.context.rfChls = {};
- switch (device.tags.zyx_info[parseInt(switchNumber) - 1].remote_type) {
+ switch (
+ device.tags.zyx_info[parseInt(switchNumber) - 1].remote_type
+ ) {
case "1":
case "2":
case "3":
@@ -428,46 +525,52 @@ class eWeLink {
);
}
let mAccessory = this.devicesInHB.get(device.deviceid + "SW0");
- device.tags.zyx_info[parseInt(switchNumber) - 1].buttonName.forEach(button => {
- let rfData;
- Object.entries(button).forEach(
- ([k, v]) =>
- (rfData = {
- rfChan: k,
- name: v,
- })
- );
- accessory.context.rfChls[rfData.rfChan] = rfData.name;
- mAccessory.context.rfChlMap[rfData.rfChan] = switchNumber;
- switch (accessory.context.sensorType) {
- case "button":
- accessory.addService(Service.Switch, rfData.name, "switch" + rfData.rfChan);
- break;
- case "water":
- accessory.addService(Service.LeakSensor);
- break;
- case "fire":
- case "smoke":
- accessory.addService(Service.SmokeSensor);
- break;
- case "co":
- accessory.addService(Service.CarbonMonoxideSensor);
- break;
- case "co2":
- accessory.addService(Service.CarbonDioxideSensor);
- break;
- case "contact":
- accessory.addService(Service.ContactSensor);
- break;
- case "occupancy":
- accessory.addService(Service.OccupancySensor);
- break;
- default:
- accessory.addService(Service.MotionSensor);
- break;
+ device.tags.zyx_info[parseInt(switchNumber) - 1].buttonName.forEach(
+ button => {
+ let rfData;
+ Object.entries(button).forEach(
+ ([k, v]) =>
+ (rfData = {
+ rfChan: k,
+ name: v,
+ })
+ );
+ accessory.context.rfChls[rfData.rfChan] = rfData.name;
+ mAccessory.context.rfChlMap[rfData.rfChan] = switchNumber;
+ switch (accessory.context.sensorType) {
+ case "button":
+ accessory.addService(
+ Service.Switch,
+ rfData.name,
+ "switch" + rfData.rfChan
+ );
+ break;
+ case "water":
+ accessory.addService(Service.LeakSensor);
+ break;
+ case "fire":
+ case "smoke":
+ accessory.addService(Service.SmokeSensor);
+ break;
+ case "co":
+ accessory.addService(Service.CarbonMonoxideSensor);
+ break;
+ case "co2":
+ accessory.addService(Service.CarbonDioxideSensor);
+ break;
+ case "contact":
+ accessory.addService(Service.ContactSensor);
+ break;
+ case "occupancy":
+ accessory.addService(Service.OccupancySensor);
+ break;
+ default:
+ accessory.addService(Service.MotionSensor);
+ break;
+ }
+ this.devicesInHB.set(mAccessory.context.hbDeviceId, mAccessory);
}
- this.devicesInHB.set(mAccessory.context.hbDeviceId, mAccessory);
- });
+ );
break;
case "zb_sub": //*** credit @tasict ***\\
accessory.addService(Service.BatteryService);
@@ -505,7 +608,9 @@ class eWeLink {
throw "device is not supported by this plugin. Please create an issue on GitHub";
}
this.devicesInHB.set(hbDeviceId, accessory);
- this.api.registerPlatformAccessories("homebridge-ewelink", "eWeLink", [accessory]);
+ this.api.registerPlatformAccessories("homebridge-ewelink", "eWeLink", [
+ accessory,
+ ]);
this.configureAccessory(accessory);
this.log("[%s] has been added to Homebridge.", newDeviceName);
} catch (err) {
@@ -524,21 +629,33 @@ class eWeLink {
.getService("Valve " + v)
.getCharacteristic(Characteristic.Active)
.on("set", (value, callback) =>
- this.internalValveUpdate(accessory, "Valve " + v, value, callback)
+ this.internalValveUpdate(
+ accessory,
+ "Valve " + v,
+ value,
+ callback
+ )
);
accessory
.getService("Valve " + v)
.getCharacteristic(Characteristic.SetDuration)
.on("set", (value, callback) => {
if (
- accessory.getService("Valve " + v).getCharacteristic(Characteristic.InUse).value
+ accessory
+ .getService("Valve " + v)
+ .getCharacteristic(Characteristic.InUse).value
) {
accessory
.getService("Valve " + v)
- .updateCharacteristic(Characteristic.RemainingDuration, value);
+ .updateCharacteristic(
+ Characteristic.RemainingDuration,
+ value
+ );
clearTimeout(accessory.getService("Valve " + v).timer);
accessory.getService("Valve " + v).timer = setTimeout(() => {
- accessory.getService("Valve " + v).setCharacteristic(Characteristic.Active, 0);
+ accessory
+ .getService("Valve " + v)
+ .setCharacteristic(Characteristic.Active, 0);
}, value * 1000);
}
callback();
@@ -549,7 +666,9 @@ class eWeLink {
accessory
.getService(Service.WindowCovering)
.getCharacteristic(Characteristic.TargetPosition)
- .on("set", (value, callback) => this.internalBlindUpdate(accessory, value, callback))
+ .on("set", (value, callback) =>
+ this.internalBlindUpdate(accessory, value, callback)
+ )
.setProps({
minStep: 100,
});
@@ -558,13 +677,17 @@ class eWeLink {
accessory
.getService(Service.GarageDoorOpener)
.getCharacteristic(Characteristic.TargetDoorState)
- .on("set", (value, callback) => this.internalGarageUpdate(accessory, value, callback));
+ .on("set", (value, callback) =>
+ this.internalGarageUpdate(accessory, value, callback)
+ );
break;
case "lock":
accessory
.getService(Service.LockMechanism)
.getCharacteristic(Characteristic.LockTargetState)
- .on("set", (value, callback) => this.internalLockUpdate(accessory, value, callback));
+ .on("set", (value, callback) =>
+ this.internalLockUpdate(accessory, value, callback)
+ );
break;
case "fan":
accessory
@@ -614,7 +737,9 @@ class eWeLink {
if (accessory.getService(Service.HumiditySensor)) {
dataToAdd.humidity = accessory
.getService(Service.HumiditySensor)
- .getCharacteristic(Characteristic.CurrentRelativeHumidity).value;
+ .getCharacteristic(
+ Characteristic.CurrentRelativeHumidity
+ ).value;
}
accessory.eveLogger.addEntry(dataToAdd);
}, 300000);
@@ -623,7 +748,9 @@ class eWeLink {
accessory
.getService(Service.Outlet)
.getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => this.internalOutletUpdate(accessory, value, callback));
+ .on("set", (value, callback) =>
+ this.internalOutletUpdate(accessory, value, callback)
+ );
accessory.log = this.log;
accessory.eveLogger = new EveHistoryService("energy", accessory, {
storage: "fs",
@@ -642,12 +769,15 @@ class eWeLink {
};
}
corrInterval.setCorrectingInterval(() => {
- let isOn = accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On)
- .value,
+ let isOn = accessory
+ .getService(Service.Outlet)
+ .getCharacteristic(Characteristic.On).value,
currentWatt = isOn
? accessory
.getService(Service.Outlet)
- .getCharacteristic(EveService.Characteristics.CurrentConsumption).value
+ .getCharacteristic(
+ EveService.Characteristics.CurrentConsumption
+ ).value
: 0;
if (accessory.eveLogger.isHistoryLoaded()) {
accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData();
@@ -662,7 +792,8 @@ class eWeLink {
});
} else {
accessory.context.totalEnergy =
- accessory.context.totalEnergyTemp + (currentWatt * 10) / 3600 / 1000;
+ accessory.context.totalEnergyTemp +
+ (currentWatt * 10) / 3600 / 1000;
accessory.eveLogger.setExtraPersistedData({
totalenergy: accessory.context.totalEnergy,
lastReset: 0,
@@ -670,7 +801,8 @@ class eWeLink {
}
accessory.context.totalEnergytemp = 0;
} else {
- accessory.context.totalEnergyTemp += (currentWatt * 10) / 3600 / 1000;
+ accessory.context.totalEnergyTemp +=
+ (currentWatt * 10) / 3600 / 1000;
accessory.context.totalEnergy = accessory.context.totalEnergyTemp;
}
accessory.eveLogger.addEntry({
@@ -684,7 +816,8 @@ class eWeLink {
.on("get", callback => {
accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData();
if (accessory.context.extraPersistedData !== undefined) {
- accessory.context.totalEnergy = accessory.context.extraPersistedData.totalPower;
+ accessory.context.totalEnergy =
+ accessory.context.extraPersistedData.totalPower;
}
callback(null, accessory.context.totalEnergy);
});
@@ -703,7 +836,8 @@ class eWeLink {
.on("get", callback => {
accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData();
if (accessory.context.extraPersistedData !== undefined) {
- accessory.context.lastReset = accessory.context.extraPersistedData.lastReset;
+ accessory.context.lastReset =
+ accessory.context.extraPersistedData.lastReset;
}
callback(null, accessory.context.lastReset);
});
@@ -712,13 +846,17 @@ class eWeLink {
accessory
.getService(Service.Outlet)
.getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => this.internalUSBUpdate(accessory, value, callback));
+ .on("set", (value, callback) =>
+ this.internalUSBUpdate(accessory, value, callback)
+ );
break;
case "scm":
accessory
.getService(Service.Switch)
.getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => this.internalSCMUpdate(accessory, value, callback));
+ .on("set", (value, callback) =>
+ this.internalSCMUpdate(accessory, value, callback)
+ );
break;
case "light":
accessory
@@ -734,8 +872,9 @@ class eWeLink {
.on("set", (value, callback) => {
if (value > 0) {
if (
- !accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On)
- .value
+ !accessory
+ .getService(Service.Lightbulb)
+ .getCharacteristic(Characteristic.On).value
) {
this.internalLightbulbUpdate(accessory, true, function () {
return;
@@ -746,15 +885,18 @@ class eWeLink {
this.internalLightbulbUpdate(accessory, false, callback);
}
});
- } else if (cns.devicesColourable.includes(accessory.context.eweUIID)) {
+ } else if (
+ cns.devicesColourable.includes(accessory.context.eweUIID)
+ ) {
accessory
.getService(Service.Lightbulb)
.getCharacteristic(Characteristic.Brightness)
.on("set", (value, callback) => {
if (value > 0) {
if (
- !accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On)
- .value
+ !accessory
+ .getService(Service.Lightbulb)
+ .getCharacteristic(Characteristic.On).value
) {
this.internalLightbulbUpdate(accessory, true, function () {
return;
@@ -781,18 +923,24 @@ class eWeLink {
accessory
.getService(Service.Switch)
.getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => this.internalSwitchUpdate(accessory, value, callback));
+ .on("set", (value, callback) =>
+ this.internalSwitchUpdate(accessory, value, callback)
+ );
break;
case "rf_sub":
accessory.context.rfChls = accessory.context.rfChls || {};
if (accessory.context.sensorType === "button") {
Object.entries(accessory.context.rfChls).forEach(([k, v]) => {
- accessory.getService(v).updateCharacteristic(Characteristic.On, false);
+ accessory
+ .getService(v)
+ .updateCharacteristic(Characteristic.On, false);
accessory
.getService(v)
.getCharacteristic(Characteristic.On)
.on("set", (value, callback) => {
- value ? this.internalRFDeviceUpdate(accessory, k, callback) : callback();
+ value
+ ? this.internalRFDeviceUpdate(accessory, k, callback)
+ : callback();
});
});
}
@@ -813,7 +961,8 @@ class eWeLink {
.getCharacteristic(Characteristic.CurrentTemperature).value,
humidity: accessory
.getService(Service.HumiditySensor)
- .getCharacteristic(Characteristic.CurrentRelativeHumidity).value,
+ .getCharacteristic(Characteristic.CurrentRelativeHumidity)
+ .value,
};
accessory.eveLogger.addEntry(dataToAdd);
}, 300000);
@@ -822,14 +971,20 @@ class eWeLink {
}
this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
} catch (err) {
- this.log.warn("[%s] could not be refreshed as %s.", accessory.displayName, err);
+ this.log.warn(
+ "[%s] could not be refreshed as %s.",
+ accessory.displayName,
+ err
+ );
}
}
refreshAccessory(accessory, newParams) {
switch (accessory.context.type) {
case "valve":
if (
- Object.keys(newParams).some(v => cns.devicesValveParams.includes(v)) &&
+ Object.keys(newParams).some(v =>
+ cns.devicesValveParams.includes(v)
+ ) &&
Array.isArray(newParams.switches)
) {
this.externalValveUpdate(accessory, newParams);
@@ -837,7 +992,9 @@ class eWeLink {
return true;
case "blind":
if (
- Object.keys(newParams).some(v => cns.devicesBlindParams.includes(v)) &&
+ Object.keys(newParams).some(v =>
+ cns.devicesBlindParams.includes(v)
+ ) &&
Array.isArray(newParams.switches)
) {
this.externalBlindUpdate(accessory, newParams);
@@ -845,34 +1002,48 @@ class eWeLink {
return true;
case "garage":
if (
- Object.keys(newParams).some(v => cns.devicesGarageParams.includes(v)) &&
+ Object.keys(newParams).some(v =>
+ cns.devicesGarageParams.includes(v)
+ ) &&
Array.isArray(newParams.switches)
) {
this.externalGarageUpdate(accessory, newParams);
}
return true;
case "lock":
- if (Object.keys(newParams).some(v => cns.devicesLockParams.includes(v))) {
+ if (
+ Object.keys(newParams).some(v => cns.devicesLockParams.includes(v))
+ ) {
this.externalLockUpdate(accessory, newParams);
}
return true;
case "sensor":
- if (Object.keys(newParams).some(v => cns.devicesSensorParams.includes(v))) {
+ if (
+ Object.keys(newParams).some(v => cns.devicesSensorParams.includes(v))
+ ) {
this.externalSensorUpdate(accessory, newParams);
}
return true;
case "fan":
- if (Object.keys(newParams).some(v => cns.devicesFanParams.includes(v))) {
+ if (
+ Object.keys(newParams).some(v => cns.devicesFanParams.includes(v))
+ ) {
this.externalFanUpdate(accessory, newParams);
}
return true;
case "thermostat":
- if (Object.keys(newParams).some(v => cns.devicesThermostatParams.includes(v))) {
+ if (
+ Object.keys(newParams).some(v =>
+ cns.devicesThermostatParams.includes(v)
+ )
+ ) {
this.externalThermostatUpdate(accessory, newParams);
}
return true;
case "outlet":
- if (Object.keys(newParams).some(v => cns.devicesOutletParams.includes(v))) {
+ if (
+ Object.keys(newParams).some(v => cns.devicesOutletParams.includes(v))
+ ) {
this.externalOutletUpdate(accessory, newParams);
}
return true;
@@ -897,7 +1068,11 @@ class eWeLink {
cns.devicesSingleSwitch.includes(accessory.context.eweUIID) &&
cns.devicesSingleSwitchLight.includes(accessory.context.eweModel)
) {
- if (Object.keys(newParams).some(v => cns.devicesSingleSwitchLightParams.includes(v))) {
+ if (
+ Object.keys(newParams).some(v =>
+ cns.devicesSingleSwitchLightParams.includes(v)
+ )
+ ) {
this.externalSingleLightUpdate(accessory, newParams);
}
} else if (
@@ -905,7 +1080,9 @@ class eWeLink {
cns.devicesMultiSwitchLight.includes(accessory.context.eweModel)
) {
if (
- Object.keys(newParams).some(v => cns.devicesMultiSwitchLightParams.includes(v)) &&
+ Object.keys(newParams).some(v =>
+ cns.devicesMultiSwitchLightParams.includes(v)
+ ) &&
Array.isArray(newParams.switches)
) {
this.externalMultiLightUpdate(accessory, newParams);
@@ -914,12 +1091,18 @@ class eWeLink {
return true;
case "switch":
if (cns.devicesSingleSwitch.includes(accessory.context.eweUIID)) {
- if (Object.keys(newParams).some(v => cns.devicesSingleSwitchParams.includes(v))) {
+ if (
+ Object.keys(newParams).some(v =>
+ cns.devicesSingleSwitchParams.includes(v)
+ )
+ ) {
this.externalSingleSwitchUpdate(accessory, newParams);
}
} else if (cns.devicesMultiSwitch.includes(accessory.context.eweUIID)) {
if (
- Object.keys(newParams).some(v => cns.devicesMultiSwitchParams.includes(v)) &&
+ Object.keys(newParams).some(v =>
+ cns.devicesMultiSwitchParams.includes(v)
+ ) &&
Array.isArray(newParams.switches)
) {
this.externalMultiSwitchUpdate(accessory, newParams);
@@ -927,7 +1110,11 @@ class eWeLink {
}
return true;
case "rf_pri":
- if (Object.keys(newParams).some(v => cns.devicesRFBridgeParams.includes(v))) {
+ if (
+ Object.keys(newParams).some(v =>
+ cns.devicesRFBridgeParams.includes(v)
+ )
+ ) {
this.externalRFDeviceUpdate(accessory, newParams);
}
return true;
@@ -935,7 +1122,11 @@ class eWeLink {
case "zb_pri":
return true;
case "zb_sub":
- if (Object.keys(newParams).some(v => cns.devicesZBBridgeParams.includes(v))) {
+ if (
+ Object.keys(newParams).some(v =>
+ cns.devicesZBBridgeParams.includes(v)
+ )
+ ) {
this.externalZBDeviceUpdate(accessory, newParams);
}
return true;
@@ -946,10 +1137,16 @@ class eWeLink {
removeAccessory(accessory) {
try {
this.devicesInHB.delete(accessory.context.hbDeviceId);
- this.api.unregisterPlatformAccessories("homebridge-ewelink", "eWeLink", [accessory]);
+ this.api.unregisterPlatformAccessories("homebridge-ewelink", "eWeLink", [
+ accessory,
+ ]);
this.log("[%s] has been removed from Homebridge.", accessory.displayName);
} catch (err) {
- this.log.warn("[%s] needed to be removed but couldn't as %s.", accessory.displayName, err);
+ this.log.warn(
+ "[%s] needed to be removed but couldn't as %s.",
+ accessory.displayName,
+ err
+ );
}
}
sendDeviceUpdate(accessory, params, callback) {
@@ -970,7 +1167,10 @@ class eWeLink {
callback("Device has failed to update");
}
};
- if (cns.devicesNonLAN.includes(accessory.context.eweUIID) || !accessory.context.reachableLAN) {
+ if (
+ cns.devicesNonLAN.includes(accessory.context.eweUIID) ||
+ !accessory.context.reachableLAN
+ ) {
sendViaWS();
} else {
this.lanClient
@@ -978,81 +1178,110 @@ class eWeLink {
.then(() => callback())
.catch(err => {
if (this.debug) {
- this.log.warn("[%s] Reverting to web socket as %s.", accessory.displayName, err);
+ this.log.warn(
+ "[%s] Reverting to web socket as %s.",
+ accessory.displayName,
+ err
+ );
}
sendViaWS();
});
}
}
receiveDeviceUpdate(device) {
- let accessory,
- deviceId = device.deviceid,
- statusChange = false;
- if (
- (accessory = this.devicesInHB.get(deviceId + "SWX") || this.devicesInHB.get(deviceId + "SW0"))
- ) {
- let isX = accessory.context.hbDeviceId.substr(-1) === "X";
-
- if (device.params.updateSource === "WS") {
- if (device.params.online != accessory.context.reachableWAN) {
- accessory.context.reachableWAN = device.params.online;
- this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
- if (accessory.context.reachableWAN) this.wsClient.requestUpdate(accessory);
- statusChange = true;
- this.log.warn(
- "[%s] has been reported [%s] via [WS].",
- accessory.displayName,
- accessory.context.reachableWAN ? "online" : "offline"
- );
- }
- }
-
- if (device.params.updateSource === "LAN") {
- if (!accessory.context.reachableLAN) {
- accessory.context.reachableLAN = true;
- this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
- this.wsClient.requestUpdate(accessory);
- statusChange = true;
- this.log.warn("[%s] has been reported [online] via [LAN].", accessory.displayName);
- }
- if (statusChange && !isX) {
- for (let i = 1; i <= accessory.context.channelCount; i++) {
- if (this.devicesInHB.has(deviceId + "SW" + i)) {
- let oAccessory = this.devicesInHB.get(deviceId + "SW" + i);
- oAccessory.context.reachableWAN = device.params.online;
- oAccessory.context.reachableLAN = true;
- this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory);
+ let accessory;
+ switch (device.action) {
+ case "sysmsg":
+ if (
+ (accessory =
+ this.devicesInHB.get(device.deviceid + "SWX") ||
+ this.devicesInHB.get(device.deviceid + "SW0"))
+ ) {
+ let isX = accessory.context.hbDeviceId.substr(-1) === "X";
+ if (device.params.updateSource === "WS") {
+ if (accessory.context.reachableWAN !== device.params.online) {
+ accessory.context.reachableWAN = device.params.online;
+ this.log(
+ "[%s] has been reported [%s] via [WS].",
+ accessory.displayName,
+ accessory.context.reachableWAN ? "online" : "offline"
+ );
+ this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
+ if (accessory.context.reachableWAN)
+ this.wsClient.requestUpdate(accessory);
+ } else {
+ if (this.debug) {
+ this.log(
+ "[%s] Nothing to update from above WS message.",
+ accessory.displayName
+ );
+ }
+ }
+ }
+ if (!isX) {
+ for (let i = 1; i <= accessory.context.channelCount; i++) {
+ if (this.devicesInHB.has(device.deviceid + "SW" + i)) {
+ let oAccessory = this.devicesInHB.get(
+ device.deviceid + "SW" + i
+ );
+ oAccessory.context.reachableWAN = device.params.online;
+ this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory);
+ }
}
}
}
- }
- if (this.debug) {
- this.log(
- "[%s] externally updated from above %s message and will be refreshed.",
- accessory.displayName,
- device.params.updateSource
- );
- }
- if (!this.refreshAccessory(accessory, device.params)) {
- this.log.warn(
- "[%s] cannot be refreshed. Please try removing accessory from the Homebridge cache along with any secondary devices (SW1, SW2, etc.). [debug:%s:%s]",
- accessory.displayName,
- accessory.context.type,
- accessory.context.channelCount
- );
- }
- } else {
- if (!(this.config.hideDevFromHB || "").includes(deviceId)) {
- this.log.warn(
- "[%s] update received via %s does not exist in Homebridge so device will be added.",
- deviceId,
- device.params.updateSource
- );
- this.httpClient
- .getDevice(deviceId)
- .then(res => this.initialiseDevice(res))
- .catch(err => this.log.error("[%s] error getting info [%s]", deviceId, err));
- }
+ break;
+ case "update":
+ if (
+ (accessory =
+ this.devicesInHB.get(device.deviceid + "SWX") ||
+ this.devicesInHB.get(device.deviceid + "SW0"))
+ ) {
+ if (
+ device.params.updateSource === "WS" &&
+ !accessory.context.reachableWAN
+ ) {
+ accessory.context.reachableWAN = true;
+ this.log(
+ "[%s] has been reported [online] via [WS].",
+ accessory.displayName
+ );
+ }
+ if (
+ device.params.updateSource === "LAN" &&
+ !accessory.context.reachableLAN
+ ) {
+ accessory.context.reachableLAN = true;
+ this.log(
+ "[%s] has been reported [online] via [LAN].",
+ accessory.displayName
+ );
+ }
+ if (this.debug) {
+ this.log(
+ "[%s] externally updated from above %s message and will be refreshed.",
+ accessory.displayName,
+ device.params.updateSource
+ );
+ }
+ if (!this.refreshAccessory(accessory, device.params)) {
+ this.log.warn(
+ "[%s] cannot be refreshed. Please try removing accessory from the Homebridge cache along with any secondary devices (SW1, SW2, etc.). [debug:%s:%s]",
+ accessory.displayName,
+ accessory.context.type,
+ accessory.context.channelCount
+ );
+ }
+ } else {
+ if (!(this.config.hideDevFromHB || "").includes(device.deviceid)) {
+ this.log.warn(
+ "[%s] Accessory received via %s update does not exist in Homebridge. If it's a new accessory please restart Homebridge so it is added.",
+ device.deviceid,
+ device.params.updateSource
+ );
+ }
+ }
+ break;
}
}
internalValveUpdate(accessory, valve, value, callback) {
@@ -1067,19 +1296,28 @@ class eWeLink {
.updateCharacteristic(Characteristic.InUse, value);
switch (value) {
case 0:
- accessory.getService(valve).updateCharacteristic(Characteristic.RemainingDuration, 0);
+ accessory
+ .getService(valve)
+ .updateCharacteristic(Characteristic.RemainingDuration, 0);
clearTimeout(accessory.getService(valve).timer);
break;
case 1:
- let timer = accessory.getService(valve).getCharacteristic(Characteristic.SetDuration)
- .value;
- accessory.getService(valve).updateCharacteristic(Characteristic.RemainingDuration, timer);
+ let timer = accessory
+ .getService(valve)
+ .getCharacteristic(Characteristic.SetDuration).value;
+ accessory
+ .getService(valve)
+ .updateCharacteristic(Characteristic.RemainingDuration, timer);
accessory.getService(valve).timer = setTimeout(() => {
- accessory.getService(valve).setCharacteristic(Characteristic.Active, 0);
+ accessory
+ .getService(valve)
+ .setCharacteristic(Characteristic.Active, 0);
}, timer * 1000);
break;
}
- params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
+ params.switches = this.devicesInEwe.get(
+ accessory.context.eweDeviceId
+ ).params.switches;
switch (valve) {
case "Valve A":
params.switches[0].switch = value ? "on" : "off";
@@ -1104,7 +1342,8 @@ class eWeLink {
params.switches[3].switch = "off";
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str =
+ "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -1118,7 +1357,10 @@ class eWeLink {
if (!(blindConfig = this.cusG.get(accessory.context.hbDeviceId))) {
throw "group config missing";
}
- if (blindConfig.type !== "blind" || !["oneSwitch", "twoSwitch"].includes(blindConfig.setup)) {
+ if (
+ blindConfig.type !== "blind" ||
+ !["oneSwitch", "twoSwitch"].includes(blindConfig.setup)
+ ) {
throw "improper configuration";
}
let oldPos,
@@ -1140,7 +1382,9 @@ class eWeLink {
params.switch = "on";
break;
case "twoSwitch":
- params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
+ params.switches = this.devicesInEwe.get(
+ accessory.context.eweDeviceId
+ ).params.switches;
params.switches[0].switch = value === 100 ? "on" : "off";
params.switches[1].switch = value === 0 ? "on" : "off";
break;
@@ -1160,7 +1404,8 @@ class eWeLink {
callback();
}, parseInt(blindConfig.operationTime) * 100);
} catch (err) {
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str =
+ "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -1188,7 +1433,10 @@ class eWeLink {
newPos = value,
params = {},
delay = 0;
- if (sensorDefinition && !(sAccessory = this.devicesInHB.get(garageConfig.sensorId + "SWX"))) {
+ if (
+ sensorDefinition &&
+ !(sAccessory = this.devicesInHB.get(garageConfig.sensorId + "SWX"))
+ ) {
throw "defined DW2 sensor doesn't exist";
}
if (sAccessory.context.type !== "sensor") {
@@ -1211,7 +1459,10 @@ class eWeLink {
if (garageConfig.setup === "oneSwitch" && [2, 3].includes(oldPos)) {
accessory
.getService(Service.GarageDoorOpener)
- .updateCharacteristic(Characteristic.CurrentDoorState, ((oldPos * 2) % 3) + 2);
+ .updateCharacteristic(
+ Characteristic.CurrentDoorState,
+ ((oldPos * 2) % 3) + 2
+ );
delay = 1500;
}
setTimeout(() => {
@@ -1225,7 +1476,9 @@ class eWeLink {
params.switch = "on";
break;
case "twoSwitch":
- params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
+ params.switches = this.devicesInEwe.get(
+ accessory.context.eweDeviceId
+ ).params.switches;
params.switches[0].switch = newPos === 0 ? "on" : "off";
params.switches[1].switch = newPos === 1 ? "on" : "off";
break;
@@ -1246,7 +1499,8 @@ class eWeLink {
callback();
} catch (err) {
accessory.context.inUse = false;
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str =
+ "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -1281,7 +1535,8 @@ class eWeLink {
}, parseInt(lockConfig.operationTime) * 100);
} catch (err) {
accessory.context.inUse = false;
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str =
+ "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -1296,36 +1551,45 @@ class eWeLink {
case "power":
newPower = value;
newSpeed = value ? 33 : 0;
- newLight = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On)
- .value;
+ newLight = accessory
+ .getService(Service.Lightbulb)
+ .getCharacteristic(Characteristic.On).value;
break;
case "speed":
newPower = value >= 33 ? 1 : 0;
newSpeed = value;
- newLight = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On)
- .value;
+ newLight = accessory
+ .getService(Service.Lightbulb)
+ .getCharacteristic(Characteristic.On).value;
break;
case "light":
- newPower = accessory.getService(Service.Fanv2).getCharacteristic(Characteristic.Active)
- .value;
+ newPower = accessory
+ .getService(Service.Fanv2)
+ .getCharacteristic(Characteristic.Active).value;
newSpeed = accessory
.getService(Service.Fanv2)
.getCharacteristic(Characteristic.RotationSpeed).value;
newLight = value;
break;
}
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, newLight);
+ accessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.On, newLight);
accessory
.getService(Service.Fanv2)
.updateCharacteristic(Characteristic.Active, newPower)
.updateCharacteristic(Characteristic.RotationSpeed, newSpeed);
let params = {
- switches: this.devicesInEW.get(accessory.context.eweDeviceId).params.switches,
+ switches: this.devicesInEwe.get(accessory.context.eweDeviceId).params
+ .switches,
};
params.switches[0].switch = newLight ? "on" : "off";
- params.switches[1].switch = newPower === 1 && newSpeed >= 33 ? "on" : "off";
- params.switches[2].switch = newPower === 1 && newSpeed >= 66 && newSpeed < 99 ? "on" : "off";
- params.switches[3].switch = newPower === 1 && newSpeed >= 99 ? "on" : "off";
+ params.switches[1].switch =
+ newPower === 1 && newSpeed >= 33 ? "on" : "off";
+ params.switches[2].switch =
+ newPower === 1 && newSpeed >= 66 && newSpeed < 99 ? "on" : "off";
+ params.switches[3].switch =
+ newPower === 1 && newSpeed >= 99 ? "on" : "off";
if (this.debug) {
this.log.warn("Fan Update - setting " + type + " to " + value);
this.log(
@@ -1338,7 +1602,8 @@ class eWeLink {
}
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str =
+ "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -1353,12 +1618,19 @@ class eWeLink {
mainSwitch: value ? "on" : "off",
};
if (this.debug) {
- this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
+ this.log(
+ "[%s] updating to turn [%s].",
+ accessory.displayName,
+ value ? "on" : "off"
+ );
}
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
+ accessory
+ .getService(Service.Switch)
+ .updateCharacteristic(Characteristic.On, value);
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str =
+ "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -1372,9 +1644,15 @@ class eWeLink {
switch: value ? "on" : "off",
};
if (this.debug) {
- this.log("[%s] requesting to turn [%s].", accessory.displayName, value ? "on" : "off");
+ this.log(
+ "[%s] requesting to turn [%s].",
+ accessory.displayName,
+ value ? "on" : "off"
+ );
}
- accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, value);
+ accessory
+ .getService(Service.Outlet)
+ .updateCharacteristic(Characteristic.On, value);
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
callback("[" + accessory.displayName + "] " + err + ".");
@@ -1386,13 +1664,20 @@ class eWeLink {
throw "it is currently offline";
}
let params = {
- switches: this.devicesInEW.get(accessory.context.eweDeviceId).params.switches,
+ switches: this.devicesInEwe.get(accessory.context.eweDeviceId).params
+ .switches,
};
params.switches[0].switch = value ? "on" : "off";
if (this.debug) {
- this.log("[%s] requesting to turn [%s].", accessory.displayName, value ? "on" : "off");
+ this.log(
+ "[%s] requesting to turn [%s].",
+ accessory.displayName,
+ value ? "on" : "off"
+ );
}
- accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, value);
+ accessory
+ .getService(Service.Outlet)
+ .updateCharacteristic(Characteristic.On, value);
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
callback("[" + accessory.displayName + "] " + err + ".");
@@ -1404,13 +1689,20 @@ class eWeLink {
throw "it is currently offline";
}
let params = {
- switches: this.devicesInEW.get(accessory.context.eweDeviceId).params.switches,
+ switches: this.devicesInEwe.get(accessory.context.eweDeviceId).params
+ .switches,
};
params.switches[0].switch = value ? "on" : "off";
if (this.debug) {
- this.log("[%s] requesting to turn [%s].", accessory.displayName, value ? "on" : "off");
+ this.log(
+ "[%s] requesting to turn [%s].",
+ accessory.displayName,
+ value ? "on" : "off"
+ );
}
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
+ accessory
+ .getService(Service.Switch)
+ .updateCharacteristic(Characteristic.On, value);
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
callback("[" + accessory.displayName + "] " + err + ".");
@@ -1432,12 +1724,20 @@ class eWeLink {
params.switch = value ? "on" : "off";
}
if (this.debug) {
- this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
+ this.log(
+ "[%s] updating to turn [%s].",
+ accessory.displayName,
+ value ? "on" : "off"
+ );
}
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
+ accessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.On, value);
break;
case "0":
- params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
+ params.switches = this.devicesInEwe.get(
+ accessory.context.eweDeviceId
+ ).params.switches;
params.switches[0].switch = value ? "on" : "off";
params.switches[1].switch = value ? "on" : "off";
params.switches[2].switch = value ? "on" : "off";
@@ -1449,10 +1749,16 @@ class eWeLink {
value ? "on" : "off"
);
}
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
+ accessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.On, value);
for (let i = 1; i <= 4; i++) {
- if (this.devicesInHB.has(accessory.context.eweDeviceId + "SW" + i)) {
- oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i);
+ if (
+ this.devicesInHB.has(accessory.context.eweDeviceId + "SW" + i)
+ ) {
+ oAccessory = this.devicesInHB.get(
+ accessory.context.eweDeviceId + "SW" + i
+ );
oAccessory
.getService(Service.Lightbulb)
.updateCharacteristic(Characteristic.On, value);
@@ -1464,14 +1770,26 @@ class eWeLink {
case "3":
case "4":
if (this.debug) {
- this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
+ this.log(
+ "[%s] updating to turn [%s].",
+ accessory.displayName,
+ value ? "on" : "off"
+ );
}
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
+ accessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.On, value);
let tAccessory,
masterState = "off";
- params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
+ params.switches = this.devicesInEwe.get(
+ accessory.context.eweDeviceId
+ ).params.switches;
for (let i = 1; i <= 4; i++) {
- if ((tAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
+ if (
+ (tAccessory = this.devicesInHB.get(
+ accessory.context.eweDeviceId + "SW" + i
+ ))
+ ) {
i === parseInt(accessory.context.switchNumber)
? (params.switches[i - 1].switch = value ? "on" : "off")
: (params.switches[i - 1].switch = tAccessory
@@ -1480,7 +1798,9 @@ class eWeLink {
? "on"
: "off");
if (
- tAccessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value
+ tAccessory
+ .getService(Service.Lightbulb)
+ .getCharacteristic(Characteristic.On).value
) {
masterState = "on";
}
@@ -1488,17 +1808,22 @@ class eWeLink {
params.switches[i - 1].switch = "off";
}
}
- oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
+ oAccessory = this.devicesInHB.get(
+ accessory.context.eweDeviceId + "SW0"
+ );
oAccessory
.getService(Service.Lightbulb)
.updateCharacteristic(Characteristic.On, masterState === "on");
break;
default:
- throw "unknown switch number [" + accessory.context.switchNumber + "]";
+ throw (
+ "unknown switch number [" + accessory.context.switchNumber + "]"
+ );
}
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str =
+ "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -1511,9 +1836,15 @@ class eWeLink {
let params = {};
if (value === 0) {
params.switch = "off";
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, false);
+ accessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.On, false);
} else {
- if (!accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value) {
+ if (
+ !accessory
+ .getService(Service.Lightbulb)
+ .getCharacteristic(Characteristic.On).value
+ ) {
params.switch = "on";
}
switch (accessory.context.eweUIID) {
@@ -1532,11 +1863,16 @@ class eWeLink {
.updateCharacteristic(Characteristic.Brightness, value);
}
if (this.debug) {
- this.log("[%s] updating brightness to [%s%].", accessory.displayName, value);
+ this.log(
+ "[%s] updating brightness to [%s%].",
+ accessory.displayName,
+ value
+ );
}
setTimeout(() => this.sendDeviceUpdate(accessory, params, callback), 250);
} catch (err) {
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str =
+ "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -1548,8 +1884,9 @@ class eWeLink {
}
let newRGB,
params = {},
- curHue = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Hue)
- .value,
+ curHue = accessory
+ .getService(Service.Lightbulb)
+ .getCharacteristic(Characteristic.Hue).value,
curSat = accessory
.getService(Service.Lightbulb)
.getCharacteristic(Characteristic.Saturation).value;
@@ -1580,9 +1917,15 @@ class eWeLink {
throw "unknown device UIID";
}
if (this.debug) {
- this.log("[%s] updating hue to [%s°].", accessory.displayName, value);
+ this.log(
+ "[%s] updating hue to [%s°].",
+ accessory.displayName,
+ value
+ );
}
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Hue, value);
+ accessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.Hue, value);
break;
case "bri":
switch (accessory.context.eweUIID) {
@@ -1606,7 +1949,11 @@ class eWeLink {
break;
}
if (this.debug) {
- this.log("[%s] updating brightness to [%s%].", accessory.displayName, value);
+ this.log(
+ "[%s] updating brightness to [%s%].",
+ accessory.displayName,
+ value
+ );
}
accessory
.getService(Service.Lightbulb)
@@ -1617,7 +1964,8 @@ class eWeLink {
}
setTimeout(() => this.sendDeviceUpdate(accessory, params, callback), 250);
} catch (err) {
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str =
+ "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -1633,12 +1981,20 @@ class eWeLink {
case "X":
params.switch = value ? "on" : "off";
if (this.debug) {
- this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
+ this.log(
+ "[%s] updating to turn [%s].",
+ accessory.displayName,
+ value ? "on" : "off"
+ );
}
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
+ accessory
+ .getService(Service.Switch)
+ .updateCharacteristic(Characteristic.On, value);
break;
case "0":
- params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
+ params.switches = this.devicesInEwe.get(
+ accessory.context.eweDeviceId
+ ).params.switches;
params.switches[0].switch = value ? "on" : "off";
params.switches[1].switch = value ? "on" : "off";
params.switches[2].switch = value ? "on" : "off";
@@ -1650,11 +2006,19 @@ class eWeLink {
value ? "on" : "off"
);
}
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
+ accessory
+ .getService(Service.Switch)
+ .updateCharacteristic(Characteristic.On, value);
for (let i = 1; i <= 4; i++) {
- if (this.devicesInHB.has(accessory.context.eweDeviceId + "SW" + i)) {
- oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i);
- oAccessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
+ if (
+ this.devicesInHB.has(accessory.context.eweDeviceId + "SW" + i)
+ ) {
+ oAccessory = this.devicesInHB.get(
+ accessory.context.eweDeviceId + "SW" + i
+ );
+ oAccessory
+ .getService(Service.Switch)
+ .updateCharacteristic(Characteristic.On, value);
}
}
break;
@@ -1663,14 +2027,26 @@ class eWeLink {
case "3":
case "4":
if (this.debug) {
- this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
+ this.log(
+ "[%s] updating to turn [%s].",
+ accessory.displayName,
+ value ? "on" : "off"
+ );
}
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
+ accessory
+ .getService(Service.Switch)
+ .updateCharacteristic(Characteristic.On, value);
let tAccessory,
masterState = "off";
- params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
+ params.switches = this.devicesInEwe.get(
+ accessory.context.eweDeviceId
+ ).params.switches;
for (let i = 1; i <= 4; i++) {
- if ((tAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
+ if (
+ (tAccessory = this.devicesInHB.get(
+ accessory.context.eweDeviceId + "SW" + i
+ ))
+ ) {
i === parseInt(accessory.context.switchNumber)
? (params.switches[i - 1].switch = value ? "on" : "off")
: (params.switches[i - 1].switch = tAccessory
@@ -1679,7 +2055,9 @@ class eWeLink {
? "on"
: "off");
if (
- tAccessory.getService(Service.Switch).getCharacteristic(Characteristic.On).value
+ tAccessory
+ .getService(Service.Switch)
+ .getCharacteristic(Characteristic.On).value
) {
masterState = "on";
}
@@ -1687,17 +2065,22 @@ class eWeLink {
params.switches[i - 1].switch = "off";
}
}
- oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
+ oAccessory = this.devicesInHB.get(
+ accessory.context.eweDeviceId + "SW0"
+ );
oAccessory
.getService(Service.Switch)
.updateCharacteristic(Characteristic.On, masterState === "on");
break;
default:
- throw "unknown switch number [" + accessory.context.switchNumber + "]";
+ throw (
+ "unknown switch number [" + accessory.context.switchNumber + "]"
+ );
}
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str =
+ "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -1731,7 +2114,14 @@ class eWeLink {
3000
);
} catch (err) {
- let str = "[" + accessory.displayName + " " + name + "] could not be updated as " + err + ".";
+ let str =
+ "[" +
+ accessory.displayName +
+ " " +
+ name +
+ "] could not be updated as " +
+ err +
+ ".";
this.log.error(str);
callback(str);
}
@@ -1741,8 +2131,14 @@ class eWeLink {
["A", "B"].forEach((v, k) => {
accessory
.getService("Valve " + v)
- .updateCharacteristic(Characteristic.Active, params.switches[k].switch === "on")
- .updateCharacteristic(Characteristic.InUse, params.switches[k].switch === "on");
+ .updateCharacteristic(
+ Characteristic.Active,
+ params.switches[k].switch === "on"
+ )
+ .updateCharacteristic(
+ Characteristic.InUse,
+ params.switches[k].switch === "on"
+ );
if (params.switches[k].switch === "on") {
let timer = accessory
.getService("Valve " + v)
@@ -1751,7 +2147,9 @@ class eWeLink {
.getService("Valve " + v)
.updateCharacteristic(Characteristic.RemainingDuration, timer);
accessory.getService("Valve " + v).timer = setTimeout(() => {
- accessory.getService("Valve " + v).setCharacteristic(Characteristic.Active, 0);
+ accessory
+ .getService("Valve " + v)
+ .setCharacteristic(Characteristic.Active, 0);
}, timer * 1000);
} else {
accessory
@@ -1761,7 +2159,11 @@ class eWeLink {
}
});
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.log.warn(
+ "[%s] could not be updated as %s.",
+ accessory.displayName,
+ err
+ );
}
}
externalBlindUpdate(accessory, params) {
@@ -1770,7 +2172,10 @@ class eWeLink {
if (!(blindConfig = this.cusG.get(accessory.context.hbDeviceId))) {
throw "group config missing";
}
- if (blindConfig.type !== "blind" || ["oneSwitch", "twoSwitch"].includes(blindConfig.setup)) {
+ if (
+ blindConfig.type !== "blind" ||
+ ["oneSwitch", "twoSwitch"].includes(blindConfig.setup)
+ ) {
throw "improper configuration";
}
switch (blindConfig.setup) {
@@ -1786,7 +2191,10 @@ class eWeLink {
: 0;
break;
case "twoSwitch":
- if (params.switches[0].switch === "off" && params.switches[1].switch === "off") {
+ if (
+ params.switches[0].switch === "off" &&
+ params.switches[1].switch === "off"
+ ) {
return;
}
let switchUp = params.switches[0].switch === "on" ? -1 : 0, // matrix of numbers to get
@@ -1805,7 +2213,11 @@ class eWeLink {
.updateCharacteristic(Characteristic.CurrentPosition, nSte * 100);
}, parseInt(blindConfig.operationTime) * 100);
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.log.warn(
+ "[%s] could not be updated as %s.",
+ accessory.displayName,
+ err
+ );
}
}
externalGarageUpdate(accessory, params) {
@@ -1859,7 +2271,11 @@ class eWeLink {
}, parseInt(garageConfig.operationTime) * 100);
} catch (err) {
accessory.context.inUse = false;
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.log.warn(
+ "[%s] could not be updated as %s.",
+ accessory.displayName,
+ err
+ );
}
}
externalLockUpdate(accessory, params) {
@@ -1888,7 +2304,11 @@ class eWeLink {
}, parseInt(lockConfig.operationTime) * 100);
} catch (err) {
accessory.context.inUse = false;
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.log.warn(
+ "[%s] could not be updated as %s.",
+ accessory.displayName,
+ err
+ );
}
}
externalSensorUpdate(accessory, params) {
@@ -1898,8 +2318,14 @@ class eWeLink {
accessory.getService(Service.BatteryService) ||
accessory.addService(Service.BatteryService),
scaledBattery = Math.round(params.battery * 33.3);
- batteryService.updateCharacteristic(Characteristic.BatteryLevel, scaledBattery);
- batteryService.updateCharacteristic(Characteristic.StatusLowBattery, scaledBattery < 25);
+ batteryService.updateCharacteristic(
+ Characteristic.BatteryLevel,
+ scaledBattery
+ );
+ batteryService.updateCharacteristic(
+ Characteristic.StatusLowBattery,
+ scaledBattery < 25
+ );
}
let newState = params.switch === "on" ? 1 : 0,
oAccessory = false;
@@ -1907,7 +2333,10 @@ class eWeLink {
.getService(Service.ContactSensor)
.updateCharacteristic(Characteristic.ContactSensorState, newState);
this.cusG.forEach(group => {
- if (group.sensorId === accessory.context.eweDeviceId && group.type === "garage") {
+ if (
+ group.sensorId === accessory.context.eweDeviceId &&
+ group.type === "garage"
+ ) {
if ((oAccessory = this.devicesInHB.get(group.deviceId + "SWX"))) {
switch (newState) {
case 0:
@@ -1931,7 +2360,11 @@ class eWeLink {
}
});
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.log.warn(
+ "[%s] could not be updated as %s.",
+ accessory.displayName,
+ err
+ );
}
}
externalFanUpdate(accessory, params) {
@@ -1939,7 +2372,11 @@ class eWeLink {
let light, status, speed;
if (Array.isArray(params.switches)) {
light = params.switches[0].switch === "on";
- switch (params.switches[1].switch + params.switches[2].switch + params.switches[3].switch) {
+ switch (
+ params.switches[1].switch +
+ params.switches[2].switch +
+ params.switches[3].switch
+ ) {
default:
status = 0;
speed = 0;
@@ -1967,13 +2404,19 @@ class eWeLink {
} else {
throw "unknown parameters received";
}
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, light);
+ accessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.On, light);
accessory
.getService(Service.Fanv2)
.updateCharacteristic(Characteristic.Active, status)
.updateCharacteristic(Characteristic.RotationSpeed, speed);
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.log.warn(
+ "[%s] could not be updated as %s.",
+ accessory.displayName,
+ err
+ );
}
}
externalThermostatUpdate(accessory, params) {
@@ -1985,7 +2428,9 @@ class eWeLink {
let newState = params.hasOwnProperty("switch")
? params.switch === "on"
: params.mainSwitch === "on";
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, newState);
+ accessory
+ .getService(Service.Switch)
+ .updateCharacteristic(Characteristic.On, newState);
}
let eveLog = {
time: Date.now(),
@@ -1995,7 +2440,9 @@ class eWeLink {
accessory.getService(Service.TemperatureSensor)
) {
let currentTemp =
- params.currentTemperature !== "unavailable" ? params.currentTemperature : 0;
+ params.currentTemperature !== "unavailable"
+ ? params.currentTemperature
+ : 0;
accessory
.getService(Service.TemperatureSensor)
.updateCharacteristic(Characteristic.CurrentTemperature, currentTemp);
@@ -2005,17 +2452,25 @@ class eWeLink {
params.hasOwnProperty("currentHumidity") &&
accessory.getService(Service.HumiditySensor)
) {
- let currentHumi = params.currentHumidity !== "unavailable" ? params.currentHumidity : 0;
+ let currentHumi =
+ params.currentHumidity !== "unavailable" ? params.currentHumidity : 0;
accessory
.getService(Service.HumiditySensor)
- .updateCharacteristic(Characteristic.CurrentRelativeHumidity, currentHumi);
+ .updateCharacteristic(
+ Characteristic.CurrentRelativeHumidity,
+ currentHumi
+ );
eveLog.humidity = parseFloat(currentHumi);
}
if (eveLog.hasOwnProperty("temp") || eveLog.hasOwnProperty("humidity")) {
accessory.eveLogger.addEntry(eveLog);
}
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.log.warn(
+ "[%s] could not be updated as %s.",
+ accessory.displayName,
+ err
+ );
}
}
externalOutletUpdate(accessory, params) {
@@ -2034,8 +2489,13 @@ class eWeLink {
);
accessory
.getService(Service.Outlet)
- .updateCharacteristic(Characteristic.OutletInUse, parseFloat(params.power) > 0);
- let isOn = accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On).value;
+ .updateCharacteristic(
+ Characteristic.OutletInUse,
+ parseFloat(params.power) > 0
+ );
+ let isOn = accessory
+ .getService(Service.Outlet)
+ .getCharacteristic(Characteristic.On).value;
accessory.eveLogger.addEntry({
time: Date.now(),
power: isOn ? parseFloat(params.power) : 0,
@@ -2044,7 +2504,10 @@ class eWeLink {
if (params.hasOwnProperty("voltage")) {
accessory
.getService(Service.Outlet)
- .updateCharacteristic(EveService.Characteristics.Voltage, parseFloat(params.voltage));
+ .updateCharacteristic(
+ EveService.Characteristics.Voltage,
+ parseFloat(params.voltage)
+ );
}
if (params.hasOwnProperty("current")) {
accessory
@@ -2055,25 +2518,43 @@ class eWeLink {
);
}
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.log.warn(
+ "[%s] could not be updated as %s.",
+ accessory.displayName,
+ err
+ );
}
}
externalUSBUpdate(accessory, params) {
try {
accessory
.getService(Service.Outlet)
- .updateCharacteristic(Characteristic.On, params.switches[0].switch === "on");
+ .updateCharacteristic(
+ Characteristic.On,
+ params.switches[0].switch === "on"
+ );
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.log.warn(
+ "[%s] could not be updated as %s.",
+ accessory.displayName,
+ err
+ );
}
}
externalSCMUpdate(accessory, params) {
try {
accessory
.getService(Service.Switch)
- .updateCharacteristic(Characteristic.On, params.switches[0].switch === "on");
+ .updateCharacteristic(
+ Characteristic.On,
+ params.switches[0].switch === "on"
+ );
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.log.warn(
+ "[%s] could not be updated as %s.",
+ accessory.displayName,
+ err
+ );
}
}
externalSingleLightUpdate(accessory, params) {
@@ -2083,13 +2564,20 @@ class eWeLink {
isOn = false;
if (accessory.context.eweUIID === 22 && params.hasOwnProperty("state")) {
isOn = params.state === "on";
- } else if (accessory.context.eweUIID !== 22 && params.hasOwnProperty("switch")) {
+ } else if (
+ accessory.context.eweUIID !== 22 &&
+ params.hasOwnProperty("switch")
+ ) {
isOn = params.switch === "on";
} else {
- isOn = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value;
+ isOn = accessory
+ .getService(Service.Lightbulb)
+ .getCharacteristic(Characteristic.On).value;
}
if (isOn) {
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, true);
+ accessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.On, true);
switch (accessory.context.eweUIID) {
case 36: // KING-M4
if (params.hasOwnProperty("bright")) {
@@ -2103,7 +2591,10 @@ class eWeLink {
if (params.hasOwnProperty("brightness")) {
accessory
.getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.Brightness, params.brightness);
+ .updateCharacteristic(
+ Characteristic.Brightness,
+ params.brightness
+ );
}
break;
case 22: // B1
@@ -2118,7 +2609,9 @@ class eWeLink {
mode = 2;
}
if (mode === 2) {
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, true);
+ accessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.On, true);
newColour = convert.rgb.hsv(
parseInt(params.channel2),
parseInt(params.channel3),
@@ -2140,7 +2633,11 @@ class eWeLink {
.updateCharacteristic(Characteristic.Brightness, params.bright);
}
if (params.hasOwnProperty("colorR")) {
- newColour = convert.rgb.hsv(params.colorR, params.colorG, params.colorB);
+ newColour = convert.rgb.hsv(
+ params.colorR,
+ params.colorG,
+ params.colorB
+ );
accessory
.getService(Service.Lightbulb)
.updateCharacteristic(Characteristic.Hue, newColour[0])
@@ -2151,10 +2648,16 @@ class eWeLink {
return;
}
} else {
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, false);
+ accessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.On, false);
}
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.log.warn(
+ "[%s] could not be updated as %s.",
+ accessory.displayName,
+ err
+ );
}
}
externalMultiLightUpdate(accessory, params) {
@@ -2166,15 +2669,24 @@ class eWeLink {
let oAccessory = this.devicesInHB.get(idToCheck + i);
oAccessory
.getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.On, params.switches[i - 1].switch === "on");
+ .updateCharacteristic(
+ Characteristic.On,
+ params.switches[i - 1].switch === "on"
+ );
if (params.switches[i - 1].switch === "on") {
primaryState = true;
}
}
}
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, primaryState);
+ accessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.On, primaryState);
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.log.warn(
+ "[%s] could not be updated as %s.",
+ accessory.displayName,
+ err
+ );
}
}
externalSingleSwitchUpdate(accessory, params) {
@@ -2183,7 +2695,11 @@ class eWeLink {
.getService(Service.Switch)
.updateCharacteristic(Characteristic.On, params.switch === "on");
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.log.warn(
+ "[%s] could not be updated as %s.",
+ accessory.displayName,
+ err
+ );
}
}
externalMultiSwitchUpdate(accessory, params) {
@@ -2195,15 +2711,24 @@ class eWeLink {
let oAccessory = this.devicesInHB.get(idToCheck + i);
oAccessory
.getService(Service.Switch)
- .updateCharacteristic(Characteristic.On, params.switches[i - 1].switch === "on");
+ .updateCharacteristic(
+ Characteristic.On,
+ params.switches[i - 1].switch === "on"
+ );
if (params.switches[i - 1].switch === "on") {
primaryState = true;
}
}
}
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, primaryState);
+ accessory
+ .getService(Service.Switch)
+ .updateCharacteristic(Characteristic.On, primaryState);
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.log.warn(
+ "[%s] could not be updated as %s.",
+ accessory.displayName,
+ err
+ );
}
}
externalRFDeviceUpdate(accessory, params) {
@@ -2219,7 +2744,9 @@ class eWeLink {
// RF Button
let bAccessory;
if (
- (bAccessory = this.devicesInHB.get(idToCheck + accessory.context.rfChlMap[params.rfChl]))
+ (bAccessory = this.devicesInHB.get(
+ idToCheck + accessory.context.rfChlMap[params.rfChl]
+ ))
) {
bAccessory
.getService(bAccessory.context.rfChls[params.rfChl])
@@ -2273,51 +2800,81 @@ class eWeLink {
case "co":
oAccessory
.getService(Service.CarbonMonoxideSensor)
- .updateCharacteristic(Characteristic.CarbonMonoxideDetected, 1);
+ .updateCharacteristic(
+ Characteristic.CarbonMonoxideDetected,
+ 1
+ );
setTimeout(() => {
oAccessory
.getService(Service.CarbonMonoxideSensor)
- .updateCharacteristic(Characteristic.CarbonMonoxideDetected, 0);
+ .updateCharacteristic(
+ Characteristic.CarbonMonoxideDetected,
+ 0
+ );
}, (this.config.sensorTimeLength || 2) * 1000);
break;
case "co2":
oAccessory
.getService(Service.CarbonDioxideSensor)
- .updateCharacteristic(Characteristic.CarbonDioxideDetected, 1);
+ .updateCharacteristic(
+ Characteristic.CarbonDioxideDetected,
+ 1
+ );
setTimeout(() => {
oAccessory
.getService(Service.CarbonDioxideSensor)
- .updateCharacteristic(Characteristic.CarbonDioxideDetected, 0);
+ .updateCharacteristic(
+ Characteristic.CarbonDioxideDetected,
+ 0
+ );
}, (this.config.sensorTimeLength || 2) * 1000);
break;
case "contact":
oAccessory
.getService(Service.ContactSensor)
- .updateCharacteristic(Characteristic.ContactSensorState, 1);
+ .updateCharacteristic(
+ Characteristic.ContactSensorState,
+ 1
+ );
setTimeout(() => {
oAccessory
.getService(Service.ContactSensor)
- .updateCharacteristic(Characteristic.ContactSensorState, 0);
+ .updateCharacteristic(
+ Characteristic.ContactSensorState,
+ 0
+ );
}, (this.config.sensorTimeLength || 2) * 1000);
break;
case "occupancy":
oAccessory
.getService(Service.OccupancySensor)
- .updateCharacteristic(Characteristic.OccupancyDetected, 1);
+ .updateCharacteristic(
+ Characteristic.OccupancyDetected,
+ 1
+ );
setTimeout(() => {
oAccessory
.getService(Service.OccupancySensor)
- .updateCharacteristic(Characteristic.OccupancyDetected, 0);
+ .updateCharacteristic(
+ Characteristic.OccupancyDetected,
+ 0
+ );
}, (this.config.sensorTimeLength || 2) * 1000);
break;
default:
oAccessory
.getService(Service.MotionSensor)
- .updateCharacteristic(Characteristic.MotionDetected, true);
+ .updateCharacteristic(
+ Characteristic.MotionDetected,
+ true
+ );
setTimeout(() => {
oAccessory
.getService(Service.MotionSensor)
- .updateCharacteristic(Characteristic.MotionDetected, false);
+ .updateCharacteristic(
+ Characteristic.MotionDetected,
+ false
+ );
}, (this.config.sensorTimeLength || 2) * 1000);
break;
}
@@ -2333,7 +2890,11 @@ class eWeLink {
});
}
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.log.warn(
+ "[%s] could not be updated as %s.",
+ accessory.displayName,
+ err
+ );
}
}
externalZBDeviceUpdate(accessory, params) {
@@ -2343,15 +2904,24 @@ class eWeLink {
let batteryService =
accessory.getService(Service.BatteryService) ||
accessory.addService(Service.BatteryService);
- batteryService.updateCharacteristic(Characteristic.BatteryLevel, params.battery);
- batteryService.updateCharacteristic(Characteristic.StatusLowBattery, params.battery < 25);
+ batteryService.updateCharacteristic(
+ Characteristic.BatteryLevel,
+ params.battery
+ );
+ batteryService.updateCharacteristic(
+ Characteristic.StatusLowBattery,
+ params.battery < 25
+ );
}
switch (accessory.context.eweUIID) {
case 1000:
if (params.hasOwnProperty("key") && [0, 1, 2].includes(params.key)) {
accessory
.getService(Service.StatelessProgrammableSwitch)
- .updateCharacteristic(Characteristic.ProgrammableSwitchEvent, params.key);
+ .updateCharacteristic(
+ Characteristic.ProgrammableSwitchEvent,
+ params.key
+ );
}
break;
case 1770:
@@ -2362,22 +2932,34 @@ class eWeLink {
let currentTemp = parseInt(params.temperature) / 100;
accessory
.getService(Service.TemperatureSensor)
- .updateCharacteristic(Characteristic.CurrentTemperature, currentTemp);
+ .updateCharacteristic(
+ Characteristic.CurrentTemperature,
+ currentTemp
+ );
eveLog.temp = parseFloat(currentTemp);
}
if (params.hasOwnProperty("humidity")) {
let currentHumi = parseInt(params.humidity) / 100;
accessory
.getService(Service.HumiditySensor)
- .updateCharacteristic(Characteristic.CurrentRelativeHumidity, currentHumi);
+ .updateCharacteristic(
+ Characteristic.CurrentRelativeHumidity,
+ currentHumi
+ );
eveLog.humidity = parseFloat(currentHumi);
}
- if (eveLog.hasOwnProperty("temp") || eveLog.hasOwnProperty("humidity")) {
+ if (
+ eveLog.hasOwnProperty("temp") ||
+ eveLog.hasOwnProperty("humidity")
+ ) {
accessory.eveLogger.addEntry(eveLog);
}
break;
case 2026:
- if (params.hasOwnProperty("motion") && params.hasOwnProperty("trigTime")) {
+ if (
+ params.hasOwnProperty("motion") &&
+ params.hasOwnProperty("trigTime")
+ ) {
let timeNow = new Date(),
diff = (timeNow.getTime() - params.trigTime) / 1000;
accessory
@@ -2395,12 +2977,19 @@ class eWeLink {
if (params.hasOwnProperty("lock") && [0, 1].includes(params.lock)) {
accessory
.getService(Service.ContactSensor)
- .updateCharacteristic(Characteristic.ContactSensorState, params.lock);
+ .updateCharacteristic(
+ Characteristic.ContactSensorState,
+ params.lock
+ );
}
break;
}
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.log.warn(
+ "[%s] could not be updated as %s.",
+ accessory.displayName,
+ err
+ );
}
}
}
diff --git a/lib/eWeLinkHTTP.js b/lib/eWeLinkHTTP.js
index 24b1a69d..1aafd1e4 100644
--- a/lib/eWeLinkHTTP.js
+++ b/lib/eWeLinkHTTP.js
@@ -5,92 +5,29 @@ const axios = require("axios"),
crypto = require("crypto");
module.exports = class eWeLinkHTTP {
constructor(config, log) {
+ this.config = config;
this.log = log;
- this.debug = config.debug || false;
- this.debugReqRes = config.debugReqRes || false;
- this.username = config.username.toString();
- this.password = config.password.toString();
- this.cCode = "+" + config.countryCode.toString().replace("+", "").replace(" ", "");
- }
- getHost() {
- let data = {
- appid: constants.appId,
- country_code: this.cCode,
- nonce: Math.random().toString(36).substr(2, 8),
- ts: Math.floor(new Date().getTime() / 1000),
- version: 8,
- },
- dataToSign = [];
- Object.keys(data).forEach(k => {
- dataToSign.push({
- key: k,
- value: data.k,
- });
- });
- dataToSign.sort((a, b) => (a.key < b.key ? -1 : 1));
- dataToSign = dataToSign.map(k => k.key + "=" + k.value).join("&");
- dataToSign = crypto
- .createHmac("sha256", constants.appSecret)
- .update(dataToSign)
- .digest("base64");
- if (this.debugReqRes) {
- let msg = JSON.stringify(data, null, 2);
- this.log.warn("Sending HTTP getHost request. This text is yellow for clarity.\n%s", msg);
- } else if (this.debug) {
- this.log("Sending HTTP getHost request.");
- }
- return new Promise((resolve, reject) => {
- axios
- .get("https://api.coolkit.cc:8080/api/user/region", {
- headers: {
- Authorization: "Sign " + dataToSign,
- "Content-Type": "application/json",
- },
- params: data,
- })
- .then(res => {
- let body = res.data;
- if (!body.region) {
- throw "Server did not respond with a region.\n" + JSON.stringify(body, null, 2);
- }
- switch (body.region) {
- case "eu":
- case "us":
- case "as":
- this.httpHost = body.region + "-apia.coolkit.cc";
- break;
- case "cn":
- this.httpHost = "cn-apia.coolkit.cn";
- break;
- default:
- throw "No valid region received - [" + body.region + "].";
- }
- if (this.debug) {
- this.log("HTTP API host received [%s].", this.httpHost);
- }
- resolve(this.httpHost);
- })
- .catch(err => {
- if (err.hasOwnProperty("code") && ["ENOTFOUND", "ETIMEDOUT"].includes(err.code)) {
- this.log.warn("Unable to reach eWeLink. Retrying in 30 seconds.");
- this.delay().then(() => resolve(this.getHost()));
- } else {
- reject(err.message || err);
- }
- });
- });
+ this.debug = this.config.debug || false;
+ this.debugReqRes = this.config.debugReqRes || false;
}
login() {
let data = {
- countryCode: this.cCode,
- password: this.password,
+ countryCode:
+ "+" +
+ this.config.countryCode.toString().replace("+", "").replace(" ", ""),
+ password: this.config.password,
};
- this.username.includes("@") ? (data.email = this.username) : (data.phoneNumber = this.username);
+ this.config.username.includes("@")
+ ? (data.email = this.config.username)
+ : (data.phoneNumber = this.config.username);
if (this.debugReqRes) {
let msg = JSON.stringify(data, null, 2)
- .replace(this.password, "**hidden**")
- .replace(this.username, "**hidden**");
- this.log.warn("Sending HTTP login request. This text is yellow for clarity.\n%s", msg);
+ .replace(this.config.password, "**hidden**")
+ .replace(this.config.username, "**hidden**");
+ this.log.warn(
+ "Sending HTTP login request. This text is yellow for clarity.\n%s",
+ msg
+ );
} else if (this.debug) {
this.log("Sending HTTP login request.");
}
@@ -119,18 +56,17 @@ module.exports = class eWeLinkHTTP {
body.hasOwnProperty("data") &&
body.data.hasOwnProperty("region")
) {
- let givenRegion = body.data.region;
- switch (givenRegion) {
+ switch (body.data.region) {
case "eu":
case "us":
case "as":
- this.httpHost = givenRegion + "-apia.coolkit.cc";
+ this.httpHost = body.data.region + "-apia.coolkit.cc";
break;
case "cn":
this.httpHost = "cn-apia.coolkit.cn";
break;
default:
- throw "No valid region received - [" + givenRegion + "].";
+ throw "No valid region received - [" + body.data.region + "].";
}
if (this.debug) {
this.log("New HTTP API host received [%s].", this.httpHost);
@@ -139,7 +75,10 @@ module.exports = class eWeLinkHTTP {
return;
}
if (!body.data.at) {
- throw "No auth token received.\n" + JSON.stringify(body, null, 2);
+ throw (
+ "Server did not respond with an authentication token. Please double check your eWeLink username and password in the Homebridge configuration.\n" +
+ JSON.stringify(body, null, 2)
+ );
}
this.aToken = body.data.at;
this.apiKey = body.data.user.apikey;
@@ -149,95 +88,111 @@ module.exports = class eWeLinkHTTP {
httpHost: this.httpHost,
});
})
- .catch(err => reject(err.message || err));
+ .catch(err => {
+ reject(err);
+ });
});
}
- getDevices() {
+ getHost() {
+ let data = {
+ appid: constants.appId,
+ country_code: this.config.countryCode
+ .toString()
+ .replace("+", "")
+ .replace(" ", ""),
+ nonce: Math.random().toString(36).substr(2, 8),
+ ts: Math.floor(new Date().getTime() / 1000),
+ version: 8,
+ },
+ dataToSign = [];
+ Object.keys(data).forEach(function (key) {
+ dataToSign.push({
+ key: key,
+ value: data[key],
+ });
+ });
+ dataToSign.sort(function (a, b) {
+ return a.key < b.key ? -1 : 1;
+ });
+ dataToSign = dataToSign
+ .map(function (kv) {
+ return kv.key + "=" + kv.value;
+ })
+ .join("&");
+ dataToSign = crypto
+ .createHmac("sha256", constants.appSecret)
+ .update(dataToSign)
+ .digest("base64");
return new Promise((resolve, reject) => {
axios
- .get("https://" + this.httpHost + "/v2/device/thing", {
+ .get("https://api.coolkit.cc:8080/api/user/region", {
headers: {
- Authorization: "Bearer " + this.aToken,
+ Authorization: "Sign " + dataToSign,
"Content-Type": "application/json",
- Host: this.httpHost,
- "X-CK-Appid": constants.appId,
- "X-CK-Nonce": Math.random().toString(36).substr(2, 8),
},
+ params: data,
})
.then(res => {
let body = res.data;
- if (
- !body.hasOwnProperty("data") ||
- !body.hasOwnProperty("error") ||
- (body.hasOwnProperty("error") && body.error !== 0)
- ) {
- throw JSON.stringify(body, null, 2);
+ if (!body.region) {
+ throw (
+ "Server did not respond with a region.\n" +
+ JSON.stringify(body, null, 2)
+ );
}
- let deviceList = [];
- if (body.data.thingList && body.data.thingList.length > 0) {
- body.data.thingList.forEach(device => deviceList.push(device.itemData));
+ switch (body.region) {
+ case "eu":
+ case "us":
+ case "as":
+ this.httpHost = body.region + "-apia.coolkit.cc";
+ break;
+ case "cn":
+ this.httpHost = "cn-apia.coolkit.cn";
+ break;
+ default:
+ throw "No valid region received - [" + body.region + "].";
}
- resolve(deviceList);
+ if (this.debug) {
+ this.log("HTTP API host received [%s].", this.httpHost);
+ }
+ resolve(this.httpHost);
})
.catch(err => {
- if (err.hasOwnProperty("code") && ["ENOTFOUND", "ETIMEDOUT"].includes(err.code)) {
- this.log.warn("Unable to reach eWeLink. Retrying in 30 seconds.");
- this.delay().then(() => resolve(this.getDevices()));
- } else {
- reject(err.message || err);
- }
+ reject(err);
});
});
}
-
- getDevice(deviceId) {
+ getDevices() {
return new Promise((resolve, reject) => {
- axios({
- url: "https://" + this.httpHost + "/v2/device/thing",
- method: "post",
- headers: {
- Authorization: "Bearer " + this.aToken,
- "Content-Type": "application/json",
- Host: this.httpHost,
- "X-CK-Appid": constants.appId,
- "X-CK-Nonce": Math.random().toString(36).substr(2, 8),
- },
- data: {
- thingList: [
- {
- itemType: 1,
- id: deviceId,
- },
- ],
- },
- })
+ axios
+ .get("https://" + this.httpHost + "/v2/device/thing", {
+ headers: {
+ Authorization: "Bearer " + this.aToken,
+ "Content-Type": "application/json",
+ Host: this.httpHost,
+ "X-CK-Appid": constants.appId,
+ "X-CK-Nonce": Math.random().toString(36).substr(2, 8),
+ },
+ })
.then(res => {
let body = res.data;
if (
- !body.hasOwnProperty("data") ||
!body.hasOwnProperty("error") ||
(body.hasOwnProperty("error") && body.error !== 0)
) {
throw JSON.stringify(body, null, 2);
}
- if (body.data.thingList && body.data.thingList.length === 1) {
- resolve(body.data.thingList[0].itemData);
- } else {
- throw "device not found in eWeLink";
+ let deviceList = [];
+ if (body.data.thingList && body.data.thingList.length > 0) {
+ body.data.thingList.forEach(device =>
+ deviceList.push(device.itemData)
+ );
}
+ resolve(deviceList);
})
.catch(err => {
- if (err.hasOwnProperty("code") && ["ENOTFOUND", "ETIMEDOUT"].includes(err.code)) {
- this.log.warn("Unable to reach eWeLink. Retrying in 30 seconds.");
- this.delay().then(() => resolve(this.getDevice(deviceId)));
- } else {
- reject(err.message || err);
- }
+ reject(err);
});
});
}
-
- delay() {
- return new Promise(resolve => setTimeout(resolve, 30000));
- }
};
diff --git a/lib/eWeLinkLAN.js b/lib/eWeLinkLAN.js
index 567c372d..25baee53 100644
--- a/lib/eWeLinkLAN.js
+++ b/lib/eWeLinkLAN.js
@@ -1,18 +1,19 @@
/* jshint esversion: 9, -W030, node: true */
"use strict";
const axios = require("axios"),
- cns = require("./constants"),
+ constants = require("./constants"),
crypto = require("crypto"),
dns = require("node-dns-sd"),
eventemitter = require("events");
module.exports = class eWeLinkLAN {
constructor(config, log, devices) {
+ this.config = config;
this.log = log;
this.devices = devices;
- this.ipOverrides = config.ipOverride || {};
- this.deviceMap = new Map();
+ this.ipOverrides = this.config.ipOverride || {};
+ let deviceMap = new Map();
devices.forEach(device => {
- this.deviceMap.set(device.deviceid, {
+ deviceMap.set(device.deviceid, {
apiKey: device.devicekey,
online: this.ipOverrides.hasOwnProperty(device.deviceid) ? true : false,
ip: this.ipOverrides.hasOwnProperty(device.deviceid)
@@ -20,8 +21,9 @@ module.exports = class eWeLinkLAN {
: null,
});
});
- this.debug = config.debug || false;
- this.debugReqRes = config.debugReqRes || false;
+ this.deviceMap = deviceMap;
+ this.debug = this.config.debug || false;
+ this.debugReqRes = this.config.debugReqRes || false;
this.emitter = new eventemitter();
}
getHosts() {
@@ -34,7 +36,9 @@ module.exports = class eWeLinkLAN {
let onlineCount = 0;
res.forEach(device => {
let d,
- deviceId = device.fqdn.replace("._ewelink._tcp.local", "").replace("eWeLink_", "");
+ deviceId = device.fqdn
+ .replace("._ewelink._tcp.local", "")
+ .replace("eWeLink_", "");
if ((d = this.deviceMap.get(deviceId))) {
if (!this.ipOverrides.hasOwnProperty(deviceId)) {
this.deviceMap.set(deviceId, {
@@ -51,7 +55,9 @@ module.exports = class eWeLinkLAN {
count: onlineCount,
});
})
- .catch(err => reject(err));
+ .catch(err => {
+ reject(err);
+ });
});
}
startMonitor() {
@@ -73,44 +79,64 @@ module.exports = class eWeLinkLAN {
.createHash("md5")
.update(Buffer.from(deviceInfo.apiKey, "utf8"))
.digest(),
- dText = crypto.createDecipheriv("aes-128-cbc", key, Buffer.from(rdata.iv, "base64")),
+ dText = crypto.createDecipheriv(
+ "aes-128-cbc",
+ key,
+ Buffer.from(rdata.iv, "base64")
+ ),
pText = Buffer.concat([
dText.update(Buffer.from(data, "base64")),
dText.final(),
]).toString("utf8"),
params;
- if (packet.address !== deviceInfo.ip && !this.ipOverrides.hasOwnProperty(rdata.id)) {
+ if (
+ packet.address !== deviceInfo.ip &&
+ !this.ipOverrides.hasOwnProperty(rdata.id)
+ ) {
this.deviceMap.set(rdata.id, {
apiKey: deviceInfo.apiKey,
online: true,
ip: packet.address,
});
if (this.debug) {
- this.log.warn("[%s] updating IP address to [%s].", rdata.id, packet.address);
+ this.log.warn(
+ "[%s] updating IP address to [%s].",
+ rdata.id,
+ packet.address
+ );
}
}
try {
params = JSON.parse(pText);
} catch (e) {
- this.log.warn("[%s] An error occured reading the LAN message [%s]", rdata.id, e);
+ this.log.warn(
+ "[%s] An error occured reading the LAN message [%s]",
+ rdata.id,
+ e
+ );
return;
}
for (let param in params) {
if (params.hasOwnProperty(param)) {
- if (!cns.paramsToKeep.includes(param.replace(/[0-9]/g, ""))) {
+ if (
+ !constants.paramsToKeep.includes(param.replace(/[0-9]/g, ""))
+ ) {
delete params[param];
}
}
}
if (Object.keys(params).length > 0) {
params.updateSource = "LAN";
- params.online = true;
let returnTemplate = {
deviceid: rdata.id,
+ action: "update",
params,
};
if (this.debugReqRes) {
- let msg = JSON.stringify(returnTemplate, null, 2).replace(rdata.id, "**hidden**");
+ let msg = JSON.stringify(returnTemplate, null, 2).replace(
+ rdata.id,
+ "**hidden**"
+ );
this.log("LAN message received.\n%s", msg);
} else if (this.debug) {
this.log("LAN message received.");
@@ -123,8 +149,12 @@ module.exports = class eWeLinkLAN {
return new Promise((resolve, reject) => {
dns
.startMonitoring()
- .then(() => resolve())
- .catch(err => reject(err));
+ .then(() => {
+ resolve();
+ })
+ .catch(err => {
+ reject(err);
+ });
});
}
sendUpdate(json) {
@@ -145,13 +175,17 @@ module.exports = class eWeLinkLAN {
throw "plugin does not support lan mode for this device yet - feel free to create a github issue";
}
if ((apiKey = this.deviceMap.get(json.deviceid).apiKey)) {
- let key = crypto.createHash("md5").update(Buffer.from(apiKey, "utf8")).digest(),
+ let key = crypto
+ .createHash("md5")
+ .update(Buffer.from(apiKey, "utf8"))
+ .digest(),
iv = crypto.randomBytes(16),
enc = crypto.createCipheriv("aes-128-cbc", key, iv),
data = {
- data: Buffer.concat([enc.update(JSON.stringify(params)), enc.final()]).toString(
- "base64"
- ),
+ data: Buffer.concat([
+ enc.update(JSON.stringify(params)),
+ enc.final(),
+ ]).toString("base64"),
deviceid: json.deviceid,
encrypt: true,
iv: iv.toString("base64"),
@@ -163,13 +197,20 @@ module.exports = class eWeLinkLAN {
.replace(json.apikey, "**hidden**")
.replace(json.apikey, "**hidden**")
.replace(json.deviceid, "**hidden**");
- this.log.warn("LAN message sent. This text is yellow for clarity.\n%s", msg);
+ this.log.warn(
+ "LAN message sent. This text is yellow for clarity.\n%s",
+ msg
+ );
} else if (this.debug) {
this.log("LAN message sent.");
}
axios({
method: "post",
- url: "http://" + this.deviceMap.get(json.deviceid).ip + ":8081/zeroconf/" + suffix,
+ url:
+ "http://" +
+ this.deviceMap.get(json.deviceid).ip +
+ ":8081/zeroconf/" +
+ suffix,
headers: {
Accept: "application/json",
"Content-Type": "application/json",
@@ -182,7 +223,9 @@ module.exports = class eWeLinkLAN {
}
throw res.data;
})
- .catch(err => reject(err));
+ .catch(err => {
+ reject(err);
+ });
}
});
}
diff --git a/lib/eWeLinkWS.js b/lib/eWeLinkWS.js
index 29d265cc..56fbeb64 100644
--- a/lib/eWeLinkWS.js
+++ b/lib/eWeLinkWS.js
@@ -1,7 +1,7 @@
/* jshint esversion: 9, -W030, node: true */
"use strict";
const axios = require("axios"),
- cns = require("./constants"),
+ constants = require("./constants"),
eventemitter = require("events"),
ws = require("ws");
module.exports = class eWeLinkWS {
@@ -21,13 +21,14 @@ module.exports = class eWeLinkWS {
return new Promise((resolve, reject) => {
axios({
method: "post",
- url: "https://" + this.httpHost.replace("-api", "-disp") + "/dispatch/app",
+ url:
+ "https://" + this.httpHost.replace("-api", "-disp") + "/dispatch/app",
headers: {
Authorization: "Bearer " + this.aToken,
"Content-Type": "application/json",
},
data: {
- appid: cns.appId,
+ appid: constants.appId,
nonce: Math.random().toString(36).substr(2, 8),
ts: Math.floor(new Date().getTime() / 1000),
version: 8,
@@ -45,12 +46,7 @@ module.exports = class eWeLinkWS {
resolve(body.domain);
})
.catch(err => {
- if (err.hasOwnProperty("code") && ["ENOTFOUND", "ETIMEDOUT"].includes(err.code)) {
- this.log.warn("Unable to reach eWeLink. Retrying in 30 seconds.");
- this.delay().then(() => resolve(this.getDevices()));
- } else {
- reject(err.message || err);
- }
+ reject(err);
});
});
}
@@ -61,7 +57,7 @@ module.exports = class eWeLinkWS {
let payload = {
action: "userOnline",
apikey: this.apiKey,
- appid: cns.appId,
+ appid: constants.appId,
at: this.aToken,
nonce: Math.random().toString(36).substr(2, 8),
sequence: Math.floor(new Date()),
@@ -74,60 +70,91 @@ module.exports = class eWeLinkWS {
let msg = JSON.stringify(payload, null, 2)
.replace(this.aToken, "**hidden**")
.replace(this.apiKey, "**hidden**");
- this.log.warn("Sending WS login request. This text is yellow for clarity.\n%s", msg);
+ this.log.warn(
+ "Sending WS login request. This text is yellow for clarity.\n%s",
+ msg
+ );
} else if (this.debug) {
this.log("Sending WS login request.");
}
});
this.ws.on("message", m => {
- if (m === "pong") return;
- let device,
- onlineStatus = true;
+ if (m === "pong") {
+ return;
+ }
+ let device;
try {
device = JSON.parse(m);
- } catch (err) {
- this.log.warn("An error occured reading the WS message [%s]", err);
+ } catch (e) {
+ this.log.warn(
+ "An error occured reading the web socket message [%s]",
+ e
+ );
return;
}
- //*** for heartbeat response ***\\
+ // for requestUpdate response
+ if (
+ device.hasOwnProperty("deviceid") &&
+ device.hasOwnProperty("params") &&
+ device.hasOwnProperty("error") &&
+ device.error === 0
+ ) {
+ device.action = "update";
+ } else if (
+ device.hasOwnProperty("deviceid") &&
+ device.hasOwnProperty("error") &&
+ device.error === 504
+ ) {
+ device.action = "sysmsg";
+ device.params = {
+ online: false,
+ };
+ }
+ // for external updates
if (
device.hasOwnProperty("config") &&
device.config.hb &&
device.config.hbInterval &&
!this.hbInterval
) {
- this.hbInterval = setInterval(
- () => this.ws.send("ping"),
- (device.config.hbInterval + 7) * 1000
- );
- return;
- }
- if (!device.hasOwnProperty("params")) device.params = {};
- //*** for requestUpdate response ***\\
- if (device.hasOwnProperty("deviceid") && device.hasOwnProperty("error")) {
- device.action = "update";
- onlineStatus = device.error === 0;
- }
- //*** for all updates including above ***\\
- if (device.hasOwnProperty("action")) {
+ this.hbInterval = setInterval(() => {
+ this.ws.send("ping");
+ }, (device.config.hbInterval + 7) * 1000);
+ } else if (device.hasOwnProperty("action")) {
switch (device.action) {
- case "update":
case "sysmsg":
- if (device.action === "sysmsg" && device.params.hasOwnProperty("online")) {
- onlineStatus = device.params.online;
+ device.params.updateSource = "WS";
+ let returnTemplate = {
+ deviceid: device.deviceid,
+ action: "sysmsg",
+ params: device.params,
+ };
+ if (this.debugReqRes) {
+ let msg = JSON.stringify(returnTemplate, null, 2).replace(
+ device.deviceid,
+ "**hidden**"
+ );
+ this.log("WS message received.\n%s", msg);
+ } else if (this.debug) {
+ this.log("WS message received.");
}
+ this.emitter.emit("update", returnTemplate);
+ break;
+ case "update":
for (let param in device.params) {
if (device.params.hasOwnProperty(param)) {
- if (!cns.paramsToKeep.includes(param.replace(/[0-9]/g, ""))) {
+ if (
+ !constants.paramsToKeep.includes(param.replace(/[0-9]/g, ""))
+ ) {
delete device.params[param];
}
}
}
- device.params.online = onlineStatus;
- device.params.updateSource = "WS";
if (Object.keys(device.params).length > 0) {
+ device.params.updateSource = "WS";
let returnTemplate = {
deviceid: device.deviceid,
+ action: "update",
params: device.params,
};
if (this.debugReqRes) {
@@ -146,7 +173,8 @@ module.exports = class eWeLinkWS {
return;
default:
this.log.warn(
- "[%s] WS message has unknown action.\n" + JSON.stringify(device, null, 2),
+ "[%s] WS message has unknown action.\n" +
+ JSON.stringify(device, null, 2),
device.deviceid
);
return;
@@ -155,7 +183,9 @@ module.exports = class eWeLinkWS {
// *** Safe to ignore these messages *** \\
} else {
if (this.debug) {
- this.log.warn("WS unknown command received.\n" + JSON.stringify(device, null, 2));
+ this.log.warn(
+ "WS unknown command received.\n" + JSON.stringify(device, null, 2)
+ );
}
}
});
@@ -163,13 +193,16 @@ module.exports = class eWeLinkWS {
if (m === "Stopping Homebridge") {
this.log("Web socket gracefully closed.");
} else {
- this.log.warn("Web socket closed - [%s%s].", e, m ? " - " + m : "");
+ this.log.warn("Web socket closed - [%s - %s].", e, m);
if (e !== 1000) {
this.log("Web socket will try to reconnect in five seconds.");
- this.ws.removeAllListeners();
- setTimeout(() => this.login(), 5000);
+ setTimeout(() => {
+ this.login();
+ }, 5000);
} else {
- this.log("Please try restarting Homebridge so that this plugin can work again.");
+ this.log(
+ "Please try restarting Homebridge so that this plugin can work again."
+ );
}
}
this.wsIsOpen = false;
@@ -186,9 +219,13 @@ module.exports = class eWeLinkWS {
"Web socket will try to reconnect in five seconds then try the command again."
);
this.ws.removeAllListeners();
- setTimeout(() => this.login(), 5000);
+ setTimeout(() => {
+ this.login();
+ }, 5000);
} else {
- this.log.warn("If this was unexpected then please try restarting Homebridge.");
+ this.log.warn(
+ "If this was unexpected then please try restarting Homebridge."
+ );
}
});
}
@@ -203,7 +240,9 @@ module.exports = class eWeLinkWS {
};
let sendOperation = req => {
if (!this.wsIsOpen) {
- setTimeout(() => sendOperation(req), 280);
+ setTimeout(() => {
+ sendOperation(req);
+ }, 280);
return;
}
if (this.ws) {
@@ -213,7 +252,10 @@ module.exports = class eWeLinkWS {
.replace(json.apikey, "**hidden**")
.replace(json.apiKey, "**hidden**")
.replace(json.deviceid, "**hidden**");
- this.log.warn("WS message sent. This text is yellow for clarity.\n%s", msg);
+ this.log.warn(
+ "WS message sent. This text is yellow for clarity.\n%s",
+ msg
+ );
} else if (this.debug) {
this.log("WS message sent.");
}
@@ -226,7 +268,9 @@ module.exports = class eWeLinkWS {
setTimeout(sendOperation, this.delaySend, string);
this.delaySend += 280;
} else {
- this.log.warn("Web socket is currently reconnecting. Command will be resent.");
+ this.log.warn(
+ "Web socket is currently reconnecting. Command will be resent."
+ );
let interval,
waitToSend = req => {
if (this.wsIsOpen) {
@@ -249,7 +293,9 @@ module.exports = class eWeLinkWS {
},
sendOperation = req => {
if (!this.wsIsOpen) {
- setTimeout(() => sendOperation(req), 280);
+ setTimeout(() => {
+ sendOperation(req);
+ }, 280);
return;
}
if (this.ws) {
@@ -259,7 +305,10 @@ module.exports = class eWeLinkWS {
.replace(json.apikey, "**hidden**")
.replace(json.apiKey, "**hidden**")
.replace(json.deviceid, "**hidden**");
- this.log.warn("WS message sent. This text is yellow for clarity.\n%s", msg);
+ this.log.warn(
+ "WS message sent. This text is yellow for clarity.\n%s",
+ msg
+ );
} else if (this.debug) {
this.log("WS message sent.");
}
@@ -272,7 +321,9 @@ module.exports = class eWeLinkWS {
setTimeout(sendOperation, this.delaySend, string);
this.delaySend += 280;
} else {
- this.log.warn("Web socket is currently reconnecting. Command will be resent.");
+ this.log.warn(
+ "Web socket is currently reconnecting. Command will be resent."
+ );
let interval,
waitToSend = req => {
if (this.wsIsOpen) {
@@ -291,7 +342,4 @@ module.exports = class eWeLinkWS {
this.ws.close(1000, "Stopping Homebridge");
}
}
- delay() {
- return new Promise(resolve => setTimeout(resolve, 30000));
- }
};
From d6bb05899b2bd2851730bbabb987d08a6f11653f Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Wed, 16 Sep 2020 16:58:55 +0100
Subject: [PATCH 0165/3183] zb door sensor battery
---
lib/eWeLink.js | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 13c6d210..38a71cdf 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -2901,6 +2901,12 @@ class eWeLink {
try {
//*** credit @tasict ***\\
if (params.hasOwnProperty("battery")) {
+ if (
+ accessory.context.eweUIID === 3026 &&
+ (this.config.ZBDWBatt || false)
+ ) {
+ params.battery *= 10;
+ }
let batteryService =
accessory.getService(Service.BatteryService) ||
accessory.addService(Service.BatteryService);
From cf6c8ff3514ded399f341668ea6a7ea42203b849 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Wed, 16 Sep 2020 17:01:23 +0100
Subject: [PATCH 0166/3183] prettier line length
---
.prettierrc.json | 3 +-
lib/constants.js | 7 +-
lib/eWeLink.js | 1082 +++++++++++---------------------------------
lib/eWeLinkHTTP.js | 28 +-
lib/eWeLinkLAN.js | 59 +--
lib/eWeLinkWS.js | 50 +-
6 files changed, 298 insertions(+), 931 deletions(-)
diff --git a/.prettierrc.json b/.prettierrc.json
index d68aa739..87f5e5e8 100644
--- a/.prettierrc.json
+++ b/.prettierrc.json
@@ -1,3 +1,4 @@
{
- "arrowParens": "avoid"
+ "arrowParens": "avoid",
+ "printWidth": 100
}
diff --git a/lib/constants.js b/lib/constants.js
index d8892025..fe7fcb40 100644
--- a/lib/constants.js
+++ b/lib/constants.js
@@ -40,12 +40,7 @@ module.exports = {
devicesSensor: [102],
devicesSensorParams: ["switch", "battery"],
devicesThermostat: [15],
- devicesThermostatParams: [
- "currentTemperature",
- "currentHumidity",
- "switch",
- "masterSwitch",
- ],
+ devicesThermostatParams: ["currentTemperature", "currentHumidity", "switch", "masterSwitch"],
devicesFan: [34],
devicesFanParams: ["switches", "light", "fan", "speed"],
devicesOutlet: [32],
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 38a71cdf..10049c96 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -13,15 +13,9 @@ class eWeLink {
constructor(log, config, api) {
if (!log || !api || !config) return;
if (!config.username || !config.password || !config.countryCode) {
- log.error(
- "**************** Cannot load homebridge-ewelink ****************"
- );
- log.error(
- "Your eWeLink credentials are missing from the Homebridge config."
- );
- log.error(
- "****************************************************************"
- );
+ log.error("**************** Cannot load homebridge-ewelink ****************");
+ log.error("Your eWeLink credentials are missing from the Homebridge config.");
+ log.error("****************************************************************");
return;
}
this.log = log;
@@ -57,22 +51,11 @@ class eWeLink {
//*** Get device IP addresses for LAN mode ***\\
this.httpDevices = res
.filter(
- device =>
- device.hasOwnProperty("extra") &&
- device.extra.hasOwnProperty("uiid")
+ device => device.hasOwnProperty("extra") && device.extra.hasOwnProperty("uiid")
)
- .filter(
- device =>
- !(this.config.hideDevFromHB || "").includes(device.deviceid)
- );
- this.lanClient = new eWeLinkLAN(
- this.config,
- this.log,
- this.httpDevices
- );
- this.httpDevices.forEach(device =>
- this.devicesInEwe.set(device.deviceid, device)
- );
+ .filter(device => !(this.config.hideDevFromHB || "").includes(device.deviceid));
+ this.lanClient = new eWeLinkLAN(this.config, this.log, this.httpDevices);
+ this.httpDevices.forEach(device => this.devicesInEwe.set(device.deviceid, device));
return this.lanClient.getHosts();
})
.then(res => {
@@ -89,9 +72,7 @@ class eWeLink {
Object.keys(this.httpDevices).length === 0 &&
Object.keys(this.lanDevices).length === 0
) {
- Array.from(this.devicesInHB.values()).forEach(a =>
- this.removeAccessory(a)
- );
+ Array.from(this.devicesInHB.values()).forEach(a => this.removeAccessory(a));
this.devicesInHB.clear();
this.log.warn("******* Not loading homebridge-ewelink *******");
this.log.warn("No devices were found in your eWeLink account.");
@@ -101,11 +82,7 @@ class eWeLink {
//*** Make a map of custom groups from Homebridge config ***\\
if (Object.keys(this.config.groups || []).length > 0) {
this.config.groups
- .filter(
- g =>
- g.hasOwnProperty("type") &&
- cns.allowedGroups.includes(g.type)
- )
+ .filter(g => g.hasOwnProperty("type") && cns.allowedGroups.includes(g.type))
.filter(
g =>
g.hasOwnProperty("deviceId") &&
@@ -157,13 +134,9 @@ class eWeLink {
})();
})
.catch(err => {
- this.log.error(
- "************** Cannot load homebridge-ewelink **************"
- );
+ this.log.error("************** Cannot load homebridge-ewelink **************");
this.log.error(err);
- this.log.error(
- "************************************************************"
- );
+ this.log.error("************************************************************");
if (this.lanClient) this.lanClient.closeConnection();
if (this.wsClient) this.wsClient.closeConnection();
});
@@ -233,9 +206,7 @@ class eWeLink {
}
} else if (cns.devicesRFBridge.includes(device.extra.uiid)) {
this.addAccessory(device, device.deviceid + "SW0", "rf_pri");
- if (
- Object.keys((device.tags && device.tags.zyx_info) || []).length > 0
- ) {
+ if (Object.keys((device.tags && device.tags.zyx_info) || []).length > 0) {
for (let i = 1; i <= Object.keys(device.tags.zyx_info).length; i++) {
this.addAccessory(device, device.deviceid + "SW" + i, "rf_sub");
}
@@ -269,19 +240,12 @@ class eWeLink {
rfBridgeChange = false;
accessory
.getService(Service.AccessoryInformation)
- .setCharacteristic(
- Characteristic.FirmwareRevision,
- device.params.fwVersion
- );
- accessory.context.reachableWAN =
- accessory.context.eweUIID !== 102 ? device.online : true;
- accessory.context.reachableLAN =
- this.lanDevices.get(device.deviceid).online || false;
+ .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion);
+ accessory.context.reachableWAN = accessory.context.eweUIID !== 102 ? device.online : true;
+ accessory.context.reachableLAN = this.lanDevices.get(device.deviceid).online || false;
accessory.context.inUse = false;
let str = accessory.context.reachableLAN
- ? "and locally with IP [" +
- this.lanDevices.get(device.deviceid).ip +
- "]"
+ ? "and locally with IP [" + this.lanDevices.get(device.deviceid).ip + "]"
: "but LAN mode unavailable as unsupported/shared device";
this.log("[%s] found in eWeLink %s.", accessory.displayName, str);
this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
@@ -289,11 +253,7 @@ class eWeLink {
for (let i = 1; i <= accessory.context.channelCount; i++) {
if (!this.devicesInHB.has(device.deviceid + "SW" + i)) {
if (cns.devicesHideable.includes(accessory.context.type)) {
- if (
- (this.config.hideFromHB || "").includes(
- device.deviceid + "SW" + i
- )
- ) {
+ if ((this.config.hideFromHB || "").includes(device.deviceid + "SW" + i)) {
continue;
} else {
this.addAccessory(device, device.deviceid + "SW" + i, "switch");
@@ -302,9 +262,7 @@ class eWeLink {
}
let oAccessory = this.devicesInHB.get(device.deviceid + "SW" + i);
if (
- (this.config.hideFromHB || "").includes(
- device.deviceid + "SW" + i
- ) &&
+ (this.config.hideFromHB || "").includes(device.deviceid + "SW" + i) &&
cns.devicesHideable.includes(accessory.context.type)
) {
this.removeAccessory(oAccessory);
@@ -318,13 +276,9 @@ class eWeLink {
}
oAccessory
.getService(Service.AccessoryInformation)
- .setCharacteristic(
- Characteristic.FirmwareRevision,
- device.params.fwVersion
- );
+ .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion);
oAccessory.context.reachableWAN = device.online;
- oAccessory.context.reachableLAN =
- this.lanDevices.get(device.deviceid).online || false;
+ oAccessory.context.reachableLAN = this.lanDevices.get(device.deviceid).online || false;
this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory);
}
}
@@ -349,18 +303,12 @@ class eWeLink {
);
}
} else {
- this.log.warn(
- "[%s] cannot be initialised as it wasn't found in Homebridge.",
- device.name
- );
+ this.log.warn("[%s] cannot be initialised as it wasn't found in Homebridge.", device.name);
}
}
addAccessory(device, hbDeviceId, type) {
let switchNumber = hbDeviceId.substr(-1).toString(),
- newDeviceName =
- type === "rf_sub"
- ? device.tags.zyx_info[switchNumber - 1].name
- : device.name,
+ newDeviceName = type === "rf_sub" ? device.tags.zyx_info[switchNumber - 1].name : device.name,
channelCount =
type === "rf_pri"
? Object.keys((device.tags && device.tags.zyx_info) || []).length
@@ -378,10 +326,7 @@ class eWeLink {
if ((this.config.nameOverride || {}).hasOwnProperty(hbDeviceId)) {
newDeviceName = this.config.nameOverride[hbDeviceId];
}
- const accessory = new Accessory(
- newDeviceName,
- UUIDGen.generate(hbDeviceId).toString()
- );
+ const accessory = new Accessory(newDeviceName, UUIDGen.generate(hbDeviceId).toString());
try {
accessory
.getService(Service.AccessoryInformation)
@@ -391,10 +336,7 @@ class eWeLink {
Characteristic.Model,
device.productModel + " (" + device.extra.model + ")"
)
- .setCharacteristic(
- Characteristic.FirmwareRevision,
- device.params.fwVersion
- )
+ .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion)
.setCharacteristic(Characteristic.Identify, false);
accessory.context = {
hbDeviceId,
@@ -410,18 +352,11 @@ class eWeLink {
case "valve":
["A", "B"].forEach(v => {
accessory
- .addService(
- Service.Valve,
- "Valve " + v,
- "valve" + v.toLowerCase()
- )
+ .addService(Service.Valve, "Valve " + v, "valve" + v.toLowerCase())
.setCharacteristic(Characteristic.Active, 0)
.setCharacteristic(Characteristic.InUse, 0)
.setCharacteristic(Characteristic.ValveType, 1)
- .setCharacteristic(
- Characteristic.SetDuration,
- this.config.valveTimeLength || 120
- )
+ .setCharacteristic(Characteristic.SetDuration, this.config.valveTimeLength || 120)
.addCharacteristic(Characteristic.RemainingDuration);
});
break;
@@ -456,8 +391,7 @@ class eWeLink {
case "thermostat":
if (!this.config.hideTHSwitch) accessory.addService(Service.Switch);
accessory.addService(Service.TemperatureSensor);
- if (device.params.sensorType !== "DS18B20")
- accessory.addService(Service.HumiditySensor);
+ if (device.params.sensorType !== "DS18B20") accessory.addService(Service.HumiditySensor);
break;
case "outlet":
accessory.addService(Service.Outlet);
@@ -503,9 +437,7 @@ class eWeLink {
break;
case "rf_sub":
accessory.context.rfChls = {};
- switch (
- device.tags.zyx_info[parseInt(switchNumber) - 1].remote_type
- ) {
+ switch (device.tags.zyx_info[parseInt(switchNumber) - 1].remote_type) {
case "1":
case "2":
case "3":
@@ -525,52 +457,46 @@ class eWeLink {
);
}
let mAccessory = this.devicesInHB.get(device.deviceid + "SW0");
- device.tags.zyx_info[parseInt(switchNumber) - 1].buttonName.forEach(
- button => {
- let rfData;
- Object.entries(button).forEach(
- ([k, v]) =>
- (rfData = {
- rfChan: k,
- name: v,
- })
- );
- accessory.context.rfChls[rfData.rfChan] = rfData.name;
- mAccessory.context.rfChlMap[rfData.rfChan] = switchNumber;
- switch (accessory.context.sensorType) {
- case "button":
- accessory.addService(
- Service.Switch,
- rfData.name,
- "switch" + rfData.rfChan
- );
- break;
- case "water":
- accessory.addService(Service.LeakSensor);
- break;
- case "fire":
- case "smoke":
- accessory.addService(Service.SmokeSensor);
- break;
- case "co":
- accessory.addService(Service.CarbonMonoxideSensor);
- break;
- case "co2":
- accessory.addService(Service.CarbonDioxideSensor);
- break;
- case "contact":
- accessory.addService(Service.ContactSensor);
- break;
- case "occupancy":
- accessory.addService(Service.OccupancySensor);
- break;
- default:
- accessory.addService(Service.MotionSensor);
- break;
- }
- this.devicesInHB.set(mAccessory.context.hbDeviceId, mAccessory);
+ device.tags.zyx_info[parseInt(switchNumber) - 1].buttonName.forEach(button => {
+ let rfData;
+ Object.entries(button).forEach(
+ ([k, v]) =>
+ (rfData = {
+ rfChan: k,
+ name: v,
+ })
+ );
+ accessory.context.rfChls[rfData.rfChan] = rfData.name;
+ mAccessory.context.rfChlMap[rfData.rfChan] = switchNumber;
+ switch (accessory.context.sensorType) {
+ case "button":
+ accessory.addService(Service.Switch, rfData.name, "switch" + rfData.rfChan);
+ break;
+ case "water":
+ accessory.addService(Service.LeakSensor);
+ break;
+ case "fire":
+ case "smoke":
+ accessory.addService(Service.SmokeSensor);
+ break;
+ case "co":
+ accessory.addService(Service.CarbonMonoxideSensor);
+ break;
+ case "co2":
+ accessory.addService(Service.CarbonDioxideSensor);
+ break;
+ case "contact":
+ accessory.addService(Service.ContactSensor);
+ break;
+ case "occupancy":
+ accessory.addService(Service.OccupancySensor);
+ break;
+ default:
+ accessory.addService(Service.MotionSensor);
+ break;
}
- );
+ this.devicesInHB.set(mAccessory.context.hbDeviceId, mAccessory);
+ });
break;
case "zb_sub": //*** credit @tasict ***\\
accessory.addService(Service.BatteryService);
@@ -608,9 +534,7 @@ class eWeLink {
throw "device is not supported by this plugin. Please create an issue on GitHub";
}
this.devicesInHB.set(hbDeviceId, accessory);
- this.api.registerPlatformAccessories("homebridge-ewelink", "eWeLink", [
- accessory,
- ]);
+ this.api.registerPlatformAccessories("homebridge-ewelink", "eWeLink", [accessory]);
this.configureAccessory(accessory);
this.log("[%s] has been added to Homebridge.", newDeviceName);
} catch (err) {
@@ -629,33 +553,21 @@ class eWeLink {
.getService("Valve " + v)
.getCharacteristic(Characteristic.Active)
.on("set", (value, callback) =>
- this.internalValveUpdate(
- accessory,
- "Valve " + v,
- value,
- callback
- )
+ this.internalValveUpdate(accessory, "Valve " + v, value, callback)
);
accessory
.getService("Valve " + v)
.getCharacteristic(Characteristic.SetDuration)
.on("set", (value, callback) => {
if (
- accessory
- .getService("Valve " + v)
- .getCharacteristic(Characteristic.InUse).value
+ accessory.getService("Valve " + v).getCharacteristic(Characteristic.InUse).value
) {
accessory
.getService("Valve " + v)
- .updateCharacteristic(
- Characteristic.RemainingDuration,
- value
- );
+ .updateCharacteristic(Characteristic.RemainingDuration, value);
clearTimeout(accessory.getService("Valve " + v).timer);
accessory.getService("Valve " + v).timer = setTimeout(() => {
- accessory
- .getService("Valve " + v)
- .setCharacteristic(Characteristic.Active, 0);
+ accessory.getService("Valve " + v).setCharacteristic(Characteristic.Active, 0);
}, value * 1000);
}
callback();
@@ -666,9 +578,7 @@ class eWeLink {
accessory
.getService(Service.WindowCovering)
.getCharacteristic(Characteristic.TargetPosition)
- .on("set", (value, callback) =>
- this.internalBlindUpdate(accessory, value, callback)
- )
+ .on("set", (value, callback) => this.internalBlindUpdate(accessory, value, callback))
.setProps({
minStep: 100,
});
@@ -677,17 +587,13 @@ class eWeLink {
accessory
.getService(Service.GarageDoorOpener)
.getCharacteristic(Characteristic.TargetDoorState)
- .on("set", (value, callback) =>
- this.internalGarageUpdate(accessory, value, callback)
- );
+ .on("set", (value, callback) => this.internalGarageUpdate(accessory, value, callback));
break;
case "lock":
accessory
.getService(Service.LockMechanism)
.getCharacteristic(Characteristic.LockTargetState)
- .on("set", (value, callback) =>
- this.internalLockUpdate(accessory, value, callback)
- );
+ .on("set", (value, callback) => this.internalLockUpdate(accessory, value, callback));
break;
case "fan":
accessory
@@ -737,9 +643,7 @@ class eWeLink {
if (accessory.getService(Service.HumiditySensor)) {
dataToAdd.humidity = accessory
.getService(Service.HumiditySensor)
- .getCharacteristic(
- Characteristic.CurrentRelativeHumidity
- ).value;
+ .getCharacteristic(Characteristic.CurrentRelativeHumidity).value;
}
accessory.eveLogger.addEntry(dataToAdd);
}, 300000);
@@ -748,9 +652,7 @@ class eWeLink {
accessory
.getService(Service.Outlet)
.getCharacteristic(Characteristic.On)
- .on("set", (value, callback) =>
- this.internalOutletUpdate(accessory, value, callback)
- );
+ .on("set", (value, callback) => this.internalOutletUpdate(accessory, value, callback));
accessory.log = this.log;
accessory.eveLogger = new EveHistoryService("energy", accessory, {
storage: "fs",
@@ -769,15 +671,12 @@ class eWeLink {
};
}
corrInterval.setCorrectingInterval(() => {
- let isOn = accessory
- .getService(Service.Outlet)
- .getCharacteristic(Characteristic.On).value,
+ let isOn = accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On)
+ .value,
currentWatt = isOn
? accessory
.getService(Service.Outlet)
- .getCharacteristic(
- EveService.Characteristics.CurrentConsumption
- ).value
+ .getCharacteristic(EveService.Characteristics.CurrentConsumption).value
: 0;
if (accessory.eveLogger.isHistoryLoaded()) {
accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData();
@@ -792,8 +691,7 @@ class eWeLink {
});
} else {
accessory.context.totalEnergy =
- accessory.context.totalEnergyTemp +
- (currentWatt * 10) / 3600 / 1000;
+ accessory.context.totalEnergyTemp + (currentWatt * 10) / 3600 / 1000;
accessory.eveLogger.setExtraPersistedData({
totalenergy: accessory.context.totalEnergy,
lastReset: 0,
@@ -801,8 +699,7 @@ class eWeLink {
}
accessory.context.totalEnergytemp = 0;
} else {
- accessory.context.totalEnergyTemp +=
- (currentWatt * 10) / 3600 / 1000;
+ accessory.context.totalEnergyTemp += (currentWatt * 10) / 3600 / 1000;
accessory.context.totalEnergy = accessory.context.totalEnergyTemp;
}
accessory.eveLogger.addEntry({
@@ -816,8 +713,7 @@ class eWeLink {
.on("get", callback => {
accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData();
if (accessory.context.extraPersistedData !== undefined) {
- accessory.context.totalEnergy =
- accessory.context.extraPersistedData.totalPower;
+ accessory.context.totalEnergy = accessory.context.extraPersistedData.totalPower;
}
callback(null, accessory.context.totalEnergy);
});
@@ -836,8 +732,7 @@ class eWeLink {
.on("get", callback => {
accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData();
if (accessory.context.extraPersistedData !== undefined) {
- accessory.context.lastReset =
- accessory.context.extraPersistedData.lastReset;
+ accessory.context.lastReset = accessory.context.extraPersistedData.lastReset;
}
callback(null, accessory.context.lastReset);
});
@@ -846,17 +741,13 @@ class eWeLink {
accessory
.getService(Service.Outlet)
.getCharacteristic(Characteristic.On)
- .on("set", (value, callback) =>
- this.internalUSBUpdate(accessory, value, callback)
- );
+ .on("set", (value, callback) => this.internalUSBUpdate(accessory, value, callback));
break;
case "scm":
accessory
.getService(Service.Switch)
.getCharacteristic(Characteristic.On)
- .on("set", (value, callback) =>
- this.internalSCMUpdate(accessory, value, callback)
- );
+ .on("set", (value, callback) => this.internalSCMUpdate(accessory, value, callback));
break;
case "light":
accessory
@@ -872,9 +763,8 @@ class eWeLink {
.on("set", (value, callback) => {
if (value > 0) {
if (
- !accessory
- .getService(Service.Lightbulb)
- .getCharacteristic(Characteristic.On).value
+ !accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On)
+ .value
) {
this.internalLightbulbUpdate(accessory, true, function () {
return;
@@ -885,18 +775,15 @@ class eWeLink {
this.internalLightbulbUpdate(accessory, false, callback);
}
});
- } else if (
- cns.devicesColourable.includes(accessory.context.eweUIID)
- ) {
+ } else if (cns.devicesColourable.includes(accessory.context.eweUIID)) {
accessory
.getService(Service.Lightbulb)
.getCharacteristic(Characteristic.Brightness)
.on("set", (value, callback) => {
if (value > 0) {
if (
- !accessory
- .getService(Service.Lightbulb)
- .getCharacteristic(Characteristic.On).value
+ !accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On)
+ .value
) {
this.internalLightbulbUpdate(accessory, true, function () {
return;
@@ -923,24 +810,18 @@ class eWeLink {
accessory
.getService(Service.Switch)
.getCharacteristic(Characteristic.On)
- .on("set", (value, callback) =>
- this.internalSwitchUpdate(accessory, value, callback)
- );
+ .on("set", (value, callback) => this.internalSwitchUpdate(accessory, value, callback));
break;
case "rf_sub":
accessory.context.rfChls = accessory.context.rfChls || {};
if (accessory.context.sensorType === "button") {
Object.entries(accessory.context.rfChls).forEach(([k, v]) => {
- accessory
- .getService(v)
- .updateCharacteristic(Characteristic.On, false);
+ accessory.getService(v).updateCharacteristic(Characteristic.On, false);
accessory
.getService(v)
.getCharacteristic(Characteristic.On)
.on("set", (value, callback) => {
- value
- ? this.internalRFDeviceUpdate(accessory, k, callback)
- : callback();
+ value ? this.internalRFDeviceUpdate(accessory, k, callback) : callback();
});
});
}
@@ -961,8 +842,7 @@ class eWeLink {
.getCharacteristic(Characteristic.CurrentTemperature).value,
humidity: accessory
.getService(Service.HumiditySensor)
- .getCharacteristic(Characteristic.CurrentRelativeHumidity)
- .value,
+ .getCharacteristic(Characteristic.CurrentRelativeHumidity).value,
};
accessory.eveLogger.addEntry(dataToAdd);
}, 300000);
@@ -971,20 +851,14 @@ class eWeLink {
}
this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
} catch (err) {
- this.log.warn(
- "[%s] could not be refreshed as %s.",
- accessory.displayName,
- err
- );
+ this.log.warn("[%s] could not be refreshed as %s.", accessory.displayName, err);
}
}
refreshAccessory(accessory, newParams) {
switch (accessory.context.type) {
case "valve":
if (
- Object.keys(newParams).some(v =>
- cns.devicesValveParams.includes(v)
- ) &&
+ Object.keys(newParams).some(v => cns.devicesValveParams.includes(v)) &&
Array.isArray(newParams.switches)
) {
this.externalValveUpdate(accessory, newParams);
@@ -992,9 +866,7 @@ class eWeLink {
return true;
case "blind":
if (
- Object.keys(newParams).some(v =>
- cns.devicesBlindParams.includes(v)
- ) &&
+ Object.keys(newParams).some(v => cns.devicesBlindParams.includes(v)) &&
Array.isArray(newParams.switches)
) {
this.externalBlindUpdate(accessory, newParams);
@@ -1002,48 +874,34 @@ class eWeLink {
return true;
case "garage":
if (
- Object.keys(newParams).some(v =>
- cns.devicesGarageParams.includes(v)
- ) &&
+ Object.keys(newParams).some(v => cns.devicesGarageParams.includes(v)) &&
Array.isArray(newParams.switches)
) {
this.externalGarageUpdate(accessory, newParams);
}
return true;
case "lock":
- if (
- Object.keys(newParams).some(v => cns.devicesLockParams.includes(v))
- ) {
+ if (Object.keys(newParams).some(v => cns.devicesLockParams.includes(v))) {
this.externalLockUpdate(accessory, newParams);
}
return true;
case "sensor":
- if (
- Object.keys(newParams).some(v => cns.devicesSensorParams.includes(v))
- ) {
+ if (Object.keys(newParams).some(v => cns.devicesSensorParams.includes(v))) {
this.externalSensorUpdate(accessory, newParams);
}
return true;
case "fan":
- if (
- Object.keys(newParams).some(v => cns.devicesFanParams.includes(v))
- ) {
+ if (Object.keys(newParams).some(v => cns.devicesFanParams.includes(v))) {
this.externalFanUpdate(accessory, newParams);
}
return true;
case "thermostat":
- if (
- Object.keys(newParams).some(v =>
- cns.devicesThermostatParams.includes(v)
- )
- ) {
+ if (Object.keys(newParams).some(v => cns.devicesThermostatParams.includes(v))) {
this.externalThermostatUpdate(accessory, newParams);
}
return true;
case "outlet":
- if (
- Object.keys(newParams).some(v => cns.devicesOutletParams.includes(v))
- ) {
+ if (Object.keys(newParams).some(v => cns.devicesOutletParams.includes(v))) {
this.externalOutletUpdate(accessory, newParams);
}
return true;
@@ -1068,11 +926,7 @@ class eWeLink {
cns.devicesSingleSwitch.includes(accessory.context.eweUIID) &&
cns.devicesSingleSwitchLight.includes(accessory.context.eweModel)
) {
- if (
- Object.keys(newParams).some(v =>
- cns.devicesSingleSwitchLightParams.includes(v)
- )
- ) {
+ if (Object.keys(newParams).some(v => cns.devicesSingleSwitchLightParams.includes(v))) {
this.externalSingleLightUpdate(accessory, newParams);
}
} else if (
@@ -1080,9 +934,7 @@ class eWeLink {
cns.devicesMultiSwitchLight.includes(accessory.context.eweModel)
) {
if (
- Object.keys(newParams).some(v =>
- cns.devicesMultiSwitchLightParams.includes(v)
- ) &&
+ Object.keys(newParams).some(v => cns.devicesMultiSwitchLightParams.includes(v)) &&
Array.isArray(newParams.switches)
) {
this.externalMultiLightUpdate(accessory, newParams);
@@ -1091,18 +943,12 @@ class eWeLink {
return true;
case "switch":
if (cns.devicesSingleSwitch.includes(accessory.context.eweUIID)) {
- if (
- Object.keys(newParams).some(v =>
- cns.devicesSingleSwitchParams.includes(v)
- )
- ) {
+ if (Object.keys(newParams).some(v => cns.devicesSingleSwitchParams.includes(v))) {
this.externalSingleSwitchUpdate(accessory, newParams);
}
} else if (cns.devicesMultiSwitch.includes(accessory.context.eweUIID)) {
if (
- Object.keys(newParams).some(v =>
- cns.devicesMultiSwitchParams.includes(v)
- ) &&
+ Object.keys(newParams).some(v => cns.devicesMultiSwitchParams.includes(v)) &&
Array.isArray(newParams.switches)
) {
this.externalMultiSwitchUpdate(accessory, newParams);
@@ -1110,11 +956,7 @@ class eWeLink {
}
return true;
case "rf_pri":
- if (
- Object.keys(newParams).some(v =>
- cns.devicesRFBridgeParams.includes(v)
- )
- ) {
+ if (Object.keys(newParams).some(v => cns.devicesRFBridgeParams.includes(v))) {
this.externalRFDeviceUpdate(accessory, newParams);
}
return true;
@@ -1122,11 +964,7 @@ class eWeLink {
case "zb_pri":
return true;
case "zb_sub":
- if (
- Object.keys(newParams).some(v =>
- cns.devicesZBBridgeParams.includes(v)
- )
- ) {
+ if (Object.keys(newParams).some(v => cns.devicesZBBridgeParams.includes(v))) {
this.externalZBDeviceUpdate(accessory, newParams);
}
return true;
@@ -1137,16 +975,10 @@ class eWeLink {
removeAccessory(accessory) {
try {
this.devicesInHB.delete(accessory.context.hbDeviceId);
- this.api.unregisterPlatformAccessories("homebridge-ewelink", "eWeLink", [
- accessory,
- ]);
+ this.api.unregisterPlatformAccessories("homebridge-ewelink", "eWeLink", [accessory]);
this.log("[%s] has been removed from Homebridge.", accessory.displayName);
} catch (err) {
- this.log.warn(
- "[%s] needed to be removed but couldn't as %s.",
- accessory.displayName,
- err
- );
+ this.log.warn("[%s] needed to be removed but couldn't as %s.", accessory.displayName, err);
}
}
sendDeviceUpdate(accessory, params, callback) {
@@ -1167,10 +999,7 @@ class eWeLink {
callback("Device has failed to update");
}
};
- if (
- cns.devicesNonLAN.includes(accessory.context.eweUIID) ||
- !accessory.context.reachableLAN
- ) {
+ if (cns.devicesNonLAN.includes(accessory.context.eweUIID) || !accessory.context.reachableLAN) {
sendViaWS();
} else {
this.lanClient
@@ -1178,11 +1007,7 @@ class eWeLink {
.then(() => callback())
.catch(err => {
if (this.debug) {
- this.log.warn(
- "[%s] Reverting to web socket as %s.",
- accessory.displayName,
- err
- );
+ this.log.warn("[%s] Reverting to web socket as %s.", accessory.displayName, err);
}
sendViaWS();
});
@@ -1207,23 +1032,17 @@ class eWeLink {
accessory.context.reachableWAN ? "online" : "offline"
);
this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
- if (accessory.context.reachableWAN)
- this.wsClient.requestUpdate(accessory);
+ if (accessory.context.reachableWAN) this.wsClient.requestUpdate(accessory);
} else {
if (this.debug) {
- this.log(
- "[%s] Nothing to update from above WS message.",
- accessory.displayName
- );
+ this.log("[%s] Nothing to update from above WS message.", accessory.displayName);
}
}
}
if (!isX) {
for (let i = 1; i <= accessory.context.channelCount; i++) {
if (this.devicesInHB.has(device.deviceid + "SW" + i)) {
- let oAccessory = this.devicesInHB.get(
- device.deviceid + "SW" + i
- );
+ let oAccessory = this.devicesInHB.get(device.deviceid + "SW" + i);
oAccessory.context.reachableWAN = device.params.online;
this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory);
}
@@ -1237,25 +1056,13 @@ class eWeLink {
this.devicesInHB.get(device.deviceid + "SWX") ||
this.devicesInHB.get(device.deviceid + "SW0"))
) {
- if (
- device.params.updateSource === "WS" &&
- !accessory.context.reachableWAN
- ) {
+ if (device.params.updateSource === "WS" && !accessory.context.reachableWAN) {
accessory.context.reachableWAN = true;
- this.log(
- "[%s] has been reported [online] via [WS].",
- accessory.displayName
- );
+ this.log("[%s] has been reported [online] via [WS].", accessory.displayName);
}
- if (
- device.params.updateSource === "LAN" &&
- !accessory.context.reachableLAN
- ) {
+ if (device.params.updateSource === "LAN" && !accessory.context.reachableLAN) {
accessory.context.reachableLAN = true;
- this.log(
- "[%s] has been reported [online] via [LAN].",
- accessory.displayName
- );
+ this.log("[%s] has been reported [online] via [LAN].", accessory.displayName);
}
if (this.debug) {
this.log(
@@ -1296,28 +1103,19 @@ class eWeLink {
.updateCharacteristic(Characteristic.InUse, value);
switch (value) {
case 0:
- accessory
- .getService(valve)
- .updateCharacteristic(Characteristic.RemainingDuration, 0);
+ accessory.getService(valve).updateCharacteristic(Characteristic.RemainingDuration, 0);
clearTimeout(accessory.getService(valve).timer);
break;
case 1:
- let timer = accessory
- .getService(valve)
- .getCharacteristic(Characteristic.SetDuration).value;
- accessory
- .getService(valve)
- .updateCharacteristic(Characteristic.RemainingDuration, timer);
+ let timer = accessory.getService(valve).getCharacteristic(Characteristic.SetDuration)
+ .value;
+ accessory.getService(valve).updateCharacteristic(Characteristic.RemainingDuration, timer);
accessory.getService(valve).timer = setTimeout(() => {
- accessory
- .getService(valve)
- .setCharacteristic(Characteristic.Active, 0);
+ accessory.getService(valve).setCharacteristic(Characteristic.Active, 0);
}, timer * 1000);
break;
}
- params.switches = this.devicesInEwe.get(
- accessory.context.eweDeviceId
- ).params.switches;
+ params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
switch (valve) {
case "Valve A":
params.switches[0].switch = value ? "on" : "off";
@@ -1342,8 +1140,7 @@ class eWeLink {
params.switches[3].switch = "off";
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
- let str =
- "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -1357,10 +1154,7 @@ class eWeLink {
if (!(blindConfig = this.cusG.get(accessory.context.hbDeviceId))) {
throw "group config missing";
}
- if (
- blindConfig.type !== "blind" ||
- !["oneSwitch", "twoSwitch"].includes(blindConfig.setup)
- ) {
+ if (blindConfig.type !== "blind" || !["oneSwitch", "twoSwitch"].includes(blindConfig.setup)) {
throw "improper configuration";
}
let oldPos,
@@ -1382,9 +1176,7 @@ class eWeLink {
params.switch = "on";
break;
case "twoSwitch":
- params.switches = this.devicesInEwe.get(
- accessory.context.eweDeviceId
- ).params.switches;
+ params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
params.switches[0].switch = value === 100 ? "on" : "off";
params.switches[1].switch = value === 0 ? "on" : "off";
break;
@@ -1404,8 +1196,7 @@ class eWeLink {
callback();
}, parseInt(blindConfig.operationTime) * 100);
} catch (err) {
- let str =
- "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -1433,10 +1224,7 @@ class eWeLink {
newPos = value,
params = {},
delay = 0;
- if (
- sensorDefinition &&
- !(sAccessory = this.devicesInHB.get(garageConfig.sensorId + "SWX"))
- ) {
+ if (sensorDefinition && !(sAccessory = this.devicesInHB.get(garageConfig.sensorId + "SWX"))) {
throw "defined DW2 sensor doesn't exist";
}
if (sAccessory.context.type !== "sensor") {
@@ -1459,10 +1247,7 @@ class eWeLink {
if (garageConfig.setup === "oneSwitch" && [2, 3].includes(oldPos)) {
accessory
.getService(Service.GarageDoorOpener)
- .updateCharacteristic(
- Characteristic.CurrentDoorState,
- ((oldPos * 2) % 3) + 2
- );
+ .updateCharacteristic(Characteristic.CurrentDoorState, ((oldPos * 2) % 3) + 2);
delay = 1500;
}
setTimeout(() => {
@@ -1499,8 +1284,7 @@ class eWeLink {
callback();
} catch (err) {
accessory.context.inUse = false;
- let str =
- "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -1535,8 +1319,7 @@ class eWeLink {
}, parseInt(lockConfig.operationTime) * 100);
} catch (err) {
accessory.context.inUse = false;
- let str =
- "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -1551,45 +1334,36 @@ class eWeLink {
case "power":
newPower = value;
newSpeed = value ? 33 : 0;
- newLight = accessory
- .getService(Service.Lightbulb)
- .getCharacteristic(Characteristic.On).value;
+ newLight = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On)
+ .value;
break;
case "speed":
newPower = value >= 33 ? 1 : 0;
newSpeed = value;
- newLight = accessory
- .getService(Service.Lightbulb)
- .getCharacteristic(Characteristic.On).value;
+ newLight = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On)
+ .value;
break;
case "light":
- newPower = accessory
- .getService(Service.Fanv2)
- .getCharacteristic(Characteristic.Active).value;
+ newPower = accessory.getService(Service.Fanv2).getCharacteristic(Characteristic.Active)
+ .value;
newSpeed = accessory
.getService(Service.Fanv2)
.getCharacteristic(Characteristic.RotationSpeed).value;
newLight = value;
break;
}
- accessory
- .getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.On, newLight);
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, newLight);
accessory
.getService(Service.Fanv2)
.updateCharacteristic(Characteristic.Active, newPower)
.updateCharacteristic(Characteristic.RotationSpeed, newSpeed);
let params = {
- switches: this.devicesInEwe.get(accessory.context.eweDeviceId).params
- .switches,
+ switches: this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches,
};
params.switches[0].switch = newLight ? "on" : "off";
- params.switches[1].switch =
- newPower === 1 && newSpeed >= 33 ? "on" : "off";
- params.switches[2].switch =
- newPower === 1 && newSpeed >= 66 && newSpeed < 99 ? "on" : "off";
- params.switches[3].switch =
- newPower === 1 && newSpeed >= 99 ? "on" : "off";
+ params.switches[1].switch = newPower === 1 && newSpeed >= 33 ? "on" : "off";
+ params.switches[2].switch = newPower === 1 && newSpeed >= 66 && newSpeed < 99 ? "on" : "off";
+ params.switches[3].switch = newPower === 1 && newSpeed >= 99 ? "on" : "off";
if (this.debug) {
this.log.warn("Fan Update - setting " + type + " to " + value);
this.log(
@@ -1602,8 +1376,7 @@ class eWeLink {
}
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
- let str =
- "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -1618,19 +1391,12 @@ class eWeLink {
mainSwitch: value ? "on" : "off",
};
if (this.debug) {
- this.log(
- "[%s] updating to turn [%s].",
- accessory.displayName,
- value ? "on" : "off"
- );
+ this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
}
- accessory
- .getService(Service.Switch)
- .updateCharacteristic(Characteristic.On, value);
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
- let str =
- "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -1644,15 +1410,9 @@ class eWeLink {
switch: value ? "on" : "off",
};
if (this.debug) {
- this.log(
- "[%s] requesting to turn [%s].",
- accessory.displayName,
- value ? "on" : "off"
- );
+ this.log("[%s] requesting to turn [%s].", accessory.displayName, value ? "on" : "off");
}
- accessory
- .getService(Service.Outlet)
- .updateCharacteristic(Characteristic.On, value);
+ accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, value);
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
callback("[" + accessory.displayName + "] " + err + ".");
@@ -1664,20 +1424,13 @@ class eWeLink {
throw "it is currently offline";
}
let params = {
- switches: this.devicesInEwe.get(accessory.context.eweDeviceId).params
- .switches,
+ switches: this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches,
};
params.switches[0].switch = value ? "on" : "off";
if (this.debug) {
- this.log(
- "[%s] requesting to turn [%s].",
- accessory.displayName,
- value ? "on" : "off"
- );
+ this.log("[%s] requesting to turn [%s].", accessory.displayName, value ? "on" : "off");
}
- accessory
- .getService(Service.Outlet)
- .updateCharacteristic(Characteristic.On, value);
+ accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, value);
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
callback("[" + accessory.displayName + "] " + err + ".");
@@ -1689,20 +1442,13 @@ class eWeLink {
throw "it is currently offline";
}
let params = {
- switches: this.devicesInEwe.get(accessory.context.eweDeviceId).params
- .switches,
+ switches: this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches,
};
params.switches[0].switch = value ? "on" : "off";
if (this.debug) {
- this.log(
- "[%s] requesting to turn [%s].",
- accessory.displayName,
- value ? "on" : "off"
- );
+ this.log("[%s] requesting to turn [%s].", accessory.displayName, value ? "on" : "off");
}
- accessory
- .getService(Service.Switch)
- .updateCharacteristic(Characteristic.On, value);
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
callback("[" + accessory.displayName + "] " + err + ".");
@@ -1724,20 +1470,12 @@ class eWeLink {
params.switch = value ? "on" : "off";
}
if (this.debug) {
- this.log(
- "[%s] updating to turn [%s].",
- accessory.displayName,
- value ? "on" : "off"
- );
+ this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
}
- accessory
- .getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.On, value);
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
break;
case "0":
- params.switches = this.devicesInEwe.get(
- accessory.context.eweDeviceId
- ).params.switches;
+ params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
params.switches[0].switch = value ? "on" : "off";
params.switches[1].switch = value ? "on" : "off";
params.switches[2].switch = value ? "on" : "off";
@@ -1749,16 +1487,10 @@ class eWeLink {
value ? "on" : "off"
);
}
- accessory
- .getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.On, value);
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
for (let i = 1; i <= 4; i++) {
- if (
- this.devicesInHB.has(accessory.context.eweDeviceId + "SW" + i)
- ) {
- oAccessory = this.devicesInHB.get(
- accessory.context.eweDeviceId + "SW" + i
- );
+ if (this.devicesInHB.has(accessory.context.eweDeviceId + "SW" + i)) {
+ oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i);
oAccessory
.getService(Service.Lightbulb)
.updateCharacteristic(Characteristic.On, value);
@@ -1770,26 +1502,14 @@ class eWeLink {
case "3":
case "4":
if (this.debug) {
- this.log(
- "[%s] updating to turn [%s].",
- accessory.displayName,
- value ? "on" : "off"
- );
+ this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
}
- accessory
- .getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.On, value);
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
let tAccessory,
masterState = "off";
- params.switches = this.devicesInEwe.get(
- accessory.context.eweDeviceId
- ).params.switches;
+ params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
for (let i = 1; i <= 4; i++) {
- if (
- (tAccessory = this.devicesInHB.get(
- accessory.context.eweDeviceId + "SW" + i
- ))
- ) {
+ if ((tAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
i === parseInt(accessory.context.switchNumber)
? (params.switches[i - 1].switch = value ? "on" : "off")
: (params.switches[i - 1].switch = tAccessory
@@ -1798,9 +1518,7 @@ class eWeLink {
? "on"
: "off");
if (
- tAccessory
- .getService(Service.Lightbulb)
- .getCharacteristic(Characteristic.On).value
+ tAccessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value
) {
masterState = "on";
}
@@ -1808,22 +1526,17 @@ class eWeLink {
params.switches[i - 1].switch = "off";
}
}
- oAccessory = this.devicesInHB.get(
- accessory.context.eweDeviceId + "SW0"
- );
+ oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
oAccessory
.getService(Service.Lightbulb)
.updateCharacteristic(Characteristic.On, masterState === "on");
break;
default:
- throw (
- "unknown switch number [" + accessory.context.switchNumber + "]"
- );
+ throw "unknown switch number [" + accessory.context.switchNumber + "]";
}
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
- let str =
- "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -1836,15 +1549,9 @@ class eWeLink {
let params = {};
if (value === 0) {
params.switch = "off";
- accessory
- .getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.On, false);
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, false);
} else {
- if (
- !accessory
- .getService(Service.Lightbulb)
- .getCharacteristic(Characteristic.On).value
- ) {
+ if (!accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value) {
params.switch = "on";
}
switch (accessory.context.eweUIID) {
@@ -1863,16 +1570,11 @@ class eWeLink {
.updateCharacteristic(Characteristic.Brightness, value);
}
if (this.debug) {
- this.log(
- "[%s] updating brightness to [%s%].",
- accessory.displayName,
- value
- );
+ this.log("[%s] updating brightness to [%s%].", accessory.displayName, value);
}
setTimeout(() => this.sendDeviceUpdate(accessory, params, callback), 250);
} catch (err) {
- let str =
- "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -1884,9 +1586,8 @@ class eWeLink {
}
let newRGB,
params = {},
- curHue = accessory
- .getService(Service.Lightbulb)
- .getCharacteristic(Characteristic.Hue).value,
+ curHue = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Hue)
+ .value,
curSat = accessory
.getService(Service.Lightbulb)
.getCharacteristic(Characteristic.Saturation).value;
@@ -1917,15 +1618,9 @@ class eWeLink {
throw "unknown device UIID";
}
if (this.debug) {
- this.log(
- "[%s] updating hue to [%s°].",
- accessory.displayName,
- value
- );
+ this.log("[%s] updating hue to [%s°].", accessory.displayName, value);
}
- accessory
- .getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.Hue, value);
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Hue, value);
break;
case "bri":
switch (accessory.context.eweUIID) {
@@ -1949,11 +1644,7 @@ class eWeLink {
break;
}
if (this.debug) {
- this.log(
- "[%s] updating brightness to [%s%].",
- accessory.displayName,
- value
- );
+ this.log("[%s] updating brightness to [%s%].", accessory.displayName, value);
}
accessory
.getService(Service.Lightbulb)
@@ -1964,8 +1655,7 @@ class eWeLink {
}
setTimeout(() => this.sendDeviceUpdate(accessory, params, callback), 250);
} catch (err) {
- let str =
- "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -1981,20 +1671,12 @@ class eWeLink {
case "X":
params.switch = value ? "on" : "off";
if (this.debug) {
- this.log(
- "[%s] updating to turn [%s].",
- accessory.displayName,
- value ? "on" : "off"
- );
+ this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
}
- accessory
- .getService(Service.Switch)
- .updateCharacteristic(Characteristic.On, value);
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
break;
case "0":
- params.switches = this.devicesInEwe.get(
- accessory.context.eweDeviceId
- ).params.switches;
+ params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
params.switches[0].switch = value ? "on" : "off";
params.switches[1].switch = value ? "on" : "off";
params.switches[2].switch = value ? "on" : "off";
@@ -2006,19 +1688,11 @@ class eWeLink {
value ? "on" : "off"
);
}
- accessory
- .getService(Service.Switch)
- .updateCharacteristic(Characteristic.On, value);
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
for (let i = 1; i <= 4; i++) {
- if (
- this.devicesInHB.has(accessory.context.eweDeviceId + "SW" + i)
- ) {
- oAccessory = this.devicesInHB.get(
- accessory.context.eweDeviceId + "SW" + i
- );
- oAccessory
- .getService(Service.Switch)
- .updateCharacteristic(Characteristic.On, value);
+ if (this.devicesInHB.has(accessory.context.eweDeviceId + "SW" + i)) {
+ oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i);
+ oAccessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
}
}
break;
@@ -2027,26 +1701,14 @@ class eWeLink {
case "3":
case "4":
if (this.debug) {
- this.log(
- "[%s] updating to turn [%s].",
- accessory.displayName,
- value ? "on" : "off"
- );
+ this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
}
- accessory
- .getService(Service.Switch)
- .updateCharacteristic(Characteristic.On, value);
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
let tAccessory,
masterState = "off";
- params.switches = this.devicesInEwe.get(
- accessory.context.eweDeviceId
- ).params.switches;
+ params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
for (let i = 1; i <= 4; i++) {
- if (
- (tAccessory = this.devicesInHB.get(
- accessory.context.eweDeviceId + "SW" + i
- ))
- ) {
+ if ((tAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
i === parseInt(accessory.context.switchNumber)
? (params.switches[i - 1].switch = value ? "on" : "off")
: (params.switches[i - 1].switch = tAccessory
@@ -2055,9 +1717,7 @@ class eWeLink {
? "on"
: "off");
if (
- tAccessory
- .getService(Service.Switch)
- .getCharacteristic(Characteristic.On).value
+ tAccessory.getService(Service.Switch).getCharacteristic(Characteristic.On).value
) {
masterState = "on";
}
@@ -2065,22 +1725,17 @@ class eWeLink {
params.switches[i - 1].switch = "off";
}
}
- oAccessory = this.devicesInHB.get(
- accessory.context.eweDeviceId + "SW0"
- );
+ oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
oAccessory
.getService(Service.Switch)
.updateCharacteristic(Characteristic.On, masterState === "on");
break;
default:
- throw (
- "unknown switch number [" + accessory.context.switchNumber + "]"
- );
+ throw "unknown switch number [" + accessory.context.switchNumber + "]";
}
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
- let str =
- "[" + accessory.displayName + "] could not be updated as " + err + ".";
+ let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -2114,14 +1769,7 @@ class eWeLink {
3000
);
} catch (err) {
- let str =
- "[" +
- accessory.displayName +
- " " +
- name +
- "] could not be updated as " +
- err +
- ".";
+ let str = "[" + accessory.displayName + " " + name + "] could not be updated as " + err + ".";
this.log.error(str);
callback(str);
}
@@ -2131,14 +1779,8 @@ class eWeLink {
["A", "B"].forEach((v, k) => {
accessory
.getService("Valve " + v)
- .updateCharacteristic(
- Characteristic.Active,
- params.switches[k].switch === "on"
- )
- .updateCharacteristic(
- Characteristic.InUse,
- params.switches[k].switch === "on"
- );
+ .updateCharacteristic(Characteristic.Active, params.switches[k].switch === "on")
+ .updateCharacteristic(Characteristic.InUse, params.switches[k].switch === "on");
if (params.switches[k].switch === "on") {
let timer = accessory
.getService("Valve " + v)
@@ -2147,9 +1789,7 @@ class eWeLink {
.getService("Valve " + v)
.updateCharacteristic(Characteristic.RemainingDuration, timer);
accessory.getService("Valve " + v).timer = setTimeout(() => {
- accessory
- .getService("Valve " + v)
- .setCharacteristic(Characteristic.Active, 0);
+ accessory.getService("Valve " + v).setCharacteristic(Characteristic.Active, 0);
}, timer * 1000);
} else {
accessory
@@ -2159,11 +1799,7 @@ class eWeLink {
}
});
} catch (err) {
- this.log.warn(
- "[%s] could not be updated as %s.",
- accessory.displayName,
- err
- );
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalBlindUpdate(accessory, params) {
@@ -2172,10 +1808,7 @@ class eWeLink {
if (!(blindConfig = this.cusG.get(accessory.context.hbDeviceId))) {
throw "group config missing";
}
- if (
- blindConfig.type !== "blind" ||
- ["oneSwitch", "twoSwitch"].includes(blindConfig.setup)
- ) {
+ if (blindConfig.type !== "blind" || ["oneSwitch", "twoSwitch"].includes(blindConfig.setup)) {
throw "improper configuration";
}
switch (blindConfig.setup) {
@@ -2191,10 +1824,7 @@ class eWeLink {
: 0;
break;
case "twoSwitch":
- if (
- params.switches[0].switch === "off" &&
- params.switches[1].switch === "off"
- ) {
+ if (params.switches[0].switch === "off" && params.switches[1].switch === "off") {
return;
}
let switchUp = params.switches[0].switch === "on" ? -1 : 0, // matrix of numbers to get
@@ -2213,11 +1843,7 @@ class eWeLink {
.updateCharacteristic(Characteristic.CurrentPosition, nSte * 100);
}, parseInt(blindConfig.operationTime) * 100);
} catch (err) {
- this.log.warn(
- "[%s] could not be updated as %s.",
- accessory.displayName,
- err
- );
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalGarageUpdate(accessory, params) {
@@ -2271,11 +1897,7 @@ class eWeLink {
}, parseInt(garageConfig.operationTime) * 100);
} catch (err) {
accessory.context.inUse = false;
- this.log.warn(
- "[%s] could not be updated as %s.",
- accessory.displayName,
- err
- );
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalLockUpdate(accessory, params) {
@@ -2304,11 +1926,7 @@ class eWeLink {
}, parseInt(lockConfig.operationTime) * 100);
} catch (err) {
accessory.context.inUse = false;
- this.log.warn(
- "[%s] could not be updated as %s.",
- accessory.displayName,
- err
- );
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalSensorUpdate(accessory, params) {
@@ -2318,14 +1936,8 @@ class eWeLink {
accessory.getService(Service.BatteryService) ||
accessory.addService(Service.BatteryService),
scaledBattery = Math.round(params.battery * 33.3);
- batteryService.updateCharacteristic(
- Characteristic.BatteryLevel,
- scaledBattery
- );
- batteryService.updateCharacteristic(
- Characteristic.StatusLowBattery,
- scaledBattery < 25
- );
+ batteryService.updateCharacteristic(Characteristic.BatteryLevel, scaledBattery);
+ batteryService.updateCharacteristic(Characteristic.StatusLowBattery, scaledBattery < 25);
}
let newState = params.switch === "on" ? 1 : 0,
oAccessory = false;
@@ -2333,10 +1945,7 @@ class eWeLink {
.getService(Service.ContactSensor)
.updateCharacteristic(Characteristic.ContactSensorState, newState);
this.cusG.forEach(group => {
- if (
- group.sensorId === accessory.context.eweDeviceId &&
- group.type === "garage"
- ) {
+ if (group.sensorId === accessory.context.eweDeviceId && group.type === "garage") {
if ((oAccessory = this.devicesInHB.get(group.deviceId + "SWX"))) {
switch (newState) {
case 0:
@@ -2360,11 +1969,7 @@ class eWeLink {
}
});
} catch (err) {
- this.log.warn(
- "[%s] could not be updated as %s.",
- accessory.displayName,
- err
- );
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalFanUpdate(accessory, params) {
@@ -2372,11 +1977,7 @@ class eWeLink {
let light, status, speed;
if (Array.isArray(params.switches)) {
light = params.switches[0].switch === "on";
- switch (
- params.switches[1].switch +
- params.switches[2].switch +
- params.switches[3].switch
- ) {
+ switch (params.switches[1].switch + params.switches[2].switch + params.switches[3].switch) {
default:
status = 0;
speed = 0;
@@ -2404,19 +2005,13 @@ class eWeLink {
} else {
throw "unknown parameters received";
}
- accessory
- .getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.On, light);
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, light);
accessory
.getService(Service.Fanv2)
.updateCharacteristic(Characteristic.Active, status)
.updateCharacteristic(Characteristic.RotationSpeed, speed);
} catch (err) {
- this.log.warn(
- "[%s] could not be updated as %s.",
- accessory.displayName,
- err
- );
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalThermostatUpdate(accessory, params) {
@@ -2428,9 +2023,7 @@ class eWeLink {
let newState = params.hasOwnProperty("switch")
? params.switch === "on"
: params.mainSwitch === "on";
- accessory
- .getService(Service.Switch)
- .updateCharacteristic(Characteristic.On, newState);
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, newState);
}
let eveLog = {
time: Date.now(),
@@ -2440,9 +2033,7 @@ class eWeLink {
accessory.getService(Service.TemperatureSensor)
) {
let currentTemp =
- params.currentTemperature !== "unavailable"
- ? params.currentTemperature
- : 0;
+ params.currentTemperature !== "unavailable" ? params.currentTemperature : 0;
accessory
.getService(Service.TemperatureSensor)
.updateCharacteristic(Characteristic.CurrentTemperature, currentTemp);
@@ -2452,25 +2043,17 @@ class eWeLink {
params.hasOwnProperty("currentHumidity") &&
accessory.getService(Service.HumiditySensor)
) {
- let currentHumi =
- params.currentHumidity !== "unavailable" ? params.currentHumidity : 0;
+ let currentHumi = params.currentHumidity !== "unavailable" ? params.currentHumidity : 0;
accessory
.getService(Service.HumiditySensor)
- .updateCharacteristic(
- Characteristic.CurrentRelativeHumidity,
- currentHumi
- );
+ .updateCharacteristic(Characteristic.CurrentRelativeHumidity, currentHumi);
eveLog.humidity = parseFloat(currentHumi);
}
if (eveLog.hasOwnProperty("temp") || eveLog.hasOwnProperty("humidity")) {
accessory.eveLogger.addEntry(eveLog);
}
} catch (err) {
- this.log.warn(
- "[%s] could not be updated as %s.",
- accessory.displayName,
- err
- );
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalOutletUpdate(accessory, params) {
@@ -2489,13 +2072,8 @@ class eWeLink {
);
accessory
.getService(Service.Outlet)
- .updateCharacteristic(
- Characteristic.OutletInUse,
- parseFloat(params.power) > 0
- );
- let isOn = accessory
- .getService(Service.Outlet)
- .getCharacteristic(Characteristic.On).value;
+ .updateCharacteristic(Characteristic.OutletInUse, parseFloat(params.power) > 0);
+ let isOn = accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On).value;
accessory.eveLogger.addEntry({
time: Date.now(),
power: isOn ? parseFloat(params.power) : 0,
@@ -2504,10 +2082,7 @@ class eWeLink {
if (params.hasOwnProperty("voltage")) {
accessory
.getService(Service.Outlet)
- .updateCharacteristic(
- EveService.Characteristics.Voltage,
- parseFloat(params.voltage)
- );
+ .updateCharacteristic(EveService.Characteristics.Voltage, parseFloat(params.voltage));
}
if (params.hasOwnProperty("current")) {
accessory
@@ -2518,43 +2093,25 @@ class eWeLink {
);
}
} catch (err) {
- this.log.warn(
- "[%s] could not be updated as %s.",
- accessory.displayName,
- err
- );
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalUSBUpdate(accessory, params) {
try {
accessory
.getService(Service.Outlet)
- .updateCharacteristic(
- Characteristic.On,
- params.switches[0].switch === "on"
- );
+ .updateCharacteristic(Characteristic.On, params.switches[0].switch === "on");
} catch (err) {
- this.log.warn(
- "[%s] could not be updated as %s.",
- accessory.displayName,
- err
- );
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalSCMUpdate(accessory, params) {
try {
accessory
.getService(Service.Switch)
- .updateCharacteristic(
- Characteristic.On,
- params.switches[0].switch === "on"
- );
+ .updateCharacteristic(Characteristic.On, params.switches[0].switch === "on");
} catch (err) {
- this.log.warn(
- "[%s] could not be updated as %s.",
- accessory.displayName,
- err
- );
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalSingleLightUpdate(accessory, params) {
@@ -2564,20 +2121,13 @@ class eWeLink {
isOn = false;
if (accessory.context.eweUIID === 22 && params.hasOwnProperty("state")) {
isOn = params.state === "on";
- } else if (
- accessory.context.eweUIID !== 22 &&
- params.hasOwnProperty("switch")
- ) {
+ } else if (accessory.context.eweUIID !== 22 && params.hasOwnProperty("switch")) {
isOn = params.switch === "on";
} else {
- isOn = accessory
- .getService(Service.Lightbulb)
- .getCharacteristic(Characteristic.On).value;
+ isOn = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value;
}
if (isOn) {
- accessory
- .getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.On, true);
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, true);
switch (accessory.context.eweUIID) {
case 36: // KING-M4
if (params.hasOwnProperty("bright")) {
@@ -2591,10 +2141,7 @@ class eWeLink {
if (params.hasOwnProperty("brightness")) {
accessory
.getService(Service.Lightbulb)
- .updateCharacteristic(
- Characteristic.Brightness,
- params.brightness
- );
+ .updateCharacteristic(Characteristic.Brightness, params.brightness);
}
break;
case 22: // B1
@@ -2609,9 +2156,7 @@ class eWeLink {
mode = 2;
}
if (mode === 2) {
- accessory
- .getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.On, true);
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, true);
newColour = convert.rgb.hsv(
parseInt(params.channel2),
parseInt(params.channel3),
@@ -2633,11 +2178,7 @@ class eWeLink {
.updateCharacteristic(Characteristic.Brightness, params.bright);
}
if (params.hasOwnProperty("colorR")) {
- newColour = convert.rgb.hsv(
- params.colorR,
- params.colorG,
- params.colorB
- );
+ newColour = convert.rgb.hsv(params.colorR, params.colorG, params.colorB);
accessory
.getService(Service.Lightbulb)
.updateCharacteristic(Characteristic.Hue, newColour[0])
@@ -2648,16 +2189,10 @@ class eWeLink {
return;
}
} else {
- accessory
- .getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.On, false);
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, false);
}
} catch (err) {
- this.log.warn(
- "[%s] could not be updated as %s.",
- accessory.displayName,
- err
- );
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalMultiLightUpdate(accessory, params) {
@@ -2669,24 +2204,15 @@ class eWeLink {
let oAccessory = this.devicesInHB.get(idToCheck + i);
oAccessory
.getService(Service.Lightbulb)
- .updateCharacteristic(
- Characteristic.On,
- params.switches[i - 1].switch === "on"
- );
+ .updateCharacteristic(Characteristic.On, params.switches[i - 1].switch === "on");
if (params.switches[i - 1].switch === "on") {
primaryState = true;
}
}
}
- accessory
- .getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.On, primaryState);
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, primaryState);
} catch (err) {
- this.log.warn(
- "[%s] could not be updated as %s.",
- accessory.displayName,
- err
- );
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalSingleSwitchUpdate(accessory, params) {
@@ -2695,11 +2221,7 @@ class eWeLink {
.getService(Service.Switch)
.updateCharacteristic(Characteristic.On, params.switch === "on");
} catch (err) {
- this.log.warn(
- "[%s] could not be updated as %s.",
- accessory.displayName,
- err
- );
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalMultiSwitchUpdate(accessory, params) {
@@ -2711,24 +2233,15 @@ class eWeLink {
let oAccessory = this.devicesInHB.get(idToCheck + i);
oAccessory
.getService(Service.Switch)
- .updateCharacteristic(
- Characteristic.On,
- params.switches[i - 1].switch === "on"
- );
+ .updateCharacteristic(Characteristic.On, params.switches[i - 1].switch === "on");
if (params.switches[i - 1].switch === "on") {
primaryState = true;
}
}
}
- accessory
- .getService(Service.Switch)
- .updateCharacteristic(Characteristic.On, primaryState);
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, primaryState);
} catch (err) {
- this.log.warn(
- "[%s] could not be updated as %s.",
- accessory.displayName,
- err
- );
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalRFDeviceUpdate(accessory, params) {
@@ -2744,9 +2257,7 @@ class eWeLink {
// RF Button
let bAccessory;
if (
- (bAccessory = this.devicesInHB.get(
- idToCheck + accessory.context.rfChlMap[params.rfChl]
- ))
+ (bAccessory = this.devicesInHB.get(idToCheck + accessory.context.rfChlMap[params.rfChl]))
) {
bAccessory
.getService(bAccessory.context.rfChls[params.rfChl])
@@ -2800,81 +2311,51 @@ class eWeLink {
case "co":
oAccessory
.getService(Service.CarbonMonoxideSensor)
- .updateCharacteristic(
- Characteristic.CarbonMonoxideDetected,
- 1
- );
+ .updateCharacteristic(Characteristic.CarbonMonoxideDetected, 1);
setTimeout(() => {
oAccessory
.getService(Service.CarbonMonoxideSensor)
- .updateCharacteristic(
- Characteristic.CarbonMonoxideDetected,
- 0
- );
+ .updateCharacteristic(Characteristic.CarbonMonoxideDetected, 0);
}, (this.config.sensorTimeLength || 2) * 1000);
break;
case "co2":
oAccessory
.getService(Service.CarbonDioxideSensor)
- .updateCharacteristic(
- Characteristic.CarbonDioxideDetected,
- 1
- );
+ .updateCharacteristic(Characteristic.CarbonDioxideDetected, 1);
setTimeout(() => {
oAccessory
.getService(Service.CarbonDioxideSensor)
- .updateCharacteristic(
- Characteristic.CarbonDioxideDetected,
- 0
- );
+ .updateCharacteristic(Characteristic.CarbonDioxideDetected, 0);
}, (this.config.sensorTimeLength || 2) * 1000);
break;
case "contact":
oAccessory
.getService(Service.ContactSensor)
- .updateCharacteristic(
- Characteristic.ContactSensorState,
- 1
- );
+ .updateCharacteristic(Characteristic.ContactSensorState, 1);
setTimeout(() => {
oAccessory
.getService(Service.ContactSensor)
- .updateCharacteristic(
- Characteristic.ContactSensorState,
- 0
- );
+ .updateCharacteristic(Characteristic.ContactSensorState, 0);
}, (this.config.sensorTimeLength || 2) * 1000);
break;
case "occupancy":
oAccessory
.getService(Service.OccupancySensor)
- .updateCharacteristic(
- Characteristic.OccupancyDetected,
- 1
- );
+ .updateCharacteristic(Characteristic.OccupancyDetected, 1);
setTimeout(() => {
oAccessory
.getService(Service.OccupancySensor)
- .updateCharacteristic(
- Characteristic.OccupancyDetected,
- 0
- );
+ .updateCharacteristic(Characteristic.OccupancyDetected, 0);
}, (this.config.sensorTimeLength || 2) * 1000);
break;
default:
oAccessory
.getService(Service.MotionSensor)
- .updateCharacteristic(
- Characteristic.MotionDetected,
- true
- );
+ .updateCharacteristic(Characteristic.MotionDetected, true);
setTimeout(() => {
oAccessory
.getService(Service.MotionSensor)
- .updateCharacteristic(
- Characteristic.MotionDetected,
- false
- );
+ .updateCharacteristic(Characteristic.MotionDetected, false);
}, (this.config.sensorTimeLength || 2) * 1000);
break;
}
@@ -2890,44 +2371,28 @@ class eWeLink {
});
}
} catch (err) {
- this.log.warn(
- "[%s] could not be updated as %s.",
- accessory.displayName,
- err
- );
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
externalZBDeviceUpdate(accessory, params) {
try {
//*** credit @tasict ***\\
if (params.hasOwnProperty("battery")) {
- if (
- accessory.context.eweUIID === 3026 &&
- (this.config.ZBDWBatt || false)
- ) {
+ if (accessory.context.eweUIID === 3026 && (this.config.ZBDWBatt || false)) {
params.battery *= 10;
}
let batteryService =
accessory.getService(Service.BatteryService) ||
accessory.addService(Service.BatteryService);
- batteryService.updateCharacteristic(
- Characteristic.BatteryLevel,
- params.battery
- );
- batteryService.updateCharacteristic(
- Characteristic.StatusLowBattery,
- params.battery < 25
- );
+ batteryService.updateCharacteristic(Characteristic.BatteryLevel, params.battery);
+ batteryService.updateCharacteristic(Characteristic.StatusLowBattery, params.battery < 25);
}
switch (accessory.context.eweUIID) {
case 1000:
if (params.hasOwnProperty("key") && [0, 1, 2].includes(params.key)) {
accessory
.getService(Service.StatelessProgrammableSwitch)
- .updateCharacteristic(
- Characteristic.ProgrammableSwitchEvent,
- params.key
- );
+ .updateCharacteristic(Characteristic.ProgrammableSwitchEvent, params.key);
}
break;
case 1770:
@@ -2938,34 +2403,22 @@ class eWeLink {
let currentTemp = parseInt(params.temperature) / 100;
accessory
.getService(Service.TemperatureSensor)
- .updateCharacteristic(
- Characteristic.CurrentTemperature,
- currentTemp
- );
+ .updateCharacteristic(Characteristic.CurrentTemperature, currentTemp);
eveLog.temp = parseFloat(currentTemp);
}
if (params.hasOwnProperty("humidity")) {
let currentHumi = parseInt(params.humidity) / 100;
accessory
.getService(Service.HumiditySensor)
- .updateCharacteristic(
- Characteristic.CurrentRelativeHumidity,
- currentHumi
- );
+ .updateCharacteristic(Characteristic.CurrentRelativeHumidity, currentHumi);
eveLog.humidity = parseFloat(currentHumi);
}
- if (
- eveLog.hasOwnProperty("temp") ||
- eveLog.hasOwnProperty("humidity")
- ) {
+ if (eveLog.hasOwnProperty("temp") || eveLog.hasOwnProperty("humidity")) {
accessory.eveLogger.addEntry(eveLog);
}
break;
case 2026:
- if (
- params.hasOwnProperty("motion") &&
- params.hasOwnProperty("trigTime")
- ) {
+ if (params.hasOwnProperty("motion") && params.hasOwnProperty("trigTime")) {
let timeNow = new Date(),
diff = (timeNow.getTime() - params.trigTime) / 1000;
accessory
@@ -2983,19 +2436,12 @@ class eWeLink {
if (params.hasOwnProperty("lock") && [0, 1].includes(params.lock)) {
accessory
.getService(Service.ContactSensor)
- .updateCharacteristic(
- Characteristic.ContactSensorState,
- params.lock
- );
+ .updateCharacteristic(Characteristic.ContactSensorState, params.lock);
}
break;
}
} catch (err) {
- this.log.warn(
- "[%s] could not be updated as %s.",
- accessory.displayName,
- err
- );
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
}
diff --git a/lib/eWeLinkHTTP.js b/lib/eWeLinkHTTP.js
index 1aafd1e4..dc8370a4 100644
--- a/lib/eWeLinkHTTP.js
+++ b/lib/eWeLinkHTTP.js
@@ -12,9 +12,7 @@ module.exports = class eWeLinkHTTP {
}
login() {
let data = {
- countryCode:
- "+" +
- this.config.countryCode.toString().replace("+", "").replace(" ", ""),
+ countryCode: "+" + this.config.countryCode.toString().replace("+", "").replace(" ", ""),
password: this.config.password,
};
this.config.username.includes("@")
@@ -24,10 +22,7 @@ module.exports = class eWeLinkHTTP {
let msg = JSON.stringify(data, null, 2)
.replace(this.config.password, "**hidden**")
.replace(this.config.username, "**hidden**");
- this.log.warn(
- "Sending HTTP login request. This text is yellow for clarity.\n%s",
- msg
- );
+ this.log.warn("Sending HTTP login request. This text is yellow for clarity.\n%s", msg);
} else if (this.debug) {
this.log("Sending HTTP login request.");
}
@@ -96,10 +91,7 @@ module.exports = class eWeLinkHTTP {
getHost() {
let data = {
appid: constants.appId,
- country_code: this.config.countryCode
- .toString()
- .replace("+", "")
- .replace(" ", ""),
+ country_code: this.config.countryCode.toString().replace("+", "").replace(" ", ""),
nonce: Math.random().toString(36).substr(2, 8),
ts: Math.floor(new Date().getTime() / 1000),
version: 8,
@@ -135,10 +127,7 @@ module.exports = class eWeLinkHTTP {
.then(res => {
let body = res.data;
if (!body.region) {
- throw (
- "Server did not respond with a region.\n" +
- JSON.stringify(body, null, 2)
- );
+ throw "Server did not respond with a region.\n" + JSON.stringify(body, null, 2);
}
switch (body.region) {
case "eu":
@@ -176,17 +165,12 @@ module.exports = class eWeLinkHTTP {
})
.then(res => {
let body = res.data;
- if (
- !body.hasOwnProperty("error") ||
- (body.hasOwnProperty("error") && body.error !== 0)
- ) {
+ if (!body.hasOwnProperty("error") || (body.hasOwnProperty("error") && body.error !== 0)) {
throw JSON.stringify(body, null, 2);
}
let deviceList = [];
if (body.data.thingList && body.data.thingList.length > 0) {
- body.data.thingList.forEach(device =>
- deviceList.push(device.itemData)
- );
+ body.data.thingList.forEach(device => deviceList.push(device.itemData));
}
resolve(deviceList);
})
diff --git a/lib/eWeLinkLAN.js b/lib/eWeLinkLAN.js
index 25baee53..9701fa06 100644
--- a/lib/eWeLinkLAN.js
+++ b/lib/eWeLinkLAN.js
@@ -36,9 +36,7 @@ module.exports = class eWeLinkLAN {
let onlineCount = 0;
res.forEach(device => {
let d,
- deviceId = device.fqdn
- .replace("._ewelink._tcp.local", "")
- .replace("eWeLink_", "");
+ deviceId = device.fqdn.replace("._ewelink._tcp.local", "").replace("eWeLink_", "");
if ((d = this.deviceMap.get(deviceId))) {
if (!this.ipOverrides.hasOwnProperty(deviceId)) {
this.deviceMap.set(deviceId, {
@@ -79,48 +77,31 @@ module.exports = class eWeLinkLAN {
.createHash("md5")
.update(Buffer.from(deviceInfo.apiKey, "utf8"))
.digest(),
- dText = crypto.createDecipheriv(
- "aes-128-cbc",
- key,
- Buffer.from(rdata.iv, "base64")
- ),
+ dText = crypto.createDecipheriv("aes-128-cbc", key, Buffer.from(rdata.iv, "base64")),
pText = Buffer.concat([
dText.update(Buffer.from(data, "base64")),
dText.final(),
]).toString("utf8"),
params;
- if (
- packet.address !== deviceInfo.ip &&
- !this.ipOverrides.hasOwnProperty(rdata.id)
- ) {
+ if (packet.address !== deviceInfo.ip && !this.ipOverrides.hasOwnProperty(rdata.id)) {
this.deviceMap.set(rdata.id, {
apiKey: deviceInfo.apiKey,
online: true,
ip: packet.address,
});
if (this.debug) {
- this.log.warn(
- "[%s] updating IP address to [%s].",
- rdata.id,
- packet.address
- );
+ this.log.warn("[%s] updating IP address to [%s].", rdata.id, packet.address);
}
}
try {
params = JSON.parse(pText);
} catch (e) {
- this.log.warn(
- "[%s] An error occured reading the LAN message [%s]",
- rdata.id,
- e
- );
+ this.log.warn("[%s] An error occured reading the LAN message [%s]", rdata.id, e);
return;
}
for (let param in params) {
if (params.hasOwnProperty(param)) {
- if (
- !constants.paramsToKeep.includes(param.replace(/[0-9]/g, ""))
- ) {
+ if (!constants.paramsToKeep.includes(param.replace(/[0-9]/g, ""))) {
delete params[param];
}
}
@@ -133,10 +114,7 @@ module.exports = class eWeLinkLAN {
params,
};
if (this.debugReqRes) {
- let msg = JSON.stringify(returnTemplate, null, 2).replace(
- rdata.id,
- "**hidden**"
- );
+ let msg = JSON.stringify(returnTemplate, null, 2).replace(rdata.id, "**hidden**");
this.log("LAN message received.\n%s", msg);
} else if (this.debug) {
this.log("LAN message received.");
@@ -175,17 +153,13 @@ module.exports = class eWeLinkLAN {
throw "plugin does not support lan mode for this device yet - feel free to create a github issue";
}
if ((apiKey = this.deviceMap.get(json.deviceid).apiKey)) {
- let key = crypto
- .createHash("md5")
- .update(Buffer.from(apiKey, "utf8"))
- .digest(),
+ let key = crypto.createHash("md5").update(Buffer.from(apiKey, "utf8")).digest(),
iv = crypto.randomBytes(16),
enc = crypto.createCipheriv("aes-128-cbc", key, iv),
data = {
- data: Buffer.concat([
- enc.update(JSON.stringify(params)),
- enc.final(),
- ]).toString("base64"),
+ data: Buffer.concat([enc.update(JSON.stringify(params)), enc.final()]).toString(
+ "base64"
+ ),
deviceid: json.deviceid,
encrypt: true,
iv: iv.toString("base64"),
@@ -197,20 +171,13 @@ module.exports = class eWeLinkLAN {
.replace(json.apikey, "**hidden**")
.replace(json.apikey, "**hidden**")
.replace(json.deviceid, "**hidden**");
- this.log.warn(
- "LAN message sent. This text is yellow for clarity.\n%s",
- msg
- );
+ this.log.warn("LAN message sent. This text is yellow for clarity.\n%s", msg);
} else if (this.debug) {
this.log("LAN message sent.");
}
axios({
method: "post",
- url:
- "http://" +
- this.deviceMap.get(json.deviceid).ip +
- ":8081/zeroconf/" +
- suffix,
+ url: "http://" + this.deviceMap.get(json.deviceid).ip + ":8081/zeroconf/" + suffix,
headers: {
Accept: "application/json",
"Content-Type": "application/json",
diff --git a/lib/eWeLinkWS.js b/lib/eWeLinkWS.js
index 56fbeb64..70e0a209 100644
--- a/lib/eWeLinkWS.js
+++ b/lib/eWeLinkWS.js
@@ -21,8 +21,7 @@ module.exports = class eWeLinkWS {
return new Promise((resolve, reject) => {
axios({
method: "post",
- url:
- "https://" + this.httpHost.replace("-api", "-disp") + "/dispatch/app",
+ url: "https://" + this.httpHost.replace("-api", "-disp") + "/dispatch/app",
headers: {
Authorization: "Bearer " + this.aToken,
"Content-Type": "application/json",
@@ -70,10 +69,7 @@ module.exports = class eWeLinkWS {
let msg = JSON.stringify(payload, null, 2)
.replace(this.aToken, "**hidden**")
.replace(this.apiKey, "**hidden**");
- this.log.warn(
- "Sending WS login request. This text is yellow for clarity.\n%s",
- msg
- );
+ this.log.warn("Sending WS login request. This text is yellow for clarity.\n%s", msg);
} else if (this.debug) {
this.log("Sending WS login request.");
}
@@ -86,10 +82,7 @@ module.exports = class eWeLinkWS {
try {
device = JSON.parse(m);
} catch (e) {
- this.log.warn(
- "An error occured reading the web socket message [%s]",
- e
- );
+ this.log.warn("An error occured reading the web socket message [%s]", e);
return;
}
// for requestUpdate response
@@ -143,9 +136,7 @@ module.exports = class eWeLinkWS {
case "update":
for (let param in device.params) {
if (device.params.hasOwnProperty(param)) {
- if (
- !constants.paramsToKeep.includes(param.replace(/[0-9]/g, ""))
- ) {
+ if (!constants.paramsToKeep.includes(param.replace(/[0-9]/g, ""))) {
delete device.params[param];
}
}
@@ -173,8 +164,7 @@ module.exports = class eWeLinkWS {
return;
default:
this.log.warn(
- "[%s] WS message has unknown action.\n" +
- JSON.stringify(device, null, 2),
+ "[%s] WS message has unknown action.\n" + JSON.stringify(device, null, 2),
device.deviceid
);
return;
@@ -183,9 +173,7 @@ module.exports = class eWeLinkWS {
// *** Safe to ignore these messages *** \\
} else {
if (this.debug) {
- this.log.warn(
- "WS unknown command received.\n" + JSON.stringify(device, null, 2)
- );
+ this.log.warn("WS unknown command received.\n" + JSON.stringify(device, null, 2));
}
}
});
@@ -200,9 +188,7 @@ module.exports = class eWeLinkWS {
this.login();
}, 5000);
} else {
- this.log(
- "Please try restarting Homebridge so that this plugin can work again."
- );
+ this.log("Please try restarting Homebridge so that this plugin can work again.");
}
}
this.wsIsOpen = false;
@@ -223,9 +209,7 @@ module.exports = class eWeLinkWS {
this.login();
}, 5000);
} else {
- this.log.warn(
- "If this was unexpected then please try restarting Homebridge."
- );
+ this.log.warn("If this was unexpected then please try restarting Homebridge.");
}
});
}
@@ -252,10 +236,7 @@ module.exports = class eWeLinkWS {
.replace(json.apikey, "**hidden**")
.replace(json.apiKey, "**hidden**")
.replace(json.deviceid, "**hidden**");
- this.log.warn(
- "WS message sent. This text is yellow for clarity.\n%s",
- msg
- );
+ this.log.warn("WS message sent. This text is yellow for clarity.\n%s", msg);
} else if (this.debug) {
this.log("WS message sent.");
}
@@ -268,9 +249,7 @@ module.exports = class eWeLinkWS {
setTimeout(sendOperation, this.delaySend, string);
this.delaySend += 280;
} else {
- this.log.warn(
- "Web socket is currently reconnecting. Command will be resent."
- );
+ this.log.warn("Web socket is currently reconnecting. Command will be resent.");
let interval,
waitToSend = req => {
if (this.wsIsOpen) {
@@ -305,10 +284,7 @@ module.exports = class eWeLinkWS {
.replace(json.apikey, "**hidden**")
.replace(json.apiKey, "**hidden**")
.replace(json.deviceid, "**hidden**");
- this.log.warn(
- "WS message sent. This text is yellow for clarity.\n%s",
- msg
- );
+ this.log.warn("WS message sent. This text is yellow for clarity.\n%s", msg);
} else if (this.debug) {
this.log("WS message sent.");
}
@@ -321,9 +297,7 @@ module.exports = class eWeLinkWS {
setTimeout(sendOperation, this.delaySend, string);
this.delaySend += 280;
} else {
- this.log.warn(
- "Web socket is currently reconnecting. Command will be resent."
- );
+ this.log.warn("Web socket is currently reconnecting. Command will be resent.");
let interval,
waitToSend = req => {
if (this.wsIsOpen) {
From 8e782a76f3bdff90e7babdcb5d733919653617d4 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Wed, 16 Sep 2020 17:05:55 +0100
Subject: [PATCH 0167/3183] 2.27.1
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 3e66d828..bc44c562 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.27.0",
+ "version": "2.27.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 015ed59c..88b3db2a 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.27.0",
+ "version": "2.27.1",
"author": "bwp91",
"contributors": [
"gbro115",
From 169ae4df8b4ac8fe44be1cd2352d128f1ffb314c Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Thu, 17 Sep 2020 14:44:38 +0100
Subject: [PATCH 0168/3183] Update eWeLink.js
---
lib/eWeLink.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 10049c96..8eafef3e 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -1227,7 +1227,7 @@ class eWeLink {
if (sensorDefinition && !(sAccessory = this.devicesInHB.get(garageConfig.sensorId + "SWX"))) {
throw "defined DW2 sensor doesn't exist";
}
- if (sAccessory.context.type !== "sensor") {
+ if (sensorDefinition && sAccessory.context.type !== "sensor") {
throw "defined DW2 sensor isn't a sensor";
}
oldPos = sAccessory
From a6b79031173339879adbae64012ba7fd52e5b8ec Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Thu, 17 Sep 2020 14:45:24 +0100
Subject: [PATCH 0169/3183] 2.27.2
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index bc44c562..93c75ca5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.27.1",
+ "version": "2.27.2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 88b3db2a..7750d662 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.27.1",
+ "version": "2.27.2",
"author": "bwp91",
"contributors": [
"gbro115",
From 14bc1f792134b57da5938b2708880bbc39a08b16 Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Sat, 19 Sep 2020 22:40:36 +0100
Subject: [PATCH 0170/3183] Update config.yml
---
.github/ISSUE_TEMPLATE/config.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
index 2194a932..af5ef704 100644
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -1,5 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: Homebridge Discord
- url: https://discord.gg/Z8jmyvb
+ url: https://discord.gg/7X36mdw
about: Chat to me on Discord - my username is bwp91.
From 404148f91f5dc90e2825a040e25a1e1134fbb0d2 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 20 Sep 2020 13:02:42 +0100
Subject: [PATCH 0171/3183] initial 3.0 beta
---
config.schema.json | 13 +-
lib/constants.js | 2 +-
lib/eWeLink.js | 1673 ++++++++++++++++++++++----------------------
lib/eWeLinkHTTP.js | 286 +++++---
lib/eWeLinkLAN.js | 36 +-
lib/eWeLinkWS.js | 330 +++++----
package-lock.json | 5 +
package.json | 1 +
8 files changed, 1201 insertions(+), 1145 deletions(-)
diff --git a/config.schema.json b/config.schema.json
index ee24e05b..e9a2b321 100644
--- a/config.schema.json
+++ b/config.schema.json
@@ -46,6 +46,12 @@
"description": "A list of eWeLink devices to hide from Homebridge. For example '10009553c8' or multiple devices separated with a comma '10009553c8,10009553c9'.",
"default": ""
},
+ "hideMasters": {
+ "type": "boolean",
+ "title": "Hide Master Switches",
+ "description": "If enabled, the 'SW0' accessory of multi-channel light and switch devices will be hidden from Homebridge.",
+ "default": false
+ },
"hideFromHB": {
"type": "string",
"title": "Hide Device Channels",
@@ -225,6 +231,7 @@
"debug",
"debugReqRes",
"hideDevFromHB",
+ "hideMasters",
"hideFromHB",
"sensorTimeLength",
"sensorTimeDifference",
@@ -261,7 +268,11 @@
"items": [
{
"type": "fieldset",
- "items": ["bridgeSensors[].deviceId", "bridgeSensors[].fullDeviceId", "bridgeSensors[].type"]
+ "items": [
+ "bridgeSensors[].deviceId",
+ "bridgeSensors[].fullDeviceId",
+ "bridgeSensors[].type"
+ ]
}
]
}
diff --git a/lib/constants.js b/lib/constants.js
index fe7fcb40..a89a48c0 100644
--- a/lib/constants.js
+++ b/lib/constants.js
@@ -5,7 +5,7 @@ module.exports = {
appId: "oeVkj2lYFGnJu5XUtWisfW4utiN4u9Mq",
// appSecret: "mXLOjea0woSMvK9gw7Fjsy7YlFO4iSu6",
appSecret: "6Nz4n0xA8s8qdxQf2GqurZj2Fs55FUvM",
- devicesHideable: ["switch", "light", "valve"],
+ devicesHideable: ["switch", "light"],
devicesNonLAN: [22, 59, 102],
devicesSingleSwitch: [1, 5, 6, 14, 15, 22, 24, 27, 32, 36, 44, 59],
devicesSingleSwitchParams: ["switch"],
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 8eafef3e..d8b093a1 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -13,9 +13,9 @@ class eWeLink {
constructor(log, config, api) {
if (!log || !api || !config) return;
if (!config.username || !config.password || !config.countryCode) {
- log.error("**************** Cannot load homebridge-ewelink ****************");
- log.error("Your eWeLink credentials are missing from the Homebridge config.");
- log.error("****************************************************************");
+ log.error("*********** Cannot load homebridge-ewelink ***********");
+ log.error("eWeLink credentials missing from the Homebridge config.");
+ log.error("*******************************************************");
return;
}
this.log = log;
@@ -23,257 +23,247 @@ class eWeLink {
this.api = api;
this.debug = this.config.debug || false;
this.devicesInHB = new Map();
- this.devicesInEwe = new Map();
+ this.devicesInEW = new Map();
this.cusG = new Map();
this.cusS = new Map();
+ this.hiddenMasters = [];
this.eveLogPath = this.api.user.storagePath() + "/homebridge-ewelink/";
this.api
- .on("didFinishLaunching", () => {
- this.log(
- "Plugin has finished initialising. Starting synchronisation with eWeLink account."
- );
- //*** Set up HTTP client and get the user HTTP host ***\\
- this.httpClient = new eWeLinkHTTP(this.config, this.log);
- this.httpClient
- .getHost()
- .then(() => this.httpClient.login())
- .then(res => {
- //*** Set up the web socket client ***\\
- this.wsClient = new eWeLinkWS(this.config, this.log, res);
- return this.wsClient.getHost();
- })
- .then(() => {
- //*** Open web socket connection and get device list via HTTP ***\\
- this.wsClient.login();
- return this.httpClient.getDevices();
- })
- .then(res => {
- //*** Get device IP addresses for LAN mode ***\\
- this.httpDevices = res
- .filter(
- device => device.hasOwnProperty("extra") && device.extra.hasOwnProperty("uiid")
- )
- .filter(device => !(this.config.hideDevFromHB || "").includes(device.deviceid));
- this.lanClient = new eWeLinkLAN(this.config, this.log, this.httpDevices);
- this.httpDevices.forEach(device => this.devicesInEwe.set(device.deviceid, device));
- return this.lanClient.getHosts();
- })
- .then(res => {
- //*** Set up the LAN mode listener ***\\
- this.lanDevices = res.map;
- this.lanDevicesOnline = res.count;
- return this.lanClient.startMonitor();
- })
- .then(() => {
- //*** Use the device list to refresh Homebridge accessories ***\\
- (() => {
- //*** Remove all Homebridge accessories if none found ***\\
- if (
- Object.keys(this.httpDevices).length === 0 &&
- Object.keys(this.lanDevices).length === 0
- ) {
- Array.from(this.devicesInHB.values()).forEach(a => this.removeAccessory(a));
- this.devicesInHB.clear();
- this.log.warn("******* Not loading homebridge-ewelink *******");
- this.log.warn("No devices were found in your eWeLink account.");
- this.log.warn("**********************************************");
- return;
- }
- //*** Make a map of custom groups from Homebridge config ***\\
- if (Object.keys(this.config.groups || []).length > 0) {
- this.config.groups
- .filter(g => g.hasOwnProperty("type") && cns.allowedGroups.includes(g.type))
- .filter(
- g =>
- g.hasOwnProperty("deviceId") &&
- this.devicesInEwe.has(g.deviceId.toLowerCase())
- )
- .forEach(g => this.cusG.set(g.deviceId + "SWX", g));
- }
- //*** Make a map of RF Bridge custom sensors from Homebridge config ***\\
- if (Object.keys(this.config.bridgeSensors || []).length > 0) {
- this.config.bridgeSensors
- .filter(
- s =>
- s.hasOwnProperty("deviceId") &&
- this.devicesInEwe.has(s.deviceId.toLowerCase())
- )
- .forEach(s => this.cusS.set(s.fullDeviceId, s));
- }
- //*** Logging always helps to see if everything is okay so far ***\\
- this.log(
- "[%s] eWeLink devices were loaded from the Homebridge cache.",
- this.devicesInHB.size
- );
- this.log(
- "[%s] primary devices were loaded from your eWeLink account.",
- this.devicesInEwe.size
- );
- this.log(
- "[%s] primary devices were discovered on your local network.",
- this.lanDevicesOnline
- );
- //*** Remove Homebridge accessories that don't appear in eWeLink ***\\
- this.devicesInHB.forEach(a => {
- if (!this.devicesInEwe.has(a.context.eweDeviceId)) {
- this.removeAccessory(a);
- }
- });
- //*** Synchronise devices between eWeLink and Homebridge and set up ws/lan listeners ***\\
- this.devicesInEwe.forEach(d => this.initialiseDevice(d));
- this.wsClient.receiveUpdate(d => this.receiveDeviceUpdate(d));
- this.lanClient.receiveUpdate(d => this.receiveDeviceUpdate(d));
- this.log(
- "eWeLink setup complete. If you're enjoying this package please consider a âī¸ on GitHub :)."
- );
- if (this.config.debugReqRes || false) {
- this.log.warn(
- "You have 'Request & Response Logging' enabled. This setting is not recommended for long-term use."
- );
- }
- })();
- })
- .catch(err => {
- this.log.error("************** Cannot load homebridge-ewelink **************");
- this.log.error(err);
- this.log.error("************************************************************");
- if (this.lanClient) this.lanClient.closeConnection();
- if (this.wsClient) this.wsClient.closeConnection();
+ .on("didFinishLaunching", () => this.eWeLinkSync())
+ .on("shutdown", () => {
+ if (this.lanClient) this.lanClient.closeConnection();
+ if (this.wsClient) this.wsClient.closeConnection();
+ });
+ }
+ eWeLinkSync() {
+ this.log("Plugin has finished initialising. Synching with eWeLink.");
+ this.httpClient = new eWeLinkHTTP(this.config, this.log);
+ this.httpClient
+ .getHost()
+ .then(() => this.httpClient.login())
+ .then(res => {
+ this.authData = res;
+ return this.httpClient.getDevices();
+ })
+ .then(res => {
+ res.forEach(device => this.devicesInEW.set(device.deviceid, device));
+ this.wsClient = new eWeLinkWS(this.config, this.log, this.authData);
+ this.lanClient = new eWeLinkLAN(this.config, this.log, res);
+ return this.wsClient.getHost();
+ })
+ .then(() => {
+ this.wsClient.login();
+ return this.lanClient.getHosts();
+ })
+ .then(res => {
+ this.lanDevices = res.map;
+ this.lanCount = res.count;
+ return this.lanClient.startMonitor();
+ })
+ .then(() => {
+ (() => {
+ //*** Make a map of custom groups from Homebridge config ***\\
+ if (Object.keys(this.config.groups || []).length > 0) {
+ this.config.groups
+ .filter(g => g.hasOwnProperty("type") && cns.allowedGroups.includes(g.type))
+ .filter(g => g.hasOwnProperty("deviceId") && this.devicesInEW.has(g.deviceId))
+ .forEach(g => this.cusG.set(g.deviceId + "SWX", g));
+ }
+ //*** Make a map of RF Bridge custom sensors from Homebridge config ***\\
+ if (Object.keys(this.config.bridgeSensors || []).length > 0) {
+ this.config.bridgeSensors
+ .filter(s => s.hasOwnProperty("deviceId") && this.devicesInEW.has(s.deviceId))
+ .forEach(s => this.cusS.set(s.fullDeviceId, s));
+ }
+ //*** Logging always helps to see if everything is okay so far ***\\
+ this.log("[%s] eWeLink devices loaded from the Homebridge cache.", this.devicesInHB.size);
+ this.log("[%s] primary devices loaded from your eWeLink account.", this.devicesInEW.size);
+ this.log("[%s] primary devices were discovered on your local network.", this.lanCount);
+ //*** Remove Homebridge accessories that don't appear in eWeLink ***\\
+ this.devicesInHB.forEach(a => {
+ if (!this.devicesInEW.has(a.context.eweDeviceId)) {
+ this.removeAccessory(a);
+ }
});
+ //*** Synchronise devices between eWeLink and Homebridge and set up ws/lan listeners ***\\
+ this.devicesInEW.forEach(d => this.initialiseDevice(d));
+ this.wsClient.receiveUpdate(d => this.receiveDeviceUpdate(d));
+ this.lanClient.receiveUpdate(d => this.receiveDeviceUpdate(d));
+ this.log("eWeLink sync complete. Don't forget to âī¸ this plugin on GitHub!");
+ if (this.config.debugReqRes || false) {
+ this.log.warn("Note: 'Request & Response Logging' is not advised for long-term use.");
+ }
+ })();
})
- .on("shutdown", () => {
+ .catch(err => {
+ this.log.error("************** Cannot load homebridge-ewelink **************");
+ this.log.error(err);
+ this.log.error("************************************************************");
if (this.lanClient) this.lanClient.closeConnection();
if (this.wsClient) this.wsClient.closeConnection();
});
}
initialiseDevice(device) {
let accessory;
- //*** First add the device if it isn't already in Homebridge. Yeah this code looks a mess :| ***\\
+ //*** First add the device if it isn't already in Homebridge ***\\
+
+ //*** IRRIGATION VALVES ***\\
if (
- !this.devicesInHB.has(device.deviceid + "SWX") &&
- !this.devicesInHB.has(device.deviceid + "SW0")
+ device.extra.uiid === 2 &&
+ device.brandName === "coolkit" &&
+ device.productModel === "0285"
) {
- if (
- device.extra.uiid === 2 &&
- device.brandName === "coolkit" &&
- device.productModel === "0285"
- ) {
- this.addAccessory(device, device.deviceid + "SWX", "valve");
- } else if (
- this.cusG.has(device.deviceid + "SWX") &&
- this.cusG.get(device.deviceid + "SWX").type === "blind"
- ) {
- this.addAccessory(device, device.deviceid + "SWX", "blind");
- } else if (
- this.cusG.has(device.deviceid + "SWX") &&
- this.cusG.get(device.deviceid + "SWX").type === "garage"
- ) {
- this.addAccessory(device, device.deviceid + "SWX", "garage");
- } else if (
- this.cusG.has(device.deviceid + "SWX") &&
- this.cusG.get(device.deviceid + "SWX").type === "lock"
- ) {
- this.addAccessory(device, device.deviceid + "SWX", "lock");
- } else if (cns.devicesSensor.includes(device.extra.uiid)) {
- this.addAccessory(device, device.deviceid + "SWX", "sensor");
- } else if (cns.devicesFan.includes(device.extra.uiid)) {
- this.addAccessory(device, device.deviceid + "SWX", "fan");
- } else if (cns.devicesThermostat.includes(device.extra.uiid)) {
- this.addAccessory(device, device.deviceid + "SWX", "thermostat");
- } else if (cns.devicesOutlet.includes(device.extra.uiid)) {
- this.addAccessory(device, device.deviceid + "SWX", "outlet");
- } else if (cns.devicesUSB.includes(device.extra.uiid)) {
- this.addAccessory(device, device.deviceid + "SWX", "usb");
- } else if (cns.devicesSCM.includes(device.extra.uiid)) {
- this.addAccessory(device, device.deviceid + "SWX", "scm");
- } else if (
- cns.devicesSingleSwitch.includes(device.extra.uiid) &&
- cns.devicesSingleSwitchLight.includes(device.productModel)
- ) {
- this.addAccessory(device, device.deviceid + "SWX", "light");
- } else if (
- cns.devicesMultiSwitch.includes(device.extra.uiid) &&
- cns.devicesMultiSwitchLight.includes(device.productModel)
- ) {
- for (let i = 0; i <= cns.chansFromUiid[device.extra.uiid]; i++) {
- this.addAccessory(device, device.deviceid + "SW" + i, "light");
- }
- } else if (cns.devicesSingleSwitch.includes(device.extra.uiid)) {
- this.addAccessory(device, device.deviceid + "SWX", "switch");
- } else if (cns.devicesMultiSwitch.includes(device.extra.uiid)) {
- for (let i = 0; i <= cns.chansFromUiid[device.extra.uiid]; i++) {
- this.addAccessory(device, device.deviceid + "SW" + i, "switch");
+ accessory = this.devicesInHB.has(device.deviceid + "SWX")
+ ? this.devicesInHB.get(device.deviceid + "SWX")
+ : this.addAccessory(device, device.deviceid + "SWX", "valve");
+ }
+
+ //*** WINDOW BLINDS ***\\
+ else if (
+ this.cusG.has(device.deviceid + "SWX") &&
+ this.cusG.get(device.deviceid + "SWX").type === "blind"
+ ) {
+ accessory = this.devicesInHB.has(device.deviceid + "SWX")
+ ? this.devicesInHB.get(device.deviceid + "SWX")
+ : this.addAccessory(device, device.deviceid + "SWX", "blind");
+ }
+
+ //*** GARAGES ***\\
+ else if (
+ this.cusG.has(device.deviceid + "SWX") &&
+ this.cusG.get(device.deviceid + "SWX").type === "garage"
+ ) {
+ accessory = this.devicesInHB.has(device.deviceid + "SWX")
+ ? this.devicesInHB.get(device.deviceid + "SWX")
+ : this.addAccessory(device, device.deviceid + "SWX", "garage");
+ }
+
+ //*** LOCKS ***\\
+ else if (
+ this.cusG.has(device.deviceid + "SWX") &&
+ this.cusG.get(device.deviceid + "SWX").type === "lock"
+ ) {
+ accessory = this.devicesInHB.has(device.deviceid + "SWX")
+ ? this.devicesInHB.get(device.deviceid + "SWX")
+ : this.addAccessory(device, device.deviceid + "SWX", "lock");
+ }
+
+ //*** DW2 SENSORS ***\\
+ else if (cns.devicesSensor.includes(device.extra.uiid)) {
+ accessory = this.devicesInHB.has(device.deviceid + "SWX")
+ ? this.devicesInHB.get(device.deviceid + "SWX")
+ : this.addAccessory(device, device.deviceid + "SWX", "sensor");
+ }
+
+ //*** FANS ***\\
+ else if (cns.devicesFan.includes(device.extra.uiid)) {
+ accessory = this.devicesInHB.has(device.deviceid + "SWX")
+ ? this.devicesInHB.get(device.deviceid + "SWX")
+ : this.addAccessory(device, device.deviceid + "SWX", "fan");
+ }
+
+ //*** THERMOSTATS ***\\
+ else if (cns.devicesThermostat.includes(device.extra.uiid)) {
+ accessory = this.devicesInHB.has(device.deviceid + "SWX")
+ ? this.devicesInHB.get(device.deviceid + "SWX")
+ : this.addAccessory(device, device.deviceid + "SWX", "thermostat");
+ }
+
+ //*** OUTLETS ***\\
+ else if (cns.devicesOutlet.includes(device.extra.uiid)) {
+ accessory = this.devicesInHB.has(device.deviceid + "SWX")
+ ? this.devicesInHB.get(device.deviceid + "SWX")
+ : this.addAccessory(device, device.deviceid + "SWX", "outlet");
+ }
+
+ //*** USB OUTLETS ***\\
+ else if (cns.devicesUSB.includes(device.extra.uiid)) {
+ accessory = this.devicesInHB.has(device.deviceid + "SWX")
+ ? this.devicesInHB.get(device.deviceid + "SWX")
+ : this.addAccessory(device, device.deviceid + "SWX", "usb");
+ }
+
+ //*** SINGLE CHANNEL [MULTI CHANNEL HARDWARE] ***\\
+ else if (cns.devicesSCM.includes(device.extra.uiid)) {
+ accessory = this.devicesInHB.has(device.deviceid + "SWX")
+ ? this.devicesInHB.get(device.deviceid + "SWX")
+ : this.addAccessory(device, device.deviceid + "SWX", "scm");
+ }
+
+ //*** SINGLE CHANNEL LIGHTS ***\\
+ else if (
+ cns.devicesSingleSwitch.includes(device.extra.uiid) &&
+ cns.devicesSingleSwitchLight.includes(device.productModel)
+ ) {
+ accessory = this.devicesInHB.has(device.deviceid + "SWX")
+ ? this.devicesInHB.get(device.deviceid + "SWX")
+ : this.addAccessory(device, device.deviceid + "SWX", "light");
+ }
+
+ //*** MULTI CHANNEL LIGHTS ***\\
+ else if (
+ cns.devicesMultiSwitch.includes(device.extra.uiid) &&
+ cns.devicesMultiSwitchLight.includes(device.productModel)
+ ) {
+ if (this.config.hideMasters) {
+ if (this.devicesInHB.has(device.deviceid + "SW0")) {
+ this.removeAccessory(this.devicesInHB.get(device.deviceid + "SW0"));
}
- } else if (cns.devicesRFBridge.includes(device.extra.uiid)) {
- this.addAccessory(device, device.deviceid + "SW0", "rf_pri");
- if (Object.keys((device.tags && device.tags.zyx_info) || []).length > 0) {
- for (let i = 1; i <= Object.keys(device.tags.zyx_info).length; i++) {
- this.addAccessory(device, device.deviceid + "SW" + i, "rf_sub");
+ this.hiddenMasters.push(device.deviceid);
+ accessory = this.addAccessory(device, device.deviceid + "SW0", "light", true);
+ } else {
+ accessory = this.devicesInHB.has(device.deviceid + "SW0")
+ ? this.devicesInHB.get(device.deviceid + "SW0")
+ : this.addAccessory(device, device.deviceid + "SW0", "light");
+ }
+ for (let i = 1; i <= cns.chansFromUiid[device.extra.uiid]; i++) {
+ if ((this.config.hideFromHB || "").includes(device.deviceid + "SW" + i)) {
+ if (this.devicesInHB.has(device.deviceid + "SW" + i)) {
+ this.removeAccessory(this.devicesInHB.get(device.deviceid + "SW" + i));
}
+ } else {
+ let oAccessory = this.devicesInHB.has(device.deviceid + "SW" + i)
+ ? this.devicesInHB.get(device.deviceid + "SW" + i)
+ : this.addAccessory(device, device.deviceid + "SW" + i, "light");
+ oAccessory
+ .getService(Service.AccessoryInformation)
+ .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion);
+ oAccessory.context.reachableWAN = device.online;
+ oAccessory.context.reachableLAN = this.lanDevices.get(device.deviceid).online || false;
+ this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory);
}
- } else if (cns.devicesZBBridge.includes(device.extra.uiid)) {
- this.addAccessory(device, device.deviceid + "SWX", "zb_pri");
- } else if (cns.devicesZB.includes(device.extra.uiid)) {
- this.addAccessory(device, device.deviceid + "SWX", "zb_sub");
- } else if (cns.devicesCamera.includes(device.extra.uiid)) {
- this.log.warn(
- '[%s] please see "https://github.com/bwp91/homebridge-ewelink/wiki/How-to-set-up-Sonoff-Camera".',
- device.name
- );
- return;
- } else {
- this.log.warn(
- "[%s] cannot be added as it is not supported by this plugin. Please make a GitHub issue request.",
- device.name
- );
- return;
}
}
- //*** Next refresh the device ***\\
- if (
- (accessory =
- this.devicesInHB.get(device.deviceid + "SWX") ||
- this.devicesInHB.get(device.deviceid + "SW0"))
- ) {
- let isX = accessory.context.hbDeviceId.substr(-1) === "X",
- isRfBridge = cns.devicesRFBridge.includes(accessory.context.eweUIID),
- rfBridgeChange = false;
- accessory
- .getService(Service.AccessoryInformation)
- .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion);
- accessory.context.reachableWAN = accessory.context.eweUIID !== 102 ? device.online : true;
- accessory.context.reachableLAN = this.lanDevices.get(device.deviceid).online || false;
- accessory.context.inUse = false;
- let str = accessory.context.reachableLAN
- ? "and locally with IP [" + this.lanDevices.get(device.deviceid).ip + "]"
- : "but LAN mode unavailable as unsupported/shared device";
- this.log("[%s] found in eWeLink %s.", accessory.displayName, str);
- this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
- if (!isX) {
- for (let i = 1; i <= accessory.context.channelCount; i++) {
- if (!this.devicesInHB.has(device.deviceid + "SW" + i)) {
- if (cns.devicesHideable.includes(accessory.context.type)) {
- if ((this.config.hideFromHB || "").includes(device.deviceid + "SW" + i)) {
- continue;
- } else {
- this.addAccessory(device, device.deviceid + "SW" + i, "switch");
- }
- }
- }
- let oAccessory = this.devicesInHB.get(device.deviceid + "SW" + i);
- if (
- (this.config.hideFromHB || "").includes(device.deviceid + "SW" + i) &&
- cns.devicesHideable.includes(accessory.context.type)
- ) {
- this.removeAccessory(oAccessory);
- continue;
- }
- if (isRfBridge && oAccessory.context.sensorType !== "button") {
- let ct = this.cusS.has(oAccessory.context.hbDeviceId)
- ? this.cusS.get(oAccessory.context.hbDeviceId).type
- : "motion";
- if (ct !== oAccessory.context.sensorType) rfBridgeChange = true;
+
+ //*** SINGLE CHANNEL SWITCHES ***\\
+ else if (cns.devicesSingleSwitch.includes(device.extra.uiid)) {
+ accessory = this.devicesInHB.has(device.deviceid + "SWX")
+ ? this.devicesInHB.get(device.deviceid + "SWX")
+ : this.addAccessory(device, device.deviceid + "SWX", "switch");
+ }
+
+ //*** MULTI CHANNEL SWITCHES ***\\
+ else if (cns.devicesMultiSwitch.includes(device.extra.uiid)) {
+ if (this.config.hideMasters) {
+ if (this.devicesInHB.has(device.deviceid + "SW0")) {
+ this.removeAccessory(this.devicesInHB.get(device.deviceid + "SW0"));
+ }
+ this.hiddenMasters.push(device.deviceid);
+ accessory = this.addAccessory(device, device.deviceid + "SW0", "switch", true);
+ } else {
+ accessory = this.devicesInHB.has(device.deviceid + "SW0")
+ ? this.devicesInHB.get(device.deviceid + "SW0")
+ : this.addAccessory(device, device.deviceid + "SW0", "switch");
+ }
+ for (let i = 1; i <= cns.chansFromUiid[device.extra.uiid]; i++) {
+ if ((this.config.hideFromHB || "").includes(device.deviceid + "SW" + i)) {
+ if (this.devicesInHB.has(device.deviceid + "SW" + i)) {
+ this.removeAccessory(this.devicesInHB.get(device.deviceid + "SW" + i));
}
+ } else {
+ let oAccessory = this.devicesInHB.has(device.deviceid + "SW" + i)
+ ? this.devicesInHB.get(device.deviceid + "SW" + i)
+ : this.addAccessory(device, device.deviceid + "SW" + i, "switch");
oAccessory
.getService(Service.AccessoryInformation)
.setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion);
@@ -282,31 +272,118 @@ class eWeLink {
this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory);
}
}
- if (rfBridgeChange) {
- this.log.warn(
- "[%s] bridge configuration changed so devices will be removed and readded.",
- accessory.displayName
- );
- for (let i = 0; i <= accessory.context.channelCount; i++) {
- let oAccessory = this.devicesInHB.get(device.deviceid + "SW" + i);
- this.removeAccessory(oAccessory);
+ }
+
+ //*** RF BRIDGES ***\\
+ else if (cns.devicesRFBridge.includes(device.extra.uiid)) {
+ accessory = this.devicesInHB.has(device.deviceid + "SW0")
+ ? this.devicesInHB.get(device.deviceid + "SW0")
+ : this.addAccessory(device, device.deviceid + "SW0", "rf_pri");
+ if (Object.keys((device.tags && device.tags.zyx_info) || []).length > 0) {
+ let rfBridgeChange = false;
+ for (let i = 1; i <= Object.keys(device.tags.zyx_info).length; i++) {
+ let oAccessory = this.devicesInHB.has(device.deviceid + "SW" + i)
+ ? this.devicesInHB.get(device.deviceid + "SW" + i)
+ : this.addAccessory(device, device.deviceid + "SW" + i, "rf_sub");
+ oAccessory
+ .getService(Service.AccessoryInformation)
+ .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion);
+ oAccessory.context.reachableWAN = device.online;
+ oAccessory.context.reachableLAN = this.lanDevices.get(device.deviceid).online || false;
+ this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory);
+ if (oAccessory.context.sensorType !== "button" && !rfBridgeChange) {
+ let ct = this.cusS.has(oAccessory.context.hbDeviceId)
+ ? this.cusS.get(oAccessory.context.hbDeviceId).type
+ : "motion";
+ if (ct !== oAccessory.context.sensorType) rfBridgeChange = true;
+ }
+ }
+ if (rfBridgeChange) {
+ this.log.warn(
+ "[%s] bridge configuration changed so devices will be removed and readded.",
+ accessory.displayName
+ );
+ for (let i = 0; i <= accessory.context.channelCount; i++) {
+ let oAccessory = this.devicesInHB.get(device.deviceid + "SW" + i);
+ this.removeAccessory(oAccessory);
+ }
+ this.initialiseDevice(device);
+ return;
}
- this.initialiseDevice(device);
- return;
}
- if (!this.refreshAccessory(accessory, device.params)) {
- this.log.warn(
- "[%s] could not be initialised. Please try removing accessory from the Homebridge cache along with any secondary devices (SW1, SW2, etc.) [debug:%s:%s].",
- accessory.displayName,
- accessory.context.type,
- accessory.context.channelCount
- );
+ }
+
+ //*** ZIGBEE BRIDGES ***\\
+ else if (cns.devicesZBBridge.includes(device.extra.uiid)) {
+ accessory = this.devicesInHB.has(device.deviceid + "SWX")
+ ? this.devicesInHB.get(device.deviceid + "SWX")
+ : this.addAccessory(device, device.deviceid + "SWX", "zb_pri");
+ }
+
+ //*** ZIGBEE DEVICES ***\\
+ else if (cns.devicesZB.includes(device.extra.uiid)) {
+ accessory = this.devicesInHB.has(device.deviceid + "SWX")
+ ? this.devicesInHB.get(device.deviceid + "SWX")
+ : this.addAccessory(device, device.deviceid + "SWX", "zb_sub");
+ }
+
+ //*** SONOFF CAMERAS ***\\
+ else if (cns.devicesCamera.includes(device.extra.uiid)) {
+ this.log.warn(
+ ' â [%s] please see "https://github.com/bwp91/homebridge-ewelink/wiki/How-to-set-up-Sonoff-Camera".',
+ device.name
+ );
+ return;
+ }
+
+ //*** ALL OTHER = UNSUPPORTED ***\\
+ else {
+ this.log.warn(
+ " â [%s] cannot be added as it is not supported by this plugin. Please make a GitHub issue request.",
+ device.name
+ );
+ return;
+ }
+
+ if (!accessory) {
+ return;
+ }
+ //*** Next refresh the device ***\\
+ if (!this.hiddenMasters.includes(device.deviceid)) {
+ accessory
+ .getService(Service.AccessoryInformation)
+ .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion);
+ }
+ accessory.context.reachableWAN = device.online;
+ accessory.context.reachableLAN = this.lanDevices.get(device.deviceid).online || false;
+ accessory.context.inUse = false;
+
+ let str = accessory.context.reachableLAN
+ ? "and found locally with IP [" + this.lanDevices.get(device.deviceid).ip + "]"
+ : "but LAN mode unavailable as device ";
+ if (!accessory.context.reachableLAN) {
+ if (cns.devicesNonLAN.includes(device.extra.uiid)) {
+ str += "doesn't support it";
+ } else if (device.hasOwnProperty("sharedBy") && device.sharedBy.hasOwnProperty("email")) {
+ str += "is shared (" + device.sharedBy.email + ")";
+ } else {
+ str += "is unreachable";
}
- } else {
- this.log.warn("[%s] cannot be initialised as it wasn't found in Homebridge.", device.name);
+ }
+
+ this.log(" â [%s] initialised %s.", device.name, str);
+ this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
+
+ if (!this.refreshAccessory(accessory, device.params)) {
+ this.log.warn(
+ "[%s] could not be initialised. Please try removing accessory from the Homebridge cache along with any secondary devices (SW1, SW2, etc.) [debug:%s:%s].",
+ accessory.displayName,
+ accessory.context.type,
+ accessory.context.channelCount
+ );
}
}
- addAccessory(device, hbDeviceId, type) {
+ addAccessory(device, hbDeviceId, type, hidden = false) {
let switchNumber = hbDeviceId.substr(-1).toString(),
newDeviceName = type === "rf_sub" ? device.tags.zyx_info[switchNumber - 1].name : device.name,
channelCount =
@@ -315,29 +392,24 @@ class eWeLink {
: cns.chansFromUiid[device.extra.uiid];
if (["1", "2", "3", "4"].includes(switchNumber) && type !== "rf_sub") {
newDeviceName += " SW" + switchNumber;
- if (
- (this.config.hideFromHB || "").includes(hbDeviceId) &&
- cns.devicesHideable.includes(type)
- ) {
- this.log("[%s] will not be added as per configuration.", newDeviceName);
- return;
- }
}
if ((this.config.nameOverride || {}).hasOwnProperty(hbDeviceId)) {
newDeviceName = this.config.nameOverride[hbDeviceId];
}
- const accessory = new Accessory(newDeviceName, UUIDGen.generate(hbDeviceId).toString());
try {
- accessory
- .getService(Service.AccessoryInformation)
- .setCharacteristic(Characteristic.SerialNumber, hbDeviceId)
- .setCharacteristic(Characteristic.Manufacturer, device.brandName)
- .setCharacteristic(
- Characteristic.Model,
- device.productModel + " (" + device.extra.model + ")"
- )
- .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion)
- .setCharacteristic(Characteristic.Identify, false);
+ const accessory = new Accessory(newDeviceName, UUIDGen.generate(hbDeviceId).toString());
+ if (!hidden) {
+ accessory
+ .getService(Service.AccessoryInformation)
+ .setCharacteristic(Characteristic.SerialNumber, hbDeviceId)
+ .setCharacteristic(Characteristic.Manufacturer, device.brandName)
+ .setCharacteristic(
+ Characteristic.Model,
+ device.productModel + " (" + device.extra.model + ")"
+ )
+ .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion)
+ .setCharacteristic(Characteristic.Identify, false);
+ }
accessory.context = {
hbDeviceId,
eweDeviceId: device.deviceid,
@@ -348,197 +420,15 @@ class eWeLink {
channelCount,
type,
};
- switch (type) {
- case "valve":
- ["A", "B"].forEach(v => {
- accessory
- .addService(Service.Valve, "Valve " + v, "valve" + v.toLowerCase())
- .setCharacteristic(Characteristic.Active, 0)
- .setCharacteristic(Characteristic.InUse, 0)
- .setCharacteristic(Characteristic.ValveType, 1)
- .setCharacteristic(Characteristic.SetDuration, this.config.valveTimeLength || 120)
- .addCharacteristic(Characteristic.RemainingDuration);
- });
- break;
- case "blind":
- accessory
- .addService(Service.WindowCovering)
- .setCharacteristic(Characteristic.CurrentPosition, 100)
- .setCharacteristic(Characteristic.TargetPosition, 100)
- .setCharacteristic(Characteristic.PositionState, 2);
- break;
- case "garage":
- accessory
- .addService(Service.GarageDoorOpener)
- .setCharacteristic(Characteristic.CurrentDoorState, 1)
- .setCharacteristic(Characteristic.TargetDoorState, 1)
- .setCharacteristic(Characteristic.ObstructionDetected, false);
- break;
- case "lock":
- accessory
- .addService(Service.LockMechanism)
- .setCharacteristic(Characteristic.LockCurrentState, 1)
- .setCharacteristic(Characteristic.LockTargetState, 1);
- break;
- case "sensor":
- accessory.addService(Service.ContactSensor);
- accessory.addService(Service.BatteryService);
- break;
- case "fan":
- accessory.addService(Service.Fanv2);
- accessory.addService(Service.Lightbulb);
- break;
- case "thermostat":
- if (!this.config.hideTHSwitch) accessory.addService(Service.Switch);
- accessory.addService(Service.TemperatureSensor);
- if (device.params.sensorType !== "DS18B20") accessory.addService(Service.HumiditySensor);
- break;
- case "outlet":
- accessory.addService(Service.Outlet);
- accessory
- .getService(Service.Outlet)
- .addCharacteristic(EveService.Characteristics.Voltage);
- accessory
- .getService(Service.Outlet)
- .addCharacteristic(EveService.Characteristics.CurrentConsumption);
- accessory
- .getService(Service.Outlet)
- .addCharacteristic(EveService.Characteristics.ElectricCurrent);
- accessory
- .getService(Service.Outlet)
- .addCharacteristic(EveService.Characteristics.TotalConsumption);
- accessory
- .getService(Service.Outlet)
- .addCharacteristic(EveService.Characteristics.ResetTotal);
- accessory.context = {
- ...accessory.context,
- ...{
- extraPersistedData: {},
- lastReset: 0,
- totalEnergy: 0,
- totalEnergyTemp: 0,
- },
- };
- break;
- case "usb":
- accessory.addService(Service.Outlet);
- break;
- case "light":
- accessory.addService(Service.Lightbulb);
- break;
- case "switch":
- case "scm":
- accessory.addService(Service.Switch);
- break;
- case "rf_pri":
- accessory.context.rfChlMap = {};
- break;
- case "zb_pri":
- break;
- case "rf_sub":
- accessory.context.rfChls = {};
- switch (device.tags.zyx_info[parseInt(switchNumber) - 1].remote_type) {
- case "1":
- case "2":
- case "3":
- case "4":
- accessory.context.sensorType = "button";
- break;
- case "6":
- accessory.context.sensorType = this.cusS.has(hbDeviceId)
- ? this.cusS.get(hbDeviceId).type
- : "motion";
- break;
- default:
- throw (
- "unsupported rf device type [" +
- device.tags.zyx_info[parseInt(switchNumber) - 1].remote_type +
- "]. Please create an issue on GitHub"
- );
- }
- let mAccessory = this.devicesInHB.get(device.deviceid + "SW0");
- device.tags.zyx_info[parseInt(switchNumber) - 1].buttonName.forEach(button => {
- let rfData;
- Object.entries(button).forEach(
- ([k, v]) =>
- (rfData = {
- rfChan: k,
- name: v,
- })
- );
- accessory.context.rfChls[rfData.rfChan] = rfData.name;
- mAccessory.context.rfChlMap[rfData.rfChan] = switchNumber;
- switch (accessory.context.sensorType) {
- case "button":
- accessory.addService(Service.Switch, rfData.name, "switch" + rfData.rfChan);
- break;
- case "water":
- accessory.addService(Service.LeakSensor);
- break;
- case "fire":
- case "smoke":
- accessory.addService(Service.SmokeSensor);
- break;
- case "co":
- accessory.addService(Service.CarbonMonoxideSensor);
- break;
- case "co2":
- accessory.addService(Service.CarbonDioxideSensor);
- break;
- case "contact":
- accessory.addService(Service.ContactSensor);
- break;
- case "occupancy":
- accessory.addService(Service.OccupancySensor);
- break;
- default:
- accessory.addService(Service.MotionSensor);
- break;
- }
- this.devicesInHB.set(mAccessory.context.hbDeviceId, mAccessory);
- });
- break;
- case "zb_sub": //*** credit @tasict ***\\
- accessory.addService(Service.BatteryService);
- switch (device.extra.uiid) {
- case 1000:
- accessory.addService(Service.StatelessProgrammableSwitch);
- if (this.config.hideZBLDPress) {
- accessory
- .getService(Service.StatelessProgrammableSwitch)
- .getCharacteristic(Characteristic.ProgrammableSwitchEvent)
- .setProps({
- validValues: [0],
- });
- }
- break;
- case 1770:
- accessory.addService(Service.TemperatureSensor);
- accessory.addService(Service.HumiditySensor);
- break;
- case 2026:
- accessory.addService(Service.MotionSensor);
- break;
- case 3026:
- accessory.addService(Service.ContactSensor);
- break;
- default:
- throw (
- "unsupported zigbee device type [" +
- device.extra.uiid +
- "]. Please create an issue on GitHub"
- );
- }
- break;
- default:
- throw "device is not supported by this plugin. Please create an issue on GitHub";
+ if (!hidden) {
+ this.api.registerPlatformAccessories("homebridge-ewelink", "eWeLink", [accessory]);
+ this.configureAccessory(accessory);
+ this.log(" â [%s] has been added to Homebridge.", newDeviceName);
}
- this.devicesInHB.set(hbDeviceId, accessory);
- this.api.registerPlatformAccessories("homebridge-ewelink", "eWeLink", [accessory]);
- this.configureAccessory(accessory);
- this.log("[%s] has been added to Homebridge.", newDeviceName);
+ return accessory;
} catch (err) {
- this.log.warn("[%s] could not be added as %s.", newDeviceName, err);
+ this.log.warn(" â [%s] could not be added as %s.", newDeviceName, err);
+ return false;
}
}
configureAccessory(accessory) {
@@ -549,25 +439,30 @@ class eWeLink {
switch (accessory.context.type) {
case "valve":
["A", "B"].forEach(v => {
- accessory
- .getService("Valve " + v)
+ let valveService;
+ if (!(valveService = accessory.getService("Valve " + v))) {
+ accessory
+ .addService(Service.Valve, "Valve " + v, "valve" + v.toLowerCase())
+ .setCharacteristic(Characteristic.Active, 0)
+ .setCharacteristic(Characteristic.InUse, 0)
+ .setCharacteristic(Characteristic.ValveType, 1)
+ .setCharacteristic(Characteristic.SetDuration, this.config.valveTimeLength || 120)
+ .addCharacteristic(Characteristic.RemainingDuration);
+ valveService = accessory.getService("Valve " + v);
+ }
+ valveService
.getCharacteristic(Characteristic.Active)
.on("set", (value, callback) =>
this.internalValveUpdate(accessory, "Valve " + v, value, callback)
);
- accessory
- .getService("Valve " + v)
+ valveService
.getCharacteristic(Characteristic.SetDuration)
.on("set", (value, callback) => {
- if (
- accessory.getService("Valve " + v).getCharacteristic(Characteristic.InUse).value
- ) {
- accessory
- .getService("Valve " + v)
- .updateCharacteristic(Characteristic.RemainingDuration, value);
- clearTimeout(accessory.getService("Valve " + v).timer);
- accessory.getService("Valve " + v).timer = setTimeout(() => {
- accessory.getService("Valve " + v).setCharacteristic(Characteristic.Active, 0);
+ if (valveService.getCharacteristic(Characteristic.InUse).value) {
+ valveService.updateCharacteristic(Characteristic.RemainingDuration, value);
+ clearTimeout(valveService.timer);
+ valveService.timer = setTimeout(() => {
+ valveService.setCharacteristic(Characteristic.Active, 0);
}, value * 1000);
}
callback();
@@ -575,8 +470,16 @@ class eWeLink {
});
break;
case "blind":
- accessory
- .getService(Service.WindowCovering)
+ let wcService;
+ if (!(wcService = accessory.getService(Service.WindowCovering))) {
+ accessory
+ .addService(Service.WindowCovering)
+ .setCharacteristic(Characteristic.CurrentPosition, 100)
+ .setCharacteristic(Characteristic.TargetPosition, 100)
+ .setCharacteristic(Characteristic.PositionState, 2);
+ wcService = accessory.getService(Service.WindowCovering);
+ }
+ wcService
.getCharacteristic(Characteristic.TargetPosition)
.on("set", (value, callback) => this.internalBlindUpdate(accessory, value, callback))
.setProps({
@@ -584,26 +487,44 @@ class eWeLink {
});
break;
case "garage":
- accessory
- .getService(Service.GarageDoorOpener)
+ let gdService;
+ if (!(gdService = accessory.getService(Service.GarageDoorOpener))) {
+ accessory
+ .addService(Service.GarageDoorOpener)
+ .setCharacteristic(Characteristic.CurrentDoorState, 1)
+ .setCharacteristic(Characteristic.TargetDoorState, 1)
+ .setCharacteristic(Characteristic.ObstructionDetected, false);
+ gdService = accessory.getService(Service.GarageDoorOpener);
+ }
+ gdService
.getCharacteristic(Characteristic.TargetDoorState)
.on("set", (value, callback) => this.internalGarageUpdate(accessory, value, callback));
break;
case "lock":
- accessory
- .getService(Service.LockMechanism)
+ let lmService =
+ accessory.getService(Service.LockMechanism) ||
+ accessory.addService(Service.LockMechanism);
+ lmService
.getCharacteristic(Characteristic.LockTargetState)
.on("set", (value, callback) => this.internalLockUpdate(accessory, value, callback));
break;
+ case "sensor":
+ accessory.getService(Service.ContactSensor) ||
+ accessory.addService(Service.ContactSensor);
+ accessory.getService(Service.BatteryService) ||
+ accessory.addService(Service.BatteryService);
+ break;
case "fan":
- accessory
- .getService(Service.Fanv2)
+ let fanService =
+ accessory.getService(Service.Fanv2) || accessory.addService(Service.Fanv2),
+ fanLightService =
+ accessory.getService(Service.Lightbulb) || accessory.addService(Service.Lightbulb);
+ fanService
.getCharacteristic(Characteristic.Active)
.on("set", (value, callback) =>
this.internalFanUpdate(accessory, "power", value, callback)
);
- accessory
- .getService(Service.Fanv2)
+ fanService
.getCharacteristic(Characteristic.RotationSpeed)
.on("set", (value, callback) =>
this.internalFanUpdate(accessory, "speed", value, callback)
@@ -611,17 +532,26 @@ class eWeLink {
.setProps({
minStep: 33,
});
- accessory
- .getService(Service.Lightbulb)
+ fanLightService
.getCharacteristic(Characteristic.On)
.on("set", (value, callback) =>
this.internalFanUpdate(accessory, "light", value, callback)
);
break;
case "thermostat":
+ let tempService =
+ accessory.getService(Service.TemperatureSensor) ||
+ accessory.addService(Service.TemperatureSensor),
+ humiService = false;
+ if (this.devicesInEW.get(accessory.context.eweDeviceId).params.sensorType !== "DS18B20") {
+ humiService =
+ accessory.getService(Service.HumiditySensor) ||
+ accessory.addService(Service.HumiditySensor);
+ }
if (!this.config.hideTHSwitch) {
- accessory
- .getService(Service.Switch)
+ let switchService =
+ accessory.getService(Service.Switch) || accessory.addService(Service.Switch);
+ switchService
.getCharacteristic(Characteristic.On)
.on("set", (value, callback) =>
this.internalThermostatUpdate(accessory, value, callback)
@@ -636,30 +566,24 @@ class eWeLink {
corrInterval.setCorrectingInterval(() => {
let dataToAdd = {
time: Date.now(),
- temp: accessory
- .getService(Service.TemperatureSensor)
- .getCharacteristic(Characteristic.CurrentTemperature).value,
+ temp: tempService.getCharacteristic(Characteristic.CurrentTemperature).value,
};
- if (accessory.getService(Service.HumiditySensor)) {
- dataToAdd.humidity = accessory
- .getService(Service.HumiditySensor)
- .getCharacteristic(Characteristic.CurrentRelativeHumidity).value;
+ if (humiService) {
+ humiService.getCharacteristic(Characteristic.CurrentRelativeHumidity).value;
}
accessory.eveLogger.addEntry(dataToAdd);
}, 300000);
break;
case "outlet":
- accessory
- .getService(Service.Outlet)
- .getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => this.internalOutletUpdate(accessory, value, callback));
- accessory.log = this.log;
- accessory.eveLogger = new EveHistoryService("energy", accessory, {
- storage: "fs",
- minutes: 5,
- path: this.eveLogPath,
- });
- if (!accessory.context.hasOwnProperty("lastReset")) {
+ let outletService;
+ if (!(outletService = accessory.getService(Service.Outlet))) {
+ accessory.addService(Service.Outlet);
+ outletService = accessory.getService(Service.Outlet);
+ outletService.addCharacteristic(EveService.Characteristics.Voltage);
+ outletService.addCharacteristic(EveService.Characteristics.CurrentConsumption);
+ outletService.addCharacteristic(EveService.Characteristics.ElectricCurrent);
+ outletService.addCharacteristic(EveService.Characteristics.TotalConsumption);
+ outletService.addCharacteristic(EveService.Characteristics.ResetTotal);
accessory.context = {
...accessory.context,
...{
@@ -670,13 +594,20 @@ class eWeLink {
},
};
}
+ outletService
+ .getCharacteristic(Characteristic.On)
+ .on("set", (value, callback) => this.internalOutletUpdate(accessory, value, callback));
+ accessory.log = this.log;
+ accessory.eveLogger = new EveHistoryService("energy", accessory, {
+ storage: "fs",
+ minutes: 5,
+ path: this.eveLogPath,
+ });
corrInterval.setCorrectingInterval(() => {
- let isOn = accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On)
- .value,
+ let isOn = outletService.getCharacteristic(Characteristic.On).value,
currentWatt = isOn
- ? accessory
- .getService(Service.Outlet)
- .getCharacteristic(EveService.Characteristics.CurrentConsumption).value
+ ? outletService.getCharacteristic(EveService.Characteristics.CurrentConsumption)
+ .value
: 0;
if (accessory.eveLogger.isHistoryLoaded()) {
accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData();
@@ -707,8 +638,7 @@ class eWeLink {
power: currentWatt,
});
}, 300000);
- accessory
- .getService(Service.Outlet)
+ outletService
.getCharacteristic(EveService.Characteristics.TotalConsumption)
.on("get", callback => {
accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData();
@@ -717,8 +647,7 @@ class eWeLink {
}
callback(null, accessory.context.totalEnergy);
});
- accessory
- .getService(Service.Outlet)
+ outletService
.getCharacteristic(EveService.Characteristics.ResetTotal)
.on("set", (value, callback) => {
accessory.context.totalEnergy = 0;
@@ -738,34 +667,33 @@ class eWeLink {
});
break;
case "usb":
- accessory
- .getService(Service.Outlet)
+ let usbService =
+ accessory.getService(Service.Outlet) || accessory.addService(Service.Outlet);
+ usbService
.getCharacteristic(Characteristic.On)
.on("set", (value, callback) => this.internalUSBUpdate(accessory, value, callback));
break;
case "scm":
- accessory
- .getService(Service.Switch)
+ let scmService =
+ accessory.getService(Service.Switch) || accessory.addService(Service.Switch);
+ scmService
.getCharacteristic(Characteristic.On)
.on("set", (value, callback) => this.internalSCMUpdate(accessory, value, callback));
break;
case "light":
- accessory
- .getService(Service.Lightbulb)
+ let lightService =
+ accessory.getService(Service.Lightbulb) || accessory.addService(Service.Lightbulb);
+ lightService
.getCharacteristic(Characteristic.On)
.on("set", (value, callback) =>
this.internalLightbulbUpdate(accessory, value, callback)
);
if (cns.devicesBrightable.includes(accessory.context.eweUIID)) {
- accessory
- .getService(Service.Lightbulb)
+ lightService
.getCharacteristic(Characteristic.Brightness)
.on("set", (value, callback) => {
if (value > 0) {
- if (
- !accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On)
- .value
- ) {
+ if (!lightService.getCharacteristic(Characteristic.On).value) {
this.internalLightbulbUpdate(accessory, true, function () {
return;
});
@@ -776,15 +704,11 @@ class eWeLink {
}
});
} else if (cns.devicesColourable.includes(accessory.context.eweUIID)) {
- accessory
- .getService(Service.Lightbulb)
+ lightService
.getCharacteristic(Characteristic.Brightness)
.on("set", (value, callback) => {
if (value > 0) {
- if (
- !accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On)
- .value
- ) {
+ if (!lightService.getCharacteristic(Characteristic.On).value) {
this.internalLightbulbUpdate(accessory, true, function () {
return;
});
@@ -794,25 +718,102 @@ class eWeLink {
this.internalLightbulbUpdate(accessory, false, callback);
}
});
- accessory
- .getService(Service.Lightbulb)
+ lightService
.getCharacteristic(Characteristic.Hue)
.on("set", (value, callback) =>
this.internalHSBUpdate(accessory, "hue", value, callback)
);
- accessory
- .getService(Service.Lightbulb)
+ lightService
.getCharacteristic(Characteristic.Saturation)
.on("set", (value, callback) => callback());
}
break;
case "switch":
- accessory
- .getService(Service.Switch)
+ let switchService =
+ accessory.getService(Service.Switch) || accessory.addService(Service.Switch);
+ switchService
.getCharacteristic(Characteristic.On)
.on("set", (value, callback) => this.internalSwitchUpdate(accessory, value, callback));
break;
+ case "rf_pri":
+ if (!accessory.context.hasOwnProperty("rfChlMap")) {
+ accessory.context.rfChlMap = {};
+ }
+ break;
case "rf_sub":
+ if (!accessory.context.hasOwnProperty("rfChls")) {
+ accessory.context.rfChls = {};
+ }
+ switch (
+ this.devicesInEW.get(accessory.context.eweDeviceId).tags.zyx_info[
+ parseInt(accessory.context.switchNumber) - 1
+ ].remote_type
+ ) {
+ case "1":
+ case "2":
+ case "3":
+ case "4":
+ accessory.context.sensorType = "button";
+ break;
+ case "6":
+ accessory.context.sensorType = this.cusS.has(accessory.context.hbDeviceId)
+ ? this.cusS.get(accessory.context.hbDeviceId).type
+ : "motion";
+ break;
+ }
+ let mAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
+ this.devicesInEW
+ .get(mAccessory.context.eweDeviceId)
+ .tags.zyx_info[parseInt(accessory.context.switchNumber) - 1].buttonName.forEach(
+ button => {
+ let rfData;
+ Object.entries(button).forEach(
+ ([k, v]) =>
+ (rfData = {
+ rfChan: k,
+ name: v,
+ })
+ );
+ accessory.context.rfChls[rfData.rfChan] = rfData.name;
+ mAccessory.context.rfChlMap[rfData.rfChan] = accessory.context.switchNumber;
+ this.devicesInHB.set(mAccessory.context.hbDeviceId, mAccessory);
+ switch (accessory.context.sensorType) {
+ case "button":
+ accessory.getService(rfData.name) ||
+ accessory.addService(Service.Switch, rfData.name, "switch" + rfData.rfChan);
+ break;
+ case "water":
+ accessory.getService(Service.LeakSensor) ||
+ accessory.addService(Service.LeakSensor);
+ break;
+ case "fire":
+ case "smoke":
+ accessory.getService(Service.SmokeSensor) ||
+ accessory.addService(Service.SmokeSensor);
+ break;
+ case "co":
+ accessory.getService(Service.CarbonMonoxideSensor) ||
+ accessory.addService(Service.CarbonMonoxideSensor);
+ break;
+ case "co2":
+ accessory.getService(Service.CarbonDioxideSensor) ||
+ accessory.addService(Service.CarbonDioxideSensor);
+ break;
+ case "contact":
+ accessory.getService(Service.ContactSensor) ||
+ accessory.addService(Service.ContactSensor);
+ break;
+ case "occupancy":
+ accessory.getService(Service.OccupancySensor) ||
+ accessory.addService(Service.OccupancySensor);
+ break;
+ default:
+ accessory.getService(Service.MotionSensor) ||
+ accessory.addService(Service.MotionSensor);
+ break;
+ }
+ }
+ );
accessory.context.rfChls = accessory.context.rfChls || {};
if (accessory.context.sensorType === "button") {
Object.entries(accessory.context.rfChls).forEach(([k, v]) => {
@@ -825,27 +826,53 @@ class eWeLink {
});
});
}
+
break;
- case "zb_sub":
- if (accessory.context.eweUIID === 1770) {
- accessory.log = this.log;
- accessory.eveLogger = new EveHistoryService("weather", accessory, {
- storage: "fs",
- minutes: 5,
- path: this.eveLogPath,
- });
- corrInterval.setCorrectingInterval(() => {
- let dataToAdd = {
- time: Date.now(),
- temp: accessory
- .getService(Service.TemperatureSensor)
- .getCharacteristic(Characteristic.CurrentTemperature).value,
- humidity: accessory
- .getService(Service.HumiditySensor)
- .getCharacteristic(Characteristic.CurrentRelativeHumidity).value,
- };
- accessory.eveLogger.addEntry(dataToAdd);
- }, 300000);
+ case "zb_sub": //*** credit @tasict ***\\
+ accessory.getService(Service.BatteryService) ||
+ accessory.addService(Service.BatteryService);
+ switch (accessory.context.eweUIID) {
+ case 1000:
+ let zbspsService =
+ accessory.getService(Service.StatelessProgrammableSwitch) ||
+ accessory.addService(Service.StatelessProgrammableSwitch);
+ if (this.config.hideZBLDPress) {
+ zbspsService.getCharacteristic(Characteristic.ProgrammableSwitchEvent).setProps({
+ validValues: [0],
+ });
+ }
+ break;
+ case 1770:
+ let zbTempService =
+ accessory.getService(Service.TemperatureSensor) ||
+ accessory.addService(Service.TemperatureSensor);
+ let zbHumiService =
+ accessory.getService(Service.HumiditySensor) ||
+ accessory.addService(Service.HumiditySensor);
+ accessory.log = this.log;
+ accessory.eveLogger = new EveHistoryService("weather", accessory, {
+ storage: "fs",
+ minutes: 5,
+ path: this.eveLogPath,
+ });
+ corrInterval.setCorrectingInterval(() => {
+ let dataToAdd = {
+ time: Date.now(),
+ temp: zbTempService.getCharacteristic(Characteristic.CurrentTemperature).value,
+ humidity: zbHumiService.getCharacteristic(Characteristic.CurrentRelativeHumidity)
+ .value,
+ };
+ accessory.eveLogger.addEntry(dataToAdd);
+ }, 300000);
+ break;
+ case 2026:
+ accessory.getService(Service.MotionSensor) ||
+ accessory.addService(Service.MotionSensor);
+ break;
+ case 3026:
+ accessory.getService(Service.ContactSensor) ||
+ accessory.addService(Service.ContactSensor);
+ break;
}
break;
}
@@ -974,11 +1001,11 @@ class eWeLink {
}
removeAccessory(accessory) {
try {
- this.devicesInHB.delete(accessory.context.hbDeviceId);
this.api.unregisterPlatformAccessories("homebridge-ewelink", "eWeLink", [accessory]);
- this.log("[%s] has been removed from Homebridge.", accessory.displayName);
+ this.devicesInHB.delete(accessory.context.hbDeviceId);
+ this.log(" â [%s] was removed from Homebridge.", accessory.displayName);
} catch (err) {
- this.log.warn("[%s] needed to be removed but couldn't as %s.", accessory.displayName, err);
+ this.log.warn(" â [%s] wasn't removed as %s.", accessory.displayName, err);
}
}
sendDeviceUpdate(accessory, params, callback) {
@@ -989,8 +1016,10 @@ class eWeLink {
};
let sendViaWS = () => {
if (accessory.context.reachableWAN) {
- this.wsClient.sendUpdate(payload);
- callback();
+ this.wsClient
+ .sendUpdate(payload)
+ .then(() => callback())
+ .catch(err => callback(err));
} else {
this.log.error(
"[%s] could not be updated as it appears to be offline.",
@@ -1014,81 +1043,73 @@ class eWeLink {
}
}
receiveDeviceUpdate(device) {
- let accessory;
- switch (device.action) {
- case "sysmsg":
- if (
- (accessory =
- this.devicesInHB.get(device.deviceid + "SWX") ||
- this.devicesInHB.get(device.deviceid + "SW0"))
- ) {
- let isX = accessory.context.hbDeviceId.substr(-1) === "X";
- if (device.params.updateSource === "WS") {
- if (accessory.context.reachableWAN !== device.params.online) {
- accessory.context.reachableWAN = device.params.online;
- this.log(
- "[%s] has been reported [%s] via [WS].",
- accessory.displayName,
- accessory.context.reachableWAN ? "online" : "offline"
- );
- this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
- if (accessory.context.reachableWAN) this.wsClient.requestUpdate(accessory);
- } else {
- if (this.debug) {
- this.log("[%s] Nothing to update from above WS message.", accessory.displayName);
- }
- }
- }
- if (!isX) {
- for (let i = 1; i <= accessory.context.channelCount; i++) {
- if (this.devicesInHB.has(device.deviceid + "SW" + i)) {
- let oAccessory = this.devicesInHB.get(device.deviceid + "SW" + i);
- oAccessory.context.reachableWAN = device.params.online;
- this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory);
- }
- }
- }
+ let accessory,
+ deviceId = device.deviceid,
+ reachableChange = false;
+ if (
+ (accessory = this.devicesInHB.get(deviceId + "SWX") || this.devicesInHB.get(deviceId + "SW0"))
+ ) {
+ let isX = accessory.context.hbDeviceId.substr(-1) === "X";
+ if (device.params.updateSource === "WS") {
+ if (device.params.online != accessory.context.reachableWAN) {
+ accessory.context.reachableWAN = device.params.online;
+ this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
+ if (accessory.context.reachableWAN)
+ this.wsClient.requestUpdate(accessory).catch(() => {});
+ reachableChange = true;
+ this.log.warn(
+ "[%s] has been reported [%s] via [WS].",
+ accessory.displayName,
+ accessory.context.reachableWAN ? "online" : "offline"
+ );
}
- break;
- case "update":
- if (
- (accessory =
- this.devicesInHB.get(device.deviceid + "SWX") ||
- this.devicesInHB.get(device.deviceid + "SW0"))
- ) {
- if (device.params.updateSource === "WS" && !accessory.context.reachableWAN) {
- accessory.context.reachableWAN = true;
- this.log("[%s] has been reported [online] via [WS].", accessory.displayName);
- }
- if (device.params.updateSource === "LAN" && !accessory.context.reachableLAN) {
- accessory.context.reachableLAN = true;
- this.log("[%s] has been reported [online] via [LAN].", accessory.displayName);
- }
- if (this.debug) {
- this.log(
- "[%s] externally updated from above %s message and will be refreshed.",
- accessory.displayName,
- device.params.updateSource
- );
- }
- if (!this.refreshAccessory(accessory, device.params)) {
- this.log.warn(
- "[%s] cannot be refreshed. Please try removing accessory from the Homebridge cache along with any secondary devices (SW1, SW2, etc.). [debug:%s:%s]",
- accessory.displayName,
- accessory.context.type,
- accessory.context.channelCount
- );
- }
- } else {
- if (!(this.config.hideDevFromHB || "").includes(device.deviceid)) {
- this.log.warn(
- "[%s] Accessory received via %s update does not exist in Homebridge. If it's a new accessory please restart Homebridge so it is added.",
- device.deviceid,
- device.params.updateSource
- );
+ }
+ if (device.params.updateSource === "LAN" && !accessory.context.reachableLAN) {
+ accessory.context.reachableLAN = true;
+ this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
+ this.wsClient.requestUpdate(accessory).catch(() => {});
+ reachableChange = true;
+ this.log.warn("[%s] has been reported [online] via [LAN].", accessory.displayName);
+ }
+ if (reachableChange && !isX) {
+ for (let i = 1; i <= accessory.context.channelCount; i++) {
+ if (this.devicesInHB.has(deviceId + "SW" + i)) {
+ let oAccessory = this.devicesInHB.get(deviceId + "SW" + i);
+ oAccessory.context.reachableWAN = device.params.online;
+ if (device.params.updateSource === "LAN") {
+ oAccessory.context.reachableLAN = true;
+ }
+ this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory);
}
}
- break;
+ }
+ if (this.debug) {
+ this.log(
+ "[%s] externally updated from above %s message and will be refreshed.",
+ accessory.displayName,
+ device.params.updateSource
+ );
+ }
+ if (!this.refreshAccessory(accessory, device.params)) {
+ this.log.warn(
+ "[%s] cannot be refreshed. Please try removing accessory from the Homebridge cache along with any secondary devices (SW1, SW2, etc.). [debug:%s:%s]",
+ accessory.displayName,
+ accessory.context.type,
+ accessory.context.channelCount
+ );
+ }
+ } else {
+ if (!(this.config.hideDevFromHB || "").includes(deviceId)) {
+ this.log.warn(
+ "[%s] update received via %s does not exist in Homebridge so device will be added.",
+ deviceId,
+ device.params.updateSource
+ );
+ this.httpClient
+ .getDevice(deviceId)
+ .then(res => this.initialiseDevice(res))
+ .catch(err => this.log.error("[%s] error getting info [%s]", deviceId, err));
+ }
}
}
internalValveUpdate(accessory, valve, value, callback) {
@@ -1096,26 +1117,26 @@ class eWeLink {
if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
throw "it is currently offline";
}
- let params = {};
- accessory
- .getService(valve)
+ let params = {},
+ serviceValve = accessory.getService(valve);
+ serviceValve
.updateCharacteristic(Characteristic.Active, value)
.updateCharacteristic(Characteristic.InUse, value);
switch (value) {
case 0:
- accessory.getService(valve).updateCharacteristic(Characteristic.RemainingDuration, 0);
+ serviceValve.updateCharacteristic(Characteristic.RemainingDuration, 0);
clearTimeout(accessory.getService(valve).timer);
break;
case 1:
- let timer = accessory.getService(valve).getCharacteristic(Characteristic.SetDuration)
- .value;
- accessory.getService(valve).updateCharacteristic(Characteristic.RemainingDuration, timer);
- accessory.getService(valve).timer = setTimeout(() => {
- accessory.getService(valve).setCharacteristic(Characteristic.Active, 0);
- }, timer * 1000);
+ let timer = serviceValve.getCharacteristic(Characteristic.SetDuration).value;
+ serviceValve.updateCharacteristic(Characteristic.RemainingDuration, timer);
+ serviceValve.timer = setTimeout(
+ () => serviceValve.setCharacteristic(Characteristic.Active, 0),
+ timer * 1000
+ );
break;
}
- params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
+ params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
switch (valve) {
case "Valve A":
params.switches[0].switch = value ? "on" : "off";
@@ -1158,14 +1179,12 @@ class eWeLink {
throw "improper configuration";
}
let oldPos,
- params = {};
+ params = {},
+ wcService = accessory.getService(Service.WindowCovering);
value = value >= 50 ? 100 : 0;
- oldPos = accessory
- .getService(Service.WindowCovering)
- .getCharacteristic(Characteristic.PositionState).value;
+ oldPos = wcService.getCharacteristic(Characteristic.PositionState).value;
if (value === oldPos * 100) {
- accessory
- .getService(Service.WindowCovering)
+ wcService
.updateCharacteristic(Characteristic.TargetPosition, value)
.updateCharacteristic(Characteristic.PositionState, oldPos);
callback();
@@ -1176,7 +1195,7 @@ class eWeLink {
params.switch = "on";
break;
case "twoSwitch":
- params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
+ params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
params.switches[0].switch = value === 100 ? "on" : "off";
params.switches[1].switch = value === 0 ? "on" : "off";
break;
@@ -1184,13 +1203,11 @@ class eWeLink {
this.sendDeviceUpdate(accessory, params, function () {
return;
});
- accessory
- .getService(Service.WindowCovering)
+ wcService
.updateCharacteristic(Characteristic.TargetPosition, value)
.updateCharacteristic(Characteristic.PositionState, value / 100);
setTimeout(() => {
- accessory
- .getService(Service.WindowCovering)
+ wcService
.updateCharacteristic(Characteristic.CurrentPosition, value)
.updateCharacteristic(Characteristic.PositionState, 2);
callback();
@@ -1223,7 +1240,8 @@ class eWeLink {
oldPos,
newPos = value,
params = {},
- delay = 0;
+ delay = 0,
+ gdService = accessory.getService(Service.GarageDoorOpener);
if (sensorDefinition && !(sAccessory = this.devicesInHB.get(garageConfig.sensorId + "SWX"))) {
throw "defined DW2 sensor doesn't exist";
}
@@ -1236,24 +1254,19 @@ class eWeLink {
.getCharacteristic(Characteristic.ContactSensorState).value === 0
? 1
: 0
- : accessory
- .getService(Service.GarageDoorOpener)
- .getCharacteristic(Characteristic.CurrentDoorState).value;
+ : gdService.getCharacteristic(Characteristic.CurrentDoorState).value;
if (newPos === oldPos % 2) {
accessory.context.inUse = false;
callback();
return;
}
if (garageConfig.setup === "oneSwitch" && [2, 3].includes(oldPos)) {
- accessory
- .getService(Service.GarageDoorOpener)
- .updateCharacteristic(Characteristic.CurrentDoorState, ((oldPos * 2) % 3) + 2);
+ gdService.updateCharacteristic(Characteristic.CurrentDoorState, ((oldPos * 2) % 3) + 2);
delay = 1500;
}
setTimeout(() => {
if (accessory.context.state === newPos) {
- accessory
- .getService(Service.GarageDoorOpener)
+ gdService
.updateCharacteristic(Characteristic.TargetDoorState, newPos)
.updateCharacteristic(Characteristic.CurrentDoorState, newPos + 2);
switch (garageConfig.setup) {
@@ -1261,9 +1274,7 @@ class eWeLink {
params.switch = "on";
break;
case "twoSwitch":
- params.switches = this.devicesInEwe.get(
- accessory.context.eweDeviceId
- ).params.switches;
+ params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
params.switches[0].switch = newPos === 0 ? "on" : "off";
params.switches[1].switch = newPos === 1 ? "on" : "off";
break;
@@ -1273,9 +1284,7 @@ class eWeLink {
});
setTimeout(() => {
if (!sAccessory) {
- accessory
- .getService(Service.GarageDoorOpener)
- .updateCharacteristic(Characteristic.CurrentDoorState, newPos);
+ gdService.updateCharacteristic(Characteristic.CurrentDoorState, newPos);
}
accessory.context.inUse = false;
}, parseInt(garageConfig.operationTime) * 100);
@@ -1295,7 +1304,8 @@ class eWeLink {
throw "it is currently offline";
}
let lockConfig,
- params = {};
+ params = {},
+ lmService = accessory.getService(Service.LockMechanism);
if (!(lockConfig = this.cusG.get(accessory.context.hbDeviceId))) {
throw "group config missing";
}
@@ -1304,15 +1314,13 @@ class eWeLink {
}
accessory.context.inUse = true;
this.log("[%s] has received request to unlock.", accessory.displayName);
- accessory
- .getService(Service.LockMechanism)
+ lmService
.updateCharacteristic(Characteristic.LockTargetState, 0)
.updateCharacteristic(Characteristic.LockCurrentState, 0);
params.switch = "on";
this.sendDeviceUpdate(accessory, params, callback);
setTimeout(() => {
- accessory
- .getService(Service.LockMechanism)
+ lmService
.updateCharacteristic(Characteristic.LockTargetState, 1)
.updateCharacteristic(Characteristic.LockCurrentState, 1);
accessory.context.inUse = false;
@@ -1329,36 +1337,34 @@ class eWeLink {
if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
throw "it is currently offline";
}
- let newPower, newSpeed, newLight;
+ let newPower,
+ newSpeed,
+ newLight,
+ lightService = accessory.getService(Service.Lightbulb),
+ fanService = accessory.getService(Service.Fanv2);
switch (type) {
case "power":
newPower = value;
newSpeed = value ? 33 : 0;
- newLight = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On)
- .value;
+ newLight = lightService.getCharacteristic(Characteristic.On).value;
break;
case "speed":
newPower = value >= 33 ? 1 : 0;
newSpeed = value;
- newLight = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On)
- .value;
+ newLight = lightService.getCharacteristic(Characteristic.On).value;
break;
case "light":
- newPower = accessory.getService(Service.Fanv2).getCharacteristic(Characteristic.Active)
- .value;
- newSpeed = accessory
- .getService(Service.Fanv2)
- .getCharacteristic(Characteristic.RotationSpeed).value;
+ newPower = fanService.getCharacteristic(Characteristic.Active).value;
+ newSpeed = fanService.getCharacteristic(Characteristic.RotationSpeed).value;
newLight = value;
break;
}
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, newLight);
- accessory
- .getService(Service.Fanv2)
+ lightService.updateCharacteristic(Characteristic.On, newLight);
+ fanService
.updateCharacteristic(Characteristic.Active, newPower)
.updateCharacteristic(Characteristic.RotationSpeed, newSpeed);
let params = {
- switches: this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches,
+ switches: this.devicesInEW.get(accessory.context.eweDeviceId).params.switches,
};
params.switches[0].switch = newLight ? "on" : "off";
params.switches[1].switch = newPower === 1 && newSpeed >= 33 ? "on" : "off";
@@ -1387,13 +1393,14 @@ class eWeLink {
throw "it is currently offline";
}
let params = {
- switch: value ? "on" : "off",
- mainSwitch: value ? "on" : "off",
- };
+ switch: value ? "on" : "off",
+ mainSwitch: value ? "on" : "off",
+ },
+ switchService = accessory.getService(Service.Switch);
if (this.debug) {
this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
}
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
+ switchService.updateCharacteristic(Characteristic.On, value);
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
@@ -1407,12 +1414,13 @@ class eWeLink {
throw "it is currently offline";
}
let params = {
- switch: value ? "on" : "off",
- };
+ switch: value ? "on" : "off",
+ },
+ outletService = accessory.getService(Service.Outlet);
if (this.debug) {
this.log("[%s] requesting to turn [%s].", accessory.displayName, value ? "on" : "off");
}
- accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, value);
+ outletService.updateCharacteristic(Characteristic.On, value);
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
callback("[" + accessory.displayName + "] " + err + ".");
@@ -1424,13 +1432,14 @@ class eWeLink {
throw "it is currently offline";
}
let params = {
- switches: this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches,
- };
+ switches: this.devicesInEW.get(accessory.context.eweDeviceId).params.switches,
+ },
+ outletService = accessory.getService(Service.Outlet);
params.switches[0].switch = value ? "on" : "off";
if (this.debug) {
this.log("[%s] requesting to turn [%s].", accessory.displayName, value ? "on" : "off");
}
- accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, value);
+ outletService.updateCharacteristic(Characteristic.On, value);
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
callback("[" + accessory.displayName + "] " + err + ".");
@@ -1442,13 +1451,14 @@ class eWeLink {
throw "it is currently offline";
}
let params = {
- switches: this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches,
- };
+ switches: this.devicesInEW.get(accessory.context.eweDeviceId).params.switches,
+ },
+ switchService = accessory.getService(Service.Switch);
params.switches[0].switch = value ? "on" : "off";
if (this.debug) {
this.log("[%s] requesting to turn [%s].", accessory.displayName, value ? "on" : "off");
}
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
+ switchService.updateCharacteristic(Characteristic.On, value);
this.sendDeviceUpdate(accessory, params, callback);
} catch (err) {
callback("[" + accessory.displayName + "] " + err + ".");
@@ -1460,7 +1470,8 @@ class eWeLink {
throw "it is currently offline";
}
let oAccessory,
- params = {};
+ params = {},
+ lightService = accessory.getService(Service.Lightbulb);
switch (accessory.context.switchNumber) {
case "X":
if (accessory.context.eweUIID === 22) {
@@ -1472,10 +1483,10 @@ class eWeLink {
if (this.debug) {
this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
}
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
+ lightService.updateCharacteristic(Characteristic.On, value);
break;
case "0":
- params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
+ params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
params.switches[0].switch = value ? "on" : "off";
params.switches[1].switch = value ? "on" : "off";
params.switches[2].switch = value ? "on" : "off";
@@ -1487,7 +1498,7 @@ class eWeLink {
value ? "on" : "off"
);
}
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
+ lightService.updateCharacteristic(Characteristic.On, value);
for (let i = 1; i <= 4; i++) {
if (this.devicesInHB.has(accessory.context.eweDeviceId + "SW" + i)) {
oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i);
@@ -1504,10 +1515,10 @@ class eWeLink {
if (this.debug) {
this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
}
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
+ lightService.updateCharacteristic(Characteristic.On, value);
let tAccessory,
masterState = "off";
- params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
+ params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
for (let i = 1; i <= 4; i++) {
if ((tAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
i === parseInt(accessory.context.switchNumber)
@@ -1526,10 +1537,12 @@ class eWeLink {
params.switches[i - 1].switch = "off";
}
}
- oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
- oAccessory
- .getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.On, masterState === "on");
+ if (!this.hiddenMasters.includes(accessory.context.eweDeviceId)) {
+ oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
+ oAccessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.On, masterState === "on");
+ }
break;
default:
throw "unknown switch number [" + accessory.context.switchNumber + "]";
@@ -1546,12 +1559,13 @@ class eWeLink {
if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
throw "it is currently offline";
}
- let params = {};
+ let params = {},
+ lightService = accessory.getService(Service.Lightbulb);
if (value === 0) {
params.switch = "off";
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, false);
+ lightService.updateCharacteristic(Characteristic.On, false);
} else {
- if (!accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value) {
+ if (!lightService.getCharacteristic(Characteristic.On).value) {
params.switch = "on";
}
switch (accessory.context.eweUIID) {
@@ -1565,9 +1579,7 @@ class eWeLink {
default:
throw "unknown device UIID";
}
- accessory
- .getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.Brightness, value);
+ lightService.updateCharacteristic(Characteristic.Brightness, value);
}
if (this.debug) {
this.log("[%s] updating brightness to [%s%].", accessory.displayName, value);
@@ -1586,11 +1598,9 @@ class eWeLink {
}
let newRGB,
params = {},
- curHue = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.Hue)
- .value,
- curSat = accessory
- .getService(Service.Lightbulb)
- .getCharacteristic(Characteristic.Saturation).value;
+ lightService = accessory.getService(Service.Lightbulb),
+ curHue = lightService.getCharacteristic(Characteristic.Hue).value,
+ curSat = lightService.getCharacteristic(Characteristic.Saturation).value;
switch (type) {
case "hue":
newRGB = convert.hsv.rgb(value, curSat, 100);
@@ -1620,7 +1630,7 @@ class eWeLink {
if (this.debug) {
this.log("[%s] updating hue to [%s°].", accessory.displayName, value);
}
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.Hue, value);
+ lightService.updateCharacteristic(Characteristic.Hue, value);
break;
case "bri":
switch (accessory.context.eweUIID) {
@@ -1646,9 +1656,7 @@ class eWeLink {
if (this.debug) {
this.log("[%s] updating brightness to [%s%].", accessory.displayName, value);
}
- accessory
- .getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.Brightness, value);
+ lightService.updateCharacteristic(Characteristic.Brightness, value);
break;
default:
throw "unknown device UIID";
@@ -1666,17 +1674,18 @@ class eWeLink {
throw "it is currently offline";
}
let oAccessory,
- params = {};
+ params = {},
+ switchService = accessory.getService(Service.Switch);
switch (accessory.context.switchNumber) {
case "X":
params.switch = value ? "on" : "off";
if (this.debug) {
this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
}
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
+ switchService.updateCharacteristic(Characteristic.On, value);
break;
case "0":
- params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
+ params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
params.switches[0].switch = value ? "on" : "off";
params.switches[1].switch = value ? "on" : "off";
params.switches[2].switch = value ? "on" : "off";
@@ -1688,7 +1697,7 @@ class eWeLink {
value ? "on" : "off"
);
}
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
+ switchService.updateCharacteristic(Characteristic.On, value);
for (let i = 1; i <= 4; i++) {
if (this.devicesInHB.has(accessory.context.eweDeviceId + "SW" + i)) {
oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i);
@@ -1703,10 +1712,10 @@ class eWeLink {
if (this.debug) {
this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
}
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
+ switchService.updateCharacteristic(Characteristic.On, value);
let tAccessory,
masterState = "off";
- params.switches = this.devicesInEwe.get(accessory.context.eweDeviceId).params.switches;
+ params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
for (let i = 1; i <= 4; i++) {
if ((tAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
i === parseInt(accessory.context.switchNumber)
@@ -1725,10 +1734,12 @@ class eWeLink {
params.switches[i - 1].switch = "off";
}
}
- oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
- oAccessory
- .getService(Service.Switch)
- .updateCharacteristic(Characteristic.On, masterState === "on");
+ if (!this.hiddenMasters.includes(accessory.context.eweDeviceId)) {
+ oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
+ oAccessory
+ .getService(Service.Switch)
+ .updateCharacteristic(Characteristic.On, masterState === "on");
+ }
break;
default:
throw "unknown switch number [" + accessory.context.switchNumber + "]";
@@ -1747,9 +1758,10 @@ class eWeLink {
}
rfChl = parseInt(rfChl);
let params = {
- cmd: "transmit",
- rfChl,
- };
+ cmd: "transmit",
+ rfChl,
+ },
+ rfService = accessory.getService(accessory.context.rfChls[rfChl]);
if (this.debug) {
this.log(
"[%s %s] mimicking RF button press.",
@@ -1757,17 +1769,9 @@ class eWeLink {
accessory.context.rfChls[rfChl]
);
}
- accessory
- .getService(accessory.context.rfChls[rfChl])
- .updateCharacteristic(Characteristic.On, true);
+ rfService.updateCharacteristic(Characteristic.On, true);
this.sendDeviceUpdate(accessory, params, callback);
- setTimeout(
- () =>
- accessory
- .getService(accessory.context.rfChls[rfChl])
- .updateCharacteristic(Characteristic.On, false),
- 3000
- );
+ setTimeout(() => rfService.updateCharacteristic(Characteristic.On, false), 3000);
} catch (err) {
let str = "[" + accessory.displayName + " " + name + "] could not be updated as " + err + ".";
this.log.error(str);
@@ -1777,25 +1781,19 @@ class eWeLink {
externalValveUpdate(accessory, params) {
try {
["A", "B"].forEach((v, k) => {
- accessory
- .getService("Valve " + v)
+ let valveService = accessory.getService("Valve " + v);
+ valveService
.updateCharacteristic(Characteristic.Active, params.switches[k].switch === "on")
.updateCharacteristic(Characteristic.InUse, params.switches[k].switch === "on");
if (params.switches[k].switch === "on") {
- let timer = accessory
- .getService("Valve " + v)
- .getCharacteristic(Characteristic.SetDuration).value;
- accessory
- .getService("Valve " + v)
- .updateCharacteristic(Characteristic.RemainingDuration, timer);
- accessory.getService("Valve " + v).timer = setTimeout(() => {
- accessory.getService("Valve " + v).setCharacteristic(Characteristic.Active, 0);
+ let timer = valveService.getCharacteristic(Characteristic.SetDuration).value;
+ valveService.updateCharacteristic(Characteristic.RemainingDuration, timer);
+ valveService.timer = setTimeout(() => {
+ valveService.setCharacteristic(Characteristic.Active, 0);
}, timer * 1000);
} else {
- accessory
- .getService("Valve " + v)
- .updateCharacteristic(Characteristic.RemainingDuration, 0);
- clearTimeout(accessory.getService("Valve " + v).timer);
+ valveService.updateCharacteristic(Characteristic.RemainingDuration, 0);
+ clearTimeout(valveService.timer);
}
});
} catch (err) {
@@ -1804,7 +1802,9 @@ class eWeLink {
}
externalBlindUpdate(accessory, params) {
try {
- let blindConfig, nSte;
+ let blindConfig,
+ nSte,
+ wcService = accessory.getService(Service.WindowCovering);
if (!(blindConfig = this.cusG.get(accessory.context.hbDeviceId))) {
throw "group config missing";
}
@@ -1816,12 +1816,7 @@ class eWeLink {
if (params.switch === "off") {
return;
}
- nSte =
- accessory
- .getService(Service.WindowCovering)
- .getCharacteristic(Characteristic.PositionState).value === 0
- ? 1
- : 0;
+ nSte = wcService.getCharacteristic(Characteristic.PositionState).value === 0 ? 1 : 0;
break;
case "twoSwitch":
if (params.switches[0].switch === "off" && params.switches[1].switch === "off") {
@@ -1832,13 +1827,11 @@ class eWeLink {
nSte = switchUp + switchDown;
break;
}
- accessory
- .getService(Service.WindowCovering)
+ wcService
.updateCharacteristic(Characteristic.PositionState, nSte)
.updateCharacteristic(Characteristic.TargetPosition, nSte * 100);
setTimeout(() => {
- accessory
- .getService(Service.WindowCovering)
+ wcService
.updateCharacteristic(Characteristic.PositionState, 2)
.updateCharacteristic(Characteristic.CurrentPosition, nSte * 100);
}, parseInt(blindConfig.operationTime) * 100);
@@ -1849,9 +1842,8 @@ class eWeLink {
externalGarageUpdate(accessory, params) {
try {
let garageConfig,
- oldPos = accessory
- .getService(Service.GarageDoorOpener)
- .getCharacteristic(Characteristic.CurrentDoorState).value,
+ gcService = accessory.getService(Service.GarageDoorOpener),
+ oldPos = gcService.getCharacteristic(Characteristic.CurrentDoorState).value,
newPos = [0, 2].includes(oldPos) ? 3 : 2;
if (!(garageConfig = this.cusG.get(accessory.context.hbDeviceId))) {
throw "group config missing";
@@ -1882,14 +1874,11 @@ class eWeLink {
}
accessory.context.inUse = true;
if (!garageConfig.sensorId) {
- accessory
- .getService(Service.GarageDoorOpener)
+ gcService
.updateCharacteristic(Characteristic.CurrentDoorState, newPos)
.updateCharacteristic(Characteristic.TargetDoorState, newPos - 2);
setTimeout(() => {
- accessory
- .getService(Service.GarageDoorOpener)
- .updateCharacteristic(Characteristic.CurrentDoorState, newPos - 2);
+ gcService.updateCharacteristic(Characteristic.CurrentDoorState, newPos - 2);
}, parseInt(garageConfig.operationTime) * 100);
}
setTimeout(() => {
@@ -1902,7 +1891,8 @@ class eWeLink {
}
externalLockUpdate(accessory, params) {
try {
- let lockConfig;
+ let lockConfig,
+ lmService = accessory.getService(Service.LockMechanism);
if (!(lockConfig = this.cusG.get(accessory.context.hbDeviceId))) {
throw "group config missing";
}
@@ -1913,13 +1903,11 @@ class eWeLink {
return;
}
accessory.context.inUse = true;
- accessory
- .getService(Service.LockMechanism)
+ lmService
.updateCharacteristic(Characteristic.LockCurrentState, 0)
.updateCharacteristic(Characteristic.LockTargetState, 0);
setTimeout(() => {
- accessory
- .getService(Service.LockMechanism)
+ lmService
.updateCharacteristic(Characteristic.LockCurrentState, 1)
.updateCharacteristic(Characteristic.LockTargetState, 1);
accessory.context.inUse = false;
@@ -1940,10 +1928,9 @@ class eWeLink {
batteryService.updateCharacteristic(Characteristic.StatusLowBattery, scaledBattery < 25);
}
let newState = params.switch === "on" ? 1 : 0,
- oAccessory = false;
- accessory
- .getService(Service.ContactSensor)
- .updateCharacteristic(Characteristic.ContactSensorState, newState);
+ oAccessory = false,
+ contactService = accessory.getService(Service.ContactSensor);
+ contactService.updateCharacteristic(Characteristic.ContactSensorState, newState);
this.cusG.forEach(group => {
if (group.sensorId === accessory.context.eweDeviceId && group.type === "garage") {
if ((oAccessory = this.devicesInHB.get(group.deviceId + "SWX"))) {
@@ -1974,7 +1961,11 @@ class eWeLink {
}
externalFanUpdate(accessory, params) {
try {
- let light, status, speed;
+ let light,
+ status,
+ speed,
+ lightService = accessory.getService(Service.Lightbulb),
+ fanService = accessory.getService(Service.Fanv2);
if (Array.isArray(params.switches)) {
light = params.switches[0].switch === "on";
switch (params.switches[1].switch + params.switches[2].switch + params.switches[3].switch) {
@@ -2005,9 +1996,8 @@ class eWeLink {
} else {
throw "unknown parameters received";
}
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, light);
- accessory
- .getService(Service.Fanv2)
+ lightService.updateCharacteristic(Characteristic.On, light);
+ fanService
.updateCharacteristic(Characteristic.Active, status)
.updateCharacteristic(Characteristic.RotationSpeed, speed);
} catch (err) {
@@ -2021,9 +2011,10 @@ class eWeLink {
(params.hasOwnProperty("switch") || params.hasOwnProperty("mainSwitch"))
) {
let newState = params.hasOwnProperty("switch")
- ? params.switch === "on"
- : params.mainSwitch === "on";
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, newState);
+ ? params.switch === "on"
+ : params.mainSwitch === "on",
+ switchService = accessory.getService(Service.Switch);
+ switchService.updateCharacteristic(Characteristic.On, newState);
}
let eveLog = {
time: Date.now(),
@@ -2058,21 +2049,19 @@ class eWeLink {
}
externalOutletUpdate(accessory, params) {
try {
+ let outletService = accessory.getService(Service.Outlet);
if (params.hasOwnProperty("switch")) {
- accessory
- .getService(Service.Outlet)
- .updateCharacteristic(Characteristic.On, params.switch === "on");
+ outletService.updateCharacteristic(Characteristic.On, params.switch === "on");
}
if (params.hasOwnProperty("power")) {
- accessory
- .getService(Service.Outlet)
- .updateCharacteristic(
- EveService.Characteristics.CurrentConsumption,
- parseFloat(params.power)
- );
- accessory
- .getService(Service.Outlet)
- .updateCharacteristic(Characteristic.OutletInUse, parseFloat(params.power) > 0);
+ outletService.updateCharacteristic(
+ EveService.Characteristics.CurrentConsumption,
+ parseFloat(params.power)
+ );
+ outletService.updateCharacteristic(
+ Characteristic.OutletInUse,
+ parseFloat(params.power) > 0
+ );
let isOn = accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On).value;
accessory.eveLogger.addEntry({
time: Date.now(),
@@ -2080,17 +2069,16 @@ class eWeLink {
});
}
if (params.hasOwnProperty("voltage")) {
- accessory
- .getService(Service.Outlet)
- .updateCharacteristic(EveService.Characteristics.Voltage, parseFloat(params.voltage));
+ outletService.updateCharacteristic(
+ EveService.Characteristics.Voltage,
+ parseFloat(params.voltage)
+ );
}
if (params.hasOwnProperty("current")) {
- accessory
- .getService(Service.Outlet)
- .updateCharacteristic(
- EveService.Characteristics.ElectricCurrent,
- parseFloat(params.current)
- );
+ outletService.updateCharacteristic(
+ EveService.Characteristics.ElectricCurrent,
+ parseFloat(params.current)
+ );
}
} catch (err) {
this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
@@ -2118,30 +2106,27 @@ class eWeLink {
try {
let newColour,
mode,
- isOn = false;
+ isOn = false,
+ lightService = accessory.getService(Service.Lightbulb);
if (accessory.context.eweUIID === 22 && params.hasOwnProperty("state")) {
isOn = params.state === "on";
} else if (accessory.context.eweUIID !== 22 && params.hasOwnProperty("switch")) {
isOn = params.switch === "on";
} else {
- isOn = accessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value;
+ isOn = lightService.getCharacteristic(Characteristic.On).value;
}
if (isOn) {
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, true);
+ lightService.updateCharacteristic(Characteristic.On, true);
switch (accessory.context.eweUIID) {
case 36: // KING-M4
if (params.hasOwnProperty("bright")) {
let nb = Math.round(((params.bright - 10) * 10) / 9); // eWeLink scale is 10-100 and HomeKit scale is 0-100.
- accessory
- .getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.Brightness, nb);
+ lightService.updateCharacteristic(Characteristic.Brightness, nb);
}
break;
case 44: // D1
if (params.hasOwnProperty("brightness")) {
- accessory
- .getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.Brightness, params.brightness);
+ lightService.updateCharacteristic(Characteristic.Brightness, params.brightness);
}
break;
case 22: // B1
@@ -2156,14 +2141,13 @@ class eWeLink {
mode = 2;
}
if (mode === 2) {
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, true);
+ lightService.updateCharacteristic(Characteristic.On, true);
newColour = convert.rgb.hsv(
parseInt(params.channel2),
parseInt(params.channel3),
parseInt(params.channel4)
);
- accessory
- .getService(Service.Lightbulb)
+ lightService
.updateCharacteristic(Characteristic.Hue, newColour[0])
.updateCharacteristic(Characteristic.Saturation, 100)
.updateCharacteristic(Characteristic.Brightness, 100);
@@ -2173,14 +2157,11 @@ class eWeLink {
break;
case 59: // L1
if (params.hasOwnProperty("bright")) {
- accessory
- .getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.Brightness, params.bright);
+ lightService.updateCharacteristic(Characteristic.Brightness, params.bright);
}
if (params.hasOwnProperty("colorR")) {
newColour = convert.rgb.hsv(params.colorR, params.colorG, params.colorB);
- accessory
- .getService(Service.Lightbulb)
+ lightService
.updateCharacteristic(Characteristic.Hue, newColour[0])
.updateCharacteristic(Characteristic.Saturation, newColour[1]);
}
@@ -2189,7 +2170,7 @@ class eWeLink {
return;
}
} else {
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, false);
+ lightService.updateCharacteristic(Characteristic.On, false);
}
} catch (err) {
this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
@@ -2210,7 +2191,11 @@ class eWeLink {
}
}
}
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, primaryState);
+ if (!this.hiddenMasters.includes(accessory.context.eweDeviceId)) {
+ accessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.On, primaryState);
+ }
} catch (err) {
this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
@@ -2239,7 +2224,9 @@ class eWeLink {
}
}
}
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, primaryState);
+ if (!this.hiddenMasters.includes(accessory.context.eweDeviceId)) {
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, primaryState);
+ }
} catch (err) {
this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
diff --git a/lib/eWeLinkHTTP.js b/lib/eWeLinkHTTP.js
index dc8370a4..48ffefb8 100644
--- a/lib/eWeLinkHTTP.js
+++ b/lib/eWeLinkHTTP.js
@@ -5,124 +5,51 @@ const axios = require("axios"),
crypto = require("crypto");
module.exports = class eWeLinkHTTP {
constructor(config, log) {
- this.config = config;
this.log = log;
- this.debug = this.config.debug || false;
- this.debugReqRes = this.config.debugReqRes || false;
+ this.debug = config.debug || false;
+ this.debugReqRes = config.debugReqRes || false;
+ this.username = config.username.toString();
+ this.password = config.password.toString();
+ this.hideDevFromHB = (config.hideDevFromHB || "").toString();
+ this.cCode = "+" + config.countryCode.toString().replace("+", "").replace(" ", "");
}
- login() {
- let data = {
- countryCode: "+" + this.config.countryCode.toString().replace("+", "").replace(" ", ""),
- password: this.config.password,
- };
- this.config.username.includes("@")
- ? (data.email = this.config.username)
- : (data.phoneNumber = this.config.username);
- if (this.debugReqRes) {
- let msg = JSON.stringify(data, null, 2)
- .replace(this.config.password, "**hidden**")
- .replace(this.config.username, "**hidden**");
- this.log.warn("Sending HTTP login request. This text is yellow for clarity.\n%s", msg);
- } else if (this.debug) {
- this.log("Sending HTTP login request.");
- }
- let dataToSign = crypto
- .createHmac("sha256", constants.appSecret)
- .update(JSON.stringify(data))
- .digest("base64");
+ getHost() {
return new Promise((resolve, reject) => {
- axios({
- url: "https://" + this.httpHost + "/v2/user/login",
- method: "post",
- headers: {
- Authorization: "Sign " + dataToSign,
- "Content-Type": "application/json",
- Host: this.httpHost,
- "X-CK-Appid": constants.appId,
- "X-CK-Nonce": Math.random().toString(36).substr(2, 8),
+ let params = {
+ appid: constants.appId,
+ country_code: this.cCode,
+ nonce: Math.random().toString(36).substr(2, 8),
+ ts: Math.floor(new Date().getTime() / 1000),
+ version: 8,
},
- data,
- })
- .then(res => {
- let body = res.data;
- if (
- body.hasOwnProperty("error") &&
- body.error === 10004 &&
- body.hasOwnProperty("data") &&
- body.data.hasOwnProperty("region")
- ) {
- switch (body.data.region) {
- case "eu":
- case "us":
- case "as":
- this.httpHost = body.data.region + "-apia.coolkit.cc";
- break;
- case "cn":
- this.httpHost = "cn-apia.coolkit.cn";
- break;
- default:
- throw "No valid region received - [" + body.data.region + "].";
- }
- if (this.debug) {
- this.log("New HTTP API host received [%s].", this.httpHost);
- }
- resolve(this.login());
- return;
- }
- if (!body.data.at) {
- throw (
- "Server did not respond with an authentication token. Please double check your eWeLink username and password in the Homebridge configuration.\n" +
- JSON.stringify(body, null, 2)
- );
- }
- this.aToken = body.data.at;
- this.apiKey = body.data.user.apikey;
- resolve({
- aToken: body.data.at,
- apiKey: body.data.user.apikey,
- httpHost: this.httpHost,
- });
- })
- .catch(err => {
- reject(err);
+ dataToSign = [];
+ Object.keys(params).forEach(k => {
+ dataToSign.push({
+ key: k,
+ value: params.k,
});
- });
- }
- getHost() {
- let data = {
- appid: constants.appId,
- country_code: this.config.countryCode.toString().replace("+", "").replace(" ", ""),
- nonce: Math.random().toString(36).substr(2, 8),
- ts: Math.floor(new Date().getTime() / 1000),
- version: 8,
- },
- dataToSign = [];
- Object.keys(data).forEach(function (key) {
- dataToSign.push({
- key: key,
- value: data[key],
});
- });
- dataToSign.sort(function (a, b) {
- return a.key < b.key ? -1 : 1;
- });
- dataToSign = dataToSign
- .map(function (kv) {
- return kv.key + "=" + kv.value;
- })
- .join("&");
- dataToSign = crypto
- .createHmac("sha256", constants.appSecret)
- .update(dataToSign)
- .digest("base64");
- return new Promise((resolve, reject) => {
+ dataToSign.sort((a, b) => (a.key < b.key ? -1 : 1));
+ dataToSign = dataToSign.map(k => k.key + "=" + k.value).join("&");
+ dataToSign = crypto
+ .createHmac("sha256", constants.appSecret)
+ .update(dataToSign)
+ .digest("base64");
+ if (this.debugReqRes) {
+ this.log.warn(
+ "Sending HTTP getHost request. This text is yellow for clarity.\n%s",
+ JSON.stringify(params, null, 2)
+ );
+ } else if (this.debug) {
+ this.log("Sending HTTP getHost request.");
+ }
axios
.get("https://api.coolkit.cc:8080/api/user/region", {
headers: {
Authorization: "Sign " + dataToSign,
"Content-Type": "application/json",
},
- params: data,
+ params,
})
.then(res => {
let body = res.data;
@@ -147,10 +74,87 @@ module.exports = class eWeLinkHTTP {
resolve(this.httpHost);
})
.catch(err => {
- reject(err);
+ if (err.hasOwnProperty("code") && ["ENOTFOUND", "ETIMEDOUT"].includes(err.code)) {
+ this.log.warn("Unable to reach eWeLink. Retrying in 30 seconds.");
+ this.delay().then(() => resolve(this.getHost()));
+ } else {
+ reject(err.message || err);
+ }
});
});
}
+ login() {
+ return new Promise((resolve, reject) => {
+ let data = {
+ countryCode: this.cCode,
+ password: this.password,
+ };
+ this.username.includes("@")
+ ? (data.email = this.username)
+ : (data.phoneNumber = this.username);
+ if (this.debugReqRes) {
+ let msg = JSON.stringify(data, null, 2)
+ .replace(this.password, "**hidden**")
+ .replace(this.username, "**hidden**");
+ this.log.warn("Sending HTTP login request. This text is yellow for clarity.\n%s", msg);
+ } else if (this.debug) {
+ this.log("Sending HTTP login request.");
+ }
+ let dataToSign = crypto
+ .createHmac("sha256", constants.appSecret)
+ .update(JSON.stringify(data))
+ .digest("base64");
+ axios
+ .post("https://" + this.httpHost + "/v2/user/login", data, {
+ headers: {
+ Authorization: "Sign " + dataToSign,
+ "Content-Type": "application/json",
+ Host: this.httpHost,
+ "X-CK-Appid": constants.appId,
+ "X-CK-Nonce": Math.random().toString(36).substr(2, 8),
+ },
+ })
+ .then(res => {
+ let body = res.data;
+ if (
+ body.hasOwnProperty("error") &&
+ body.error === 10004 &&
+ body.hasOwnProperty("data") &&
+ body.data.hasOwnProperty("region")
+ ) {
+ let givenRegion = body.data.region;
+ switch (givenRegion) {
+ case "eu":
+ case "us":
+ case "as":
+ this.httpHost = givenRegion + "-apia.coolkit.cc";
+ break;
+ case "cn":
+ this.httpHost = "cn-apia.coolkit.cn";
+ break;
+ default:
+ throw "No valid region received - [" + givenRegion + "].";
+ }
+ if (this.debug) {
+ this.log("New HTTP API host received [%s].", this.httpHost);
+ }
+ resolve(this.login());
+ return;
+ }
+ if (!body.data.at) {
+ throw "No auth token received.\n" + JSON.stringify(body, null, 2);
+ }
+ this.aToken = body.data.at;
+ this.apiKey = body.data.user.apikey;
+ resolve({
+ aToken: this.aToken,
+ apiKey: this.apiKey,
+ httpHost: this.httpHost,
+ });
+ })
+ .catch(err => reject(err.message || err));
+ });
+ }
getDevices() {
return new Promise((resolve, reject) => {
axios
@@ -165,18 +169,82 @@ module.exports = class eWeLinkHTTP {
})
.then(res => {
let body = res.data;
- if (!body.hasOwnProperty("error") || (body.hasOwnProperty("error") && body.error !== 0)) {
+ if (
+ !body.hasOwnProperty("data") ||
+ !body.hasOwnProperty("error") ||
+ (body.hasOwnProperty("error") && body.error !== 0)
+ ) {
throw JSON.stringify(body, null, 2);
}
let deviceList = [];
if (body.data.thingList && body.data.thingList.length > 0) {
body.data.thingList.forEach(device => deviceList.push(device.itemData));
}
+ deviceList
+ .filter(d => d.hasOwnProperty("extra") && d.extra.hasOwnProperty("uiid"))
+ .filter(d => !this.hideDevFromHB.includes(d.deviceid));
resolve(deviceList);
})
.catch(err => {
- reject(err);
+ if (err.hasOwnProperty("code") && ["ENOTFOUND", "ETIMEDOUT"].includes(err.code)) {
+ this.log.warn("Unable to reach eWeLink. Retrying in 30 seconds.");
+ this.delay().then(() => resolve(this.getDevices()));
+ } else {
+ reject(err.message || err);
+ }
+ });
+ });
+ }
+
+ getDevice(deviceId) {
+ return new Promise((resolve, reject) => {
+ axios
+ .post(
+ "https://" + this.httpHost + "/v2/device/thing",
+ {
+ thingList: [
+ {
+ itemType: 1,
+ id: deviceId,
+ },
+ ],
+ },
+ {
+ headers: {
+ Authorization: "Bearer " + this.aToken,
+ "Content-Type": "application/json",
+ Host: this.httpHost,
+ "X-CK-Appid": constants.appId,
+ "X-CK-Nonce": Math.random().toString(36).substr(2, 8),
+ },
+ }
+ )
+ .then(res => {
+ let body = res.data;
+ if (
+ !body.hasOwnProperty("data") ||
+ !body.hasOwnProperty("error") ||
+ (body.hasOwnProperty("error") && body.error !== 0)
+ ) {
+ throw JSON.stringify(body, null, 2);
+ }
+ if (body.data.thingList && body.data.thingList.length === 1) {
+ resolve(body.data.thingList[0].itemData);
+ } else {
+ throw "device not found in eWeLink";
+ }
+ })
+ .catch(err => {
+ if (err.hasOwnProperty("code") && ["ENOTFOUND", "ETIMEDOUT"].includes(err.code)) {
+ this.log.warn("Unable to reach eWeLink. Retrying in 30 seconds.");
+ this.delay().then(() => resolve(this.getDevice(deviceId)));
+ } else {
+ reject(err.message || err);
+ }
});
});
}
+ delay() {
+ return new Promise(resolve => setTimeout(resolve, 30000));
+ }
};
diff --git a/lib/eWeLinkLAN.js b/lib/eWeLinkLAN.js
index 9701fa06..c996e682 100644
--- a/lib/eWeLinkLAN.js
+++ b/lib/eWeLinkLAN.js
@@ -1,19 +1,18 @@
/* jshint esversion: 9, -W030, node: true */
"use strict";
const axios = require("axios"),
- constants = require("./constants"),
+ cns = require("./constants"),
crypto = require("crypto"),
dns = require("node-dns-sd"),
eventemitter = require("events");
module.exports = class eWeLinkLAN {
constructor(config, log, devices) {
- this.config = config;
this.log = log;
this.devices = devices;
- this.ipOverrides = this.config.ipOverride || {};
- let deviceMap = new Map();
+ this.ipOverrides = config.ipOverride || {};
+ this.deviceMap = new Map();
devices.forEach(device => {
- deviceMap.set(device.deviceid, {
+ this.deviceMap.set(device.deviceid, {
apiKey: device.devicekey,
online: this.ipOverrides.hasOwnProperty(device.deviceid) ? true : false,
ip: this.ipOverrides.hasOwnProperty(device.deviceid)
@@ -21,9 +20,8 @@ module.exports = class eWeLinkLAN {
: null,
});
});
- this.deviceMap = deviceMap;
- this.debug = this.config.debug || false;
- this.debugReqRes = this.config.debugReqRes || false;
+ this.debug = config.debug || false;
+ this.debugReqRes = config.debugReqRes || false;
this.emitter = new eventemitter();
}
getHosts() {
@@ -53,9 +51,7 @@ module.exports = class eWeLinkLAN {
count: onlineCount,
});
})
- .catch(err => {
- reject(err);
- });
+ .catch(err => reject(err));
});
}
startMonitor() {
@@ -101,16 +97,16 @@ module.exports = class eWeLinkLAN {
}
for (let param in params) {
if (params.hasOwnProperty(param)) {
- if (!constants.paramsToKeep.includes(param.replace(/[0-9]/g, ""))) {
+ if (!cns.paramsToKeep.includes(param.replace(/[0-9]/g, ""))) {
delete params[param];
}
}
}
if (Object.keys(params).length > 0) {
params.updateSource = "LAN";
+ params.online = true;
let returnTemplate = {
deviceid: rdata.id,
- action: "update",
params,
};
if (this.debugReqRes) {
@@ -127,18 +123,14 @@ module.exports = class eWeLinkLAN {
return new Promise((resolve, reject) => {
dns
.startMonitoring()
- .then(() => {
- resolve();
- })
- .catch(err => {
- reject(err);
- });
+ .then(() => resolve())
+ .catch(err => reject(err));
});
}
sendUpdate(json) {
return new Promise((resolve, reject) => {
if (!this.deviceMap.get(json.deviceid).online) {
- throw "device does not support LAN mode";
+ throw "device isn't reachable by LAN mode";
}
let apiKey,
suffix,
@@ -190,9 +182,7 @@ module.exports = class eWeLinkLAN {
}
throw res.data;
})
- .catch(err => {
- reject(err);
- });
+ .catch(err => reject(err));
}
});
}
diff --git a/lib/eWeLinkWS.js b/lib/eWeLinkWS.js
index 70e0a209..1d8cab1c 100644
--- a/lib/eWeLinkWS.js
+++ b/lib/eWeLinkWS.js
@@ -1,9 +1,10 @@
/* jshint esversion: 9, -W030, node: true */
"use strict";
const axios = require("axios"),
- constants = require("./constants"),
+ cns = require("./constants"),
eventemitter = require("events"),
- ws = require("ws");
+ ws = require("ws"),
+ wsp = require("websocket-as-promised");
module.exports = class eWeLinkWS {
constructor(config, log, res) {
this.config = config;
@@ -27,7 +28,7 @@ module.exports = class eWeLinkWS {
"Content-Type": "application/json",
},
data: {
- appid: constants.appId,
+ appid: cns.appId,
nonce: Math.random().toString(36).substr(2, 8),
ts: Math.floor(new Date().getTime() / 1000),
version: 8,
@@ -45,26 +46,47 @@ module.exports = class eWeLinkWS {
resolve(body.domain);
})
.catch(err => {
- reject(err);
+ if (err.hasOwnProperty("code") && ["ENOTFOUND", "ETIMEDOUT"].includes(err.code)) {
+ this.log.warn("Unable to reach eWeLink. Retrying in 30 seconds.");
+ this.delay().then(() => resolve(this.getDevices()));
+ } else {
+ reject(err.message || err);
+ }
});
});
}
login() {
- this.ws = new ws("wss://" + this.wsHost + ":8080/api/ws");
- this.ws.on("open", () => {
+ this.wsp = new wsp("wss://" + this.wsHost + ":8080/api/ws", {
+ createWebSocket: url => new ws(url),
+ extractMessageData: event => event,
+ attachRequestId: (data, requestId) =>
+ Object.assign(
+ {
+ sequence: requestId,
+ },
+ data
+ ),
+ extractRequestId: data => data && data.sequence,
+ packMessage: data => JSON.stringify(data),
+ unpackMessage: data => {
+ return data === "pong" ? data : JSON.parse(data);
+ },
+ });
+ this.wsp.open();
+ this.wsp.onOpen.addListener(() => {
this.wsIsOpen = true;
- let payload = {
- action: "userOnline",
- apikey: this.apiKey,
- appid: constants.appId,
- at: this.aToken,
- nonce: Math.random().toString(36).substr(2, 8),
- sequence: Math.floor(new Date()),
- ts: Math.floor(new Date() / 1000),
- userAgent: "app",
- version: 8,
- };
- this.ws.send(JSON.stringify(payload));
+ let sequence = Math.floor(new Date()).toString(),
+ payload = {
+ action: "userOnline",
+ apikey: this.apiKey,
+ appid: cns.appId,
+ at: this.aToken,
+ nonce: Math.random().toString(36).substr(2, 8),
+ sequence,
+ ts: Math.floor(new Date() / 1000),
+ userAgent: "app",
+ version: 8,
+ };
if (this.debugReqRes) {
let msg = JSON.stringify(payload, null, 2)
.replace(this.aToken, "**hidden**")
@@ -73,79 +95,55 @@ module.exports = class eWeLinkWS {
} else if (this.debug) {
this.log("Sending WS login request.");
}
+ this.wsp
+ .sendRequest(payload, {
+ requestId: sequence,
+ })
+ .then(res => {
+ if (
+ res.hasOwnProperty("config") &&
+ res.config.hb &&
+ res.config.hbInterval &&
+ !this.hbInterval
+ ) {
+ this.hbInterval = setInterval(() => {
+ this.wsp.send("ping");
+ }, (res.config.hbInterval + 7) * 1000);
+ } else {
+ throw "Unknown parameters received";
+ }
+ })
+ .catch(err => {
+ this.log.error("WS login failed [%s].", err);
+ });
});
- this.ws.on("message", m => {
- if (m === "pong") {
- return;
- }
- let device;
- try {
- device = JSON.parse(m);
- } catch (e) {
- this.log.warn("An error occured reading the web socket message [%s]", e);
- return;
- }
- // for requestUpdate response
- if (
- device.hasOwnProperty("deviceid") &&
- device.hasOwnProperty("params") &&
- device.hasOwnProperty("error") &&
- device.error === 0
- ) {
+ this.wsp.onUnpackedMessage.addListener(device => {
+ if (device === "pong") return;
+ let onlineStatus = true;
+ if (!device.hasOwnProperty("params")) device.params = {};
+ if (device.hasOwnProperty("deviceid") && device.hasOwnProperty("error")) {
device.action = "update";
- } else if (
- device.hasOwnProperty("deviceid") &&
- device.hasOwnProperty("error") &&
- device.error === 504
- ) {
- device.action = "sysmsg";
- device.params = {
- online: false,
- };
+ onlineStatus = device.error === 0;
}
- // for external updates
- if (
- device.hasOwnProperty("config") &&
- device.config.hb &&
- device.config.hbInterval &&
- !this.hbInterval
- ) {
- this.hbInterval = setInterval(() => {
- this.ws.send("ping");
- }, (device.config.hbInterval + 7) * 1000);
- } else if (device.hasOwnProperty("action")) {
+ if (device.hasOwnProperty("action")) {
switch (device.action) {
+ case "update":
case "sysmsg":
- device.params.updateSource = "WS";
- let returnTemplate = {
- deviceid: device.deviceid,
- action: "sysmsg",
- params: device.params,
- };
- if (this.debugReqRes) {
- let msg = JSON.stringify(returnTemplate, null, 2).replace(
- device.deviceid,
- "**hidden**"
- );
- this.log("WS message received.\n%s", msg);
- } else if (this.debug) {
- this.log("WS message received.");
+ if (device.action === "sysmsg" && device.params.hasOwnProperty("online")) {
+ onlineStatus = device.params.online;
}
- this.emitter.emit("update", returnTemplate);
- break;
- case "update":
for (let param in device.params) {
if (device.params.hasOwnProperty(param)) {
- if (!constants.paramsToKeep.includes(param.replace(/[0-9]/g, ""))) {
+ if (!cns.paramsToKeep.includes(param.replace(/[0-9]/g, ""))) {
delete device.params[param];
}
}
}
+ device.params.online = onlineStatus;
+ device.params.updateSource = "WS";
if (Object.keys(device.params).length > 0) {
- device.params.updateSource = "WS";
let returnTemplate = {
deviceid: device.deviceid,
- action: "update",
params: device.params,
};
if (this.debugReqRes) {
@@ -177,16 +175,14 @@ module.exports = class eWeLinkWS {
}
}
});
- this.ws.on("close", (e, m) => {
- if (m === "Stopping Homebridge") {
+ this.wsp.onClose.addListener(e => {
+ if (e.reason === "Stopping Homebridge") {
this.log("Web socket gracefully closed.");
} else {
- this.log.warn("Web socket closed - [%s - %s].", e, m);
+ this.log.warn("Web socket closed - [%s - %s].", e.code, e.reason);
if (e !== 1000) {
this.log("Web socket will try to reconnect in five seconds.");
- setTimeout(() => {
- this.login();
- }, 5000);
+ setTimeout(() => this.login(), 5000);
} else {
this.log("Please try restarting Homebridge so that this plugin can work again.");
}
@@ -196,89 +192,88 @@ module.exports = class eWeLinkWS {
clearInterval(this.hbInterval);
this.hbInterval = null;
}
- this.ws.removeAllListeners();
+ this.wsp.removeAllListeners();
});
- this.ws.on("error", e => {
+ this.wsp.onError.addListener(e => {
this.log.error("Web socket error - [%s].", e);
if (e.code === "ECONNREFUSED") {
this.log.warn(
"Web socket will try to reconnect in five seconds then try the command again."
);
- this.ws.removeAllListeners();
- setTimeout(() => {
- this.login();
- }, 5000);
+ this.wsp.removeAllListeners();
+ setTimeout(() => this.login(), 5000);
} else {
this.log.warn("If this was unexpected then please try restarting Homebridge.");
}
});
}
sendUpdate(json) {
- json = {
- ...json,
- ...{
- action: "update",
- sequence: Math.floor(new Date()),
- userAgent: "app",
- },
- };
- let sendOperation = req => {
- if (!this.wsIsOpen) {
- setTimeout(() => {
- sendOperation(req);
- }, 280);
- return;
- }
- if (this.ws) {
- this.ws.send(req);
- if (this.debugReqRes) {
- let msg = JSON.stringify(json, null, 2)
- .replace(json.apikey, "**hidden**")
- .replace(json.apiKey, "**hidden**")
- .replace(json.deviceid, "**hidden**");
- this.log.warn("WS message sent. This text is yellow for clarity.\n%s", msg);
- } else if (this.debug) {
- this.log("WS message sent.");
+ return new Promise((resolve, reject) => {
+ let sequence = Math.floor(new Date()).toString();
+ json = {
+ ...json,
+ ...{
+ action: "update",
+ sequence,
+ userAgent: "app",
+ },
+ };
+ let sendOperation = () => {
+ this.wsp
+ .sendRequest(json, {
+ requestId: sequence,
+ })
+ .then(device => {
+ if (this.debugReqRes) {
+ let msg = JSON.stringify(json, null, 2)
+ .replace(json.apikey, "**hidden**")
+ .replace(json.apiKey, "**hidden**")
+ .replace(json.deviceid, "**hidden**");
+ this.log.warn("WS message sent. This text is yellow for clarity.\n%s", msg);
+ } else if (this.debug) {
+ this.log("WS message sent.");
+ }
+ device.error = device.hasOwnProperty("error") ? device.error : 504; // mimic ewelink device offline
+ switch (device.error) {
+ case 0:
+ resolve();
+ break;
+ case 504:
+ default:
+ throw "Unknown response";
+ }
+ })
+ .catch(err => reject("Device update failed [" + err + "]."));
+ };
+ let checkToSend = () => {
+ if (this.wsp && this.wsIsOpen) {
+ sendOperation();
+ } else {
+ this.delay(2500).then(() => {
+ if (this.debug) {
+ this.log.warn("Will resend command when WS is reconnected.");
+ }
+ checkToSend();
+ });
}
- return;
- }
- this.delaySend = this.delaySend <= 0 ? 0 : (this.delaySend -= 280);
- };
- let string = JSON.stringify(json);
- if (this.wsIsOpen) {
- setTimeout(sendOperation, this.delaySend, string);
- this.delaySend += 280;
- } else {
- this.log.warn("Web socket is currently reconnecting. Command will be resent.");
- let interval,
- waitToSend = req => {
- if (this.wsIsOpen) {
- clearInterval(interval);
- sendOperation(req);
- }
- };
- interval = setInterval(waitToSend, 2500, string);
- }
+ };
+ checkToSend();
+ });
}
requestUpdate(accessory) {
- let json = {
- action: "query",
- apikey: accessory.context.eweApiKey,
- deviceid: accessory.context.eweDeviceId,
- params: [],
- sequence: Math.floor(new Date()),
- ts: 0,
- userAgent: "app",
- },
- sendOperation = req => {
- if (!this.wsIsOpen) {
- setTimeout(() => {
- sendOperation(req);
- }, 280);
- return;
- }
- if (this.ws) {
- this.ws.send(req);
+ return new Promise(resolve => {
+ let sequence = Math.floor(new Date()).toString(),
+ json = {
+ action: "query",
+ apikey: accessory.context.eweApiKey,
+ deviceid: accessory.context.eweDeviceId,
+ params: [],
+ sequence,
+ ts: 0,
+ userAgent: "app",
+ },
+ sendOperation = () => {
+ this.wsp.send(json);
if (this.debugReqRes) {
let msg = JSON.stringify(json, null, 2)
.replace(json.apikey, "**hidden**")
@@ -288,32 +283,31 @@ module.exports = class eWeLinkWS {
} else if (this.debug) {
this.log("WS message sent.");
}
- return;
- }
- this.delaySend = this.delaySend <= 0 ? 0 : (this.delaySend -= 280);
- },
- string = JSON.stringify(json);
- if (this.wsIsOpen) {
- setTimeout(sendOperation, this.delaySend, string);
- this.delaySend += 280;
- } else {
- this.log.warn("Web socket is currently reconnecting. Command will be resent.");
- let interval,
- waitToSend = req => {
- if (this.wsIsOpen) {
- clearInterval(interval);
- sendOperation(req);
+ },
+ checkToSend = () => {
+ if (this.wsp && this.wsIsOpen) {
+ sendOperation();
+ } else {
+ this.delay(2500).then(() => {
+ if (this.debug) {
+ this.log.warn("Will resend command when WS is reconnected.");
+ }
+ checkToSend();
+ });
}
};
- interval = setInterval(waitToSend, 2500, string);
- }
+ checkToSend();
+ });
}
receiveUpdate(f) {
this.emitter.addListener("update", f);
}
closeConnection() {
if (this.ws && this.wsIsOpen) {
- this.ws.close(1000, "Stopping Homebridge");
+ this.wsp.close(1000, "Stopping Homebridge");
}
}
+ delay(ms) {
+ return new Promise(resolve => setTimeout(resolve, ms));
+ }
};
diff --git a/package-lock.json b/package-lock.json
index 93c75ca5..f6b09335 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -122,6 +122,11 @@
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
+ "color-temp": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/color-temp/-/color-temp-0.0.2.tgz",
+ "integrity": "sha1-GxTzI9nLdq0fn1p140DWHW2WA/s="
+ },
"correcting-interval": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/correcting-interval/-/correcting-interval-2.0.0.tgz",
diff --git a/package.json b/package.json
index 7750d662..b54b8f8c 100644
--- a/package.json
+++ b/package.json
@@ -59,6 +59,7 @@
"dependencies": {
"axios": "0.20.0",
"color-convert": "2.0.1",
+ "color-temp": "0.0.2",
"correcting-interval": "2.0.0",
"fakegato-history": "0.5.6",
"homebridge-lib": "4.7.14",
From f3528162a218eb9015e5e641951609ed53eb4074 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 20 Sep 2020 13:10:32 +0100
Subject: [PATCH 0172/3183] 3.0.0-0
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index f6b09335..b2ff8a53 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.27.2",
+ "version": "3.0.0-0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index b54b8f8c..52cd1d9a 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "2.27.2",
+ "version": "3.0.0-0",
"author": "bwp91",
"contributors": [
"gbro115",
From b7bb52fe7a8cf74f486b1be8774b1704c6c27fb6 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 20 Sep 2020 15:12:43 +0100
Subject: [PATCH 0173/3183] update deps
---
package-lock.json | 54 +++++++++++++++++++++++++++++++++++------------
package.json | 2 +-
2 files changed, 41 insertions(+), 15 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index b2ff8a53..e100f5ec 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -351,9 +351,9 @@
"integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg=="
},
"homebridge-lib": {
- "version": "4.7.14",
- "resolved": "https://registry.npmjs.org/homebridge-lib/-/homebridge-lib-4.7.14.tgz",
- "integrity": "sha512-8eUGTVrCRd7WHwEH49CgqYUu2q9WjeTVDnEA5WXL2ZvPevTMCck5GcVIXtvVWxr9we8Ay0ybFp0N5RRlrIzH/g==",
+ "version": "4.7.15",
+ "resolved": "https://registry.npmjs.org/homebridge-lib/-/homebridge-lib-4.7.15.tgz",
+ "integrity": "sha512-654DQEwyhcHbZ1++1qv0k4lhoYWaZsHcriFRts4XHnGFQOgdO1G6VyP3hUjt/+y5FemoRVjqf6Tv0/IKNPDC4w==",
"requires": {
"bonjour": "^3.5.0",
"chalk": "^4.1.0",
@@ -362,11 +362,11 @@
},
"dependencies": {
"debug": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
- "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz",
+ "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==",
"requires": {
- "ms": "^2.1.1"
+ "ms": "2.1.2"
}
},
"ms": {
@@ -420,6 +420,11 @@
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz",
"integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g=="
},
+ "is-negative-zero": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.0.tgz",
+ "integrity": "sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE="
+ },
"is-regex": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz",
@@ -540,14 +545,35 @@
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="
},
"object.assign": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
- "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.1.tgz",
+ "integrity": "sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA==",
"requires": {
- "define-properties": "^1.1.2",
- "function-bind": "^1.1.1",
- "has-symbols": "^1.0.0",
- "object-keys": "^1.0.11"
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.18.0-next.0",
+ "has-symbols": "^1.0.1",
+ "object-keys": "^1.1.1"
+ },
+ "dependencies": {
+ "es-abstract": {
+ "version": "1.18.0-next.0",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.0.tgz",
+ "integrity": "sha512-elZXTZXKn51hUBdJjSZGYRujuzilgXo8vSPQzjGYXLvSlGiCo8VO8ZGV3kjo9a0WNJJ57hENagwbtlRuHuzkcQ==",
+ "requires": {
+ "es-to-primitive": "^1.2.1",
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1",
+ "is-callable": "^1.2.0",
+ "is-negative-zero": "^2.0.0",
+ "is-regex": "^1.1.1",
+ "object-inspect": "^1.8.0",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.0",
+ "string.prototype.trimend": "^1.0.1",
+ "string.prototype.trimstart": "^1.0.1"
+ }
+ }
}
},
"prettier": {
diff --git a/package.json b/package.json
index 52cd1d9a..0ebc8b68 100644
--- a/package.json
+++ b/package.json
@@ -62,7 +62,7 @@
"color-temp": "0.0.2",
"correcting-interval": "2.0.0",
"fakegato-history": "0.5.6",
- "homebridge-lib": "4.7.14",
+ "homebridge-lib": "4.7.15",
"node-dns-sd": "0.4.1",
"ws": "7.3.1"
},
From 63799d1d7cbe48004aa0ff8a88a6caf40acf97d8 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 20 Sep 2020 15:13:31 +0100
Subject: [PATCH 0174/3183] syntax error
---
lib/eWeLinkWS.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/eWeLinkWS.js b/lib/eWeLinkWS.js
index 1d8cab1c..fd077cff 100644
--- a/lib/eWeLinkWS.js
+++ b/lib/eWeLinkWS.js
@@ -303,7 +303,7 @@ module.exports = class eWeLinkWS {
this.emitter.addListener("update", f);
}
closeConnection() {
- if (this.ws && this.wsIsOpen) {
+ if (this.wsp && this.wsIsOpen) {
this.wsp.close(1000, "Stopping Homebridge");
}
}
From b08561b41b86cdfe26a72da48126fcf85ede6972 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 20 Sep 2020 15:13:46 +0100
Subject: [PATCH 0175/3183] batt
---
config.schema.json | 9 +++++++++
lib/eWeLink.js | 10 ++++++++--
2 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/config.schema.json b/config.schema.json
index e9a2b321..e1d15c4d 100644
--- a/config.schema.json
+++ b/config.schema.json
@@ -58,6 +58,14 @@
"description": "A list of device channels to hide from Homebridge. For example '10009553c8SW1' or multiple channels separated with a comma '10009553c8SW1,10009553c9SW2'. Only channels from switches, lights and irrigation valves can be hidden.",
"default": ""
},
+ "lowBattThreshold": {
+ "type": "integer",
+ "title": "Low Battery Threshold",
+ "description": "Homebridge will set the low battery status for supported devices when the device battery reaches this pecentage level.",
+ "default": 25,
+ "minimum": 5,
+ "maximum": 50
+ },
"sensorTimeLength": {
"type": "integer",
"title": "Sensor Length",
@@ -233,6 +241,7 @@
"hideDevFromHB",
"hideMasters",
"hideFromHB",
+ "lowBattThreshold",
"sensorTimeLength",
"sensorTimeDifference",
"valveTimeLength",
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index d8b093a1..16af13da 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -1925,7 +1925,10 @@ class eWeLink {
accessory.addService(Service.BatteryService),
scaledBattery = Math.round(params.battery * 33.3);
batteryService.updateCharacteristic(Characteristic.BatteryLevel, scaledBattery);
- batteryService.updateCharacteristic(Characteristic.StatusLowBattery, scaledBattery < 25);
+ batteryService.updateCharacteristic(
+ Characteristic.StatusLowBattery,
+ scaledBattery < (this.config.lowBattThreshold || 25)
+ );
}
let newState = params.switch === "on" ? 1 : 0,
oAccessory = false,
@@ -2372,7 +2375,10 @@ class eWeLink {
accessory.getService(Service.BatteryService) ||
accessory.addService(Service.BatteryService);
batteryService.updateCharacteristic(Characteristic.BatteryLevel, params.battery);
- batteryService.updateCharacteristic(Characteristic.StatusLowBattery, params.battery < 25);
+ batteryService.updateCharacteristic(
+ Characteristic.StatusLowBattery,
+ params.battery < (this.config.lowBattThreshold || 25)
+ );
}
switch (accessory.context.eweUIID) {
case 1000:
From ae2e12a83a2c3cda25fdc80d373f29c31e7b89a2 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Mon, 21 Sep 2020 11:31:58 +0100
Subject: [PATCH 0176/3183] 3.0.0-1 bump
---
lib/constants.js | 2 +-
lib/eWeLink.js | 386 ++++++++++++++++++++-------------------------
lib/eWeLinkHTTP.js | 13 +-
lib/eWeLinkWS.js | 11 +-
package-lock.json | 70 ++++----
package.json | 1 +
6 files changed, 227 insertions(+), 256 deletions(-)
diff --git a/lib/constants.js b/lib/constants.js
index a89a48c0..faa906f4 100644
--- a/lib/constants.js
+++ b/lib/constants.js
@@ -6,7 +6,7 @@ module.exports = {
// appSecret: "mXLOjea0woSMvK9gw7Fjsy7YlFO4iSu6",
appSecret: "6Nz4n0xA8s8qdxQf2GqurZj2Fs55FUvM",
devicesHideable: ["switch", "light"],
- devicesNonLAN: [22, 59, 102],
+ devicesNonLAN: [22, 28, 59, 102],
devicesSingleSwitch: [1, 5, 6, 14, 15, 22, 24, 27, 32, 36, 44, 59],
devicesSingleSwitchParams: ["switch"],
devicesMultiSwitch: [2, 3, 4, 7, 8, 9, 29, 30, 31, 34, 41],
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 16af13da..fd4aa371 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -166,7 +166,9 @@ class eWeLink {
else if (cns.devicesThermostat.includes(device.extra.uiid)) {
accessory = this.devicesInHB.has(device.deviceid + "SWX")
? this.devicesInHB.get(device.deviceid + "SWX")
- : this.addAccessory(device, device.deviceid + "SWX", "thermostat");
+ : this.addAccessory(device, device.deviceid + "SWX", "thermostat", false, {
+ sensorType: device.params.sensorType,
+ });
}
//*** OUTLETS ***\\
@@ -276,55 +278,94 @@ class eWeLink {
//*** RF BRIDGES ***\\
else if (cns.devicesRFBridge.includes(device.extra.uiid)) {
+ let accessory,
+ rfChlCounter = 0,
+ rfMap = [];
+
+ if (device.hasOwnProperty("tags") && device.tags.hasOwnProperty("zyx_info")) {
+ device.tags.zyx_info.forEach(remote =>
+ rfMap.push({
+ name: remote.name,
+ type: remote.remote_type,
+ buttons: Object.assign({}, ...remote.buttonName),
+ })
+ );
+ }
+
accessory = this.devicesInHB.has(device.deviceid + "SW0")
? this.devicesInHB.get(device.deviceid + "SW0")
- : this.addAccessory(device, device.deviceid + "SW0", "rf_pri");
- if (Object.keys((device.tags && device.tags.zyx_info) || []).length > 0) {
- let rfBridgeChange = false;
- for (let i = 1; i <= Object.keys(device.tags.zyx_info).length; i++) {
- let oAccessory = this.devicesInHB.has(device.deviceid + "SW" + i)
- ? this.devicesInHB.get(device.deviceid + "SW" + i)
- : this.addAccessory(device, device.deviceid + "SW" + i, "rf_sub");
- oAccessory
- .getService(Service.AccessoryInformation)
- .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion);
- oAccessory.context.reachableWAN = device.online;
- oAccessory.context.reachableLAN = this.lanDevices.get(device.deviceid).online || false;
- this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory);
- if (oAccessory.context.sensorType !== "button" && !rfBridgeChange) {
- let ct = this.cusS.has(oAccessory.context.hbDeviceId)
- ? this.cusS.get(oAccessory.context.hbDeviceId).type
+ : this.addAccessory(device, device.deviceid + "SW0", "rf_pri", true, {
+ rfMap,
+ });
+
+ this.log.error(JSON.stringify(accessory.context, null, 2));
+
+ rfMap.forEach(subDevice => {
+ let swNumber = rfChlCounter + 1,
+ subAccessory,
+ subType,
+ subExtraContext = {};
+ switch (subDevice.type) {
+ case "1":
+ case "2":
+ case "3":
+ case "4":
+ subType = "button";
+ break;
+ case "6":
+ subType = this.cusS.has(device.deviceid + "SW" + swNumber)
+ ? this.cusS.get(device.deviceid + "SW" + swNumber).type
: "motion";
- if (ct !== oAccessory.context.sensorType) rfBridgeChange = true;
- }
+ break;
+ default:
+ return;
}
- if (rfBridgeChange) {
- this.log.warn(
- "[%s] bridge configuration changed so devices will be removed and readded.",
- accessory.displayName
- );
- for (let i = 0; i <= accessory.context.channelCount; i++) {
- let oAccessory = this.devicesInHB.get(device.deviceid + "SW" + i);
- this.removeAccessory(oAccessory);
+ subExtraContext = {
+ buttons: subDevice.buttons,
+ subType,
+ swNumber,
+ };
+ if ((subAccessory = this.devicesInHB.get(device.deviceid + "SW" + swNumber))) {
+ if (
+ subAccessory.context.subType !== subType ||
+ subAccessory.context.swNumber !== swNumber
+ ) {
+ this.removeAccessory(subAccessory);
}
- this.initialiseDevice(device);
- return;
}
- }
+
+ subAccessory = this.devicesInHB.has(device.deviceid + "SW" + swNumber)
+ ? this.devicesInHB.get(device.deviceid + "SW" + swNumber)
+ : this.addAccessory(
+ device,
+ device.deviceid + "SW" + swNumber,
+ "rf_sub",
+ false,
+ subExtraContext
+ );
+ subAccessory
+ .getService(Service.AccessoryInformation)
+ .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion);
+ subAccessory.context.reachableWAN = device.online;
+ subAccessory.context.reachableLAN = false;
+ this.devicesInHB.set(subAccessory.context.hbDeviceId, subAccessory);
+ this.log.warn(JSON.stringify(subAccessory.context, null, 2));
+ rfChlCounter += Object.keys(subDevice.buttons || {}).length;
+ });
+ accessory.context.channelCount = rfChlCounter;
+ this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
}
//*** ZIGBEE BRIDGES ***\\
else if (cns.devicesZBBridge.includes(device.extra.uiid)) {
- accessory = this.devicesInHB.has(device.deviceid + "SWX")
- ? this.devicesInHB.get(device.deviceid + "SWX")
- : this.addAccessory(device, device.deviceid + "SWX", "zb_pri");
+ // Nothing to do here but needed to avoid the below not supported error
}
//*** ZIGBEE DEVICES ***\\
else if (cns.devicesZB.includes(device.extra.uiid)) {
accessory = this.devicesInHB.has(device.deviceid + "SWX")
? this.devicesInHB.get(device.deviceid + "SWX")
- : this.addAccessory(device, device.deviceid + "SWX", "zb_sub");
+ : this.addAccessory(device, device.deviceid + "SWX", "zb_dev");
}
//*** SONOFF CAMERAS ***\\
@@ -383,7 +424,7 @@ class eWeLink {
);
}
}
- addAccessory(device, hbDeviceId, type, hidden = false) {
+ addAccessory(device, hbDeviceId, type, hidden = false, extraContext = {}) {
let switchNumber = hbDeviceId.substr(-1).toString(),
newDeviceName = type === "rf_sub" ? device.tags.zyx_info[switchNumber - 1].name : device.name,
channelCount =
@@ -411,14 +452,17 @@ class eWeLink {
.setCharacteristic(Characteristic.Identify, false);
}
accessory.context = {
- hbDeviceId,
- eweDeviceId: device.deviceid,
- eweUIID: device.extra.uiid,
- eweModel: device.productModel,
- eweApiKey: device.apikey,
- switchNumber,
- channelCount,
- type,
+ ...{
+ hbDeviceId,
+ eweDeviceId: device.deviceid,
+ eweUIID: device.extra.uiid,
+ eweModel: device.productModel,
+ eweApiKey: device.apikey,
+ switchNumber,
+ channelCount,
+ type,
+ },
+ ...extraContext,
};
if (!hidden) {
this.api.registerPlatformAccessories("homebridge-ewelink", "eWeLink", [accessory]);
@@ -474,8 +518,8 @@ class eWeLink {
if (!(wcService = accessory.getService(Service.WindowCovering))) {
accessory
.addService(Service.WindowCovering)
- .setCharacteristic(Characteristic.CurrentPosition, 100)
- .setCharacteristic(Characteristic.TargetPosition, 100)
+ .setCharacteristic(Characteristic.CurrentPosition, 0)
+ .setCharacteristic(Characteristic.TargetPosition, 0)
.setCharacteristic(Characteristic.PositionState, 2);
wcService = accessory.getService(Service.WindowCovering);
}
@@ -543,7 +587,7 @@ class eWeLink {
accessory.getService(Service.TemperatureSensor) ||
accessory.addService(Service.TemperatureSensor),
humiService = false;
- if (this.devicesInEW.get(accessory.context.eweDeviceId).params.sensorType !== "DS18B20") {
+ if (accessory.context.sensorType !== "DS18B20") {
humiService =
accessory.getService(Service.HumiditySensor) ||
accessory.addService(Service.HumiditySensor);
@@ -735,100 +779,52 @@ class eWeLink {
.getCharacteristic(Characteristic.On)
.on("set", (value, callback) => this.internalSwitchUpdate(accessory, value, callback));
break;
- case "rf_pri":
- if (!accessory.context.hasOwnProperty("rfChlMap")) {
- accessory.context.rfChlMap = {};
- }
- break;
case "rf_sub":
- if (!accessory.context.hasOwnProperty("rfChls")) {
- accessory.context.rfChls = {};
- }
- switch (
- this.devicesInEW.get(accessory.context.eweDeviceId).tags.zyx_info[
- parseInt(accessory.context.switchNumber) - 1
- ].remote_type
- ) {
- case "1":
- case "2":
- case "3":
- case "4":
- accessory.context.sensorType = "button";
+ switch (accessory.context.subType) {
+ case "water":
+ accessory.getService(Service.LeakSensor) || accessory.addService(Service.LeakSensor);
break;
- case "6":
- accessory.context.sensorType = this.cusS.has(accessory.context.hbDeviceId)
- ? this.cusS.get(accessory.context.hbDeviceId).type
- : "motion";
+ case "fire":
+ case "smoke":
+ accessory.getService(Service.SmokeSensor) ||
+ accessory.addService(Service.SmokeSensor);
+ break;
+ case "co":
+ accessory.getService(Service.CarbonMonoxideSensor) ||
+ accessory.addService(Service.CarbonMonoxideSensor);
+ break;
+ case "co2":
+ accessory.getService(Service.CarbonDioxideSensor) ||
+ accessory.addService(Service.CarbonDioxideSensor);
+ break;
+ case "contact":
+ accessory.getService(Service.ContactSensor) ||
+ accessory.addService(Service.ContactSensor);
+ break;
+ case "occupancy":
+ accessory.getService(Service.OccupancySensor) ||
+ accessory.addService(Service.OccupancySensor);
+ break;
+ default:
+ accessory.getService(Service.MotionSensor) ||
+ accessory.addService(Service.MotionSensor);
+ break;
+ case "button":
+ Object.entries(accessory.context.buttons).forEach(([chan, name]) => {
+ accessory.getService(name) ||
+ accessory.addService(Service.Switch, name, "switch" + chan);
+ accessory.getService(name).updateCharacteristic(Characteristic.On, false);
+ accessory
+ .getService(name)
+ .getCharacteristic(Characteristic.On)
+ .on("set", (value, callback) => {
+ value ? this.internalRFDeviceUpdate(accessory, k, callback) : callback();
+ });
+ });
break;
}
- let mAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
- this.devicesInEW
- .get(mAccessory.context.eweDeviceId)
- .tags.zyx_info[parseInt(accessory.context.switchNumber) - 1].buttonName.forEach(
- button => {
- let rfData;
- Object.entries(button).forEach(
- ([k, v]) =>
- (rfData = {
- rfChan: k,
- name: v,
- })
- );
- accessory.context.rfChls[rfData.rfChan] = rfData.name;
- mAccessory.context.rfChlMap[rfData.rfChan] = accessory.context.switchNumber;
- this.devicesInHB.set(mAccessory.context.hbDeviceId, mAccessory);
- switch (accessory.context.sensorType) {
- case "button":
- accessory.getService(rfData.name) ||
- accessory.addService(Service.Switch, rfData.name, "switch" + rfData.rfChan);
- break;
- case "water":
- accessory.getService(Service.LeakSensor) ||
- accessory.addService(Service.LeakSensor);
- break;
- case "fire":
- case "smoke":
- accessory.getService(Service.SmokeSensor) ||
- accessory.addService(Service.SmokeSensor);
- break;
- case "co":
- accessory.getService(Service.CarbonMonoxideSensor) ||
- accessory.addService(Service.CarbonMonoxideSensor);
- break;
- case "co2":
- accessory.getService(Service.CarbonDioxideSensor) ||
- accessory.addService(Service.CarbonDioxideSensor);
- break;
- case "contact":
- accessory.getService(Service.ContactSensor) ||
- accessory.addService(Service.ContactSensor);
- break;
- case "occupancy":
- accessory.getService(Service.OccupancySensor) ||
- accessory.addService(Service.OccupancySensor);
- break;
- default:
- accessory.getService(Service.MotionSensor) ||
- accessory.addService(Service.MotionSensor);
- break;
- }
- }
- );
- accessory.context.rfChls = accessory.context.rfChls || {};
- if (accessory.context.sensorType === "button") {
- Object.entries(accessory.context.rfChls).forEach(([k, v]) => {
- accessory.getService(v).updateCharacteristic(Characteristic.On, false);
- accessory
- .getService(v)
- .getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => {
- value ? this.internalRFDeviceUpdate(accessory, k, callback) : callback();
- });
- });
- }
-
break;
- case "zb_sub": //*** credit @tasict ***\\
+ case "zb_dev": //*** credit @tasict ***\\
accessory.getService(Service.BatteryService) ||
accessory.addService(Service.BatteryService);
switch (accessory.context.eweUIID) {
@@ -988,9 +984,8 @@ class eWeLink {
}
return true;
case "rf_sub":
- case "zb_pri":
return true;
- case "zb_sub":
+ case "zb_dev":
if (Object.keys(newParams).some(v => cns.devicesZBBridgeParams.includes(v))) {
this.externalZBDeviceUpdate(accessory, newParams);
}
@@ -1808,7 +1803,7 @@ class eWeLink {
if (!(blindConfig = this.cusG.get(accessory.context.hbDeviceId))) {
throw "group config missing";
}
- if (blindConfig.type !== "blind" || ["oneSwitch", "twoSwitch"].includes(blindConfig.setup)) {
+ if (blindConfig.type !== "blind" || !["oneSwitch", "twoSwitch"].includes(blindConfig.setup)) {
throw "improper configuration";
}
switch (blindConfig.setup) {
@@ -2237,25 +2232,27 @@ class eWeLink {
externalRFDeviceUpdate(accessory, params) {
try {
if (!params.hasOwnProperty("updateSource")) return;
- let idToCheck = accessory.context.hbDeviceId.slice(0, -1),
- timeNow = new Date();
+ let timeNow = new Date();
if (
params.hasOwnProperty("cmd") &&
params.cmd === "transmit" &&
params.hasOwnProperty("rfChl")
) {
- // RF Button
- let bAccessory;
- if (
- (bAccessory = this.devicesInHB.get(idToCheck + accessory.context.rfChlMap[params.rfChl]))
- ) {
- bAccessory
- .getService(bAccessory.context.rfChls[params.rfChl])
+ //*** RF Button ***\\
+ let oAccessory,
+ accObject = this.devicesInHB
+ .filter(a => a.context.type === "rf_sub")
+ .filter(a => a.context.eweDeviceId === accessory.context.eweDeviceId)
+ .filter(a => a.context.buttons.hasOwnProperty(params.rfChl));
+
+ if ((oAccessory = accObject[0])) {
+ oAccessory
+ .getService(oAccessory.context.buttons[params.rfChl])
.updateCharacteristic(Characteristic.On, 1);
setTimeout(
() =>
- bAccessory
- .getService(bAccessory.context.rfChls[params.rfChl])
+ oAccessory
+ .getService(oAccessory.context.buttons[params.rfChl])
.updateCharacteristic(Characteristic.On, 0),
3000
);
@@ -2263,92 +2260,59 @@ class eWeLink {
throw "rf button not found in Homebridge";
}
} else if (params.hasOwnProperty("cmd") && params.cmd === "trigger") {
- // RF Sensor
+ //*** RF Sensor ***\\
Object.keys(params)
.filter(name => /rfTrig/.test(name))
.forEach(chan => {
- let chanNum = chan.substr(-1).toString(),
- accessoryNum = accessory.context.rfChlMap[chanNum],
- oAccessory;
- if ((oAccessory = this.devicesInHB.get(idToCheck + accessoryNum))) {
+ let rfChanToUpdate = chan.substr(-1).toString(),
+ oAccessory,
+ accObject = this.devicesInHB
+ .filter(acc => acc.context.type === "rf_sub")
+ .filter(acc => acc.context.eweDeviceId === accessory.context.eweDeviceId)
+ .filter(acc => acc.context.buttons.hasOwnProperty(rfChanToUpdate));
+ if ((oAccessory = accObject[0])) {
let timeOfMotion = new Date(params[chan]),
- diff = (timeNow.getTime() - timeOfMotion.getTime()) / 1000;
+ diff = (timeNow.getTime() - timeOfMotion.getTime()) / 1000,
+ serv,
+ char;
if (diff < (this.config.sensorTimeDifference || 120)) {
switch (oAccessory.context.sensorType) {
case "button":
break;
case "water":
- oAccessory
- .getService(Service.LeakSensor)
- .updateCharacteristic(Characteristic.LeakDetected, 1);
- setTimeout(() => {
- oAccessory
- .getService(Service.LeakSensor)
- .updateCharacteristic(Characteristic.LeakDetected, 0);
- }, (this.config.sensorTimeLength || 2) * 1000);
+ serv = Service.LeakSensor;
+ char = Characteristic.LeakDetected;
break;
case "fire":
case "smoke":
- oAccessory
- .getService(Service.SmokeSensor)
- .updateCharacteristic(Characteristic.SmokeDetected, 1);
- setTimeout(() => {
- oAccessory
- .getService(Service.SmokeSensor)
- .updateCharacteristic(Characteristic.SmokeDetected, 0);
- }, (this.config.sensorTimeLength || 2) * 1000);
+ serv = Service.SmokeSensor;
+ char = Characteristic.LeakDetected;
break;
case "co":
- oAccessory
- .getService(Service.CarbonMonoxideSensor)
- .updateCharacteristic(Characteristic.CarbonMonoxideDetected, 1);
- setTimeout(() => {
- oAccessory
- .getService(Service.CarbonMonoxideSensor)
- .updateCharacteristic(Characteristic.CarbonMonoxideDetected, 0);
- }, (this.config.sensorTimeLength || 2) * 1000);
+ serv = Service.CarbonMonoxideSensor;
+ char = Characteristic.CarbonMonoxideDetected;
break;
case "co2":
- oAccessory
- .getService(Service.CarbonDioxideSensor)
- .updateCharacteristic(Characteristic.CarbonDioxideDetected, 1);
- setTimeout(() => {
- oAccessory
- .getService(Service.CarbonDioxideSensor)
- .updateCharacteristic(Characteristic.CarbonDioxideDetected, 0);
- }, (this.config.sensorTimeLength || 2) * 1000);
+ serv = Service.CarbonDioxideSensor;
+ char = Characteristic.CarbonDioxideDetected;
break;
case "contact":
- oAccessory
- .getService(Service.ContactSensor)
- .updateCharacteristic(Characteristic.ContactSensorState, 1);
- setTimeout(() => {
- oAccessory
- .getService(Service.ContactSensor)
- .updateCharacteristic(Characteristic.ContactSensorState, 0);
- }, (this.config.sensorTimeLength || 2) * 1000);
+ serv = Service.ContactSensor;
+ char = Characteristic.ContactSensorState;
break;
case "occupancy":
- oAccessory
- .getService(Service.OccupancySensor)
- .updateCharacteristic(Characteristic.OccupancyDetected, 1);
- setTimeout(() => {
- oAccessory
- .getService(Service.OccupancySensor)
- .updateCharacteristic(Characteristic.OccupancyDetected, 0);
- }, (this.config.sensorTimeLength || 2) * 1000);
+ serv = Service.OccupancySensor;
+ char = Characteristic.OccupancyDetected;
break;
default:
- oAccessory
- .getService(Service.MotionSensor)
- .updateCharacteristic(Characteristic.MotionDetected, true);
- setTimeout(() => {
- oAccessory
- .getService(Service.MotionSensor)
- .updateCharacteristic(Characteristic.MotionDetected, false);
- }, (this.config.sensorTimeLength || 2) * 1000);
+ serv = Service.MotionSensor;
+ char = Characteristic.MotionDetected;
break;
}
+ oAccessory.getService(serv).updateCharacteristic(char, 1);
+ setTimeout(() => {
+ oAccessory.getService(serv).updateCharacteristic(char, 0);
+ }, (this.config.sensorTimeLength || 2) * 1000);
if (this.debug) {
this.log(
"[%s] has detected [%s].",
diff --git a/lib/eWeLinkHTTP.js b/lib/eWeLinkHTTP.js
index 48ffefb8..7f2410b0 100644
--- a/lib/eWeLinkHTTP.js
+++ b/lib/eWeLinkHTTP.js
@@ -74,8 +74,11 @@ module.exports = class eWeLinkHTTP {
resolve(this.httpHost);
})
.catch(err => {
- if (err.hasOwnProperty("code") && ["ENOTFOUND", "ETIMEDOUT"].includes(err.code)) {
- this.log.warn("Unable to reach eWeLink. Retrying in 30 seconds.");
+ if (
+ err.hasOwnProperty("code") &&
+ ["ENOTFOUND", "ETIMEDOUT", "EAI_AGAIN"].includes(err.code)
+ ) {
+ this.log.warn("Unable to reach eWeLink. Retrying in 15 seconds.");
this.delay().then(() => resolve(this.getHost()));
} else {
reject(err.message || err);
@@ -187,7 +190,7 @@ module.exports = class eWeLinkHTTP {
})
.catch(err => {
if (err.hasOwnProperty("code") && ["ENOTFOUND", "ETIMEDOUT"].includes(err.code)) {
- this.log.warn("Unable to reach eWeLink. Retrying in 30 seconds.");
+ this.log.warn("Unable to reach eWeLink. Retrying in 15 seconds.");
this.delay().then(() => resolve(this.getDevices()));
} else {
reject(err.message || err);
@@ -236,7 +239,7 @@ module.exports = class eWeLinkHTTP {
})
.catch(err => {
if (err.hasOwnProperty("code") && ["ENOTFOUND", "ETIMEDOUT"].includes(err.code)) {
- this.log.warn("Unable to reach eWeLink. Retrying in 30 seconds.");
+ this.log.warn("Unable to reach eWeLink. Retrying in 15 seconds.");
this.delay().then(() => resolve(this.getDevice(deviceId)));
} else {
reject(err.message || err);
@@ -245,6 +248,6 @@ module.exports = class eWeLinkHTTP {
});
}
delay() {
- return new Promise(resolve => setTimeout(resolve, 30000));
+ return new Promise(resolve => setTimeout(resolve, 15000));
}
};
diff --git a/lib/eWeLinkWS.js b/lib/eWeLinkWS.js
index fd077cff..df427482 100644
--- a/lib/eWeLinkWS.js
+++ b/lib/eWeLinkWS.js
@@ -175,11 +175,9 @@ module.exports = class eWeLinkWS {
}
}
});
- this.wsp.onClose.addListener(e => {
- if (e.reason === "Stopping Homebridge") {
- this.log("Web socket gracefully closed.");
- } else {
- this.log.warn("Web socket closed - [%s - %s].", e.code, e.reason);
+ this.wsp.onClose.addListener((e, m) => {
+ if (e !== 1005) {
+ this.log.warn("Web socket closed [%s].", e);
if (e !== 1000) {
this.log("Web socket will try to reconnect in five seconds.");
setTimeout(() => this.login(), 5000);
@@ -304,7 +302,8 @@ module.exports = class eWeLinkWS {
}
closeConnection() {
if (this.wsp && this.wsIsOpen) {
- this.wsp.close(1000, "Stopping Homebridge");
+ this.wsp.close();
+ this.log("Web socket gracefully closed.");
}
}
delay(ms) {
diff --git a/package-lock.json b/package-lock.json
index e100f5ec..7cd45f9b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -109,6 +109,11 @@
"supports-color": "^7.1.0"
}
},
+ "chnl": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/chnl/-/chnl-1.2.0.tgz",
+ "integrity": "sha512-g5gJb59edwCliFbX2j7G6sBfY4sX9YLy211yctONI2GRaiX0f2zIbKWmBm+sPqFNEpM7Ljzm7IJX/xrjiEbPrw=="
+ },
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
@@ -420,11 +425,6 @@
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz",
"integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g=="
},
- "is-negative-zero": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.0.tgz",
- "integrity": "sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE="
- },
"is-regex": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz",
@@ -545,35 +545,14 @@
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="
},
"object.assign": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.1.tgz",
- "integrity": "sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA==",
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
+ "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
"requires": {
- "define-properties": "^1.1.3",
- "es-abstract": "^1.18.0-next.0",
- "has-symbols": "^1.0.1",
- "object-keys": "^1.1.1"
- },
- "dependencies": {
- "es-abstract": {
- "version": "1.18.0-next.0",
- "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.0.tgz",
- "integrity": "sha512-elZXTZXKn51hUBdJjSZGYRujuzilgXo8vSPQzjGYXLvSlGiCo8VO8ZGV3kjo9a0WNJJ57hENagwbtlRuHuzkcQ==",
- "requires": {
- "es-to-primitive": "^1.2.1",
- "function-bind": "^1.1.1",
- "has": "^1.0.3",
- "has-symbols": "^1.0.1",
- "is-callable": "^1.2.0",
- "is-negative-zero": "^2.0.0",
- "is-regex": "^1.1.1",
- "object-inspect": "^1.8.0",
- "object-keys": "^1.1.1",
- "object.assign": "^4.1.0",
- "string.prototype.trimend": "^1.0.1",
- "string.prototype.trimstart": "^1.0.1"
- }
- }
+ "define-properties": "^1.1.2",
+ "function-bind": "^1.1.1",
+ "has-symbols": "^1.0.0",
+ "object-keys": "^1.0.11"
}
},
"prettier": {
@@ -582,6 +561,21 @@
"integrity": "sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg==",
"dev": true
},
+ "promise-controller": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/promise-controller/-/promise-controller-1.0.0.tgz",
+ "integrity": "sha512-goA0zA9L91tuQbUmiMinSYqlyUtEgg4fxJcjYnLYOQnrktb4o4UqciXDNXiRUPiDBPACmsr1k8jDW4r7UDq9Qw=="
+ },
+ "promise.prototype.finally": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/promise.prototype.finally/-/promise.prototype.finally-3.1.2.tgz",
+ "integrity": "sha512-A2HuJWl2opDH0EafgdjwEw7HysI8ff/n4lW4QEVBCUXFk9QeGecBWv0Deph0UmLe3tTNYegz8MOjsVuE6SMoJA==",
+ "requires": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.0-next.0",
+ "function-bind": "^1.1.1"
+ }
+ },
"qs": {
"version": "6.9.4",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz",
@@ -647,6 +641,16 @@
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.0.tgz",
"integrity": "sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ=="
},
+ "websocket-as-promised": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/websocket-as-promised/-/websocket-as-promised-1.0.1.tgz",
+ "integrity": "sha512-+gBevna4yxisb8cigL8NxcS8s241cvfMeyy1fNFcFgBcX/6vknMT84MwMmBNLYmsYH2giVoxOSEiAeeb7txFOw==",
+ "requires": {
+ "chnl": "^1.0.0",
+ "promise-controller": "^1.0.0",
+ "promise.prototype.finally": "^3.1.1"
+ }
+ },
"ws": {
"version": "7.3.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz",
diff --git a/package.json b/package.json
index 0ebc8b68..251d9f95 100644
--- a/package.json
+++ b/package.json
@@ -64,6 +64,7 @@
"fakegato-history": "0.5.6",
"homebridge-lib": "4.7.15",
"node-dns-sd": "0.4.1",
+ "websocket-as-promised": "1.0.1",
"ws": "7.3.1"
},
"devDependencies": {
From cd9bb9efa0a93df33b27b92db1462a4ad460f9db Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Mon, 21 Sep 2020 11:34:16 +0100
Subject: [PATCH 0177/3183] 3.0.0-1
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 7cd45f9b..d113ad56 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.0.0-0",
+ "version": "3.0.0-1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 251d9f95..db5f1146 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.0.0-0",
+ "version": "3.0.0-1",
"author": "bwp91",
"contributors": [
"gbro115",
From 66b924f74f712a2c9b3f1054f5ea4bc99fe513c1 Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Mon, 21 Sep 2020 11:43:55 +0100
Subject: [PATCH 0178/3183] Update stale.yml
---
.github/stale.yml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.github/stale.yml b/.github/stale.yml
index 89b61309..c75e5812 100644
--- a/.github/stale.yml
+++ b/.github/stale.yml
@@ -4,6 +4,8 @@ daysUntilStale: 7
daysUntilClose: 7
# Issues with these labels will never be considered stale
exemptLabels:
+ - "feedback wanted"
+ - "don't close"
# Label to use when marking an issue as stale
staleLabel: inactive
# Comment to post when marking an issue as stale. Set to `false` to disable
From ebd9a69ef0b6b829e4973ad7269a603f149b96bf Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Mon, 21 Sep 2020 15:18:00 +0100
Subject: [PATCH 0179/3183] misc
---
index.js | 2 +-
lib/constants.js | 2 +-
lib/eWeLinkHTTP.js | 2 +-
lib/eWeLinkLAN.js | 2 +-
lib/eWeLinkWS.js | 2 +-
package.json | 4 ++--
6 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/index.js b/index.js
index d25bb094..01e13ba7 100644
--- a/index.js
+++ b/index.js
@@ -1,4 +1,4 @@
-/* jshint esversion: 9, -W030, node: true */
+/* jshint esversion: 9, -W014, -W030, node: true */
"use strict";
module.exports = function (homebridge) {
const eWeLink = require("./lib/eWeLink.js")(homebridge);
diff --git a/lib/constants.js b/lib/constants.js
index faa906f4..3da14a6e 100644
--- a/lib/constants.js
+++ b/lib/constants.js
@@ -1,4 +1,4 @@
-/* jshint esversion: 9, -W030, node: true */
+/* jshint esversion: 9, -W014, -W030, node: true */
"use strict";
module.exports = {
// appId: "Uw83EKZFxdif7XFXEsrpduz5YyjP7nTl",
diff --git a/lib/eWeLinkHTTP.js b/lib/eWeLinkHTTP.js
index 7f2410b0..817bbade 100644
--- a/lib/eWeLinkHTTP.js
+++ b/lib/eWeLinkHTTP.js
@@ -1,4 +1,4 @@
-/* jshint esversion: 9, -W030, node: true */
+/* jshint esversion: 9, -W014, -W030, node: true */
"use strict";
const axios = require("axios"),
constants = require("./constants"),
diff --git a/lib/eWeLinkLAN.js b/lib/eWeLinkLAN.js
index c996e682..3923e97d 100644
--- a/lib/eWeLinkLAN.js
+++ b/lib/eWeLinkLAN.js
@@ -1,4 +1,4 @@
-/* jshint esversion: 9, -W030, node: true */
+/* jshint esversion: 9, -W014, -W030, node: true */
"use strict";
const axios = require("axios"),
cns = require("./constants"),
diff --git a/lib/eWeLinkWS.js b/lib/eWeLinkWS.js
index df427482..31192209 100644
--- a/lib/eWeLinkWS.js
+++ b/lib/eWeLinkWS.js
@@ -1,4 +1,4 @@
-/* jshint esversion: 9, -W030, node: true */
+/* jshint esversion: 9, -W014, -W030, node: true */
"use strict";
const axios = require("axios"),
cns = require("./constants"),
diff --git a/package.json b/package.json
index db5f1146..f7f0b9d9 100644
--- a/package.json
+++ b/package.json
@@ -32,8 +32,8 @@
"ewelink"
],
"engines": {
- "node": ">=6.0.0",
- "homebridge": ">=0.2.0"
+ "node": ">=10.0.0",
+ "homebridge": ">=1.0.0"
},
"repository": {
"type": "git",
From 45e6502e0d201f4d3ca3bcd44cc3dc126f303fda Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Mon, 21 Sep 2020 15:18:22 +0100
Subject: [PATCH 0180/3183] rf
---
lib/eWeLink.js | 53 +++++++++++++++++++++++++++-----------------------
1 file changed, 29 insertions(+), 24 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index fd4aa371..23f4b93c 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -1,4 +1,4 @@
-/* jshint esversion: 9, -W030, node: true */
+/* jshint esversion: 9, -W014, -W030, node: true */
"use strict";
let Accessory, Characteristic, EveService, EveHistoryService, Service, UUIDGen;
const cns = require("./constants"),
@@ -411,10 +411,8 @@ class eWeLink {
str += "is unreachable";
}
}
-
this.log(" â [%s] initialised %s.", device.name, str);
this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
-
if (!this.refreshAccessory(accessory, device.params)) {
this.log.warn(
"[%s] could not be initialised. Please try removing accessory from the Homebridge cache along with any secondary devices (SW1, SW2, etc.) [debug:%s:%s].",
@@ -818,7 +816,7 @@ class eWeLink {
.getService(name)
.getCharacteristic(Characteristic.On)
.on("set", (value, callback) => {
- value ? this.internalRFDeviceUpdate(accessory, k, callback) : callback();
+ value ? this.internalRFUpdate(accessory, chan, name, callback) : callback();
});
});
break;
@@ -980,14 +978,14 @@ class eWeLink {
return true;
case "rf_pri":
if (Object.keys(newParams).some(v => cns.devicesRFBridgeParams.includes(v))) {
- this.externalRFDeviceUpdate(accessory, newParams);
+ this.externalRFUpdate(accessory, newParams);
}
return true;
case "rf_sub":
return true;
case "zb_dev":
if (Object.keys(newParams).some(v => cns.devicesZBBridgeParams.includes(v))) {
- this.externalZBDeviceUpdate(accessory, newParams);
+ this.externalZBUpdate(accessory, newParams);
}
return true;
default:
@@ -1746,7 +1744,7 @@ class eWeLink {
callback(str);
}
}
- internalRFDeviceUpdate(accessory, rfChl, callback) {
+ internalRFUpdate(accessory, rfChl, service, callback) {
try {
if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
throw "it is currently offline";
@@ -1756,7 +1754,7 @@ class eWeLink {
cmd: "transmit",
rfChl,
},
- rfService = accessory.getService(accessory.context.rfChls[rfChl]);
+ rfService = accessory.getService(service);
if (this.debug) {
this.log(
"[%s %s] mimicking RF button press.",
@@ -2229,23 +2227,28 @@ class eWeLink {
this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
- externalRFDeviceUpdate(accessory, params) {
+ externalRFUpdate(accessory, params) {
try {
if (!params.hasOwnProperty("updateSource")) return;
- let timeNow = new Date();
+ let timeNow = new Date(),
+ oAccessory = false;
if (
params.hasOwnProperty("cmd") &&
params.cmd === "transmit" &&
params.hasOwnProperty("rfChl")
) {
//*** RF Button ***\\
- let oAccessory,
- accObject = this.devicesInHB
- .filter(a => a.context.type === "rf_sub")
- .filter(a => a.context.eweDeviceId === accessory.context.eweDeviceId)
- .filter(a => a.context.buttons.hasOwnProperty(params.rfChl));
+ // the device needed is SW% corresponding to params.rfChl
- if ((oAccessory = accObject[0])) {
+ this.devicesInHB.forEach(acc => {
+ if (
+ acc.context.eweDeviceId === accessory.context.eweDeviceId &&
+ acc.context.buttons.hasOwnProperty(params.rfChl.toString())
+ ) {
+ oAccessory = acc;
+ }
+ });
+ if (oAccessory) {
oAccessory
.getService(oAccessory.context.buttons[params.rfChl])
.updateCharacteristic(Characteristic.On, 1);
@@ -2264,13 +2267,15 @@ class eWeLink {
Object.keys(params)
.filter(name => /rfTrig/.test(name))
.forEach(chan => {
- let rfChanToUpdate = chan.substr(-1).toString(),
- oAccessory,
- accObject = this.devicesInHB
- .filter(acc => acc.context.type === "rf_sub")
- .filter(acc => acc.context.eweDeviceId === accessory.context.eweDeviceId)
- .filter(acc => acc.context.buttons.hasOwnProperty(rfChanToUpdate));
- if ((oAccessory = accObject[0])) {
+ this.devicesInHB.forEach(acc => {
+ if (
+ acc.context.eweDeviceId === accessory.context.eweDeviceId &&
+ acc.context.buttons.hasOwnProperty(chan.substr(-1).toString())
+ ) {
+ oAccessory = acc;
+ }
+ });
+ if (oAccessory) {
let timeOfMotion = new Date(params[chan]),
diff = (timeNow.getTime() - timeOfMotion.getTime()) / 1000,
serv,
@@ -2328,7 +2333,7 @@ class eWeLink {
this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
- externalZBDeviceUpdate(accessory, params) {
+ externalZBUpdate(accessory, params) {
try {
//*** credit @tasict ***\\
if (params.hasOwnProperty("battery")) {
From a0bdc5a0a8e9e92cf266c2aa7367bbfe1e4cf8b9 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Mon, 21 Sep 2020 15:32:53 +0100
Subject: [PATCH 0181/3183] check th sensor
---
lib/eWeLink.js | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 23f4b93c..e0bd27c2 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -169,6 +169,10 @@ class eWeLink {
: this.addAccessory(device, device.deviceid + "SWX", "thermostat", false, {
sensorType: device.params.sensorType,
});
+ if (accessory.context.sensorType !== device.params.sensorType) {
+ accessory.context.sensorType = device.params.sensorType;
+ this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
+ }
}
//*** OUTLETS ***\\
@@ -589,6 +593,10 @@ class eWeLink {
humiService =
accessory.getService(Service.HumiditySensor) ||
accessory.addService(Service.HumiditySensor);
+ } else {
+ if (accessory.getService(Service.HumiditySensor)) {
+ accessory.removeService(Service.HumiditySensor);
+ }
}
if (!this.config.hideTHSwitch) {
let switchService =
From 73fd656d8c6fae673dda170ae737858ca5e8710c Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Mon, 21 Sep 2020 17:31:34 +0100
Subject: [PATCH 0182/3183] blinds
---
lib/eWeLink.js | 37 ++++++++++++++++++++++++++++++-------
1 file changed, 30 insertions(+), 7 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index e0bd27c2..07123396 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -1179,6 +1179,7 @@ class eWeLink {
if (blindConfig.type !== "blind" || !["oneSwitch", "twoSwitch"].includes(blindConfig.setup)) {
throw "improper configuration";
}
+
let oldPos,
params = {},
wcService = accessory.getService(Service.WindowCovering);
@@ -1191,6 +1192,10 @@ class eWeLink {
callback();
return;
}
+
+ // target position -> 0 for closed 100 for open (value)
+ // current position -> 0 going down, 1 going up
+
switch (blindConfig.setup) {
case "oneSwitch":
params.switch = "on";
@@ -1211,8 +1216,22 @@ class eWeLink {
wcService
.updateCharacteristic(Characteristic.CurrentPosition, value)
.updateCharacteristic(Characteristic.PositionState, 2);
- callback();
+
+ switch (blindConfig.setup) {
+ case "oneSwitch":
+ params.switch = "off";
+ break;
+ case "twoSwitch":
+ params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
+ params.switches[0].switch = "off";
+ params.switches[1].switch = "off";
+ break;
+ }
+ this.sendDeviceUpdate(accessory, params, function () {
+ return;
+ });
}, parseInt(blindConfig.operationTime) * 100);
+ callback();
} catch (err) {
let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
this.log.error(str);
@@ -1804,7 +1823,7 @@ class eWeLink {
externalBlindUpdate(accessory, params) {
try {
let blindConfig,
- nSte,
+ newPosition,
wcService = accessory.getService(Service.WindowCovering);
if (!(blindConfig = this.cusG.get(accessory.context.hbDeviceId))) {
throw "group config missing";
@@ -1812,12 +1831,16 @@ class eWeLink {
if (blindConfig.type !== "blind" || !["oneSwitch", "twoSwitch"].includes(blindConfig.setup)) {
throw "improper configuration";
}
+ // target position -> 0 for closed 100 for open (value)
+ // current position -> 0 going down, 1 going up
+
switch (blindConfig.setup) {
case "oneSwitch":
if (params.switch === "off") {
return;
}
- nSte = wcService.getCharacteristic(Characteristic.PositionState).value === 0 ? 1 : 0;
+ newPosition =
+ wcService.getCharacteristic(Characteristic.PositionState).value === 0 ? 1 : 0;
break;
case "twoSwitch":
if (params.switches[0].switch === "off" && params.switches[1].switch === "off") {
@@ -1825,16 +1848,16 @@ class eWeLink {
}
let switchUp = params.switches[0].switch === "on" ? -1 : 0, // matrix of numbers to get
switchDown = params.switches[1].switch === "on" ? 0 : 2; // ... the correct HomeKit value
- nSte = switchUp + switchDown;
+ newPosition = switchUp + switchDown;
break;
}
wcService
- .updateCharacteristic(Characteristic.PositionState, nSte)
- .updateCharacteristic(Characteristic.TargetPosition, nSte * 100);
+ .updateCharacteristic(Characteristic.PositionState, newPosition)
+ .updateCharacteristic(Characteristic.TargetPosition, newPosition * 100);
setTimeout(() => {
wcService
.updateCharacteristic(Characteristic.PositionState, 2)
- .updateCharacteristic(Characteristic.CurrentPosition, nSte * 100);
+ .updateCharacteristic(Characteristic.CurrentPosition, newPosition * 100);
}, parseInt(blindConfig.operationTime) * 100);
} catch (err) {
this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
From 6f734f81a7317711a246d883c4d6b8e545156b12 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Mon, 21 Sep 2020 17:34:28 +0100
Subject: [PATCH 0183/3183] 3.0.0-2
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index d113ad56..447393fd 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.0.0-1",
+ "version": "3.0.0-2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index f7f0b9d9..d1803b2b 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.0.0-1",
+ "version": "3.0.0-2",
"author": "bwp91",
"contributors": [
"gbro115",
From 03e4a232e860c0a9e473a30a030feea7b2e9ca07 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Mon, 21 Sep 2020 18:20:34 +0100
Subject: [PATCH 0184/3183] http change
---
lib/eWeLink.js | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 07123396..2a9a2f2e 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -417,13 +417,15 @@ class eWeLink {
}
this.log(" â [%s] initialised %s.", device.name, str);
this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
- if (!this.refreshAccessory(accessory, device.params)) {
- this.log.warn(
- "[%s] could not be initialised. Please try removing accessory from the Homebridge cache along with any secondary devices (SW1, SW2, etc.) [debug:%s:%s].",
- accessory.displayName,
- accessory.context.type,
- accessory.context.channelCount
- );
+ if (!(this.config.disableHTTPRefresh || false)) {
+ if (!this.refreshAccessory(accessory, device.params)) {
+ this.log.warn(
+ "[%s] could not be initialised. Please try removing accessory from the Homebridge cache along with any secondary devices (SW1, SW2, etc.) [debug:%s:%s].",
+ accessory.displayName,
+ accessory.context.type,
+ accessory.context.channelCount
+ );
+ }
}
}
addAccessory(device, hbDeviceId, type, hidden = false, extraContext = {}) {
From 6671e0203b01c9266280c1da7847852e66791235 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Mon, 21 Sep 2020 18:21:50 +0100
Subject: [PATCH 0185/3183] 3.0.0-3
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 447393fd..d5c2bc87 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.0.0-2",
+ "version": "3.0.0-3",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index d1803b2b..a442dbb2 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.0.0-2",
+ "version": "3.0.0-3",
"author": "bwp91",
"contributors": [
"gbro115",
From 21e7b7a8c0ec12d7c535e61587d054609a0c8010 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Mon, 21 Sep 2020 19:03:29 +0100
Subject: [PATCH 0186/3183] blinds to twoSwitch only
---
config.schema.json | 4 ++--
lib/eWeLink.js | 56 +++++++++++++---------------------------------
2 files changed, 18 insertions(+), 42 deletions(-)
diff --git a/config.schema.json b/config.schema.json
index e1d15c4d..f44541f9 100644
--- a/config.schema.json
+++ b/config.schema.json
@@ -138,7 +138,7 @@
"type": "string",
"title": "Device Setup",
"default": "null",
- "description": "The device setup. Please ignore this setting for locks",
+ "description": "The device setup. Blinds must be set up with two switches. Please ignore this setting for locks.",
"oneOf": [
{
"title": "One Switch - for up and down",
@@ -161,7 +161,7 @@
"sensorId": {
"type": "string",
"title": "Sensor",
- "description": "A Sonoff DW2 sensor can optionally be used for blinds and garage doors. This is to determine the current open/closed state of the device. Please enter the 10 digit device ID (normally in the format 1000ab23cd). Otherwise leave this blank."
+ "description": "A Sonoff DW2 sensor can optionally be used for garage doors. This is to determine the current open/closed state of the garage door. Please enter the 10 digit device ID (normally in the format 1000ab23cd). Otherwise leave this blank."
}
}
}
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 2a9a2f2e..e8952e3a 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -1178,7 +1178,7 @@ class eWeLink {
if (!(blindConfig = this.cusG.get(accessory.context.hbDeviceId))) {
throw "group config missing";
}
- if (blindConfig.type !== "blind" || !["oneSwitch", "twoSwitch"].includes(blindConfig.setup)) {
+ if (blindConfig.type !== "blind" || blindConfig.setup !== "twoSwitch") {
throw "improper configuration";
}
@@ -1198,16 +1198,11 @@ class eWeLink {
// target position -> 0 for closed 100 for open (value)
// current position -> 0 going down, 1 going up
- switch (blindConfig.setup) {
- case "oneSwitch":
- params.switch = "on";
- break;
- case "twoSwitch":
- params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
- params.switches[0].switch = value === 100 ? "on" : "off";
- params.switches[1].switch = value === 0 ? "on" : "off";
- break;
- }
+ params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
+ params.switches[0].switch = value === 100 ? "on" : "off";
+ params.switches[1].switch = value === 0 ? "on" : "off";
+ break;
+
this.sendDeviceUpdate(accessory, params, function () {
return;
});
@@ -1218,17 +1213,9 @@ class eWeLink {
wcService
.updateCharacteristic(Characteristic.CurrentPosition, value)
.updateCharacteristic(Characteristic.PositionState, 2);
-
- switch (blindConfig.setup) {
- case "oneSwitch":
- params.switch = "off";
- break;
- case "twoSwitch":
- params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
- params.switches[0].switch = "off";
- params.switches[1].switch = "off";
- break;
- }
+ params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
+ params.switches[0].switch = "off";
+ params.switches[1].switch = "off";
this.sendDeviceUpdate(accessory, params, function () {
return;
});
@@ -1830,29 +1817,18 @@ class eWeLink {
if (!(blindConfig = this.cusG.get(accessory.context.hbDeviceId))) {
throw "group config missing";
}
- if (blindConfig.type !== "blind" || !["oneSwitch", "twoSwitch"].includes(blindConfig.setup)) {
+ if (blindConfig.type !== "blind" || blindConfig.setup !== "twoSwitch") {
throw "improper configuration";
}
// target position -> 0 for closed 100 for open (value)
// current position -> 0 going down, 1 going up
-
- switch (blindConfig.setup) {
- case "oneSwitch":
- if (params.switch === "off") {
- return;
- }
- newPosition =
- wcService.getCharacteristic(Characteristic.PositionState).value === 0 ? 1 : 0;
- break;
- case "twoSwitch":
- if (params.switches[0].switch === "off" && params.switches[1].switch === "off") {
- return;
- }
- let switchUp = params.switches[0].switch === "on" ? -1 : 0, // matrix of numbers to get
- switchDown = params.switches[1].switch === "on" ? 0 : 2; // ... the correct HomeKit value
- newPosition = switchUp + switchDown;
- break;
+ if (params.switches[0].switch === "off" && params.switches[1].switch === "off") {
+ return;
}
+ let switchUp = params.switches[0].switch === "on" ? -1 : 0, // matrix of numbers to get
+ switchDown = params.switches[1].switch === "on" ? 0 : 2; // ... the correct HomeKit value
+ newPosition = switchUp + switchDown;
+
wcService
.updateCharacteristic(Characteristic.PositionState, newPosition)
.updateCharacteristic(Characteristic.TargetPosition, newPosition * 100);
From 8749a526cda23ecb4e52a77fb5ebe82c10aa4fb2 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 22 Sep 2020 08:25:04 +0100
Subject: [PATCH 0187/3183] king q4 try
---
lib/constants.js | 5 ++-
lib/eWeLink.js | 91 +++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 91 insertions(+), 5 deletions(-)
diff --git a/lib/constants.js b/lib/constants.js
index 3da14a6e..75e59b9e 100644
--- a/lib/constants.js
+++ b/lib/constants.js
@@ -37,6 +37,8 @@ module.exports = {
devicesMultiSwitchLightParams: ["switches"],
devicesBrightable: [36, 44],
devicesColourable: [22, 59],
+ devicesCurtain: [11],
+ devicesCurtainParams: ["switch", "setclose"],
devicesSensor: [102],
devicesSensorParams: ["switch", "battery"],
devicesThermostat: [15],
@@ -94,6 +96,7 @@ module.exports = {
"rfList",
"rfTrig",
"sensorType",
+ "setclose",
"speed",
"state",
"switch",
@@ -115,7 +118,7 @@ module.exports = {
8: 3, // "SWITCH_3" \\ T1 3C, TX3C
9: 4, // "SWITCH_4" \\
10: 0, // "OSPF" \\
- 11: 0, // "CURTAIN" \\ King Q4 Cover
+ 11: 1, // "CURTAIN" \\ King Q4 Cover
12: 0, // "EW-RE" \\
13: 0, // "FIREPLACE" \\
14: 1, // "SWITCH_CHANGE" \\
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index e8952e3a..cdd80fca 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -125,7 +125,11 @@ class eWeLink {
) {
accessory = this.devicesInHB.has(device.deviceid + "SWX")
? this.devicesInHB.get(device.deviceid + "SWX")
- : this.addAccessory(device, device.deviceid + "SWX", "blind");
+ : this.addAccessory(device, device.deviceid + "SWX", "blind", false, {
+ cacheLastPosition: 0,
+ cachePositionState: 2,
+ cacheTargetPosition: 0,
+ });
}
//*** GARAGES ***\\
@@ -148,6 +152,13 @@ class eWeLink {
: this.addAccessory(device, device.deviceid + "SWX", "lock");
}
+ //*** CURTAINS ***\\
+ else if (cns.devicesCurtain.includes(device.extra.uiid)) {
+ accessory = this.devicesInHB.has(device.deviceid + "SWX")
+ ? this.devicesInHB.get(device.deviceid + "SWX")
+ : this.addAccessory(device, device.deviceid + "SWX", "curtain");
+ }
+
//*** DW2 SENSORS ***\\
else if (cns.devicesSensor.includes(device.extra.uiid)) {
accessory = this.devicesInHB.has(device.deviceid + "SWX")
@@ -534,6 +545,23 @@ class eWeLink {
minStep: 100,
});
break;
+ case "curtain":
+ let cService;
+ if (!(cService = accessory.getService(Service.WindowCovering))) {
+ accessory
+ .addService(Service.WindowCovering)
+ .setCharacteristic(Characteristic.CurrentPosition, 0)
+ .setCharacteristic(Characteristic.TargetPosition, 0)
+ .setCharacteristic(Characteristic.PositionState, 2);
+ cService = accessory.getService(Service.WindowCovering);
+ }
+ cService
+ .getCharacteristic(Characteristic.TargetPosition)
+ .on("set", (value, callback) => this.internalCurtainUpdate(accessory, value, callback))
+ .setProps({
+ minStep: 100,
+ });
+ break;
case "garage":
let gdService;
if (!(gdService = accessory.getService(Service.GarageDoorOpener))) {
@@ -916,6 +944,11 @@ class eWeLink {
this.externalLockUpdate(accessory, newParams);
}
return true;
+ case "curtain":
+ if (Object.keys(newParams).some(v => cns.devicesCurtainParams.includes(v))) {
+ this.externalCurtainUpdate(accessory, newParams);
+ }
+ return true;
case "sensor":
if (Object.keys(newParams).some(v => cns.devicesSensorParams.includes(v))) {
this.externalSensorUpdate(accessory, newParams);
@@ -1201,7 +1234,6 @@ class eWeLink {
params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
params.switches[0].switch = value === 100 ? "on" : "off";
params.switches[1].switch = value === 0 ? "on" : "off";
- break;
this.sendDeviceUpdate(accessory, params, function () {
return;
@@ -1341,6 +1373,40 @@ class eWeLink {
callback(str);
}
}
+ internalCurtainUpdate(accessory, value, callback) {
+ try {
+ if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
+ throw "it is currently offline";
+ }
+ let params,
+ cService = accessory.getService(Service.WindowCovering),
+ prevPos = accessory.context.prevPos;
+
+ if (value === prevPos) {
+ //nothing to do as no change
+ callback();
+ return;
+ }
+ if (value === 0 || value === 100) {
+ // so to fully open, our $value will be 100, we send switch: "on"
+ // to fully shut, our $value will be 0, we send switch: "off"
+ params = { switch: value === 100 ? "on" : "off" };
+ } else {
+ // for a % midway, scale the $value >--< 100 and setclose: newVal AS INT
+ params = { setclose: Math.abs(100 - value) };
+ }
+ cService
+ .updateCharacteristic(Characteristic.TargetPosition, value)
+ .updateCharacteristic(Characteristic.PositionState, value > prevPos ? 1 : 0);
+ // TargetPosition -> 0 for closed 100 for open (value)
+ // CurrentPosition -> 0 for closed 100 for open
+ // PositionState -> 0 going down, 1 going up, 2 = stopped
+
+ this.sendDeviceUpdate(accessory, params, callback);
+ } catch (err) {
+ callback("[" + accessory.displayName + "] " + err + ".");
+ }
+ }
internalFanUpdate(accessory, type, value, callback) {
try {
if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
@@ -1820,8 +1886,9 @@ class eWeLink {
if (blindConfig.type !== "blind" || blindConfig.setup !== "twoSwitch") {
throw "improper configuration";
}
- // target position -> 0 for closed 100 for open (value)
- // current position -> 0 going down, 1 going up
+ // TargetPosition -> 0 for closed 100 for open (value)
+ // CurrentPosition -> 0 for closed 100 for open
+ // PositionState -> 0 going down, 1 going up, 2 = stopped
if (params.switches[0].switch === "off" && params.switches[1].switch === "off") {
return;
}
@@ -1919,6 +1986,22 @@ class eWeLink {
this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
+ externalCurtainUpdate(accessory, params) {
+ try {
+ let cService = accessory.getService(Service.WindowCovering);
+ if (params.hasOwnProperty("switch") && params.hasOwnProperty("setclose")) {
+ cService
+ .updateCharacteristic(
+ Characteristic.TargetPosition,
+ Math.abs(100 - parseInt(params.setclose))
+ )
+ .updateCharacteristic(Characteristic.PositionState, 2);
+ return;
+ }
+ } catch (err) {
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
externalSensorUpdate(accessory, params) {
try {
if (params.hasOwnProperty("battery")) {
From f7cd49c889b3d42eef98a207cd2daed99febc630 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 22 Sep 2020 16:13:19 +0100
Subject: [PATCH 0188/3183] 3.0.0-4 updates
---
lib/eWeLink.js | 866 ++++++++++++++++++++++++---------------------
lib/eWeLinkHTTP.js | 14 +-
lib/eWeLinkLAN.js | 8 +-
lib/eWeLinkWS.js | 22 +-
4 files changed, 496 insertions(+), 414 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index cdd80fca..acd6c6a7 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -33,6 +33,7 @@ class eWeLink {
.on("shutdown", () => {
if (this.lanClient) this.lanClient.closeConnection();
if (this.wsClient) this.wsClient.closeConnection();
+ if (this.wsRefresh) clearInterval(this.wsRefresh);
});
}
eWeLinkSync() {
@@ -53,6 +54,18 @@ class eWeLink {
})
.then(() => {
this.wsClient.login();
+ this.wsRefresh = setInterval(() => {
+ if (this.wsClient) {
+ this.wsClient
+ .getHost()
+ .then(() => this.wsClient.closeConnection())
+ .then(() => {
+ return new Promise(resolve => setTimeout(resolve, 250));
+ })
+ .then(() => this.wsClient.login())
+ .catch(err => this.log.warn(err));
+ }
+ }, 1800000);
return this.lanClient.getHosts();
})
.then(res => {
@@ -106,7 +119,6 @@ class eWeLink {
initialiseDevice(device) {
let accessory;
//*** First add the device if it isn't already in Homebridge ***\\
-
//*** IRRIGATION VALVES ***\\
if (
device.extra.uiid === 2 &&
@@ -117,7 +129,6 @@ class eWeLink {
? this.devicesInHB.get(device.deviceid + "SWX")
: this.addAccessory(device, device.deviceid + "SWX", "valve");
}
-
//*** WINDOW BLINDS ***\\
else if (
this.cusG.has(device.deviceid + "SWX") &&
@@ -131,7 +142,6 @@ class eWeLink {
cacheTargetPosition: 0,
});
}
-
//*** GARAGES ***\\
else if (
this.cusG.has(device.deviceid + "SWX") &&
@@ -141,7 +151,6 @@ class eWeLink {
? this.devicesInHB.get(device.deviceid + "SWX")
: this.addAccessory(device, device.deviceid + "SWX", "garage");
}
-
//*** LOCKS ***\\
else if (
this.cusG.has(device.deviceid + "SWX") &&
@@ -151,28 +160,26 @@ class eWeLink {
? this.devicesInHB.get(device.deviceid + "SWX")
: this.addAccessory(device, device.deviceid + "SWX", "lock");
}
-
//*** CURTAINS ***\\
else if (cns.devicesCurtain.includes(device.extra.uiid)) {
accessory = this.devicesInHB.has(device.deviceid + "SWX")
? this.devicesInHB.get(device.deviceid + "SWX")
- : this.addAccessory(device, device.deviceid + "SWX", "curtain");
+ : this.addAccessory(device, device.deviceid + "SWX", "curtain", false, {
+ prevPos: 0,
+ });
}
-
//*** DW2 SENSORS ***\\
else if (cns.devicesSensor.includes(device.extra.uiid)) {
accessory = this.devicesInHB.has(device.deviceid + "SWX")
? this.devicesInHB.get(device.deviceid + "SWX")
: this.addAccessory(device, device.deviceid + "SWX", "sensor");
}
-
//*** FANS ***\\
else if (cns.devicesFan.includes(device.extra.uiid)) {
accessory = this.devicesInHB.has(device.deviceid + "SWX")
? this.devicesInHB.get(device.deviceid + "SWX")
: this.addAccessory(device, device.deviceid + "SWX", "fan");
}
-
//*** THERMOSTATS ***\\
else if (cns.devicesThermostat.includes(device.extra.uiid)) {
accessory = this.devicesInHB.has(device.deviceid + "SWX")
@@ -185,28 +192,27 @@ class eWeLink {
this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
}
}
-
//*** OUTLETS ***\\
- else if (cns.devicesOutlet.includes(device.extra.uiid)) {
+ else if (
+ cns.devicesOutlet.includes(device.extra.uiid) ||
+ device.productModel === "Sonoff Pow"
+ ) {
accessory = this.devicesInHB.has(device.deviceid + "SWX")
? this.devicesInHB.get(device.deviceid + "SWX")
: this.addAccessory(device, device.deviceid + "SWX", "outlet");
}
-
//*** USB OUTLETS ***\\
else if (cns.devicesUSB.includes(device.extra.uiid)) {
accessory = this.devicesInHB.has(device.deviceid + "SWX")
? this.devicesInHB.get(device.deviceid + "SWX")
: this.addAccessory(device, device.deviceid + "SWX", "usb");
}
-
//*** SINGLE CHANNEL [MULTI CHANNEL HARDWARE] ***\\
else if (cns.devicesSCM.includes(device.extra.uiid)) {
accessory = this.devicesInHB.has(device.deviceid + "SWX")
? this.devicesInHB.get(device.deviceid + "SWX")
: this.addAccessory(device, device.deviceid + "SWX", "scm");
}
-
//*** SINGLE CHANNEL LIGHTS ***\\
else if (
cns.devicesSingleSwitch.includes(device.extra.uiid) &&
@@ -216,7 +222,6 @@ class eWeLink {
? this.devicesInHB.get(device.deviceid + "SWX")
: this.addAccessory(device, device.deviceid + "SWX", "light");
}
-
//*** MULTI CHANNEL LIGHTS ***\\
else if (
cns.devicesMultiSwitch.includes(device.extra.uiid) &&
@@ -251,14 +256,12 @@ class eWeLink {
}
}
}
-
//*** SINGLE CHANNEL SWITCHES ***\\
else if (cns.devicesSingleSwitch.includes(device.extra.uiid)) {
accessory = this.devicesInHB.has(device.deviceid + "SWX")
? this.devicesInHB.get(device.deviceid + "SWX")
: this.addAccessory(device, device.deviceid + "SWX", "switch");
}
-
//*** MULTI CHANNEL SWITCHES ***\\
else if (cns.devicesMultiSwitch.includes(device.extra.uiid)) {
if (this.config.hideMasters) {
@@ -290,13 +293,11 @@ class eWeLink {
}
}
}
-
//*** RF BRIDGES ***\\
else if (cns.devicesRFBridge.includes(device.extra.uiid)) {
let accessory,
rfChlCounter = 0,
rfMap = [];
-
if (device.hasOwnProperty("tags") && device.tags.hasOwnProperty("zyx_info")) {
device.tags.zyx_info.forEach(remote =>
rfMap.push({
@@ -306,15 +307,12 @@ class eWeLink {
})
);
}
-
accessory = this.devicesInHB.has(device.deviceid + "SW0")
? this.devicesInHB.get(device.deviceid + "SW0")
: this.addAccessory(device, device.deviceid + "SW0", "rf_pri", true, {
rfMap,
});
-
this.log.error(JSON.stringify(accessory.context, null, 2));
-
rfMap.forEach(subDevice => {
let swNumber = rfChlCounter + 1,
subAccessory,
@@ -348,7 +346,6 @@ class eWeLink {
this.removeAccessory(subAccessory);
}
}
-
subAccessory = this.devicesInHB.has(device.deviceid + "SW" + swNumber)
? this.devicesInHB.get(device.deviceid + "SW" + swNumber)
: this.addAccessory(
@@ -370,19 +367,16 @@ class eWeLink {
accessory.context.channelCount = rfChlCounter;
this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
}
-
//*** ZIGBEE BRIDGES ***\\
else if (cns.devicesZBBridge.includes(device.extra.uiid)) {
// Nothing to do here but needed to avoid the below not supported error
}
-
//*** ZIGBEE DEVICES ***\\
else if (cns.devicesZB.includes(device.extra.uiid)) {
accessory = this.devicesInHB.has(device.deviceid + "SWX")
? this.devicesInHB.get(device.deviceid + "SWX")
: this.addAccessory(device, device.deviceid + "SWX", "zb_dev");
}
-
//*** SONOFF CAMERAS ***\\
else if (cns.devicesCamera.includes(device.extra.uiid)) {
this.log.warn(
@@ -391,7 +385,6 @@ class eWeLink {
);
return;
}
-
//*** ALL OTHER = UNSUPPORTED ***\\
else {
this.log.warn(
@@ -400,7 +393,6 @@ class eWeLink {
);
return;
}
-
if (!accessory) {
return;
}
@@ -413,7 +405,6 @@ class eWeLink {
accessory.context.reachableWAN = device.online;
accessory.context.reachableLAN = this.lanDevices.get(device.deviceid).online || false;
accessory.context.inUse = false;
-
let str = accessory.context.reachableLAN
? "and found locally with IP [" + this.lanDevices.get(device.deviceid).ip + "]"
: "but LAN mode unavailable as device ";
@@ -1044,39 +1035,40 @@ class eWeLink {
this.log.warn(" â [%s] wasn't removed as %s.", accessory.displayName, err);
}
}
- sendDeviceUpdate(accessory, params, callback) {
- let payload = {
- apikey: accessory.context.eweApiKey,
- deviceid: accessory.context.eweDeviceId,
- params,
- };
- let sendViaWS = () => {
- if (accessory.context.reachableWAN) {
- this.wsClient
- .sendUpdate(payload)
- .then(() => callback())
- .catch(err => callback(err));
+ sendDeviceUpdate(accessory, params) {
+ return new Promise((resolve, reject) => {
+ let payload = {
+ apikey: accessory.context.eweApiKey,
+ deviceid: accessory.context.eweDeviceId,
+ params,
+ };
+ let sendViaWS = () => {
+ if (accessory.context.reachableWAN) {
+ this.wsClient
+ .sendUpdate(payload)
+ .then(() => resolve())
+ .catch(err => reject(err));
+ } else {
+ reject("it is unreachable");
+ }
+ };
+ if (
+ cns.devicesNonLAN.includes(accessory.context.eweUIID) ||
+ !accessory.context.reachableLAN
+ ) {
+ sendViaWS();
} else {
- this.log.error(
- "[%s] could not be updated as it appears to be offline.",
- accessory.displayName
- );
- callback("Device has failed to update");
+ this.lanClient
+ .sendUpdate(payload)
+ .then(() => resolve())
+ .catch(err => {
+ if (this.debug) {
+ this.log.warn("[%s] Reverting to web socket as %s.", accessory.displayName, err);
+ }
+ sendViaWS();
+ });
}
- };
- if (cns.devicesNonLAN.includes(accessory.context.eweUIID) || !accessory.context.reachableLAN) {
- sendViaWS();
- } else {
- this.lanClient
- .sendUpdate(payload)
- .then(() => callback())
- .catch(err => {
- if (this.debug) {
- this.log.warn("[%s] Reverting to web socket as %s.", accessory.displayName, err);
- }
- sendViaWS();
- });
- }
+ });
}
receiveDeviceUpdate(device) {
let accessory,
@@ -1149,29 +1141,10 @@ class eWeLink {
}
}
internalValveUpdate(accessory, valve, value, callback) {
+ callback();
try {
- if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
- throw "it is currently offline";
- }
let params = {},
serviceValve = accessory.getService(valve);
- serviceValve
- .updateCharacteristic(Characteristic.Active, value)
- .updateCharacteristic(Characteristic.InUse, value);
- switch (value) {
- case 0:
- serviceValve.updateCharacteristic(Characteristic.RemainingDuration, 0);
- clearTimeout(accessory.getService(valve).timer);
- break;
- case 1:
- let timer = serviceValve.getCharacteristic(Characteristic.SetDuration).value;
- serviceValve.updateCharacteristic(Characteristic.RemainingDuration, timer);
- serviceValve.timer = setTimeout(
- () => serviceValve.setCharacteristic(Characteristic.Active, 0),
- timer * 1000
- );
- break;
- }
params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
switch (valve) {
case "Valve A":
@@ -1190,80 +1163,103 @@ class eWeLink {
: "off";
params.switches[1].switch = value ? "on" : "off";
break;
- default:
- throw "unknown valve [" + valve + "]";
}
params.switches[2].switch = "off";
params.switches[3].switch = "off";
- this.sendDeviceUpdate(accessory, params, callback);
+ //2. send the request
+ //3a. update the accessory if (2) is resolved
+ //3b. revert the device status if (2) is rejected with a requestDeviceStatus.
+ this.sendDeviceUpdate(accessory, params)
+ .then(() => {
+ serviceValve
+ .updateCharacteristic(Characteristic.Active, value)
+ .updateCharacteristic(Characteristic.InUse, value);
+ switch (value) {
+ case 0:
+ serviceValve.updateCharacteristic(Characteristic.RemainingDuration, 0);
+ clearTimeout(accessory.getService(valve).timer);
+ break;
+ case 1:
+ let timer = serviceValve.getCharacteristic(Characteristic.SetDuration).value;
+ serviceValve.updateCharacteristic(Characteristic.RemainingDuration, timer);
+ serviceValve.timer = setTimeout(
+ () => serviceValve.setCharacteristic(Characteristic.Active, 0),
+ timer * 1000
+ );
+ break;
+ }
+ })
+ .catch(err => {
+ throw err;
+ });
} catch (err) {
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
- this.log.error(str);
- callback(str);
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ if (accessory.context.reachableWAN) {
+ this.wsClient.requestUpdate(accessory).catch(() => {});
+ this.log.warn(
+ "[%s] requesting previous state to revert Homebridge status.",
+ accessory.displayName
+ );
+ }
}
}
internalBlindUpdate(accessory, value, callback) {
+ callback();
try {
- if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
- throw "it is currently offline";
- }
- let blindConfig;
+ let blindConfig,
+ params = {},
+ wcService = accessory.getService(Service.WindowCovering),
+ oldPos = wcService.getCharacteristic(Characteristic.PositionState).value;
if (!(blindConfig = this.cusG.get(accessory.context.hbDeviceId))) {
throw "group config missing";
}
if (blindConfig.type !== "blind" || blindConfig.setup !== "twoSwitch") {
throw "improper configuration";
}
-
- let oldPos,
- params = {},
- wcService = accessory.getService(Service.WindowCovering);
value = value >= 50 ? 100 : 0;
- oldPos = wcService.getCharacteristic(Characteristic.PositionState).value;
- if (value === oldPos * 100) {
- wcService
- .updateCharacteristic(Characteristic.TargetPosition, value)
- .updateCharacteristic(Characteristic.PositionState, oldPos);
- callback();
- return;
- }
-
+ if (value === oldPos * 100) return;
// target position -> 0 for closed 100 for open (value)
// current position -> 0 going down, 1 going up
-
params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
params.switches[0].switch = value === 100 ? "on" : "off";
params.switches[1].switch = value === 0 ? "on" : "off";
-
- this.sendDeviceUpdate(accessory, params, function () {
- return;
- });
- wcService
- .updateCharacteristic(Characteristic.TargetPosition, value)
- .updateCharacteristic(Characteristic.PositionState, value / 100);
- setTimeout(() => {
- wcService
- .updateCharacteristic(Characteristic.CurrentPosition, value)
- .updateCharacteristic(Characteristic.PositionState, 2);
- params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
- params.switches[0].switch = "off";
- params.switches[1].switch = "off";
- this.sendDeviceUpdate(accessory, params, function () {
- return;
+ this.sendDeviceUpdate(accessory, params)
+ .then(() => {
+ wcService
+ .updateCharacteristic(Characteristic.TargetPosition, value)
+ .updateCharacteristic(Characteristic.PositionState, value / 100);
+ return new Promise(resolve =>
+ setTimeout(resolve, parseInt(blindConfig.operationTime) * 100)
+ );
+ })
+ .then(() => {
+ params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
+ params.switches[0].switch = "off";
+ params.switches[1].switch = "off";
+ return this.sendDeviceUpdate(accessory, params);
+ })
+ .then(() => {
+ wcService
+ .updateCharacteristic(Characteristic.CurrentPosition, value)
+ .updateCharacteristic(Characteristic.PositionState, 2);
+ })
+ .catch(err => {
+ throw err;
});
- }, parseInt(blindConfig.operationTime) * 100);
- callback();
} catch (err) {
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
- this.log.error(str);
- callback(str);
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ if (accessory.context.reachableWAN) {
+ this.wsClient.requestUpdate(accessory).catch(() => {});
+ this.log.warn(
+ "[%s] requesting previous state to revert Homebridge status.",
+ accessory.displayName
+ );
+ }
}
}
internalGarageUpdate(accessory, value, callback) {
+ callback();
try {
- if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
- throw "it is currently offline";
- }
let garageConfig;
if (!(garageConfig = this.cusG.get(accessory.context.hbDeviceId))) {
throw "group config missing";
@@ -1274,8 +1270,6 @@ class eWeLink {
) {
throw "improper configuration";
}
- accessory.context.inUse = true;
- accessory.context.state = value;
let sensorDefinition = garageConfig.sensorId || false,
sAccessory = false,
oldPos,
@@ -1296,17 +1290,17 @@ class eWeLink {
? 1
: 0
: gdService.getCharacteristic(Characteristic.CurrentDoorState).value;
- if (newPos === oldPos % 2) {
- accessory.context.inUse = false;
- callback();
- return;
- }
+ if (newPos === oldPos % 2) return;
+ accessory.context.inUse = true;
+ accessory.context.state = value;
if (garageConfig.setup === "oneSwitch" && [2, 3].includes(oldPos)) {
gdService.updateCharacteristic(Characteristic.CurrentDoorState, ((oldPos * 2) % 3) + 2);
delay = 1500;
}
- setTimeout(() => {
- if (accessory.context.state === newPos) {
+ if (accessory.context.state !== newPos) return;
+ let delayPromise = new Promise(resolve => setTimeout(resolve, delay));
+ delayPromise
+ .then(() => {
gdService
.updateCharacteristic(Characteristic.TargetDoorState, newPos)
.updateCharacteristic(Characteristic.CurrentDoorState, newPos + 2);
@@ -1320,32 +1314,41 @@ class eWeLink {
params.switches[1].switch = newPos === 1 ? "on" : "off";
break;
}
- this.sendDeviceUpdate(accessory, params, function () {
- return;
- });
- setTimeout(() => {
- if (!sAccessory) {
- gdService.updateCharacteristic(Characteristic.CurrentDoorState, newPos);
- }
- accessory.context.inUse = false;
- }, parseInt(garageConfig.operationTime) * 100);
- }
- }, delay);
- callback();
+ return this.sendDeviceUpdate(accessory, params);
+ })
+ .then(() => {
+ return new Promise(resolve =>
+ setTimeout(resolve, parseInt(garageConfig.operationTime) * 100)
+ );
+ })
+ .then(() => {
+ if (!sAccessory) {
+ gdService.updateCharacteristic(Characteristic.CurrentDoorState, newPos);
+ }
+ accessory.context.inUse = false;
+ })
+ .catch(err => {
+ throw err;
+ });
} catch (err) {
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
accessory.context.inUse = false;
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
- this.log.error(str);
- callback(str);
+ if (accessory.context.reachableWAN) {
+ this.wsClient.requestUpdate(accessory).catch(() => {});
+ this.log.warn(
+ "[%s] requesting previous state to revert Homebridge status.",
+ accessory.displayName
+ );
+ }
}
}
internalLockUpdate(accessory, value, callback) {
+ callback();
try {
- if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
- throw "it is currently offline";
- }
let lockConfig,
- params = {},
+ params = {
+ switch: "on",
+ },
lmService = accessory.getService(Service.LockMechanism);
if (!(lockConfig = this.cusG.get(accessory.context.hbDeviceId))) {
throw "group config missing";
@@ -1354,64 +1357,79 @@ class eWeLink {
throw "improper configuration";
}
accessory.context.inUse = true;
- this.log("[%s] has received request to unlock.", accessory.displayName);
- lmService
- .updateCharacteristic(Characteristic.LockTargetState, 0)
- .updateCharacteristic(Characteristic.LockCurrentState, 0);
- params.switch = "on";
- this.sendDeviceUpdate(accessory, params, callback);
- setTimeout(() => {
- lmService
- .updateCharacteristic(Characteristic.LockTargetState, 1)
- .updateCharacteristic(Characteristic.LockCurrentState, 1);
- accessory.context.inUse = false;
- }, parseInt(lockConfig.operationTime) * 100);
+ this.sendDeviceUpdate(accessory, params)
+ .then(() => {
+ lmService
+ .updateCharacteristic(Characteristic.LockTargetState, 0)
+ .updateCharacteristic(Characteristic.LockCurrentState, 0);
+ setTimeout(() => {
+ lmService
+ .updateCharacteristic(Characteristic.LockTargetState, 1)
+ .updateCharacteristic(Characteristic.LockCurrentState, 1);
+ accessory.context.inUse = false;
+ }, parseInt(lockConfig.operationTime) * 100);
+ })
+ .catch(err => {
+ throw err;
+ });
} catch (err) {
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
accessory.context.inUse = false;
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
- this.log.error(str);
- callback(str);
+ if (accessory.context.reachableWAN) {
+ this.wsClient.requestUpdate(accessory).catch(() => {});
+ this.log.warn(
+ "[%s] requesting previous state to revert Homebridge status.",
+ accessory.displayName
+ );
+ }
}
}
internalCurtainUpdate(accessory, value, callback) {
+ callback();
try {
- if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
- throw "it is currently offline";
- }
let params,
cService = accessory.getService(Service.WindowCovering),
prevPos = accessory.context.prevPos;
-
- if (value === prevPos) {
- //nothing to do as no change
- callback();
- return;
- }
+ if (value === prevPos) return;
if (value === 0 || value === 100) {
// so to fully open, our $value will be 100, we send switch: "on"
// to fully shut, our $value will be 0, we send switch: "off"
- params = { switch: value === 100 ? "on" : "off" };
+ params = {
+ switch: value === 100 ? "on" : "off",
+ };
} else {
// for a % midway, scale the $value >--< 100 and setclose: newVal AS INT
- params = { setclose: Math.abs(100 - value) };
+ params = {
+ setclose: Math.abs(100 - value),
+ };
}
- cService
- .updateCharacteristic(Characteristic.TargetPosition, value)
- .updateCharacteristic(Characteristic.PositionState, value > prevPos ? 1 : 0);
- // TargetPosition -> 0 for closed 100 for open (value)
- // CurrentPosition -> 0 for closed 100 for open
- // PositionState -> 0 going down, 1 going up, 2 = stopped
-
- this.sendDeviceUpdate(accessory, params, callback);
+ this.sendDeviceUpdate(accessory, params)
+ .then(() => {
+ cService
+ .updateCharacteristic(Characteristic.TargetPosition, value)
+ .updateCharacteristic(Characteristic.PositionState, value > prevPos ? 1 : 0);
+ // TargetPosition -> 0 for closed 100 for open (value)
+ // CurrentPosition -> 0 for closed 100 for open
+ // PositionState -> 0 going down, 1 going up, 2 = stopped
+ accessory.context.prevPos = value;
+ })
+ .catch(err => {
+ throw err;
+ });
} catch (err) {
- callback("[" + accessory.displayName + "] " + err + ".");
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ if (accessory.context.reachableWAN) {
+ this.wsClient.requestUpdate(accessory).catch(() => {});
+ this.log.warn(
+ "[%s] requesting previous state to revert Homebridge status.",
+ accessory.displayName
+ );
+ }
}
}
internalFanUpdate(accessory, type, value, callback) {
+ callback();
try {
- if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
- throw "it is currently offline";
- }
let newPower,
newSpeed,
newLight,
@@ -1434,10 +1452,6 @@ class eWeLink {
newLight = value;
break;
}
- lightService.updateCharacteristic(Characteristic.On, newLight);
- fanService
- .updateCharacteristic(Characteristic.Active, newPower)
- .updateCharacteristic(Characteristic.RotationSpeed, newSpeed);
let params = {
switches: this.devicesInEW.get(accessory.context.eweDeviceId).params.switches,
};
@@ -1445,105 +1459,133 @@ class eWeLink {
params.switches[1].switch = newPower === 1 && newSpeed >= 33 ? "on" : "off";
params.switches[2].switch = newPower === 1 && newSpeed >= 66 && newSpeed < 99 ? "on" : "off";
params.switches[3].switch = newPower === 1 && newSpeed >= 99 ? "on" : "off";
- if (this.debug) {
- this.log.warn("Fan Update - setting " + type + " to " + value);
- this.log(
- "[%s] new stats: power [%s], speed [%s%], light [%s].",
- accessory.displayName,
- newPower,
- newSpeed,
- newLight
+ this.sendDeviceUpdate(accessory, params)
+ .then(() => {
+ lightService.updateCharacteristic(Characteristic.On, newLight);
+ fanService
+ .updateCharacteristic(Characteristic.Active, newPower)
+ .updateCharacteristic(Characteristic.RotationSpeed, newSpeed);
+ })
+ .catch(err => {
+ throw err;
+ });
+ } catch (err) {
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ if (accessory.context.reachableWAN) {
+ this.wsClient.requestUpdate(accessory).catch(() => {});
+ this.log.warn(
+ "[%s] requesting previous state to revert Homebridge status.",
+ accessory.displayName
);
}
- this.sendDeviceUpdate(accessory, params, callback);
- } catch (err) {
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
- this.log.error(str);
- callback(str);
}
}
internalThermostatUpdate(accessory, value, callback) {
+ callback();
try {
- if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
- throw "it is currently offline";
- }
let params = {
switch: value ? "on" : "off",
mainSwitch: value ? "on" : "off",
},
switchService = accessory.getService(Service.Switch);
- if (this.debug) {
- this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
- }
- switchService.updateCharacteristic(Characteristic.On, value);
- this.sendDeviceUpdate(accessory, params, callback);
+ this.sendDeviceUpdate(accessory, params)
+ .then(() => {
+ switchService.updateCharacteristic(Characteristic.On, value);
+ })
+ .catch(err => {
+ throw err;
+ });
} catch (err) {
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
- this.log.error(str);
- callback(str);
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ if (accessory.context.reachableWAN) {
+ this.wsClient.requestUpdate(accessory).catch(() => {});
+ this.log.warn(
+ "[%s] requesting previous state to revert Homebridge status.",
+ accessory.displayName
+ );
+ }
}
}
internalOutletUpdate(accessory, value, callback) {
+ callback();
try {
- if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
- throw "it is currently offline";
- }
let params = {
switch: value ? "on" : "off",
},
outletService = accessory.getService(Service.Outlet);
- if (this.debug) {
- this.log("[%s] requesting to turn [%s].", accessory.displayName, value ? "on" : "off");
- }
- outletService.updateCharacteristic(Characteristic.On, value);
- this.sendDeviceUpdate(accessory, params, callback);
+ this.sendDeviceUpdate(accessory, params)
+ .then(() => {
+ outletService.updateCharacteristic(Characteristic.On, value);
+ })
+ .catch(err => {
+ throw err;
+ });
} catch (err) {
- callback("[" + accessory.displayName + "] " + err + ".");
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ if (accessory.context.reachableWAN) {
+ this.wsClient.requestUpdate(accessory).catch(() => {});
+ this.log.warn(
+ "[%s] requesting previous state to revert Homebridge status.",
+ accessory.displayName
+ );
+ }
}
}
internalUSBUpdate(accessory, value, callback) {
+ callback();
try {
- if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
- throw "it is currently offline";
- }
let params = {
switches: this.devicesInEW.get(accessory.context.eweDeviceId).params.switches,
},
outletService = accessory.getService(Service.Outlet);
params.switches[0].switch = value ? "on" : "off";
- if (this.debug) {
- this.log("[%s] requesting to turn [%s].", accessory.displayName, value ? "on" : "off");
- }
- outletService.updateCharacteristic(Characteristic.On, value);
- this.sendDeviceUpdate(accessory, params, callback);
+ this.sendDeviceUpdate(accessory, params)
+ .then(() => {
+ outletService.updateCharacteristic(Characteristic.On, value);
+ })
+ .catch(err => {
+ throw err;
+ });
} catch (err) {
- callback("[" + accessory.displayName + "] " + err + ".");
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ if (accessory.context.reachableWAN) {
+ this.wsClient.requestUpdate(accessory).catch(() => {});
+ this.log.warn(
+ "[%s] requesting previous state to revert Homebridge status.",
+ accessory.displayName
+ );
+ }
}
}
internalSCMUpdate(accessory, value, callback) {
+ callback();
try {
- if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
- throw "it is currently offline";
- }
let params = {
switches: this.devicesInEW.get(accessory.context.eweDeviceId).params.switches,
},
switchService = accessory.getService(Service.Switch);
params.switches[0].switch = value ? "on" : "off";
- if (this.debug) {
- this.log("[%s] requesting to turn [%s].", accessory.displayName, value ? "on" : "off");
- }
- switchService.updateCharacteristic(Characteristic.On, value);
- this.sendDeviceUpdate(accessory, params, callback);
+ this.sendDeviceUpdate(accessory, params)
+ .then(() => {
+ switchService.updateCharacteristic(Characteristic.On, value);
+ })
+ .catch(err => {
+ throw err;
+ });
} catch (err) {
- callback("[" + accessory.displayName + "] " + err + ".");
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ if (accessory.context.reachableWAN) {
+ this.wsClient.requestUpdate(accessory).catch(() => {});
+ this.log.warn(
+ "[%s] requesting previous state to revert Homebridge status.",
+ accessory.displayName
+ );
+ }
}
}
internalLightbulbUpdate(accessory, value, callback) {
+ callback();
try {
- if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
- throw "it is currently offline";
- }
let oAccessory,
params = {},
lightService = accessory.getService(Service.Lightbulb);
@@ -1555,10 +1597,6 @@ class eWeLink {
} else {
params.switch = value ? "on" : "off";
}
- if (this.debug) {
- this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
- }
- lightService.updateCharacteristic(Characteristic.On, value);
break;
case "0":
params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
@@ -1566,79 +1604,88 @@ class eWeLink {
params.switches[1].switch = value ? "on" : "off";
params.switches[2].switch = value ? "on" : "off";
params.switches[3].switch = value ? "on" : "off";
- if (this.debug) {
- this.log(
- "[%s] updating to turn group [%s].",
- accessory.displayName,
- value ? "on" : "off"
- );
- }
- lightService.updateCharacteristic(Characteristic.On, value);
- for (let i = 1; i <= 4; i++) {
- if (this.devicesInHB.has(accessory.context.eweDeviceId + "SW" + i)) {
- oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i);
- oAccessory
- .getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.On, value);
- }
- }
break;
case "1":
case "2":
case "3":
case "4":
- if (this.debug) {
- this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
- }
- lightService.updateCharacteristic(Characteristic.On, value);
- let tAccessory,
- masterState = "off";
params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
for (let i = 1; i <= 4; i++) {
- if ((tAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
+ if ((oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
i === parseInt(accessory.context.switchNumber)
? (params.switches[i - 1].switch = value ? "on" : "off")
- : (params.switches[i - 1].switch = tAccessory
+ : (params.switches[i - 1].switch = oAccessory
.getService(Service.Lightbulb)
.getCharacteristic(Characteristic.On).value
? "on"
: "off");
- if (
- tAccessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value
- ) {
- masterState = "on";
- }
} else {
params.switches[i - 1].switch = "off";
}
}
- if (!this.hiddenMasters.includes(accessory.context.eweDeviceId)) {
- oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
- oAccessory
- .getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.On, masterState === "on");
- }
break;
- default:
- throw "unknown switch number [" + accessory.context.switchNumber + "]";
}
- this.sendDeviceUpdate(accessory, params, callback);
+ this.sendDeviceUpdate(accessory, params)
+ .then(() => {
+ switch (accessory.context.switchNumber) {
+ case "X":
+ lightService.updateCharacteristic(Characteristic.On, value);
+ break;
+ case "0":
+ for (let i = 0; i <= 4; i++) {
+ if ((oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
+ oAccessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.On, value);
+ }
+ }
+ break;
+ case "1":
+ case "2":
+ case "3":
+ case "4":
+ lightService.updateCharacteristic(Characteristic.On, value);
+ let masterState = "off";
+ for (let i = 1; i <= 4; i++) {
+ if ((oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
+ if (
+ oAccessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On)
+ .value
+ ) {
+ masterState = "on";
+ }
+ }
+ }
+ if (!this.hiddenMasters.includes(accessory.context.eweDeviceId)) {
+ oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
+ oAccessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.On, masterState === "on");
+ }
+ break;
+ }
+ })
+ .catch(err => {
+ throw err;
+ });
} catch (err) {
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
- this.log.error(str);
- callback(str);
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ if (accessory.context.reachableWAN) {
+ this.wsClient.requestUpdate(accessory).catch(() => {});
+ this.log.warn(
+ "[%s] requesting previous state to revert Homebridge status.",
+ accessory.displayName
+ );
+ }
}
}
internalBrightnessUpdate(accessory, value, callback) {
+ callback();
try {
- if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
- throw "it is currently offline";
- }
let params = {},
lightService = accessory.getService(Service.Lightbulb);
if (value === 0) {
params.switch = "off";
- lightService.updateCharacteristic(Characteristic.On, false);
} else {
if (!lightService.getCharacteristic(Characteristic.On).value) {
params.switch = "on";
@@ -1651,22 +1698,34 @@ class eWeLink {
params.brightness = value;
params.mode = 0;
break;
- default:
- throw "unknown device UIID";
}
- lightService.updateCharacteristic(Characteristic.Brightness, value);
}
- if (this.debug) {
- this.log("[%s] updating brightness to [%s%].", accessory.displayName, value);
- }
- setTimeout(() => this.sendDeviceUpdate(accessory, params, callback), 250);
+ setTimeout(() => {
+ this.sendDeviceUpdate(accessory, params)
+ .then(() => {
+ if (value === 0) {
+ lightService.updateCharacteristic(Characteristic.On, false);
+ } else {
+ lightService.updateCharacteristic(Characteristic.Brightness, value);
+ }
+ })
+ .catch(err => {
+ throw err;
+ });
+ }, 250);
} catch (err) {
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
- this.log.error(str);
- callback(str);
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ if (accessory.context.reachableWAN) {
+ this.wsClient.requestUpdate(accessory).catch(() => {});
+ this.log.warn(
+ "[%s] requesting previous state to revert Homebridge status.",
+ accessory.displayName
+ );
+ }
}
}
internalHSBUpdate(accessory, type, value, callback) {
+ callback();
try {
if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
throw "it is currently offline";
@@ -1699,13 +1758,7 @@ class eWeLink {
colorB: newRGB[2],
};
break;
- default:
- throw "unknown device UIID";
- }
- if (this.debug) {
- this.log("[%s] updating hue to [%s°].", accessory.displayName, value);
}
- lightService.updateCharacteristic(Characteristic.Hue, value);
break;
case "bri":
switch (accessory.context.eweUIID) {
@@ -1728,36 +1781,44 @@ class eWeLink {
};
break;
}
- if (this.debug) {
- this.log("[%s] updating brightness to [%s%].", accessory.displayName, value);
- }
- lightService.updateCharacteristic(Characteristic.Brightness, value);
break;
- default:
- throw "unknown device UIID";
}
- setTimeout(() => this.sendDeviceUpdate(accessory, params, callback), 250);
+ setTimeout(() => {
+ this.sendDeviceUpdate(accessory, params)
+ .then(() => {
+ switch (type) {
+ case "hue":
+ lightService.updateCharacteristic(Characteristic.Hue, value);
+ break;
+ case "bri":
+ lightService.updateCharacteristic(Characteristic.Brightness, value);
+ break;
+ }
+ })
+ .catch(err => {
+ throw err;
+ });
+ }, 250);
} catch (err) {
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
- this.log.error(str);
- callback(str);
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ if (accessory.context.reachableWAN) {
+ this.wsClient.requestUpdate(accessory).catch(() => {});
+ this.log.warn(
+ "[%s] requesting previous state to revert Homebridge status.",
+ accessory.displayName
+ );
+ }
}
}
internalSwitchUpdate(accessory, value, callback) {
+ callback();
try {
- if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
- throw "it is currently offline";
- }
let oAccessory,
params = {},
switchService = accessory.getService(Service.Switch);
switch (accessory.context.switchNumber) {
case "X":
params.switch = value ? "on" : "off";
- if (this.debug) {
- this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
- }
- switchService.updateCharacteristic(Characteristic.On, value);
break;
case "0":
params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
@@ -1765,92 +1826,105 @@ class eWeLink {
params.switches[1].switch = value ? "on" : "off";
params.switches[2].switch = value ? "on" : "off";
params.switches[3].switch = value ? "on" : "off";
- if (this.debug) {
- this.log(
- "[%s] updating to turn group [%s].",
- accessory.displayName,
- value ? "on" : "off"
- );
- }
- switchService.updateCharacteristic(Characteristic.On, value);
- for (let i = 1; i <= 4; i++) {
- if (this.devicesInHB.has(accessory.context.eweDeviceId + "SW" + i)) {
- oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i);
- oAccessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
- }
- }
break;
case "1":
case "2":
case "3":
case "4":
- if (this.debug) {
- this.log("[%s] updating to turn [%s].", accessory.displayName, value ? "on" : "off");
- }
- switchService.updateCharacteristic(Characteristic.On, value);
- let tAccessory,
- masterState = "off";
params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
for (let i = 1; i <= 4; i++) {
- if ((tAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
+ if ((oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
i === parseInt(accessory.context.switchNumber)
? (params.switches[i - 1].switch = value ? "on" : "off")
- : (params.switches[i - 1].switch = tAccessory
+ : (params.switches[i - 1].switch = oAccessory
.getService(Service.Switch)
.getCharacteristic(Characteristic.On).value
? "on"
: "off");
- if (
- tAccessory.getService(Service.Switch).getCharacteristic(Characteristic.On).value
- ) {
- masterState = "on";
- }
} else {
params.switches[i - 1].switch = "off";
}
}
- if (!this.hiddenMasters.includes(accessory.context.eweDeviceId)) {
- oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
- oAccessory
- .getService(Service.Switch)
- .updateCharacteristic(Characteristic.On, masterState === "on");
- }
break;
- default:
- throw "unknown switch number [" + accessory.context.switchNumber + "]";
}
- this.sendDeviceUpdate(accessory, params, callback);
+ this.sendDeviceUpdate(accessory, params)
+ .then(() => {
+ switch (accessory.context.switchNumber) {
+ case "X":
+ switchService.updateCharacteristic(Characteristic.On, value);
+ break;
+ case "0":
+ for (let i = 0; i <= 4; i++) {
+ if ((oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
+ oAccessory
+ .getService(Service.Switch)
+ .updateCharacteristic(Characteristic.On, value);
+ }
+ }
+ break;
+ case "1":
+ case "2":
+ case "3":
+ case "4":
+ switchService.updateCharacteristic(Characteristic.On, value);
+ let masterState = "off";
+ for (let i = 1; i <= 4; i++) {
+ if ((oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
+ if (
+ oAccessory.getService(Service.Switch).getCharacteristic(Characteristic.On).value
+ ) {
+ masterState = "on";
+ }
+ }
+ }
+ if (!this.hiddenMasters.includes(accessory.context.eweDeviceId)) {
+ oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
+ oAccessory
+ .getService(Service.Switch)
+ .updateCharacteristic(Characteristic.On, masterState === "on");
+ }
+ break;
+ }
+ })
+ .catch(err => {
+ throw err;
+ });
} catch (err) {
- let str = "[" + accessory.displayName + "] could not be updated as " + err + ".";
- this.log.error(str);
- callback(str);
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ if (accessory.context.reachableWAN) {
+ this.wsClient.requestUpdate(accessory).catch(() => {});
+ this.log.warn(
+ "[%s] requesting previous state to revert Homebridge status.",
+ accessory.displayName
+ );
+ }
}
}
internalRFUpdate(accessory, rfChl, service, callback) {
+ callback();
try {
- if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
- throw "it is currently offline";
- }
- rfChl = parseInt(rfChl);
let params = {
cmd: "transmit",
- rfChl,
+ rfChl: parseInt(rfChl),
},
rfService = accessory.getService(service);
- if (this.debug) {
- this.log(
- "[%s %s] mimicking RF button press.",
- accessory.displayName,
- accessory.context.rfChls[rfChl]
+ this.sendDeviceUpdate(accessory, params)
+ .then(() => {
+ rfService.updateCharacteristic(Characteristic.On, true);
+ setTimeout(() => rfService.updateCharacteristic(Characteristic.On, false), 3000);
+ })
+ .catch(err => {
+ throw err;
+ });
+ } catch (err) {
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ if (accessory.context.reachableWAN) {
+ this.wsClient.requestUpdate(accessory).catch(() => {});
+ this.log.warn(
+ "[%s] requesting previous state to revert Homebridge status.",
+ accessory.displayName
);
}
- rfService.updateCharacteristic(Characteristic.On, true);
- this.sendDeviceUpdate(accessory, params, callback);
- setTimeout(() => rfService.updateCharacteristic(Characteristic.On, false), 3000);
- } catch (err) {
- let str = "[" + accessory.displayName + " " + name + "] could not be updated as " + err + ".";
- this.log.error(str);
- callback(str);
}
}
externalValveUpdate(accessory, params) {
@@ -1895,7 +1969,6 @@ class eWeLink {
let switchUp = params.switches[0].switch === "on" ? -1 : 0, // matrix of numbers to get
switchDown = params.switches[1].switch === "on" ? 0 : 2; // ... the correct HomeKit value
newPosition = switchUp + switchDown;
-
wcService
.updateCharacteristic(Characteristic.PositionState, newPosition)
.updateCharacteristic(Characteristic.TargetPosition, newPosition * 100);
@@ -1990,12 +2063,12 @@ class eWeLink {
try {
let cService = accessory.getService(Service.WindowCovering);
if (params.hasOwnProperty("switch") && params.hasOwnProperty("setclose")) {
+ let newPos = Math.abs(100 - parseInt(params.setclose));
cService
- .updateCharacteristic(
- Characteristic.TargetPosition,
- Math.abs(100 - parseInt(params.setclose))
- )
+ .updateCharacteristic(Characteristic.TargetPosition, newPos)
+ .updateCharacteristic(Characteristic.CurrentPosition, newPos)
.updateCharacteristic(Characteristic.PositionState, 2);
+ accessory.context.prevPos = Math.abs(100 - parseInt(params.setclose));
return;
}
} catch (err) {
@@ -2148,7 +2221,7 @@ class eWeLink {
);
outletService.updateCharacteristic(
Characteristic.OutletInUse,
- parseFloat(params.power) > 0
+ parseFloat(params.power) > (this.config.inUsePowerThreshold || 0)
);
let isOn = accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On).value;
accessory.eveLogger.addEntry({
@@ -2331,7 +2404,6 @@ class eWeLink {
) {
//*** RF Button ***\\
// the device needed is SW% corresponding to params.rfChl
-
this.devicesInHB.forEach(acc => {
if (
acc.context.eweDeviceId === accessory.context.eweDeviceId &&
diff --git a/lib/eWeLinkHTTP.js b/lib/eWeLinkHTTP.js
index 817bbade..3301c18e 100644
--- a/lib/eWeLinkHTTP.js
+++ b/lib/eWeLinkHTTP.js
@@ -54,7 +54,7 @@ module.exports = class eWeLinkHTTP {
.then(res => {
let body = res.data;
if (!body.region) {
- throw "Server did not respond with a region.\n" + JSON.stringify(body, null, 2);
+ reject("Server did not respond with a region.\n" + JSON.stringify(body, null, 2));
}
switch (body.region) {
case "eu":
@@ -66,7 +66,7 @@ module.exports = class eWeLinkHTTP {
this.httpHost = "cn-apia.coolkit.cn";
break;
default:
- throw "No valid region received - [" + body.region + "].";
+ reject("No valid region received - [" + body.region + "].");
}
if (this.debug) {
this.log("HTTP API host received [%s].", this.httpHost);
@@ -136,7 +136,7 @@ module.exports = class eWeLinkHTTP {
this.httpHost = "cn-apia.coolkit.cn";
break;
default:
- throw "No valid region received - [" + givenRegion + "].";
+ reject("No valid region received - [" + givenRegion + "].");
}
if (this.debug) {
this.log("New HTTP API host received [%s].", this.httpHost);
@@ -145,7 +145,7 @@ module.exports = class eWeLinkHTTP {
return;
}
if (!body.data.at) {
- throw "No auth token received.\n" + JSON.stringify(body, null, 2);
+ reject("No auth token received.\n" + JSON.stringify(body, null, 2));
}
this.aToken = body.data.at;
this.apiKey = body.data.user.apikey;
@@ -177,7 +177,7 @@ module.exports = class eWeLinkHTTP {
!body.hasOwnProperty("error") ||
(body.hasOwnProperty("error") && body.error !== 0)
) {
- throw JSON.stringify(body, null, 2);
+ reject(JSON.stringify(body, null, 2));
}
let deviceList = [];
if (body.data.thingList && body.data.thingList.length > 0) {
@@ -229,12 +229,12 @@ module.exports = class eWeLinkHTTP {
!body.hasOwnProperty("error") ||
(body.hasOwnProperty("error") && body.error !== 0)
) {
- throw JSON.stringify(body, null, 2);
+ reject(JSON.stringify(body, null, 2));
}
if (body.data.thingList && body.data.thingList.length === 1) {
resolve(body.data.thingList[0].itemData);
} else {
- throw "device not found in eWeLink";
+ reject("device not found in eWeLink");
}
})
.catch(err => {
diff --git a/lib/eWeLinkLAN.js b/lib/eWeLinkLAN.js
index 3923e97d..da6bfe8d 100644
--- a/lib/eWeLinkLAN.js
+++ b/lib/eWeLinkLAN.js
@@ -130,7 +130,7 @@ module.exports = class eWeLinkLAN {
sendUpdate(json) {
return new Promise((resolve, reject) => {
if (!this.deviceMap.get(json.deviceid).online) {
- throw "device isn't reachable by LAN mode";
+ reject("device isn't reachable by LAN mode");
}
let apiKey,
suffix,
@@ -142,7 +142,9 @@ module.exports = class eWeLinkLAN {
params.switch = json.params.switch;
suffix = "switch";
} else {
- throw "plugin does not support lan mode for this device yet - feel free to create a github issue";
+ reject(
+ "plugin does not support lan mode for this device yet - feel free to create a github issue"
+ );
}
if ((apiKey = this.deviceMap.get(json.deviceid).apiKey)) {
let key = crypto.createHash("md5").update(Buffer.from(apiKey, "utf8")).digest(),
@@ -180,7 +182,7 @@ module.exports = class eWeLinkLAN {
if (res.data.hasOwnProperty("error") && res.data.error === 0) {
resolve();
}
- throw res.data;
+ reject(res.data);
})
.catch(err => reject(err));
}
diff --git a/lib/eWeLinkWS.js b/lib/eWeLinkWS.js
index 31192209..e925836c 100644
--- a/lib/eWeLinkWS.js
+++ b/lib/eWeLinkWS.js
@@ -37,7 +37,7 @@ module.exports = class eWeLinkWS {
.then(res => {
let body = res.data;
if (!body.domain) {
- throw "Server did not respond with a web socket host.";
+ reject("Server did not respond with a web socket host.");
}
if (this.debug) {
this.log("Web socket host received [%s].", body.domain);
@@ -176,6 +176,7 @@ module.exports = class eWeLinkWS {
}
});
this.wsp.onClose.addListener((e, m) => {
+ this.wsIsOpen = false;
if (e !== 1005) {
this.log.warn("Web socket closed [%s].", e);
if (e !== 1000) {
@@ -185,7 +186,6 @@ module.exports = class eWeLinkWS {
this.log("Please try restarting Homebridge so that this plugin can work again.");
}
}
- this.wsIsOpen = false;
if (this.hbInterval) {
clearInterval(this.hbInterval);
this.hbInterval = null;
@@ -238,7 +238,7 @@ module.exports = class eWeLinkWS {
break;
case 504:
default:
- throw "Unknown response";
+ reject("Unknown response");
}
})
.catch(err => reject("Device update failed [" + err + "]."));
@@ -301,10 +301,18 @@ module.exports = class eWeLinkWS {
this.emitter.addListener("update", f);
}
closeConnection() {
- if (this.wsp && this.wsIsOpen) {
- this.wsp.close();
- this.log("Web socket gracefully closed.");
- }
+ return new Promise((resolve, reject) => {
+ if (this.wsp && this.wsIsOpen) {
+ this.wsp
+ .close()
+ .then(() => {
+ this.log("Web socket gracefully closed.");
+ resolve();
+ })
+ .catch(err => reject(err));
+ }
+ resolve();
+ });
}
delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
From 0ddfa292fc874167325e09e7990c830e21de9af9 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 22 Sep 2020 16:14:03 +0100
Subject: [PATCH 0189/3183] 3.0.0-4
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index d5c2bc87..2760225f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.0.0-3",
+ "version": "3.0.0-4",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index a442dbb2..a08b6aa2 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.0.0-3",
+ "version": "3.0.0-4",
"author": "bwp91",
"contributors": [
"gbro115",
From 906c2a55ee5d87c7a5f2223c273885ae0152e3a7 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 22 Sep 2020 16:56:02 +0100
Subject: [PATCH 0190/3183] next
---
lib/eWeLink.js | 5 +----
lib/eWeLinkHTTP.js | 14 +++++++-------
lib/eWeLinkWS.js | 4 ++--
3 files changed, 10 insertions(+), 13 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index acd6c6a7..b779d1e3 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -548,10 +548,7 @@ class eWeLink {
}
cService
.getCharacteristic(Characteristic.TargetPosition)
- .on("set", (value, callback) => this.internalCurtainUpdate(accessory, value, callback))
- .setProps({
- minStep: 100,
- });
+ .on("set", (value, callback) => this.internalCurtainUpdate(accessory, value, callback));
break;
case "garage":
let gdService;
diff --git a/lib/eWeLinkHTTP.js b/lib/eWeLinkHTTP.js
index 3301c18e..817bbade 100644
--- a/lib/eWeLinkHTTP.js
+++ b/lib/eWeLinkHTTP.js
@@ -54,7 +54,7 @@ module.exports = class eWeLinkHTTP {
.then(res => {
let body = res.data;
if (!body.region) {
- reject("Server did not respond with a region.\n" + JSON.stringify(body, null, 2));
+ throw "Server did not respond with a region.\n" + JSON.stringify(body, null, 2);
}
switch (body.region) {
case "eu":
@@ -66,7 +66,7 @@ module.exports = class eWeLinkHTTP {
this.httpHost = "cn-apia.coolkit.cn";
break;
default:
- reject("No valid region received - [" + body.region + "].");
+ throw "No valid region received - [" + body.region + "].";
}
if (this.debug) {
this.log("HTTP API host received [%s].", this.httpHost);
@@ -136,7 +136,7 @@ module.exports = class eWeLinkHTTP {
this.httpHost = "cn-apia.coolkit.cn";
break;
default:
- reject("No valid region received - [" + givenRegion + "].");
+ throw "No valid region received - [" + givenRegion + "].";
}
if (this.debug) {
this.log("New HTTP API host received [%s].", this.httpHost);
@@ -145,7 +145,7 @@ module.exports = class eWeLinkHTTP {
return;
}
if (!body.data.at) {
- reject("No auth token received.\n" + JSON.stringify(body, null, 2));
+ throw "No auth token received.\n" + JSON.stringify(body, null, 2);
}
this.aToken = body.data.at;
this.apiKey = body.data.user.apikey;
@@ -177,7 +177,7 @@ module.exports = class eWeLinkHTTP {
!body.hasOwnProperty("error") ||
(body.hasOwnProperty("error") && body.error !== 0)
) {
- reject(JSON.stringify(body, null, 2));
+ throw JSON.stringify(body, null, 2);
}
let deviceList = [];
if (body.data.thingList && body.data.thingList.length > 0) {
@@ -229,12 +229,12 @@ module.exports = class eWeLinkHTTP {
!body.hasOwnProperty("error") ||
(body.hasOwnProperty("error") && body.error !== 0)
) {
- reject(JSON.stringify(body, null, 2));
+ throw JSON.stringify(body, null, 2);
}
if (body.data.thingList && body.data.thingList.length === 1) {
resolve(body.data.thingList[0].itemData);
} else {
- reject("device not found in eWeLink");
+ throw "device not found in eWeLink";
}
})
.catch(err => {
diff --git a/lib/eWeLinkWS.js b/lib/eWeLinkWS.js
index e925836c..e99df8fd 100644
--- a/lib/eWeLinkWS.js
+++ b/lib/eWeLinkWS.js
@@ -37,7 +37,7 @@ module.exports = class eWeLinkWS {
.then(res => {
let body = res.data;
if (!body.domain) {
- reject("Server did not respond with a web socket host.");
+ throw "Server did not respond with a web socket host.";
}
if (this.debug) {
this.log("Web socket host received [%s].", body.domain);
@@ -238,7 +238,7 @@ module.exports = class eWeLinkWS {
break;
case 504:
default:
- reject("Unknown response");
+ throw "Unknown response";
}
})
.catch(err => reject("Device update failed [" + err + "]."));
From de2bc9fe077ab87fe1e6fb1d0e2390a024731a65 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 22 Sep 2020 16:56:45 +0100
Subject: [PATCH 0191/3183] 3.0.0-5
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 2760225f..e096c48a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.0.0-4",
+ "version": "3.0.0-5",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index a08b6aa2..38bcdaab 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.0.0-4",
+ "version": "3.0.0-5",
"author": "bwp91",
"contributors": [
"gbro115",
From e807c07d1786f4b149ea58d3feb4bbee03102e38 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 22 Sep 2020 22:23:23 +0100
Subject: [PATCH 0192/3183] 3.0 new settings
---
config.schema.json | 36 +++++++++++++++++++++++++++++++-----
1 file changed, 31 insertions(+), 5 deletions(-)
diff --git a/config.schema.json b/config.schema.json
index f44541f9..f1e23146 100644
--- a/config.schema.json
+++ b/config.schema.json
@@ -55,9 +55,15 @@
"hideFromHB": {
"type": "string",
"title": "Hide Device Channels",
- "description": "A list of device channels to hide from Homebridge. For example '10009553c8SW1' or multiple channels separated with a comma '10009553c8SW1,10009553c9SW2'. Only channels from switches, lights and irrigation valves can be hidden.",
+ "description": "A list of SW1, SW2, SW3 and SW4 to hide from Homebridge. For example '10009553c8SW1' or multiple channels separated with a comma '10009553c8SW1,10009553c9SW2'. Only channels from switches and lights can be hidden. This setting cannot be used to hide master devices (SW0).",
"default": ""
},
+ "disableHTTPRefresh": {
+ "type": "boolean",
+ "title": "Disable Initial Device Refresh",
+ "description": "If enabled, devices will not be refreshed with their most recent status from eWeLink when Homebridge starts. This setting can be useful for users who block their devices from accessing the internet.",
+ "default": false
+ },
"lowBattThreshold": {
"type": "integer",
"title": "Low Battery Threshold",
@@ -90,14 +96,22 @@
"minimum": 10,
"maximum": 1800
},
+ "inUsePowerThreshold": {
+ "type": "integer",
+ "title": "Outlet 'In Use' Threshold",
+ "description": "Homebridge will set the 'In Use' status of outlet devices to true when the wattage is above this number.",
+ "default": 0,
+ "minimum": 0,
+ "maximum": 100
+ },
"hideTHSwitch": {
- "title": "Hide TH10/TH16 Switch",
+ "title": "TH10/TH16 Hide Switch",
"type": "boolean",
"description": "If enabled, the switch for the TH10/TH16 devices will be hidden from Homebridge.",
"default": false
},
"hideZBLDPress": {
- "title": "Hide Double/Long Press",
+ "title": "Zigbee Button Hide Double/Long Press",
"type": "boolean",
"description": "If enabled, double and long press options will be hidden for the ZigBee button.",
"default": false
@@ -228,12 +242,14 @@
"layout": [
{
"type": "fieldset",
+ "title": "Required Settings",
+ "description": "These are the basic settings that are required for this plugin to work.",
"items": ["countryCode", "username", "password"]
},
{
"type": "fieldset",
- "title": "Optional",
- "description": "Only adjust these settings if you know what you are doing.",
+ "title": "Optional Settings (General)",
+ "description": "A variety of optional settings for general use of this plugin.",
"expandable": true,
"items": [
"debug",
@@ -241,7 +257,17 @@
"hideDevFromHB",
"hideMasters",
"hideFromHB",
+ "disableHTTPRefresh"
+ ]
+ },
+ {
+ "type": "fieldset",
+ "title": "Optional Settings (Device Specific)",
+ "description": "A variety of optional settings for specific device types.",
+ "expandable": true,
+ "items": [
"lowBattThreshold",
+ "inUsePowerThreshold",
"sensorTimeLength",
"sensorTimeDifference",
"valveTimeLength",
From 5799bc1af6bc7469d93954b618a6850368b63625 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 22 Sep 2020 22:41:09 +0100
Subject: [PATCH 0193/3183] Update eWeLinkHTTP.js
---
lib/eWeLinkHTTP.js | 1 -
1 file changed, 1 deletion(-)
diff --git a/lib/eWeLinkHTTP.js b/lib/eWeLinkHTTP.js
index 817bbade..beb48f3b 100644
--- a/lib/eWeLinkHTTP.js
+++ b/lib/eWeLinkHTTP.js
@@ -198,7 +198,6 @@ module.exports = class eWeLinkHTTP {
});
});
}
-
getDevice(deviceId) {
return new Promise((resolve, reject) => {
axios
From 79ab91a2ec32d58ff3417777640cb977d231c571 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 22 Sep 2020 22:41:38 +0100
Subject: [PATCH 0194/3183] add device to lan map
---
lib/eWeLink.js | 11 ++++++++---
lib/eWeLinkLAN.js | 9 +++++++++
2 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index b779d1e3..c355fc74 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -403,7 +403,9 @@ class eWeLink {
.setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion);
}
accessory.context.reachableWAN = device.online;
- accessory.context.reachableLAN = this.lanDevices.get(device.deviceid).online || false;
+ accessory.context.reachableLAN = this.lanDevices.has(device.deviceid)
+ ? this.lanDevices.get(device.deviceid).online
+ : false;
accessory.context.inUse = false;
let str = accessory.context.reachableLAN
? "and found locally with IP [" + this.lanDevices.get(device.deviceid).ip + "]"
@@ -1132,7 +1134,10 @@ class eWeLink {
);
this.httpClient
.getDevice(deviceId)
- .then(res => this.initialiseDevice(res))
+ .then(device => {
+ this.initialiseDevice(device);
+ this.lanClient.addDeviceToMap(device);
+ })
.catch(err => this.log.error("[%s] error getting info [%s]", deviceId, err));
}
}
@@ -2550,7 +2555,7 @@ class eWeLink {
Characteristic.MotionDetected,
params.hasOwnProperty("updateSource") &&
params.motion === 1 &&
- diff < (this.config.sensortimeDifference || 120)
+ diff < (this.config.sensorTimeDifference || 120)
);
break;
}
diff --git a/lib/eWeLinkLAN.js b/lib/eWeLinkLAN.js
index da6bfe8d..6958c166 100644
--- a/lib/eWeLinkLAN.js
+++ b/lib/eWeLinkLAN.js
@@ -191,6 +191,15 @@ module.exports = class eWeLinkLAN {
receiveUpdate(f) {
this.emitter.addListener("update", f);
}
+ addDeviceToMap(device) {
+ this.deviceMap.set(device.deviceid, {
+ apiKey: device.devicekey,
+ online: this.ipOverrides.hasOwnProperty(device.deviceid) ? true : false,
+ ip: this.ipOverrides.hasOwnProperty(device.deviceid)
+ ? this.ipOverrides[device.deviceid]
+ : null,
+ });
+ }
closeConnection() {
dns.stopMonitoring();
this.log("LAN monitoring gracefully stopped.");
From e47c72478813e2a6479bc20e6f03b059f9d463a5 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 22 Sep 2020 22:50:50 +0100
Subject: [PATCH 0195/3183] format blind service
---
lib/eWeLink.js | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index c355fc74..c9e4b958 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -533,10 +533,7 @@ class eWeLink {
}
wcService
.getCharacteristic(Characteristic.TargetPosition)
- .on("set", (value, callback) => this.internalBlindUpdate(accessory, value, callback))
- .setProps({
- minStep: 100,
- });
+ .on("set", (value, callback) => this.internalBlindUpdate(accessory, value, callback));
break;
case "curtain":
let cService;
@@ -1168,9 +1165,6 @@ class eWeLink {
}
params.switches[2].switch = "off";
params.switches[3].switch = "off";
- //2. send the request
- //3a. update the accessory if (2) is resolved
- //3b. revert the device status if (2) is rejected with a requestDeviceStatus.
this.sendDeviceUpdate(accessory, params)
.then(() => {
serviceValve
From 7408bff113cf22ec69677d4bac794034cfa4f911 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 22 Sep 2020 22:56:36 +0100
Subject: [PATCH 0196/3183] code formatting
---
lib/eWeLinkWS.js | 321 +----------------------------------------------
1 file changed, 1 insertion(+), 320 deletions(-)
diff --git a/lib/eWeLinkWS.js b/lib/eWeLinkWS.js
index e99df8fd..8bca24bb 100644
--- a/lib/eWeLinkWS.js
+++ b/lib/eWeLinkWS.js
@@ -1,320 +1 @@
-/* jshint esversion: 9, -W014, -W030, node: true */
-"use strict";
-const axios = require("axios"),
- cns = require("./constants"),
- eventemitter = require("events"),
- ws = require("ws"),
- wsp = require("websocket-as-promised");
-module.exports = class eWeLinkWS {
- constructor(config, log, res) {
- this.config = config;
- this.log = log;
- this.debug = this.config.debug || false;
- this.debugReqRes = this.config.debugReqRes || false;
- this.httpHost = res.httpHost;
- this.aToken = res.aToken;
- this.apiKey = res.apiKey;
- this.wsIsOpen = false;
- this.emitter = new eventemitter();
- this.delaySend = 0;
- }
- getHost() {
- return new Promise((resolve, reject) => {
- axios({
- method: "post",
- url: "https://" + this.httpHost.replace("-api", "-disp") + "/dispatch/app",
- headers: {
- Authorization: "Bearer " + this.aToken,
- "Content-Type": "application/json",
- },
- data: {
- appid: cns.appId,
- nonce: Math.random().toString(36).substr(2, 8),
- ts: Math.floor(new Date().getTime() / 1000),
- version: 8,
- },
- })
- .then(res => {
- let body = res.data;
- if (!body.domain) {
- throw "Server did not respond with a web socket host.";
- }
- if (this.debug) {
- this.log("Web socket host received [%s].", body.domain);
- }
- this.wsHost = body.domain;
- resolve(body.domain);
- })
- .catch(err => {
- if (err.hasOwnProperty("code") && ["ENOTFOUND", "ETIMEDOUT"].includes(err.code)) {
- this.log.warn("Unable to reach eWeLink. Retrying in 30 seconds.");
- this.delay().then(() => resolve(this.getDevices()));
- } else {
- reject(err.message || err);
- }
- });
- });
- }
- login() {
- this.wsp = new wsp("wss://" + this.wsHost + ":8080/api/ws", {
- createWebSocket: url => new ws(url),
- extractMessageData: event => event,
- attachRequestId: (data, requestId) =>
- Object.assign(
- {
- sequence: requestId,
- },
- data
- ),
- extractRequestId: data => data && data.sequence,
- packMessage: data => JSON.stringify(data),
- unpackMessage: data => {
- return data === "pong" ? data : JSON.parse(data);
- },
- });
- this.wsp.open();
- this.wsp.onOpen.addListener(() => {
- this.wsIsOpen = true;
- let sequence = Math.floor(new Date()).toString(),
- payload = {
- action: "userOnline",
- apikey: this.apiKey,
- appid: cns.appId,
- at: this.aToken,
- nonce: Math.random().toString(36).substr(2, 8),
- sequence,
- ts: Math.floor(new Date() / 1000),
- userAgent: "app",
- version: 8,
- };
- if (this.debugReqRes) {
- let msg = JSON.stringify(payload, null, 2)
- .replace(this.aToken, "**hidden**")
- .replace(this.apiKey, "**hidden**");
- this.log.warn("Sending WS login request. This text is yellow for clarity.\n%s", msg);
- } else if (this.debug) {
- this.log("Sending WS login request.");
- }
- this.wsp
- .sendRequest(payload, {
- requestId: sequence,
- })
- .then(res => {
- if (
- res.hasOwnProperty("config") &&
- res.config.hb &&
- res.config.hbInterval &&
- !this.hbInterval
- ) {
- this.hbInterval = setInterval(() => {
- this.wsp.send("ping");
- }, (res.config.hbInterval + 7) * 1000);
- } else {
- throw "Unknown parameters received";
- }
- })
- .catch(err => {
- this.log.error("WS login failed [%s].", err);
- });
- });
- this.wsp.onUnpackedMessage.addListener(device => {
- if (device === "pong") return;
- let onlineStatus = true;
- if (!device.hasOwnProperty("params")) device.params = {};
- if (device.hasOwnProperty("deviceid") && device.hasOwnProperty("error")) {
- device.action = "update";
- onlineStatus = device.error === 0;
- }
- if (device.hasOwnProperty("action")) {
- switch (device.action) {
- case "update":
- case "sysmsg":
- if (device.action === "sysmsg" && device.params.hasOwnProperty("online")) {
- onlineStatus = device.params.online;
- }
- for (let param in device.params) {
- if (device.params.hasOwnProperty(param)) {
- if (!cns.paramsToKeep.includes(param.replace(/[0-9]/g, ""))) {
- delete device.params[param];
- }
- }
- }
- device.params.online = onlineStatus;
- device.params.updateSource = "WS";
- if (Object.keys(device.params).length > 0) {
- let returnTemplate = {
- deviceid: device.deviceid,
- params: device.params,
- };
- if (this.debugReqRes) {
- let msg = JSON.stringify(returnTemplate, null, 2).replace(
- device.deviceid,
- "**hidden**"
- );
- this.log("WS message received.\n%s", msg);
- } else if (this.debug) {
- this.log("WS message received.");
- }
- this.emitter.emit("update", returnTemplate);
- }
- break;
- case "reportSubDevice":
- return;
- default:
- this.log.warn(
- "[%s] WS message has unknown action.\n" + JSON.stringify(device, null, 2),
- device.deviceid
- );
- return;
- }
- } else if (device.hasOwnProperty("error") && device.error === 0) {
- // *** Safe to ignore these messages *** \\
- } else {
- if (this.debug) {
- this.log.warn("WS unknown command received.\n" + JSON.stringify(device, null, 2));
- }
- }
- });
- this.wsp.onClose.addListener((e, m) => {
- this.wsIsOpen = false;
- if (e !== 1005) {
- this.log.warn("Web socket closed [%s].", e);
- if (e !== 1000) {
- this.log("Web socket will try to reconnect in five seconds.");
- setTimeout(() => this.login(), 5000);
- } else {
- this.log("Please try restarting Homebridge so that this plugin can work again.");
- }
- }
- if (this.hbInterval) {
- clearInterval(this.hbInterval);
- this.hbInterval = null;
- }
- this.wsp.removeAllListeners();
- });
- this.wsp.onError.addListener(e => {
- this.log.error("Web socket error - [%s].", e);
- if (e.code === "ECONNREFUSED") {
- this.log.warn(
- "Web socket will try to reconnect in five seconds then try the command again."
- );
- this.wsp.removeAllListeners();
- setTimeout(() => this.login(), 5000);
- } else {
- this.log.warn("If this was unexpected then please try restarting Homebridge.");
- }
- });
- }
- sendUpdate(json) {
- return new Promise((resolve, reject) => {
- let sequence = Math.floor(new Date()).toString();
- json = {
- ...json,
- ...{
- action: "update",
- sequence,
- userAgent: "app",
- },
- };
- let sendOperation = () => {
- this.wsp
- .sendRequest(json, {
- requestId: sequence,
- })
- .then(device => {
- if (this.debugReqRes) {
- let msg = JSON.stringify(json, null, 2)
- .replace(json.apikey, "**hidden**")
- .replace(json.apiKey, "**hidden**")
- .replace(json.deviceid, "**hidden**");
- this.log.warn("WS message sent. This text is yellow for clarity.\n%s", msg);
- } else if (this.debug) {
- this.log("WS message sent.");
- }
- device.error = device.hasOwnProperty("error") ? device.error : 504; // mimic ewelink device offline
- switch (device.error) {
- case 0:
- resolve();
- break;
- case 504:
- default:
- throw "Unknown response";
- }
- })
- .catch(err => reject("Device update failed [" + err + "]."));
- };
- let checkToSend = () => {
- if (this.wsp && this.wsIsOpen) {
- sendOperation();
- } else {
- this.delay(2500).then(() => {
- if (this.debug) {
- this.log.warn("Will resend command when WS is reconnected.");
- }
- checkToSend();
- });
- }
- };
- checkToSend();
- });
- }
- requestUpdate(accessory) {
- return new Promise(resolve => {
- let sequence = Math.floor(new Date()).toString(),
- json = {
- action: "query",
- apikey: accessory.context.eweApiKey,
- deviceid: accessory.context.eweDeviceId,
- params: [],
- sequence,
- ts: 0,
- userAgent: "app",
- },
- sendOperation = () => {
- this.wsp.send(json);
- if (this.debugReqRes) {
- let msg = JSON.stringify(json, null, 2)
- .replace(json.apikey, "**hidden**")
- .replace(json.apiKey, "**hidden**")
- .replace(json.deviceid, "**hidden**");
- this.log.warn("WS message sent. This text is yellow for clarity.\n%s", msg);
- } else if (this.debug) {
- this.log("WS message sent.");
- }
- },
- checkToSend = () => {
- if (this.wsp && this.wsIsOpen) {
- sendOperation();
- } else {
- this.delay(2500).then(() => {
- if (this.debug) {
- this.log.warn("Will resend command when WS is reconnected.");
- }
- checkToSend();
- });
- }
- };
- checkToSend();
- });
- }
- receiveUpdate(f) {
- this.emitter.addListener("update", f);
- }
- closeConnection() {
- return new Promise((resolve, reject) => {
- if (this.wsp && this.wsIsOpen) {
- this.wsp
- .close()
- .then(() => {
- this.log("Web socket gracefully closed.");
- resolve();
- })
- .catch(err => reject(err));
- }
- resolve();
- });
- }
- delay(ms) {
- return new Promise(resolve => setTimeout(resolve, ms));
- }
-};
+zb_dev;
From 8aec5f067ec5e39859e90be9c38678541daccf99 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 22 Sep 2020 22:57:44 +0100
Subject: [PATCH 0197/3183] 3.0.0-6
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index e096c48a..fbe82755 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.0.0-5",
+ "version": "3.0.0-6",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 38bcdaab..9d03ce36 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.0.0-5",
+ "version": "3.0.0-6",
"author": "bwp91",
"contributors": [
"gbro115",
From 651ec7ad329a337dbfa76c8f0cc431aaf595797d Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Wed, 23 Sep 2020 09:44:02 +0100
Subject: [PATCH 0198/3183] remove lan count
---
lib/eWeLinkLAN.js | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/lib/eWeLinkLAN.js b/lib/eWeLinkLAN.js
index 6958c166..68aa7eb7 100644
--- a/lib/eWeLinkLAN.js
+++ b/lib/eWeLinkLAN.js
@@ -31,7 +31,6 @@ module.exports = class eWeLinkLAN {
name: "_ewelink._tcp.local",
})
.then(res => {
- let onlineCount = 0;
res.forEach(device => {
let d,
deviceId = device.fqdn.replace("._ewelink._tcp.local", "").replace("eWeLink_", "");
@@ -43,13 +42,9 @@ module.exports = class eWeLinkLAN {
ip: device.address,
});
}
- onlineCount++;
}
});
- resolve({
- map: this.deviceMap,
- count: onlineCount,
- });
+ resolve(this.deviceMap);
})
.catch(err => reject(err));
});
From 286387f143ceb715e181f4a7969fa78bb7ae72f9 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Wed, 23 Sep 2020 09:44:12 +0100
Subject: [PATCH 0199/3183] Update eWeLinkWS.js
---
lib/eWeLinkWS.js | 321 ++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 320 insertions(+), 1 deletion(-)
diff --git a/lib/eWeLinkWS.js b/lib/eWeLinkWS.js
index 8bca24bb..e99df8fd 100644
--- a/lib/eWeLinkWS.js
+++ b/lib/eWeLinkWS.js
@@ -1 +1,320 @@
-zb_dev;
+/* jshint esversion: 9, -W014, -W030, node: true */
+"use strict";
+const axios = require("axios"),
+ cns = require("./constants"),
+ eventemitter = require("events"),
+ ws = require("ws"),
+ wsp = require("websocket-as-promised");
+module.exports = class eWeLinkWS {
+ constructor(config, log, res) {
+ this.config = config;
+ this.log = log;
+ this.debug = this.config.debug || false;
+ this.debugReqRes = this.config.debugReqRes || false;
+ this.httpHost = res.httpHost;
+ this.aToken = res.aToken;
+ this.apiKey = res.apiKey;
+ this.wsIsOpen = false;
+ this.emitter = new eventemitter();
+ this.delaySend = 0;
+ }
+ getHost() {
+ return new Promise((resolve, reject) => {
+ axios({
+ method: "post",
+ url: "https://" + this.httpHost.replace("-api", "-disp") + "/dispatch/app",
+ headers: {
+ Authorization: "Bearer " + this.aToken,
+ "Content-Type": "application/json",
+ },
+ data: {
+ appid: cns.appId,
+ nonce: Math.random().toString(36).substr(2, 8),
+ ts: Math.floor(new Date().getTime() / 1000),
+ version: 8,
+ },
+ })
+ .then(res => {
+ let body = res.data;
+ if (!body.domain) {
+ throw "Server did not respond with a web socket host.";
+ }
+ if (this.debug) {
+ this.log("Web socket host received [%s].", body.domain);
+ }
+ this.wsHost = body.domain;
+ resolve(body.domain);
+ })
+ .catch(err => {
+ if (err.hasOwnProperty("code") && ["ENOTFOUND", "ETIMEDOUT"].includes(err.code)) {
+ this.log.warn("Unable to reach eWeLink. Retrying in 30 seconds.");
+ this.delay().then(() => resolve(this.getDevices()));
+ } else {
+ reject(err.message || err);
+ }
+ });
+ });
+ }
+ login() {
+ this.wsp = new wsp("wss://" + this.wsHost + ":8080/api/ws", {
+ createWebSocket: url => new ws(url),
+ extractMessageData: event => event,
+ attachRequestId: (data, requestId) =>
+ Object.assign(
+ {
+ sequence: requestId,
+ },
+ data
+ ),
+ extractRequestId: data => data && data.sequence,
+ packMessage: data => JSON.stringify(data),
+ unpackMessage: data => {
+ return data === "pong" ? data : JSON.parse(data);
+ },
+ });
+ this.wsp.open();
+ this.wsp.onOpen.addListener(() => {
+ this.wsIsOpen = true;
+ let sequence = Math.floor(new Date()).toString(),
+ payload = {
+ action: "userOnline",
+ apikey: this.apiKey,
+ appid: cns.appId,
+ at: this.aToken,
+ nonce: Math.random().toString(36).substr(2, 8),
+ sequence,
+ ts: Math.floor(new Date() / 1000),
+ userAgent: "app",
+ version: 8,
+ };
+ if (this.debugReqRes) {
+ let msg = JSON.stringify(payload, null, 2)
+ .replace(this.aToken, "**hidden**")
+ .replace(this.apiKey, "**hidden**");
+ this.log.warn("Sending WS login request. This text is yellow for clarity.\n%s", msg);
+ } else if (this.debug) {
+ this.log("Sending WS login request.");
+ }
+ this.wsp
+ .sendRequest(payload, {
+ requestId: sequence,
+ })
+ .then(res => {
+ if (
+ res.hasOwnProperty("config") &&
+ res.config.hb &&
+ res.config.hbInterval &&
+ !this.hbInterval
+ ) {
+ this.hbInterval = setInterval(() => {
+ this.wsp.send("ping");
+ }, (res.config.hbInterval + 7) * 1000);
+ } else {
+ throw "Unknown parameters received";
+ }
+ })
+ .catch(err => {
+ this.log.error("WS login failed [%s].", err);
+ });
+ });
+ this.wsp.onUnpackedMessage.addListener(device => {
+ if (device === "pong") return;
+ let onlineStatus = true;
+ if (!device.hasOwnProperty("params")) device.params = {};
+ if (device.hasOwnProperty("deviceid") && device.hasOwnProperty("error")) {
+ device.action = "update";
+ onlineStatus = device.error === 0;
+ }
+ if (device.hasOwnProperty("action")) {
+ switch (device.action) {
+ case "update":
+ case "sysmsg":
+ if (device.action === "sysmsg" && device.params.hasOwnProperty("online")) {
+ onlineStatus = device.params.online;
+ }
+ for (let param in device.params) {
+ if (device.params.hasOwnProperty(param)) {
+ if (!cns.paramsToKeep.includes(param.replace(/[0-9]/g, ""))) {
+ delete device.params[param];
+ }
+ }
+ }
+ device.params.online = onlineStatus;
+ device.params.updateSource = "WS";
+ if (Object.keys(device.params).length > 0) {
+ let returnTemplate = {
+ deviceid: device.deviceid,
+ params: device.params,
+ };
+ if (this.debugReqRes) {
+ let msg = JSON.stringify(returnTemplate, null, 2).replace(
+ device.deviceid,
+ "**hidden**"
+ );
+ this.log("WS message received.\n%s", msg);
+ } else if (this.debug) {
+ this.log("WS message received.");
+ }
+ this.emitter.emit("update", returnTemplate);
+ }
+ break;
+ case "reportSubDevice":
+ return;
+ default:
+ this.log.warn(
+ "[%s] WS message has unknown action.\n" + JSON.stringify(device, null, 2),
+ device.deviceid
+ );
+ return;
+ }
+ } else if (device.hasOwnProperty("error") && device.error === 0) {
+ // *** Safe to ignore these messages *** \\
+ } else {
+ if (this.debug) {
+ this.log.warn("WS unknown command received.\n" + JSON.stringify(device, null, 2));
+ }
+ }
+ });
+ this.wsp.onClose.addListener((e, m) => {
+ this.wsIsOpen = false;
+ if (e !== 1005) {
+ this.log.warn("Web socket closed [%s].", e);
+ if (e !== 1000) {
+ this.log("Web socket will try to reconnect in five seconds.");
+ setTimeout(() => this.login(), 5000);
+ } else {
+ this.log("Please try restarting Homebridge so that this plugin can work again.");
+ }
+ }
+ if (this.hbInterval) {
+ clearInterval(this.hbInterval);
+ this.hbInterval = null;
+ }
+ this.wsp.removeAllListeners();
+ });
+ this.wsp.onError.addListener(e => {
+ this.log.error("Web socket error - [%s].", e);
+ if (e.code === "ECONNREFUSED") {
+ this.log.warn(
+ "Web socket will try to reconnect in five seconds then try the command again."
+ );
+ this.wsp.removeAllListeners();
+ setTimeout(() => this.login(), 5000);
+ } else {
+ this.log.warn("If this was unexpected then please try restarting Homebridge.");
+ }
+ });
+ }
+ sendUpdate(json) {
+ return new Promise((resolve, reject) => {
+ let sequence = Math.floor(new Date()).toString();
+ json = {
+ ...json,
+ ...{
+ action: "update",
+ sequence,
+ userAgent: "app",
+ },
+ };
+ let sendOperation = () => {
+ this.wsp
+ .sendRequest(json, {
+ requestId: sequence,
+ })
+ .then(device => {
+ if (this.debugReqRes) {
+ let msg = JSON.stringify(json, null, 2)
+ .replace(json.apikey, "**hidden**")
+ .replace(json.apiKey, "**hidden**")
+ .replace(json.deviceid, "**hidden**");
+ this.log.warn("WS message sent. This text is yellow for clarity.\n%s", msg);
+ } else if (this.debug) {
+ this.log("WS message sent.");
+ }
+ device.error = device.hasOwnProperty("error") ? device.error : 504; // mimic ewelink device offline
+ switch (device.error) {
+ case 0:
+ resolve();
+ break;
+ case 504:
+ default:
+ throw "Unknown response";
+ }
+ })
+ .catch(err => reject("Device update failed [" + err + "]."));
+ };
+ let checkToSend = () => {
+ if (this.wsp && this.wsIsOpen) {
+ sendOperation();
+ } else {
+ this.delay(2500).then(() => {
+ if (this.debug) {
+ this.log.warn("Will resend command when WS is reconnected.");
+ }
+ checkToSend();
+ });
+ }
+ };
+ checkToSend();
+ });
+ }
+ requestUpdate(accessory) {
+ return new Promise(resolve => {
+ let sequence = Math.floor(new Date()).toString(),
+ json = {
+ action: "query",
+ apikey: accessory.context.eweApiKey,
+ deviceid: accessory.context.eweDeviceId,
+ params: [],
+ sequence,
+ ts: 0,
+ userAgent: "app",
+ },
+ sendOperation = () => {
+ this.wsp.send(json);
+ if (this.debugReqRes) {
+ let msg = JSON.stringify(json, null, 2)
+ .replace(json.apikey, "**hidden**")
+ .replace(json.apiKey, "**hidden**")
+ .replace(json.deviceid, "**hidden**");
+ this.log.warn("WS message sent. This text is yellow for clarity.\n%s", msg);
+ } else if (this.debug) {
+ this.log("WS message sent.");
+ }
+ },
+ checkToSend = () => {
+ if (this.wsp && this.wsIsOpen) {
+ sendOperation();
+ } else {
+ this.delay(2500).then(() => {
+ if (this.debug) {
+ this.log.warn("Will resend command when WS is reconnected.");
+ }
+ checkToSend();
+ });
+ }
+ };
+ checkToSend();
+ });
+ }
+ receiveUpdate(f) {
+ this.emitter.addListener("update", f);
+ }
+ closeConnection() {
+ return new Promise((resolve, reject) => {
+ if (this.wsp && this.wsIsOpen) {
+ this.wsp
+ .close()
+ .then(() => {
+ this.log("Web socket gracefully closed.");
+ resolve();
+ })
+ .catch(err => reject(err));
+ }
+ resolve();
+ });
+ }
+ delay(ms) {
+ return new Promise(resolve => setTimeout(resolve, ms));
+ }
+};
From 6a011a41f5f8792dd5b72bc91eb34c9eeb0d9619 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Wed, 23 Sep 2020 09:44:33 +0100
Subject: [PATCH 0200/3183] reorder functions for ease
---
lib/eWeLink.js | 1078 ++++++++++++++++++++++++------------------------
1 file changed, 539 insertions(+), 539 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index c9e4b958..76fe7030 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -69,8 +69,7 @@ class eWeLink {
return this.lanClient.getHosts();
})
.then(res => {
- this.lanDevices = res.map;
- this.lanCount = res.count;
+ this.lanDevices = res;
return this.lanClient.startMonitor();
})
.then(() => {
@@ -91,7 +90,6 @@ class eWeLink {
//*** Logging always helps to see if everything is okay so far ***\\
this.log("[%s] eWeLink devices loaded from the Homebridge cache.", this.devicesInHB.size);
this.log("[%s] primary devices loaded from your eWeLink account.", this.devicesInEW.size);
- this.log("[%s] primary devices were discovered on your local network.", this.lanCount);
//*** Remove Homebridge accessories that don't appear in eWeLink ***\\
this.devicesInHB.forEach(a => {
if (!this.devicesInEW.has(a.context.eweDeviceId)) {
@@ -118,7 +116,6 @@ class eWeLink {
}
initialiseDevice(device) {
let accessory;
- //*** First add the device if it isn't already in Homebridge ***\\
//*** IRRIGATION VALVES ***\\
if (
device.extra.uiid === 2 &&
@@ -129,6 +126,14 @@ class eWeLink {
? this.devicesInHB.get(device.deviceid + "SWX")
: this.addAccessory(device, device.deviceid + "SWX", "valve");
}
+ //*** CURTAINS ***\\
+ else if (cns.devicesCurtain.includes(device.extra.uiid)) {
+ accessory = this.devicesInHB.has(device.deviceid + "SWX")
+ ? this.devicesInHB.get(device.deviceid + "SWX")
+ : this.addAccessory(device, device.deviceid + "SWX", "curtain", false, {
+ prevPos: 0,
+ });
+ }
//*** WINDOW BLINDS ***\\
else if (
this.cusG.has(device.deviceid + "SWX") &&
@@ -142,7 +147,7 @@ class eWeLink {
cacheTargetPosition: 0,
});
}
- //*** GARAGES ***\\
+ //*** GARAGE DOORS ***\\
else if (
this.cusG.has(device.deviceid + "SWX") &&
this.cusG.get(device.deviceid + "SWX").type === "garage"
@@ -160,15 +165,7 @@ class eWeLink {
? this.devicesInHB.get(device.deviceid + "SWX")
: this.addAccessory(device, device.deviceid + "SWX", "lock");
}
- //*** CURTAINS ***\\
- else if (cns.devicesCurtain.includes(device.extra.uiid)) {
- accessory = this.devicesInHB.has(device.deviceid + "SWX")
- ? this.devicesInHB.get(device.deviceid + "SWX")
- : this.addAccessory(device, device.deviceid + "SWX", "curtain", false, {
- prevPos: 0,
- });
- }
- //*** DW2 SENSORS ***\\
+ //*** SENSORS (DW2) ***\\
else if (cns.devicesSensor.includes(device.extra.uiid)) {
accessory = this.devicesInHB.has(device.deviceid + "SWX")
? this.devicesInHB.get(device.deviceid + "SWX")
@@ -393,10 +390,7 @@ class eWeLink {
);
return;
}
- if (!accessory) {
- return;
- }
- //*** Next refresh the device ***\\
+ if (!accessory) return;
if (!this.hiddenMasters.includes(device.deviceid)) {
accessory
.getService(Service.AccessoryInformation)
@@ -429,6 +423,9 @@ class eWeLink {
accessory.context.type,
accessory.context.channelCount
);
+ this.log.warn(
+ 'If you are unsure how to do this, please see "https://github.com/bwp91/homebridge-ewelink/wiki/How-to-remove-an-accessory-from-the-cache'
+ );
}
}
}
@@ -521,33 +518,33 @@ class eWeLink {
});
});
break;
- case "blind":
- let wcService;
- if (!(wcService = accessory.getService(Service.WindowCovering))) {
+ case "curtain":
+ let cService;
+ if (!(cService = accessory.getService(Service.WindowCovering))) {
accessory
.addService(Service.WindowCovering)
.setCharacteristic(Characteristic.CurrentPosition, 0)
.setCharacteristic(Characteristic.TargetPosition, 0)
.setCharacteristic(Characteristic.PositionState, 2);
- wcService = accessory.getService(Service.WindowCovering);
+ cService = accessory.getService(Service.WindowCovering);
}
- wcService
+ cService
.getCharacteristic(Characteristic.TargetPosition)
- .on("set", (value, callback) => this.internalBlindUpdate(accessory, value, callback));
+ .on("set", (value, callback) => this.internalCurtainUpdate(accessory, value, callback));
break;
- case "curtain":
- let cService;
- if (!(cService = accessory.getService(Service.WindowCovering))) {
+ case "blind":
+ let wcService;
+ if (!(wcService = accessory.getService(Service.WindowCovering))) {
accessory
.addService(Service.WindowCovering)
.setCharacteristic(Characteristic.CurrentPosition, 0)
.setCharacteristic(Characteristic.TargetPosition, 0)
.setCharacteristic(Characteristic.PositionState, 2);
- cService = accessory.getService(Service.WindowCovering);
+ wcService = accessory.getService(Service.WindowCovering);
}
- cService
+ wcService
.getCharacteristic(Characteristic.TargetPosition)
- .on("set", (value, callback) => this.internalCurtainUpdate(accessory, value, callback));
+ .on("set", (value, callback) => this.internalBlindUpdate(accessory, value, callback));
break;
case "garage":
let gdService;
@@ -910,6 +907,11 @@ class eWeLink {
this.externalValveUpdate(accessory, newParams);
}
return true;
+ case "curtain":
+ if (Object.keys(newParams).some(v => cns.devicesCurtainParams.includes(v))) {
+ this.externalCurtainUpdate(accessory, newParams);
+ }
+ return true;
case "blind":
if (
Object.keys(newParams).some(v => cns.devicesBlindParams.includes(v)) &&
@@ -931,11 +933,6 @@ class eWeLink {
this.externalLockUpdate(accessory, newParams);
}
return true;
- case "curtain":
- if (Object.keys(newParams).some(v => cns.devicesCurtainParams.includes(v))) {
- this.externalCurtainUpdate(accessory, newParams);
- }
- return true;
case "sensor":
if (Object.keys(newParams).some(v => cns.devicesSensorParams.includes(v))) {
this.externalSensorUpdate(accessory, newParams);
@@ -1121,6 +1118,9 @@ class eWeLink {
accessory.context.type,
accessory.context.channelCount
);
+ this.log.warn(
+ 'If you are unsure how to do this, please see "https://github.com/bwp91/homebridge-ewelink/wiki/How-to-remove-an-accessory-from-the-cache'
+ );
}
} else {
if (!(this.config.hideDevFromHB || "").includes(deviceId)) {
@@ -1135,7 +1135,13 @@ class eWeLink {
this.initialiseDevice(device);
this.lanClient.addDeviceToMap(device);
})
- .catch(err => this.log.error("[%s] error getting info [%s]", deviceId, err));
+ .catch(err => {
+ this.log.error("[%s] error getting info [%s]", deviceId, err);
+ this.log.error(
+ "[%s] Please try restarting Homebridge so this device is added.",
+ deviceId
+ );
+ });
}
}
}
@@ -1199,6 +1205,81 @@ class eWeLink {
}
}
}
+ externalValveUpdate(accessory, params) {
+ try {
+ ["A", "B"].forEach((v, k) => {
+ let valveService = accessory.getService("Valve " + v);
+ valveService
+ .updateCharacteristic(Characteristic.Active, params.switches[k].switch === "on")
+ .updateCharacteristic(Characteristic.InUse, params.switches[k].switch === "on");
+ if (params.switches[k].switch === "on") {
+ let timer = valveService.getCharacteristic(Characteristic.SetDuration).value;
+ valveService.updateCharacteristic(Characteristic.RemainingDuration, timer);
+ valveService.timer = setTimeout(() => {
+ valveService.setCharacteristic(Characteristic.Active, 0);
+ }, timer * 1000);
+ } else {
+ valveService.updateCharacteristic(Characteristic.RemainingDuration, 0);
+ clearTimeout(valveService.timer);
+ }
+ });
+ } catch (err) {
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
+ internalCurtainUpdate(accessory, value, callback) {
+ callback();
+ try {
+ let params,
+ cService = accessory.getService(Service.WindowCovering),
+ prevPos = accessory.context.prevPos;
+ if (value === prevPos) return;
+ if (value === 0 || value === 100) {
+ params = {
+ switch: value === 100 ? "on" : "off",
+ };
+ } else {
+ params = {
+ setclose: Math.abs(100 - value),
+ };
+ }
+ this.sendDeviceUpdate(accessory, params)
+ .then(() => {
+ cService
+ .updateCharacteristic(Characteristic.TargetPosition, value)
+ .updateCharacteristic(Characteristic.PositionState, value > prevPos ? 1 : 0);
+ accessory.context.prevPos = value;
+ })
+ .catch(err => {
+ throw err;
+ });
+ } catch (err) {
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ if (accessory.context.reachableWAN) {
+ this.wsClient.requestUpdate(accessory).catch(() => {});
+ this.log.warn(
+ "[%s] requesting previous state to revert Homebridge status.",
+ accessory.displayName
+ );
+ }
+ }
+ }
+ externalCurtainUpdate(accessory, params) {
+ try {
+ let cService = accessory.getService(Service.WindowCovering);
+ if (params.hasOwnProperty("switch") && params.hasOwnProperty("setclose")) {
+ let newPos = Math.abs(100 - parseInt(params.setclose));
+ cService
+ .updateCharacteristic(Characteristic.TargetPosition, newPos)
+ .updateCharacteristic(Characteristic.CurrentPosition, newPos)
+ .updateCharacteristic(Characteristic.PositionState, 2);
+ accessory.context.prevPos = Math.abs(100 - parseInt(params.setclose));
+ return;
+ }
+ } catch (err) {
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
internalBlindUpdate(accessory, value, callback) {
callback();
try {
@@ -1253,6 +1334,38 @@ class eWeLink {
}
}
}
+ externalBlindUpdate(accessory, params) {
+ try {
+ let blindConfig,
+ newPosition,
+ wcService = accessory.getService(Service.WindowCovering);
+ if (!(blindConfig = this.cusG.get(accessory.context.hbDeviceId))) {
+ throw "group config missing";
+ }
+ if (blindConfig.type !== "blind" || blindConfig.setup !== "twoSwitch") {
+ throw "improper configuration";
+ }
+ // TargetPosition -> 0 for closed 100 for open (value)
+ // CurrentPosition -> 0 for closed 100 for open
+ // PositionState -> 0 going down, 1 going up, 2 = stopped
+ if (params.switches[0].switch === "off" && params.switches[1].switch === "off") {
+ return;
+ }
+ let switchUp = params.switches[0].switch === "on" ? -1 : 0, // matrix of numbers to get
+ switchDown = params.switches[1].switch === "on" ? 0 : 2; // ... the correct HomeKit value
+ newPosition = switchUp + switchDown;
+ wcService
+ .updateCharacteristic(Characteristic.PositionState, newPosition)
+ .updateCharacteristic(Characteristic.TargetPosition, newPosition * 100);
+ setTimeout(() => {
+ wcService
+ .updateCharacteristic(Characteristic.PositionState, 2)
+ .updateCharacteristic(Characteristic.CurrentPosition, newPosition * 100);
+ }, parseInt(blindConfig.operationTime) * 100);
+ } catch (err) {
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
internalGarageUpdate(accessory, value, callback) {
callback();
try {
@@ -1338,6 +1451,56 @@ class eWeLink {
}
}
}
+ externalGarageUpdate(accessory, params) {
+ try {
+ let garageConfig,
+ gcService = accessory.getService(Service.GarageDoorOpener),
+ oldPos = gcService.getCharacteristic(Characteristic.CurrentDoorState).value,
+ newPos = [0, 2].includes(oldPos) ? 3 : 2;
+ if (!(garageConfig = this.cusG.get(accessory.context.hbDeviceId))) {
+ throw "group config missing";
+ }
+ if (
+ garageConfig.type !== "garage" ||
+ !["oneSwitch", "twoSwitch"].includes(garageConfig.setup)
+ ) {
+ throw "improper configuration";
+ }
+ if (accessory.context.inUse || garageConfig.sensorId) {
+ return;
+ }
+ switch (garageConfig.setup) {
+ case "oneSwitch":
+ if (params.switch === "off") {
+ return;
+ }
+ break;
+ case "twoSwitch":
+ if (
+ params.switches[0].switch === params.switches[1].switch ||
+ params.switches[oldPos % 2].switch === "on"
+ ) {
+ return;
+ }
+ break;
+ }
+ accessory.context.inUse = true;
+ if (!garageConfig.sensorId) {
+ gcService
+ .updateCharacteristic(Characteristic.CurrentDoorState, newPos)
+ .updateCharacteristic(Characteristic.TargetDoorState, newPos - 2);
+ setTimeout(() => {
+ gcService.updateCharacteristic(Characteristic.CurrentDoorState, newPos - 2);
+ }, parseInt(garageConfig.operationTime) * 100);
+ }
+ setTimeout(() => {
+ accessory.context.inUse = false;
+ }, parseInt(garageConfig.operationTime) * 100);
+ } catch (err) {
+ accessory.context.inUse = false;
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
internalLockUpdate(accessory, value, callback) {
callback();
try {
@@ -1380,48 +1543,78 @@ class eWeLink {
}
}
}
- internalCurtainUpdate(accessory, value, callback) {
- callback();
+ externalLockUpdate(accessory, params) {
try {
- let params,
- cService = accessory.getService(Service.WindowCovering),
- prevPos = accessory.context.prevPos;
- if (value === prevPos) return;
- if (value === 0 || value === 100) {
- // so to fully open, our $value will be 100, we send switch: "on"
- // to fully shut, our $value will be 0, we send switch: "off"
- params = {
- switch: value === 100 ? "on" : "off",
- };
- } else {
- // for a % midway, scale the $value >--< 100 and setclose: newVal AS INT
- params = {
- setclose: Math.abs(100 - value),
- };
+ let lockConfig,
+ lmService = accessory.getService(Service.LockMechanism);
+ if (!(lockConfig = this.cusG.get(accessory.context.hbDeviceId))) {
+ throw "group config missing";
}
- this.sendDeviceUpdate(accessory, params)
- .then(() => {
- cService
- .updateCharacteristic(Characteristic.TargetPosition, value)
- .updateCharacteristic(Characteristic.PositionState, value > prevPos ? 1 : 0);
- // TargetPosition -> 0 for closed 100 for open (value)
- // CurrentPosition -> 0 for closed 100 for open
- // PositionState -> 0 going down, 1 going up, 2 = stopped
- accessory.context.prevPos = value;
- })
- .catch(err => {
- throw err;
- });
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- if (accessory.context.reachableWAN) {
- this.wsClient.requestUpdate(accessory).catch(() => {});
- this.log.warn(
- "[%s] requesting previous state to revert Homebridge status.",
- accessory.displayName
- );
+ if (lockConfig.type !== "lock") {
+ throw "improper configuration";
}
- }
+ if (params.switch === "off" || accessory.context.inUse) {
+ return;
+ }
+ accessory.context.inUse = true;
+ lmService
+ .updateCharacteristic(Characteristic.LockCurrentState, 0)
+ .updateCharacteristic(Characteristic.LockTargetState, 0);
+ setTimeout(() => {
+ lmService
+ .updateCharacteristic(Characteristic.LockCurrentState, 1)
+ .updateCharacteristic(Characteristic.LockTargetState, 1);
+ accessory.context.inUse = false;
+ }, parseInt(lockConfig.operationTime) * 100);
+ } catch (err) {
+ accessory.context.inUse = false;
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
+ externalSensorUpdate(accessory, params) {
+ try {
+ if (params.hasOwnProperty("battery")) {
+ let batteryService =
+ accessory.getService(Service.BatteryService) ||
+ accessory.addService(Service.BatteryService),
+ scaledBattery = Math.round(params.battery * 33.3);
+ batteryService.updateCharacteristic(Characteristic.BatteryLevel, scaledBattery);
+ batteryService.updateCharacteristic(
+ Characteristic.StatusLowBattery,
+ scaledBattery < (this.config.lowBattThreshold || 25)
+ );
+ }
+ let newState = params.switch === "on" ? 1 : 0,
+ oAccessory = false,
+ contactService = accessory.getService(Service.ContactSensor);
+ contactService.updateCharacteristic(Characteristic.ContactSensorState, newState);
+ this.cusG.forEach(group => {
+ if (group.sensorId === accessory.context.eweDeviceId && group.type === "garage") {
+ if ((oAccessory = this.devicesInHB.get(group.deviceId + "SWX"))) {
+ switch (newState) {
+ case 0:
+ oAccessory
+ .getService(Service.GarageDoorOpener)
+ .updateCharacteristic(Characteristic.TargetDoorState, 1)
+ .updateCharacteristic(Characteristic.CurrentDoorState, 1);
+ break;
+ case 1:
+ setTimeout(() => {
+ oAccessory
+ .getService(Service.GarageDoorOpener)
+ .updateCharacteristic(Characteristic.TargetDoorState, 0)
+ .updateCharacteristic(Characteristic.CurrentDoorState, 0);
+ }, group.operationTime * 100);
+ break;
+ default:
+ throw "unknown sensor status received [" + newState + "]";
+ }
+ }
+ }
+ });
+ } catch (err) {
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
}
internalFanUpdate(accessory, type, value, callback) {
callback();
@@ -1476,6 +1669,51 @@ class eWeLink {
}
}
}
+ externalFanUpdate(accessory, params) {
+ try {
+ let light,
+ status,
+ speed,
+ lightService = accessory.getService(Service.Lightbulb),
+ fanService = accessory.getService(Service.Fanv2);
+ if (Array.isArray(params.switches)) {
+ light = params.switches[0].switch === "on";
+ switch (params.switches[1].switch + params.switches[2].switch + params.switches[3].switch) {
+ default:
+ status = 0;
+ speed = 0;
+ break;
+ case "onoffoff":
+ status = 1;
+ speed = 33;
+ break;
+ case "ononoff":
+ status = 1;
+ speed = 66;
+ break;
+ case "onoffon":
+ status = 1;
+ speed = 99;
+ }
+ } else if (
+ params.hasOwnProperty("light") &&
+ params.hasOwnProperty("fan") &&
+ params.hasOwnProperty("speed")
+ ) {
+ light = params.light === "on";
+ status = params.fan === "on" ? 1 : 0;
+ speed = params.speed * 33 * status;
+ } else {
+ throw "unknown parameters received";
+ }
+ lightService.updateCharacteristic(Characteristic.On, light);
+ fanService
+ .updateCharacteristic(Characteristic.Active, status)
+ .updateCharacteristic(Characteristic.RotationSpeed, speed);
+ } catch (err) {
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
internalThermostatUpdate(accessory, value, callback) {
callback();
try {
@@ -1502,6 +1740,49 @@ class eWeLink {
}
}
}
+ externalThermostatUpdate(accessory, params) {
+ try {
+ if (
+ !this.config.hideTHSwitch &&
+ (params.hasOwnProperty("switch") || params.hasOwnProperty("mainSwitch"))
+ ) {
+ let newState = params.hasOwnProperty("switch")
+ ? params.switch === "on"
+ : params.mainSwitch === "on",
+ switchService = accessory.getService(Service.Switch);
+ switchService.updateCharacteristic(Characteristic.On, newState);
+ }
+ let eveLog = {
+ time: Date.now(),
+ };
+ if (
+ params.hasOwnProperty("currentTemperature") &&
+ accessory.getService(Service.TemperatureSensor)
+ ) {
+ let currentTemp =
+ params.currentTemperature !== "unavailable" ? params.currentTemperature : 0;
+ accessory
+ .getService(Service.TemperatureSensor)
+ .updateCharacteristic(Characteristic.CurrentTemperature, currentTemp);
+ eveLog.temp = parseFloat(currentTemp);
+ }
+ if (
+ params.hasOwnProperty("currentHumidity") &&
+ accessory.getService(Service.HumiditySensor)
+ ) {
+ let currentHumi = params.currentHumidity !== "unavailable" ? params.currentHumidity : 0;
+ accessory
+ .getService(Service.HumiditySensor)
+ .updateCharacteristic(Characteristic.CurrentRelativeHumidity, currentHumi);
+ eveLog.humidity = parseFloat(currentHumi);
+ }
+ if (eveLog.hasOwnProperty("temp") || eveLog.hasOwnProperty("humidity")) {
+ accessory.eveLogger.addEntry(eveLog);
+ }
+ } catch (err) {
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
internalOutletUpdate(accessory, value, callback) {
callback();
try {
@@ -1527,6 +1808,43 @@ class eWeLink {
}
}
}
+ externalOutletUpdate(accessory, params) {
+ try {
+ let outletService = accessory.getService(Service.Outlet);
+ if (params.hasOwnProperty("switch")) {
+ outletService.updateCharacteristic(Characteristic.On, params.switch === "on");
+ }
+ if (params.hasOwnProperty("power")) {
+ outletService.updateCharacteristic(
+ EveService.Characteristics.CurrentConsumption,
+ parseFloat(params.power)
+ );
+ outletService.updateCharacteristic(
+ Characteristic.OutletInUse,
+ parseFloat(params.power) > (this.config.inUsePowerThreshold || 0)
+ );
+ let isOn = accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On).value;
+ accessory.eveLogger.addEntry({
+ time: Date.now(),
+ power: isOn ? parseFloat(params.power) : 0,
+ });
+ }
+ if (params.hasOwnProperty("voltage")) {
+ outletService.updateCharacteristic(
+ EveService.Characteristics.Voltage,
+ parseFloat(params.voltage)
+ );
+ }
+ if (params.hasOwnProperty("current")) {
+ outletService.updateCharacteristic(
+ EveService.Characteristics.ElectricCurrent,
+ parseFloat(params.current)
+ );
+ }
+ } catch (err) {
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
internalUSBUpdate(accessory, value, callback) {
callback();
try {
@@ -1553,6 +1871,15 @@ class eWeLink {
}
}
}
+ externalUSBUpdate(accessory, params) {
+ try {
+ accessory
+ .getService(Service.Outlet)
+ .updateCharacteristic(Characteristic.On, params.switches[0].switch === "on");
+ } catch (err) {
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
internalSCMUpdate(accessory, value, callback) {
callback();
try {
@@ -1579,6 +1906,15 @@ class eWeLink {
}
}
}
+ externalSCMUpdate(accessory, params) {
+ try {
+ accessory
+ .getService(Service.Switch)
+ .updateCharacteristic(Characteristic.On, params.switches[0].switch === "on");
+ } catch (err) {
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
internalLightbulbUpdate(accessory, value, callback) {
callback();
try {
@@ -1806,471 +2142,18 @@ class eWeLink {
}
}
}
- internalSwitchUpdate(accessory, value, callback) {
- callback();
+ externalSingleLightUpdate(accessory, params) {
try {
- let oAccessory,
- params = {},
- switchService = accessory.getService(Service.Switch);
- switch (accessory.context.switchNumber) {
- case "X":
- params.switch = value ? "on" : "off";
- break;
- case "0":
- params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
- params.switches[0].switch = value ? "on" : "off";
- params.switches[1].switch = value ? "on" : "off";
- params.switches[2].switch = value ? "on" : "off";
- params.switches[3].switch = value ? "on" : "off";
- break;
- case "1":
- case "2":
- case "3":
- case "4":
- params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
- for (let i = 1; i <= 4; i++) {
- if ((oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
- i === parseInt(accessory.context.switchNumber)
- ? (params.switches[i - 1].switch = value ? "on" : "off")
- : (params.switches[i - 1].switch = oAccessory
- .getService(Service.Switch)
- .getCharacteristic(Characteristic.On).value
- ? "on"
- : "off");
- } else {
- params.switches[i - 1].switch = "off";
- }
- }
- break;
- }
- this.sendDeviceUpdate(accessory, params)
- .then(() => {
- switch (accessory.context.switchNumber) {
- case "X":
- switchService.updateCharacteristic(Characteristic.On, value);
- break;
- case "0":
- for (let i = 0; i <= 4; i++) {
- if ((oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
- oAccessory
- .getService(Service.Switch)
- .updateCharacteristic(Characteristic.On, value);
- }
- }
- break;
- case "1":
- case "2":
- case "3":
- case "4":
- switchService.updateCharacteristic(Characteristic.On, value);
- let masterState = "off";
- for (let i = 1; i <= 4; i++) {
- if ((oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
- if (
- oAccessory.getService(Service.Switch).getCharacteristic(Characteristic.On).value
- ) {
- masterState = "on";
- }
- }
- }
- if (!this.hiddenMasters.includes(accessory.context.eweDeviceId)) {
- oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
- oAccessory
- .getService(Service.Switch)
- .updateCharacteristic(Characteristic.On, masterState === "on");
- }
- break;
- }
- })
- .catch(err => {
- throw err;
- });
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- if (accessory.context.reachableWAN) {
- this.wsClient.requestUpdate(accessory).catch(() => {});
- this.log.warn(
- "[%s] requesting previous state to revert Homebridge status.",
- accessory.displayName
- );
- }
- }
- }
- internalRFUpdate(accessory, rfChl, service, callback) {
- callback();
- try {
- let params = {
- cmd: "transmit",
- rfChl: parseInt(rfChl),
- },
- rfService = accessory.getService(service);
- this.sendDeviceUpdate(accessory, params)
- .then(() => {
- rfService.updateCharacteristic(Characteristic.On, true);
- setTimeout(() => rfService.updateCharacteristic(Characteristic.On, false), 3000);
- })
- .catch(err => {
- throw err;
- });
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- if (accessory.context.reachableWAN) {
- this.wsClient.requestUpdate(accessory).catch(() => {});
- this.log.warn(
- "[%s] requesting previous state to revert Homebridge status.",
- accessory.displayName
- );
- }
- }
- }
- externalValveUpdate(accessory, params) {
- try {
- ["A", "B"].forEach((v, k) => {
- let valveService = accessory.getService("Valve " + v);
- valveService
- .updateCharacteristic(Characteristic.Active, params.switches[k].switch === "on")
- .updateCharacteristic(Characteristic.InUse, params.switches[k].switch === "on");
- if (params.switches[k].switch === "on") {
- let timer = valveService.getCharacteristic(Characteristic.SetDuration).value;
- valveService.updateCharacteristic(Characteristic.RemainingDuration, timer);
- valveService.timer = setTimeout(() => {
- valveService.setCharacteristic(Characteristic.Active, 0);
- }, timer * 1000);
- } else {
- valveService.updateCharacteristic(Characteristic.RemainingDuration, 0);
- clearTimeout(valveService.timer);
- }
- });
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- externalBlindUpdate(accessory, params) {
- try {
- let blindConfig,
- newPosition,
- wcService = accessory.getService(Service.WindowCovering);
- if (!(blindConfig = this.cusG.get(accessory.context.hbDeviceId))) {
- throw "group config missing";
- }
- if (blindConfig.type !== "blind" || blindConfig.setup !== "twoSwitch") {
- throw "improper configuration";
- }
- // TargetPosition -> 0 for closed 100 for open (value)
- // CurrentPosition -> 0 for closed 100 for open
- // PositionState -> 0 going down, 1 going up, 2 = stopped
- if (params.switches[0].switch === "off" && params.switches[1].switch === "off") {
- return;
- }
- let switchUp = params.switches[0].switch === "on" ? -1 : 0, // matrix of numbers to get
- switchDown = params.switches[1].switch === "on" ? 0 : 2; // ... the correct HomeKit value
- newPosition = switchUp + switchDown;
- wcService
- .updateCharacteristic(Characteristic.PositionState, newPosition)
- .updateCharacteristic(Characteristic.TargetPosition, newPosition * 100);
- setTimeout(() => {
- wcService
- .updateCharacteristic(Characteristic.PositionState, 2)
- .updateCharacteristic(Characteristic.CurrentPosition, newPosition * 100);
- }, parseInt(blindConfig.operationTime) * 100);
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- externalGarageUpdate(accessory, params) {
- try {
- let garageConfig,
- gcService = accessory.getService(Service.GarageDoorOpener),
- oldPos = gcService.getCharacteristic(Characteristic.CurrentDoorState).value,
- newPos = [0, 2].includes(oldPos) ? 3 : 2;
- if (!(garageConfig = this.cusG.get(accessory.context.hbDeviceId))) {
- throw "group config missing";
- }
- if (
- garageConfig.type !== "garage" ||
- !["oneSwitch", "twoSwitch"].includes(garageConfig.setup)
- ) {
- throw "improper configuration";
- }
- if (accessory.context.inUse || garageConfig.sensorId) {
- return;
- }
- switch (garageConfig.setup) {
- case "oneSwitch":
- if (params.switch === "off") {
- return;
- }
- break;
- case "twoSwitch":
- if (
- params.switches[0].switch === params.switches[1].switch ||
- params.switches[oldPos % 2].switch === "on"
- ) {
- return;
- }
- break;
- }
- accessory.context.inUse = true;
- if (!garageConfig.sensorId) {
- gcService
- .updateCharacteristic(Characteristic.CurrentDoorState, newPos)
- .updateCharacteristic(Characteristic.TargetDoorState, newPos - 2);
- setTimeout(() => {
- gcService.updateCharacteristic(Characteristic.CurrentDoorState, newPos - 2);
- }, parseInt(garageConfig.operationTime) * 100);
- }
- setTimeout(() => {
- accessory.context.inUse = false;
- }, parseInt(garageConfig.operationTime) * 100);
- } catch (err) {
- accessory.context.inUse = false;
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- externalLockUpdate(accessory, params) {
- try {
- let lockConfig,
- lmService = accessory.getService(Service.LockMechanism);
- if (!(lockConfig = this.cusG.get(accessory.context.hbDeviceId))) {
- throw "group config missing";
- }
- if (lockConfig.type !== "lock") {
- throw "improper configuration";
- }
- if (params.switch === "off" || accessory.context.inUse) {
- return;
- }
- accessory.context.inUse = true;
- lmService
- .updateCharacteristic(Characteristic.LockCurrentState, 0)
- .updateCharacteristic(Characteristic.LockTargetState, 0);
- setTimeout(() => {
- lmService
- .updateCharacteristic(Characteristic.LockCurrentState, 1)
- .updateCharacteristic(Characteristic.LockTargetState, 1);
- accessory.context.inUse = false;
- }, parseInt(lockConfig.operationTime) * 100);
- } catch (err) {
- accessory.context.inUse = false;
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- externalCurtainUpdate(accessory, params) {
- try {
- let cService = accessory.getService(Service.WindowCovering);
- if (params.hasOwnProperty("switch") && params.hasOwnProperty("setclose")) {
- let newPos = Math.abs(100 - parseInt(params.setclose));
- cService
- .updateCharacteristic(Characteristic.TargetPosition, newPos)
- .updateCharacteristic(Characteristic.CurrentPosition, newPos)
- .updateCharacteristic(Characteristic.PositionState, 2);
- accessory.context.prevPos = Math.abs(100 - parseInt(params.setclose));
- return;
- }
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- externalSensorUpdate(accessory, params) {
- try {
- if (params.hasOwnProperty("battery")) {
- let batteryService =
- accessory.getService(Service.BatteryService) ||
- accessory.addService(Service.BatteryService),
- scaledBattery = Math.round(params.battery * 33.3);
- batteryService.updateCharacteristic(Characteristic.BatteryLevel, scaledBattery);
- batteryService.updateCharacteristic(
- Characteristic.StatusLowBattery,
- scaledBattery < (this.config.lowBattThreshold || 25)
- );
- }
- let newState = params.switch === "on" ? 1 : 0,
- oAccessory = false,
- contactService = accessory.getService(Service.ContactSensor);
- contactService.updateCharacteristic(Characteristic.ContactSensorState, newState);
- this.cusG.forEach(group => {
- if (group.sensorId === accessory.context.eweDeviceId && group.type === "garage") {
- if ((oAccessory = this.devicesInHB.get(group.deviceId + "SWX"))) {
- switch (newState) {
- case 0:
- oAccessory
- .getService(Service.GarageDoorOpener)
- .updateCharacteristic(Characteristic.TargetDoorState, 1)
- .updateCharacteristic(Characteristic.CurrentDoorState, 1);
- break;
- case 1:
- setTimeout(() => {
- oAccessory
- .getService(Service.GarageDoorOpener)
- .updateCharacteristic(Characteristic.TargetDoorState, 0)
- .updateCharacteristic(Characteristic.CurrentDoorState, 0);
- }, group.operationTime * 100);
- break;
- default:
- throw "unknown sensor status received [" + newState + "]";
- }
- }
- }
- });
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- externalFanUpdate(accessory, params) {
- try {
- let light,
- status,
- speed,
- lightService = accessory.getService(Service.Lightbulb),
- fanService = accessory.getService(Service.Fanv2);
- if (Array.isArray(params.switches)) {
- light = params.switches[0].switch === "on";
- switch (params.switches[1].switch + params.switches[2].switch + params.switches[3].switch) {
- default:
- status = 0;
- speed = 0;
- break;
- case "onoffoff":
- status = 1;
- speed = 33;
- break;
- case "ononoff":
- status = 1;
- speed = 66;
- break;
- case "onoffon":
- status = 1;
- speed = 99;
- }
- } else if (
- params.hasOwnProperty("light") &&
- params.hasOwnProperty("fan") &&
- params.hasOwnProperty("speed")
- ) {
- light = params.light === "on";
- status = params.fan === "on" ? 1 : 0;
- speed = params.speed * 33 * status;
- } else {
- throw "unknown parameters received";
- }
- lightService.updateCharacteristic(Characteristic.On, light);
- fanService
- .updateCharacteristic(Characteristic.Active, status)
- .updateCharacteristic(Characteristic.RotationSpeed, speed);
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- externalThermostatUpdate(accessory, params) {
- try {
- if (
- !this.config.hideTHSwitch &&
- (params.hasOwnProperty("switch") || params.hasOwnProperty("mainSwitch"))
- ) {
- let newState = params.hasOwnProperty("switch")
- ? params.switch === "on"
- : params.mainSwitch === "on",
- switchService = accessory.getService(Service.Switch);
- switchService.updateCharacteristic(Characteristic.On, newState);
- }
- let eveLog = {
- time: Date.now(),
- };
- if (
- params.hasOwnProperty("currentTemperature") &&
- accessory.getService(Service.TemperatureSensor)
- ) {
- let currentTemp =
- params.currentTemperature !== "unavailable" ? params.currentTemperature : 0;
- accessory
- .getService(Service.TemperatureSensor)
- .updateCharacteristic(Characteristic.CurrentTemperature, currentTemp);
- eveLog.temp = parseFloat(currentTemp);
- }
- if (
- params.hasOwnProperty("currentHumidity") &&
- accessory.getService(Service.HumiditySensor)
- ) {
- let currentHumi = params.currentHumidity !== "unavailable" ? params.currentHumidity : 0;
- accessory
- .getService(Service.HumiditySensor)
- .updateCharacteristic(Characteristic.CurrentRelativeHumidity, currentHumi);
- eveLog.humidity = parseFloat(currentHumi);
- }
- if (eveLog.hasOwnProperty("temp") || eveLog.hasOwnProperty("humidity")) {
- accessory.eveLogger.addEntry(eveLog);
- }
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- externalOutletUpdate(accessory, params) {
- try {
- let outletService = accessory.getService(Service.Outlet);
- if (params.hasOwnProperty("switch")) {
- outletService.updateCharacteristic(Characteristic.On, params.switch === "on");
- }
- if (params.hasOwnProperty("power")) {
- outletService.updateCharacteristic(
- EveService.Characteristics.CurrentConsumption,
- parseFloat(params.power)
- );
- outletService.updateCharacteristic(
- Characteristic.OutletInUse,
- parseFloat(params.power) > (this.config.inUsePowerThreshold || 0)
- );
- let isOn = accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On).value;
- accessory.eveLogger.addEntry({
- time: Date.now(),
- power: isOn ? parseFloat(params.power) : 0,
- });
- }
- if (params.hasOwnProperty("voltage")) {
- outletService.updateCharacteristic(
- EveService.Characteristics.Voltage,
- parseFloat(params.voltage)
- );
- }
- if (params.hasOwnProperty("current")) {
- outletService.updateCharacteristic(
- EveService.Characteristics.ElectricCurrent,
- parseFloat(params.current)
- );
- }
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- externalUSBUpdate(accessory, params) {
- try {
- accessory
- .getService(Service.Outlet)
- .updateCharacteristic(Characteristic.On, params.switches[0].switch === "on");
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- externalSCMUpdate(accessory, params) {
- try {
- accessory
- .getService(Service.Switch)
- .updateCharacteristic(Characteristic.On, params.switches[0].switch === "on");
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- externalSingleLightUpdate(accessory, params) {
- try {
- let newColour,
- mode,
- isOn = false,
- lightService = accessory.getService(Service.Lightbulb);
- if (accessory.context.eweUIID === 22 && params.hasOwnProperty("state")) {
- isOn = params.state === "on";
- } else if (accessory.context.eweUIID !== 22 && params.hasOwnProperty("switch")) {
- isOn = params.switch === "on";
- } else {
- isOn = lightService.getCharacteristic(Characteristic.On).value;
+ let newColour,
+ mode,
+ isOn = false,
+ lightService = accessory.getService(Service.Lightbulb);
+ if (accessory.context.eweUIID === 22 && params.hasOwnProperty("state")) {
+ isOn = params.state === "on";
+ } else if (accessory.context.eweUIID !== 22 && params.hasOwnProperty("switch")) {
+ isOn = params.switch === "on";
+ } else {
+ isOn = lightService.getCharacteristic(Characteristic.On).value;
}
if (isOn) {
lightService.updateCharacteristic(Characteristic.On, true);
@@ -2357,6 +2240,96 @@ class eWeLink {
this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
+ internalSwitchUpdate(accessory, value, callback) {
+ callback();
+ try {
+ let oAccessory,
+ params = {},
+ switchService = accessory.getService(Service.Switch);
+ switch (accessory.context.switchNumber) {
+ case "X":
+ params.switch = value ? "on" : "off";
+ break;
+ case "0":
+ params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
+ params.switches[0].switch = value ? "on" : "off";
+ params.switches[1].switch = value ? "on" : "off";
+ params.switches[2].switch = value ? "on" : "off";
+ params.switches[3].switch = value ? "on" : "off";
+ break;
+ case "1":
+ case "2":
+ case "3":
+ case "4":
+ params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
+ for (let i = 1; i <= 4; i++) {
+ if ((oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
+ i === parseInt(accessory.context.switchNumber)
+ ? (params.switches[i - 1].switch = value ? "on" : "off")
+ : (params.switches[i - 1].switch = oAccessory
+ .getService(Service.Switch)
+ .getCharacteristic(Characteristic.On).value
+ ? "on"
+ : "off");
+ } else {
+ params.switches[i - 1].switch = "off";
+ }
+ }
+ break;
+ }
+ this.sendDeviceUpdate(accessory, params)
+ .then(() => {
+ switch (accessory.context.switchNumber) {
+ case "X":
+ switchService.updateCharacteristic(Characteristic.On, value);
+ break;
+ case "0":
+ for (let i = 0; i <= 4; i++) {
+ if ((oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
+ oAccessory
+ .getService(Service.Switch)
+ .updateCharacteristic(Characteristic.On, value);
+ }
+ }
+ break;
+ case "1":
+ case "2":
+ case "3":
+ case "4":
+ switchService.updateCharacteristic(Characteristic.On, value);
+ let masterState = "off";
+ for (let i = 1; i <= 4; i++) {
+ if ((oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
+ if (
+ oAccessory.getService(Service.Switch).getCharacteristic(Characteristic.On).value
+ ) {
+ masterState = "on";
+ }
+ }
+ }
+ if (!this.hiddenMasters.includes(accessory.context.eweDeviceId)) {
+ oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
+ oAccessory
+ .getService(Service.Switch)
+ .updateCharacteristic(Characteristic.On, masterState === "on");
+ }
+ break;
+ }
+ })
+ .catch(err => {
+ throw err;
+ });
+ } catch (err) {
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ if (accessory.context.reachableWAN) {
+ this.wsClient.requestUpdate(accessory).catch(() => {});
+ this.log.warn(
+ "[%s] requesting previous state to revert Homebridge status.",
+ accessory.displayName
+ );
+ }
+ }
+ }
externalSingleSwitchUpdate(accessory, params) {
try {
accessory
@@ -2388,6 +2361,33 @@ class eWeLink {
this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
+ internalRFUpdate(accessory, rfChl, service, callback) {
+ callback();
+ try {
+ let params = {
+ cmd: "transmit",
+ rfChl: parseInt(rfChl),
+ },
+ rfService = accessory.getService(service);
+ this.sendDeviceUpdate(accessory, params)
+ .then(() => {
+ rfService.updateCharacteristic(Characteristic.On, true);
+ setTimeout(() => rfService.updateCharacteristic(Characteristic.On, false), 3000);
+ })
+ .catch(err => {
+ throw err;
+ });
+ } catch (err) {
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ if (accessory.context.reachableWAN) {
+ this.wsClient.requestUpdate(accessory).catch(() => {});
+ this.log.warn(
+ "[%s] requesting previous state to revert Homebridge status.",
+ accessory.displayName
+ );
+ }
+ }
+ }
externalRFUpdate(accessory, params) {
try {
if (!params.hasOwnProperty("updateSource")) return;
From faefd89cb5d566ff0325dd8bde99760e480b253e Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Wed, 23 Sep 2020 11:56:38 +0100
Subject: [PATCH 0201/3183] 3.0.0-7
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index fbe82755..c0bf7d5d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.0.0-6",
+ "version": "3.0.0-7",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 9d03ce36..60292074 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.0.0-6",
+ "version": "3.0.0-7",
"author": "bwp91",
"contributors": [
"gbro115",
From 1746d4c46772876195d2fd32308c1c701f264d54 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Wed, 23 Sep 2020 13:43:02 +0100
Subject: [PATCH 0202/3183] blind and garage caching
---
lib/constants.js | 1 +
lib/eWeLink.js | 83 ++++++++++++++++++++++++++++++++++++++++--------
2 files changed, 71 insertions(+), 13 deletions(-)
diff --git a/lib/constants.js b/lib/constants.js
index 75e59b9e..75bdeaf1 100644
--- a/lib/constants.js
+++ b/lib/constants.js
@@ -9,6 +9,7 @@ module.exports = {
devicesNonLAN: [22, 28, 59, 102],
devicesSingleSwitch: [1, 5, 6, 14, 15, 22, 24, 27, 32, 36, 44, 59],
devicesSingleSwitchParams: ["switch"],
+ devicesSingleSwitchOutlet: ["Sonoff Pow"],
devicesMultiSwitch: [2, 3, 4, 7, 8, 9, 29, 30, 31, 34, 41],
devicesMultiSwitchParams: ["switches"],
devicesSingleSwitchLight: [
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 76fe7030..ea6fb02f 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -131,8 +131,18 @@ class eWeLink {
accessory = this.devicesInHB.has(device.deviceid + "SWX")
? this.devicesInHB.get(device.deviceid + "SWX")
: this.addAccessory(device, device.deviceid + "SWX", "curtain", false, {
- prevPos: 0,
+ cacheCurrentPosition: 0,
});
+ //*** @UPGRADE from v2 -> v3 23.09.2020 ***\\
+ if (accessory.context.hasOwnProperty("prevPos")) {
+ accessory.context.cacheCurrentPosition = accessory.context.prevPos;
+ delete accessory.context.prevPos;
+ //*** @ENDUPGRADE ***\\
+ }
+ if (!accessory.context.hasOwnProperty("cacheCurrentPosition")) {
+ accessory.context.cacheCurrentPosition = 0;
+ //*** @ENDUPGRADE ***\\
+ }
}
//*** WINDOW BLINDS ***\\
else if (
@@ -142,10 +152,17 @@ class eWeLink {
accessory = this.devicesInHB.has(device.deviceid + "SWX")
? this.devicesInHB.get(device.deviceid + "SWX")
: this.addAccessory(device, device.deviceid + "SWX", "blind", false, {
- cacheLastPosition: 0,
+ cacheCurrentPosition: 0,
cachePositionState: 2,
cacheTargetPosition: 0,
});
+ //*** @UPGRADE from v2 -> v3 23.09.2020 ***\\
+ if (!accessory.context.hasOwnProperty("cacheCurrentPosition")) {
+ accessory.context.cacheCurrentPosition = 0;
+ accessory.context.cachePositionState = 2;
+ accessory.context.cacheTargetPosition = 0;
+ }
+ //*** @ENDUPGRADE ***\\
}
//*** GARAGE DOORS ***\\
else if (
@@ -154,7 +171,16 @@ class eWeLink {
) {
accessory = this.devicesInHB.has(device.deviceid + "SWX")
? this.devicesInHB.get(device.deviceid + "SWX")
- : this.addAccessory(device, device.deviceid + "SWX", "garage");
+ : this.addAccessory(device, device.deviceid + "SWX", "garage", false, {
+ cacheCurrentDoorState: 1,
+ cacheTargetDoorState: 1,
+ });
+ //*** @UPGRADE from v2 -> v3 23.09.2020 ***\\
+ if (!accessory.context.hasOwnProperty("cacheCurrentDoorState")) {
+ accessory.context.cacheCurrentDoorState = 1;
+ accessory.context.cacheTargetDoorState = 1;
+ }
+ //*** @ENDUPGRADE ***\\
}
//*** LOCKS ***\\
else if (
@@ -184,6 +210,11 @@ class eWeLink {
: this.addAccessory(device, device.deviceid + "SWX", "thermostat", false, {
sensorType: device.params.sensorType,
});
+ //*** @UPGRADE from v2 -> v3 23.09.2020 ***\\
+ if (!accessory.context.hasOwnProperty("sensorType")) {
+ accessory.context.sensorType = device.params.sensorType;
+ }
+ //*** @ENDUPGRADE ***\\
if (accessory.context.sensorType !== device.params.sensorType) {
accessory.context.sensorType = device.params.sensorType;
this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
@@ -192,7 +223,8 @@ class eWeLink {
//*** OUTLETS ***\\
else if (
cns.devicesOutlet.includes(device.extra.uiid) ||
- device.productModel === "Sonoff Pow"
+ (cns.devicesSingleSwitch.includes(device.extra.uiid) &&
+ cns.devicesSingleSwitchOutlet.includes(device.productModel))
) {
accessory = this.devicesInHB.has(device.deviceid + "SWX")
? this.devicesInHB.get(device.deviceid + "SWX")
@@ -367,12 +399,22 @@ class eWeLink {
//*** ZIGBEE BRIDGES ***\\
else if (cns.devicesZBBridge.includes(device.extra.uiid)) {
// Nothing to do here but needed to avoid the below not supported error
+ //*** @UPGRADE from v2 -> v3 23.09.2020 ***\\
+ if ((accessory = this.devicesInHB.get(device.deviceid + "SWX"))) {
+ this.removeAccessory(accessory);
+ }
+ //*** @ENDUPGRADE ***\\
}
//*** ZIGBEE DEVICES ***\\
else if (cns.devicesZB.includes(device.extra.uiid)) {
accessory = this.devicesInHB.has(device.deviceid + "SWX")
? this.devicesInHB.get(device.deviceid + "SWX")
: this.addAccessory(device, device.deviceid + "SWX", "zb_dev");
+ //*** @UPGRADE from v2 -> v3 23.09.2020 ***\\
+ if (accessory.context.type === "zb_sub") {
+ accessory.context.type = "zb_dev";
+ }
+ //*** @ENDUPGRADE ***\\
}
//*** SONOFF CAMERAS ***\\
else if (cns.devicesCamera.includes(device.extra.uiid)) {
@@ -1232,7 +1274,7 @@ class eWeLink {
try {
let params,
cService = accessory.getService(Service.WindowCovering),
- prevPos = accessory.context.prevPos;
+ prevPos = accessory.context.cacheCurrentPosition;
if (value === prevPos) return;
if (value === 0 || value === 100) {
params = {
@@ -1248,7 +1290,7 @@ class eWeLink {
cService
.updateCharacteristic(Characteristic.TargetPosition, value)
.updateCharacteristic(Characteristic.PositionState, value > prevPos ? 1 : 0);
- accessory.context.prevPos = value;
+ accessory.context.cacheCurrentPosition = value;
})
.catch(err => {
throw err;
@@ -1273,7 +1315,7 @@ class eWeLink {
.updateCharacteristic(Characteristic.TargetPosition, newPos)
.updateCharacteristic(Characteristic.CurrentPosition, newPos)
.updateCharacteristic(Characteristic.PositionState, 2);
- accessory.context.prevPos = Math.abs(100 - parseInt(params.setclose));
+ accessory.context.cacheCurrentPosition = Math.abs(100 - parseInt(params.setclose));
return;
}
} catch (err) {
@@ -1286,7 +1328,7 @@ class eWeLink {
let blindConfig,
params = {},
wcService = accessory.getService(Service.WindowCovering),
- oldPos = wcService.getCharacteristic(Characteristic.PositionState).value;
+ oldPos = accessory.context.cachePositionState;
if (!(blindConfig = this.cusG.get(accessory.context.hbDeviceId))) {
throw "group config missing";
}
@@ -1297,6 +1339,9 @@ class eWeLink {
if (value === oldPos * 100) return;
// target position -> 0 for closed 100 for open (value)
// current position -> 0 going down, 1 going up
+ accessory.context.cacheCurrentPosition = wcService.getCharacteristic(
+ Characteristic.CurrentPosition
+ ).value;
params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
params.switches[0].switch = value === 100 ? "on" : "off";
params.switches[1].switch = value === 0 ? "on" : "off";
@@ -1305,6 +1350,8 @@ class eWeLink {
wcService
.updateCharacteristic(Characteristic.TargetPosition, value)
.updateCharacteristic(Characteristic.PositionState, value / 100);
+ accessory.context.cachePositionState = value / 100;
+ accessory.context.cacheTargetPosition = value;
return new Promise(resolve =>
setTimeout(resolve, parseInt(blindConfig.operationTime) * 100)
);
@@ -1319,6 +1366,8 @@ class eWeLink {
wcService
.updateCharacteristic(Characteristic.CurrentPosition, value)
.updateCharacteristic(Characteristic.PositionState, 2);
+ accessory.context.cachePositionState = 2;
+ accessory.context.cacheCurrentPosition = value;
})
.catch(err => {
throw err;
@@ -1345,9 +1394,6 @@ class eWeLink {
if (blindConfig.type !== "blind" || blindConfig.setup !== "twoSwitch") {
throw "improper configuration";
}
- // TargetPosition -> 0 for closed 100 for open (value)
- // CurrentPosition -> 0 for closed 100 for open
- // PositionState -> 0 going down, 1 going up, 2 = stopped
if (params.switches[0].switch === "off" && params.switches[1].switch === "off") {
return;
}
@@ -1357,10 +1403,14 @@ class eWeLink {
wcService
.updateCharacteristic(Characteristic.PositionState, newPosition)
.updateCharacteristic(Characteristic.TargetPosition, newPosition * 100);
+ accessory.context.cachePositionState = newPosition;
+ accessory.context.cacheTargetPosition = newPosition * 100;
setTimeout(() => {
wcService
.updateCharacteristic(Characteristic.PositionState, 2)
.updateCharacteristic(Characteristic.CurrentPosition, newPosition * 100);
+ accessory.context.cachePositionState = 2;
+ accessory.context.cacheCurrentPosition = newPosition * 100;
}, parseInt(blindConfig.operationTime) * 100);
} catch (err) {
this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
@@ -1398,12 +1448,13 @@ class eWeLink {
.getCharacteristic(Characteristic.ContactSensorState).value === 0
? 1
: 0
- : gdService.getCharacteristic(Characteristic.CurrentDoorState).value;
+ : accessory.context.cacheCurrentDoorState;
if (newPos === oldPos % 2) return;
accessory.context.inUse = true;
accessory.context.state = value;
if (garageConfig.setup === "oneSwitch" && [2, 3].includes(oldPos)) {
gdService.updateCharacteristic(Characteristic.CurrentDoorState, ((oldPos * 2) % 3) + 2);
+ accessory.context.cacheCurrentDoorState = ((oldPos * 2) % 3) + 2;
delay = 1500;
}
if (accessory.context.state !== newPos) return;
@@ -1413,6 +1464,8 @@ class eWeLink {
gdService
.updateCharacteristic(Characteristic.TargetDoorState, newPos)
.updateCharacteristic(Characteristic.CurrentDoorState, newPos + 2);
+ accessory.context.cacheTargetDoorState = newPos;
+ accessory.context.cacheCurrentDoorState = newPos + 2;
switch (garageConfig.setup) {
case "oneSwitch":
params.switch = "on";
@@ -1433,6 +1486,7 @@ class eWeLink {
.then(() => {
if (!sAccessory) {
gdService.updateCharacteristic(Characteristic.CurrentDoorState, newPos);
+ accessory.context.cacheCurrentDoorState = newPos;
}
accessory.context.inUse = false;
})
@@ -1455,7 +1509,7 @@ class eWeLink {
try {
let garageConfig,
gcService = accessory.getService(Service.GarageDoorOpener),
- oldPos = gcService.getCharacteristic(Characteristic.CurrentDoorState).value,
+ oldPos = accessory.context.cacheCurrentDoorState,
newPos = [0, 2].includes(oldPos) ? 3 : 2;
if (!(garageConfig = this.cusG.get(accessory.context.hbDeviceId))) {
throw "group config missing";
@@ -1489,8 +1543,11 @@ class eWeLink {
gcService
.updateCharacteristic(Characteristic.CurrentDoorState, newPos)
.updateCharacteristic(Characteristic.TargetDoorState, newPos - 2);
+ accessory.context.cacheCurrentDoorState = newPos;
+ accessory.context.cacheTargetDoorState = newPos - 2;
setTimeout(() => {
gcService.updateCharacteristic(Characteristic.CurrentDoorState, newPos - 2);
+ accessory.context.cacheCurrentDoorState = newPos - 2;
}, parseInt(garageConfig.operationTime) * 100);
}
setTimeout(() => {
From 08b7b9a31011a1715ef4098af74e3f1964079503 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Wed, 23 Sep 2020 13:50:37 +0100
Subject: [PATCH 0203/3183] 3.0.0
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index c0bf7d5d..5f52a260 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.0.0-7",
+ "version": "3.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 60292074..497d1edf 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.0.0-7",
+ "version": "3.0.0",
"author": "bwp91",
"contributors": [
"gbro115",
From c6a1a4a45a5c667fdf861e88dc06112f68d38538 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Wed, 23 Sep 2020 18:41:57 +0100
Subject: [PATCH 0204/3183] Update eWeLink.js
---
lib/eWeLink.js | 57 +++++++++++++++++++++++++++++---------------------
1 file changed, 33 insertions(+), 24 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index ea6fb02f..aaa22f0f 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -1071,38 +1071,47 @@ class eWeLink {
}
}
sendDeviceUpdate(accessory, params) {
- return new Promise((resolve, reject) => {
- let payload = {
+ let payload = {
apikey: accessory.context.eweApiKey,
deviceid: accessory.context.eweDeviceId,
params,
+ },
+ delayPromise = new Promise(resolve => setTimeout(resolve, Math.random() * 150 + 350)),
+ sendViaWS = () => {
+ return new Promise((resolve, reject) => {
+ if (accessory.context.reachableWAN) {
+ this.wsClient
+ .sendUpdate(payload)
+ .then(() => resolve())
+ .catch(err => reject(err));
+ } else {
+ reject("it is unreachable");
+ }
+ });
};
- let sendViaWS = () => {
- if (accessory.context.reachableWAN) {
- this.wsClient
- .sendUpdate(payload)
+ return new Promise((resolve, reject) => {
+ delayPromise.then(() => {
+ if (
+ cns.devicesNonLAN.includes(accessory.context.eweUIID) ||
+ !accessory.context.reachableLAN
+ ) {
+ sendViaWS()
.then(() => resolve())
.catch(err => reject(err));
} else {
- reject("it is unreachable");
+ this.lanClient
+ .sendUpdate(payload)
+ .then(() => resolve())
+ .catch(err => {
+ if (this.debug) {
+ this.log.warn("[%s] Reverting to web socket as %s.", accessory.displayName, err);
+ }
+ sendViaWS()
+ .then(() => resolve())
+ .catch(err => reject(err));
+ });
}
- };
- if (
- cns.devicesNonLAN.includes(accessory.context.eweUIID) ||
- !accessory.context.reachableLAN
- ) {
- sendViaWS();
- } else {
- this.lanClient
- .sendUpdate(payload)
- .then(() => resolve())
- .catch(err => {
- if (this.debug) {
- this.log.warn("[%s] Reverting to web socket as %s.", accessory.displayName, err);
- }
- sendViaWS();
- });
- }
+ });
});
}
receiveDeviceUpdate(device) {
From a484e29fddc23f88b52a77e67b23573591b0ab71 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Wed, 23 Sep 2020 18:42:40 +0100
Subject: [PATCH 0205/3183] 3.0.1-0
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 5f52a260..4b4267f1 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.0.0",
+ "version": "3.0.1-0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 497d1edf..f8f82af6 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.0.0",
+ "version": "3.0.1-0",
"author": "bwp91",
"contributors": [
"gbro115",
From ef8b19d04546f715c0607c99ddb8d0df3c531cdc Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Thu, 24 Sep 2020 14:29:30 +0100
Subject: [PATCH 0206/3183] more updates
---
lib/eWeLink.js | 192 +++++++++++++++++++++++++++-------------------
lib/eWeLinkLAN.js | 6 +-
lib/eWeLinkWS.js | 45 +++++------
3 files changed, 132 insertions(+), 111 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index aaa22f0f..9b29b4da 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -1,6 +1,6 @@
/* jshint esversion: 9, -W014, -W030, node: true */
"use strict";
-let Accessory, Characteristic, EveService, EveHistoryService, Service, UUIDGen;
+let Accessory, Characteristic, EveService, EveHistoryService, Service;
const cns = require("./constants"),
convert = require("color-convert"),
corrInterval = require("correcting-interval"),
@@ -485,7 +485,10 @@ class eWeLink {
newDeviceName = this.config.nameOverride[hbDeviceId];
}
try {
- const accessory = new Accessory(newDeviceName, UUIDGen.generate(hbDeviceId).toString());
+ const accessory = new Accessory(
+ newDeviceName,
+ this.api.hap.uuid.generate(hbDeviceId).toString()
+ );
if (!hidden) {
accessory
.getService(Service.AccessoryInformation)
@@ -1071,46 +1074,30 @@ class eWeLink {
}
}
sendDeviceUpdate(accessory, params) {
- let payload = {
- apikey: accessory.context.eweApiKey,
- deviceid: accessory.context.eweDeviceId,
- params,
- },
- delayPromise = new Promise(resolve => setTimeout(resolve, Math.random() * 150 + 350)),
- sendViaWS = () => {
- return new Promise((resolve, reject) => {
- if (accessory.context.reachableWAN) {
- this.wsClient
- .sendUpdate(payload)
- .then(() => resolve())
- .catch(err => reject(err));
- } else {
- reject("it is unreachable");
- }
- });
- };
return new Promise((resolve, reject) => {
+ let payload = {
+ apikey: accessory.context.eweApiKey,
+ deviceid: accessory.context.eweDeviceId,
+ params,
+ },
+ delayPromise = new Promise(resolve => setTimeout(resolve, Math.random() * 100 + 200));
delayPromise.then(() => {
- if (
- cns.devicesNonLAN.includes(accessory.context.eweUIID) ||
- !accessory.context.reachableLAN
- ) {
- sendViaWS()
- .then(() => resolve())
- .catch(err => reject(err));
- } else {
- this.lanClient
- .sendUpdate(payload)
- .then(() => resolve())
- .catch(err => {
- if (this.debug) {
- this.log.warn("[%s] Reverting to web socket as %s.", accessory.displayName, err);
- }
- sendViaWS()
+ this.lanClient
+ .sendUpdate(payload)
+ .then(() => resolve())
+ .catch(err => {
+ if (this.debug) {
+ this.log.warn("[%s] Reverting to web socket as %s.", accessory.displayName, err);
+ }
+ if (accessory.context.reachableWAN) {
+ this.wsClient
+ .sendUpdate(payload)
.then(() => resolve())
.catch(err => reject(err));
- });
- }
+ } else {
+ reject("it is unreachable");
+ }
+ });
});
});
}
@@ -1283,23 +1270,24 @@ class eWeLink {
try {
let params,
cService = accessory.getService(Service.WindowCovering),
- prevPos = accessory.context.cacheCurrentPosition;
- if (value === prevPos) return;
- if (value === 0 || value === 100) {
+ prevPos = accessory.context.cacheCurrentPosition,
+ newPos = value;
+ if (newPos === prevPos) return;
+ if (newPos === 0 || newPos === 100) {
params = {
- switch: value === 100 ? "on" : "off",
+ switch: newPos === 100 ? "on" : "off",
};
} else {
params = {
- setclose: Math.abs(100 - value),
+ setclose: Math.abs(100 - newPos),
};
}
this.sendDeviceUpdate(accessory, params)
.then(() => {
cService
- .updateCharacteristic(Characteristic.TargetPosition, value)
- .updateCharacteristic(Characteristic.PositionState, value > prevPos ? 1 : 0);
- accessory.context.cacheCurrentPosition = value;
+ .updateCharacteristic(Characteristic.TargetPosition, newPos)
+ .updateCharacteristic(Characteristic.PositionState, newPos > prevPos ? 1 : 0);
+ accessory.context.cacheCurrentPosition = newPos;
})
.catch(err => {
throw err;
@@ -1324,7 +1312,7 @@ class eWeLink {
.updateCharacteristic(Characteristic.TargetPosition, newPos)
.updateCharacteristic(Characteristic.CurrentPosition, newPos)
.updateCharacteristic(Characteristic.PositionState, 2);
- accessory.context.cacheCurrentPosition = Math.abs(100 - parseInt(params.setclose));
+ accessory.context.cacheCurrentPosition = newPos;
return;
}
} catch (err) {
@@ -1337,52 +1325,81 @@ class eWeLink {
let blindConfig,
params = {},
wcService = accessory.getService(Service.WindowCovering),
- oldPos = accessory.context.cachePositionState;
+ prevState = accessory.context.cachePositionState,
+ prevPos = accessory.context.cacheCurrentPosition,
+ newTarget = value,
+ timeNow = Date.now();
if (!(blindConfig = this.cusG.get(accessory.context.hbDeviceId))) {
throw "group config missing";
}
if (blindConfig.type !== "blind" || blindConfig.setup !== "twoSwitch") {
throw "improper configuration";
}
- value = value >= 50 ? 100 : 0;
- if (value === oldPos * 100) return;
- // target position -> 0 for closed 100 for open (value)
- // current position -> 0 going down, 1 going up
- accessory.context.cacheCurrentPosition = wcService.getCharacteristic(
- Characteristic.CurrentPosition
- ).value;
- params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
- params.switches[0].switch = value === 100 ? "on" : "off";
- params.switches[1].switch = value === 0 ? "on" : "off";
+ if (newTarget === prevPos) return;
+ params.switches = [
+ {
+ switch: "off",
+ outlet: 0,
+ },
+ {
+ switch: "off",
+ outlet: 1,
+ },
+ {
+ switch: "off",
+ outlet: 2,
+ },
+ {
+ switch: "off",
+ outlet: 3,
+ },
+ ];
+ let logger = str => this.log.warn("[%s] %s.", accessory.displayName, str);
+ accessory.context.inUse = true;
+ if (prevState !== 2) {
+ this.log.warn(
+ "[%s] tried to move the blinds to [%s%] but they are already moving.",
+ accessory.displayName,
+ newTarget
+ );
+ wcService.updateCharacteristic(
+ Characteristic.TargetPosition,
+ accessory.context.cacheTargetPosition
+ );
+ return;
+ }
+ wcService.updateCharacteristic(Characteristic.TargetPosition, newTarget);
+ accessory.context.cacheTargetPosition = newTarget;
+ let moveUp = newTarget > prevPos,
+ duration = Math.round(Math.abs(newTarget - prevPos) * blindConfig.operationTime);
+ accessory.context.startTimestamp = timeNow;
+ accessory.context.targetTimestamp = timeNow + duration;
+ params.switches[0].switch = moveUp ? "on" : "off";
+ params.switches[1].switch = moveUp ? "off" : "on";
this.sendDeviceUpdate(accessory, params)
.then(() => {
- wcService
- .updateCharacteristic(Characteristic.TargetPosition, value)
- .updateCharacteristic(Characteristic.PositionState, value / 100);
- accessory.context.cachePositionState = value / 100;
- accessory.context.cacheTargetPosition = value;
- return new Promise(resolve =>
- setTimeout(resolve, parseInt(blindConfig.operationTime) * 100)
- );
+ wcService.updateCharacteristic(Characteristic.PositionState, moveUp ? 0 : 1);
+ accessory.context.cachePositionState = moveUp ? 0 : 1;
+ return new Promise(resolve => setTimeout(resolve, duration));
})
.then(() => {
- params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
params.switches[0].switch = "off";
params.switches[1].switch = "off";
return this.sendDeviceUpdate(accessory, params);
})
.then(() => {
- wcService
- .updateCharacteristic(Characteristic.CurrentPosition, value)
- .updateCharacteristic(Characteristic.PositionState, 2);
+ wcService.updateCharacteristic(Characteristic.PositionState, 2);
+ wcService.updateCharacteristic(Characteristic.CurrentPosition, newTarget);
+ accessory.context.cacheCurrentPosition = newTarget;
accessory.context.cachePositionState = 2;
- accessory.context.cacheCurrentPosition = value;
+ accessory.context.inUse = false;
})
.catch(err => {
throw err;
});
} catch (err) {
this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ accessory.context.inUse = false;
if (accessory.context.reachableWAN) {
this.wsClient.requestUpdate(accessory).catch(() => {});
this.log.warn(
@@ -1403,6 +1420,20 @@ class eWeLink {
if (blindConfig.type !== "blind" || blindConfig.setup !== "twoSwitch") {
throw "improper configuration";
}
+ if (!params.hasOwnProperty("updateSource")) {
+ wcService
+ .updateCharacteristic(Characteristic.PositionState, accessory.context.cachePositionState)
+ .updateCharacteristic(
+ Characteristic.TargetPosition,
+ accessory.context.cacheTargetPosition
+ )
+ .updateCharacteristic(
+ Characteristic.CurrentPosition,
+ accessory.context.cacheCurrentPosition
+ );
+ return;
+ }
+ if (accessory.context.inUse) return;
if (params.switches[0].switch === "off" && params.switches[1].switch === "off") {
return;
}
@@ -1440,7 +1471,7 @@ class eWeLink {
}
let sensorDefinition = garageConfig.sensorId || false,
sAccessory = false,
- oldPos,
+ prevState,
newPos = value,
params = {},
delay = 0,
@@ -1451,19 +1482,19 @@ class eWeLink {
if (sensorDefinition && sAccessory.context.type !== "sensor") {
throw "defined DW2 sensor isn't a sensor";
}
- oldPos = sAccessory
+ prevState = sAccessory
? sAccessory
.getService(Service.ContactSensor)
.getCharacteristic(Characteristic.ContactSensorState).value === 0
? 1
: 0
: accessory.context.cacheCurrentDoorState;
- if (newPos === oldPos % 2) return;
+ if (newPos === prevState % 2) return;
accessory.context.inUse = true;
accessory.context.state = value;
- if (garageConfig.setup === "oneSwitch" && [2, 3].includes(oldPos)) {
- gdService.updateCharacteristic(Characteristic.CurrentDoorState, ((oldPos * 2) % 3) + 2);
- accessory.context.cacheCurrentDoorState = ((oldPos * 2) % 3) + 2;
+ if (garageConfig.setup === "oneSwitch" && [2, 3].includes(prevState)) {
+ gdService.updateCharacteristic(Characteristic.CurrentDoorState, ((prevState * 2) % 3) + 2);
+ accessory.context.cacheCurrentDoorState = ((prevState * 2) % 3) + 2;
delay = 1500;
}
if (accessory.context.state !== newPos) return;
@@ -1518,8 +1549,8 @@ class eWeLink {
try {
let garageConfig,
gcService = accessory.getService(Service.GarageDoorOpener),
- oldPos = accessory.context.cacheCurrentDoorState,
- newPos = [0, 2].includes(oldPos) ? 3 : 2;
+ prevState = accessory.context.cacheCurrentDoorState,
+ newPos = [0, 2].includes(prevState) ? 3 : 2;
if (!(garageConfig = this.cusG.get(accessory.context.hbDeviceId))) {
throw "group config missing";
}
@@ -1541,7 +1572,7 @@ class eWeLink {
case "twoSwitch":
if (
params.switches[0].switch === params.switches[1].switch ||
- params.switches[oldPos % 2].switch === "on"
+ params.switches[prevState % 2].switch === "on"
) {
return;
}
@@ -2639,6 +2670,5 @@ module.exports = function (homebridge) {
EveService = new hbLib.EveHomeKitTypes(homebridge);
EveHistoryService = fakegato(homebridge);
Service = homebridge.hap.Service;
- UUIDGen = homebridge.hap.uuid;
return eWeLink;
};
diff --git a/lib/eWeLinkLAN.js b/lib/eWeLinkLAN.js
index 68aa7eb7..56a983ec 100644
--- a/lib/eWeLinkLAN.js
+++ b/lib/eWeLinkLAN.js
@@ -125,7 +125,7 @@ module.exports = class eWeLinkLAN {
sendUpdate(json) {
return new Promise((resolve, reject) => {
if (!this.deviceMap.get(json.deviceid).online) {
- reject("device isn't reachable by LAN mode");
+ throw "device isn't reachable by LAN mode";
}
let apiKey,
suffix,
@@ -137,9 +137,7 @@ module.exports = class eWeLinkLAN {
params.switch = json.params.switch;
suffix = "switch";
} else {
- reject(
- "plugin does not support lan mode for this device yet - feel free to create a github issue"
- );
+ throw "plugin does not support lan mode for this device yet - feel free to create a github issue";
}
if ((apiKey = this.deviceMap.get(json.deviceid).apiKey)) {
let key = crypto.createHash("md5").update(Buffer.from(apiKey, "utf8")).digest(),
diff --git a/lib/eWeLinkWS.js b/lib/eWeLinkWS.js
index e99df8fd..6f30b2ea 100644
--- a/lib/eWeLinkWS.js
+++ b/lib/eWeLinkWS.js
@@ -207,18 +207,18 @@ module.exports = class eWeLinkWS {
}
sendUpdate(json) {
return new Promise((resolve, reject) => {
- let sequence = Math.floor(new Date()).toString();
- json = {
- ...json,
- ...{
- action: "update",
- sequence,
- userAgent: "app",
- },
- };
- let sendOperation = () => {
+ let sequence = Math.floor(new Date()).toString(),
+ jsonToSend = {
+ ...json,
+ ...{
+ action: "update",
+ sequence,
+ userAgent: "app",
+ },
+ };
+ if (this.wsp && this.wsIsOpen) {
this.wsp
- .sendRequest(json, {
+ .sendRequest(jsonToSend, {
requestId: sequence,
})
.then(device => {
@@ -236,26 +236,19 @@ module.exports = class eWeLinkWS {
case 0:
resolve();
break;
- case 504:
default:
throw "Unknown response";
}
})
.catch(err => reject("Device update failed [" + err + "]."));
- };
- let checkToSend = () => {
- if (this.wsp && this.wsIsOpen) {
- sendOperation();
- } else {
- this.delay(2500).then(() => {
- if (this.debug) {
- this.log.warn("Will resend command when WS is reconnected.");
- }
- checkToSend();
- });
- }
- };
- checkToSend();
+ } else {
+ this.delay(2500).then(() => {
+ if (this.debug) {
+ this.log.warn("Will resend command when WS is reconnected.");
+ }
+ resolve(this.sendUpdate(json));
+ });
+ }
});
}
requestUpdate(accessory) {
From ea8ae45de9cc50a5a9f3d51dac4667dd639ac79c Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Thu, 24 Sep 2020 14:30:38 +0100
Subject: [PATCH 0207/3183] 3.0.1-1
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 4b4267f1..1ec031ed 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.0.1-0",
+ "version": "3.0.1-1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index f8f82af6..f5a71fc9 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.0.1-0",
+ "version": "3.0.1-1",
"author": "bwp91",
"contributors": [
"gbro115",
From 622ce4a1df1330f8a33340f8d50a4bcb9486b3fc Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Thu, 24 Sep 2020 17:10:29 +0100
Subject: [PATCH 0208/3183] fixing broken promises
---
lib/eWeLink.js | 98 ++++++++++++++++++++++------------------------
lib/eWeLinkHTTP.js | 32 +++++++++------
lib/eWeLinkLAN.js | 4 +-
3 files changed, 67 insertions(+), 67 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 9b29b4da..db8502ed 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -59,9 +59,7 @@ class eWeLink {
this.wsClient
.getHost()
.then(() => this.wsClient.closeConnection())
- .then(() => {
- return new Promise(resolve => setTimeout(resolve, 250));
- })
+ .then(() => Promise(resolve => setTimeout(resolve, 250)))
.then(() => this.wsClient.login())
.catch(err => this.log.warn(err));
}
@@ -1081,24 +1079,22 @@ class eWeLink {
params,
},
delayPromise = new Promise(resolve => setTimeout(resolve, Math.random() * 100 + 200));
- delayPromise.then(() => {
- this.lanClient
- .sendUpdate(payload)
- .then(() => resolve())
- .catch(err => {
+ delayPromise
+ .then(() => this.lanClient.sendUpdate(payload))
+ .then(() => resolve())
+ .catch(err => {
+ if (accessory.context.reachableWAN) {
if (this.debug) {
this.log.warn("[%s] Reverting to web socket as %s.", accessory.displayName, err);
}
- if (accessory.context.reachableWAN) {
- this.wsClient
- .sendUpdate(payload)
- .then(() => resolve())
- .catch(err => reject(err));
- } else {
- reject("it is unreachable");
- }
- });
- });
+ this.wsClient
+ .sendUpdate(payload)
+ .then(() => resolve())
+ .catch(err => reject(err));
+ } else {
+ reject("it is unreachable");
+ }
+ });
});
}
receiveDeviceUpdate(device) {
@@ -1518,11 +1514,9 @@ class eWeLink {
}
return this.sendDeviceUpdate(accessory, params);
})
- .then(() => {
- return new Promise(resolve =>
- setTimeout(resolve, parseInt(garageConfig.operationTime) * 100)
- );
- })
+ .then(() =>
+ Promise(resolve => setTimeout(resolve, parseInt(garageConfig.operationTime) * 100))
+ )
.then(() => {
if (!sAccessory) {
gdService.updateCharacteristic(Characteristic.CurrentDoorState, newPos);
@@ -2129,19 +2123,19 @@ class eWeLink {
break;
}
}
- setTimeout(() => {
- this.sendDeviceUpdate(accessory, params)
- .then(() => {
- if (value === 0) {
- lightService.updateCharacteristic(Characteristic.On, false);
- } else {
- lightService.updateCharacteristic(Characteristic.Brightness, value);
- }
- })
- .catch(err => {
- throw err;
- });
- }, 250);
+ let delayPromise = new Promise(resolve => setTimeout(resolve, 250));
+ delayPromise
+ .then(() => this.sendDeviceUpdate(accessory, params))
+ .then(() => {
+ if (value === 0) {
+ lightService.updateCharacteristic(Characteristic.On, false);
+ } else {
+ lightService.updateCharacteristic(Characteristic.Brightness, value);
+ }
+ })
+ .catch(err => {
+ throw err;
+ });
} catch (err) {
this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
if (accessory.context.reachableWAN) {
@@ -2212,22 +2206,22 @@ class eWeLink {
}
break;
}
- setTimeout(() => {
- this.sendDeviceUpdate(accessory, params)
- .then(() => {
- switch (type) {
- case "hue":
- lightService.updateCharacteristic(Characteristic.Hue, value);
- break;
- case "bri":
- lightService.updateCharacteristic(Characteristic.Brightness, value);
- break;
- }
- })
- .catch(err => {
- throw err;
- });
- }, 250);
+ let delayPromise = new Promise(resolve => setTimeout(resolve, 250));
+ delayPromise
+ .then(() => this.sendDeviceUpdate(accessory, params))
+ .then(() => {
+ switch (type) {
+ case "hue":
+ lightService.updateCharacteristic(Characteristic.Hue, value);
+ break;
+ case "bri":
+ lightService.updateCharacteristic(Characteristic.Brightness, value);
+ break;
+ }
+ })
+ .catch(err => {
+ throw err;
+ });
} catch (err) {
this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
if (accessory.context.reachableWAN) {
diff --git a/lib/eWeLinkHTTP.js b/lib/eWeLinkHTTP.js
index beb48f3b..36d099cf 100644
--- a/lib/eWeLinkHTTP.js
+++ b/lib/eWeLinkHTTP.js
@@ -78,7 +78,7 @@ module.exports = class eWeLinkHTTP {
err.hasOwnProperty("code") &&
["ENOTFOUND", "ETIMEDOUT", "EAI_AGAIN"].includes(err.code)
) {
- this.log.warn("Unable to reach eWeLink. Retrying in 15 seconds.");
+ this.log.warn("Unable to reach eWeLink. Retrying in 30 seconds.");
this.delay().then(() => resolve(this.getHost()));
} else {
reject(err.message || err);
@@ -144,16 +144,22 @@ module.exports = class eWeLinkHTTP {
resolve(this.login());
return;
}
- if (!body.data.at) {
- throw "No auth token received.\n" + JSON.stringify(body, null, 2);
+ if (body.data.at) {
+ this.aToken = body.data.at;
+ this.apiKey = body.data.user.apikey;
+ resolve({
+ aToken: this.aToken,
+ apiKey: this.apiKey,
+ httpHost: this.httpHost,
+ });
+ } else {
+ if (body.error === 500) {
+ this.log.warn("An eWeLink error [500] occured. Retrying in 30 seconds.");
+ this.delay().then(() => resolve(this.login()));
+ } else {
+ throw "No auth token received.\n" + JSON.stringify(body, null, 2);
+ }
}
- this.aToken = body.data.at;
- this.apiKey = body.data.user.apikey;
- resolve({
- aToken: this.aToken,
- apiKey: this.apiKey,
- httpHost: this.httpHost,
- });
})
.catch(err => reject(err.message || err));
});
@@ -190,7 +196,7 @@ module.exports = class eWeLinkHTTP {
})
.catch(err => {
if (err.hasOwnProperty("code") && ["ENOTFOUND", "ETIMEDOUT"].includes(err.code)) {
- this.log.warn("Unable to reach eWeLink. Retrying in 15 seconds.");
+ this.log.warn("Unable to reach eWeLink. Retrying in 30 seconds.");
this.delay().then(() => resolve(this.getDevices()));
} else {
reject(err.message || err);
@@ -238,7 +244,7 @@ module.exports = class eWeLinkHTTP {
})
.catch(err => {
if (err.hasOwnProperty("code") && ["ENOTFOUND", "ETIMEDOUT"].includes(err.code)) {
- this.log.warn("Unable to reach eWeLink. Retrying in 15 seconds.");
+ this.log.warn("Unable to reach eWeLink. Retrying in 30 seconds.");
this.delay().then(() => resolve(this.getDevice(deviceId)));
} else {
reject(err.message || err);
@@ -247,6 +253,6 @@ module.exports = class eWeLinkHTTP {
});
}
delay() {
- return new Promise(resolve => setTimeout(resolve, 15000));
+ return new Promise(resolve => setTimeout(resolve, 30000));
}
};
diff --git a/lib/eWeLinkLAN.js b/lib/eWeLinkLAN.js
index 56a983ec..647e2c1c 100644
--- a/lib/eWeLinkLAN.js
+++ b/lib/eWeLinkLAN.js
@@ -125,7 +125,7 @@ module.exports = class eWeLinkLAN {
sendUpdate(json) {
return new Promise((resolve, reject) => {
if (!this.deviceMap.get(json.deviceid).online) {
- throw "device isn't reachable by LAN mode";
+ throw "device isn't reachable via LAN mode";
}
let apiKey,
suffix,
@@ -137,7 +137,7 @@ module.exports = class eWeLinkLAN {
params.switch = json.params.switch;
suffix = "switch";
} else {
- throw "plugin does not support lan mode for this device yet - feel free to create a github issue";
+ throw "device isn't reachable via LAN mode";
}
if ((apiKey = this.deviceMap.get(json.deviceid).apiKey)) {
let key = crypto.createHash("md5").update(Buffer.from(apiKey, "utf8")).digest(),
From fa841abb6dfdd224b7216725b6bc3b2e951f0913 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Thu, 24 Sep 2020 17:11:49 +0100
Subject: [PATCH 0209/3183] 3.0.1-2
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 1ec031ed..88ddc263 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.0.1-1",
+ "version": "3.0.1-2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index f5a71fc9..91e793dc 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.0.1-1",
+ "version": "3.0.1-2",
"author": "bwp91",
"contributors": [
"gbro115",
From b6f81f48cd3f5cf652854f64c4d04964c399b65b Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Thu, 24 Sep 2020 19:36:08 +0100
Subject: [PATCH 0210/3183] promises
---
lib/constants.js | 2 +-
lib/eWeLink.js | 170 +++++++++++++++++++++++++----------------------
lib/eWeLinkWS.js | 2 +-
3 files changed, 91 insertions(+), 83 deletions(-)
diff --git a/lib/constants.js b/lib/constants.js
index 75bdeaf1..9e1ce0d4 100644
--- a/lib/constants.js
+++ b/lib/constants.js
@@ -9,7 +9,7 @@ module.exports = {
devicesNonLAN: [22, 28, 59, 102],
devicesSingleSwitch: [1, 5, 6, 14, 15, 22, 24, 27, 32, 36, 44, 59],
devicesSingleSwitchParams: ["switch"],
- devicesSingleSwitchOutlet: ["Sonoff Pow"],
+ devicesSingleSwitchOutlet: ["Sonoff Pow", "S26"],
devicesMultiSwitch: [2, 3, 4, 7, 8, 9, 29, 30, 31, 34, 41],
devicesMultiSwitchParams: ["switches"],
devicesSingleSwitchLight: [
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index db8502ed..08ece724 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -59,7 +59,7 @@ class eWeLink {
this.wsClient
.getHost()
.then(() => this.wsClient.closeConnection())
- .then(() => Promise(resolve => setTimeout(resolve, 250)))
+ .then(() => new Promise(resolve => setTimeout(resolve, 250)))
.then(() => this.wsClient.login())
.catch(err => this.log.warn(err));
}
@@ -686,92 +686,96 @@ class eWeLink {
if (!(outletService = accessory.getService(Service.Outlet))) {
accessory.addService(Service.Outlet);
outletService = accessory.getService(Service.Outlet);
- outletService.addCharacteristic(EveService.Characteristics.Voltage);
- outletService.addCharacteristic(EveService.Characteristics.CurrentConsumption);
- outletService.addCharacteristic(EveService.Characteristics.ElectricCurrent);
- outletService.addCharacteristic(EveService.Characteristics.TotalConsumption);
- outletService.addCharacteristic(EveService.Characteristics.ResetTotal);
- accessory.context = {
- ...accessory.context,
- ...{
- extraPersistedData: {},
- lastReset: 0,
- totalEnergy: 0,
- totalEnergyTemp: 0,
- },
- };
+ if (accessory.context.eweModel !== "S26" && !(this.config.disableEveLogging || false)) {
+ outletService.addCharacteristic(EveService.Characteristics.Voltage);
+ outletService.addCharacteristic(EveService.Characteristics.CurrentConsumption);
+ outletService.addCharacteristic(EveService.Characteristics.ElectricCurrent);
+ outletService.addCharacteristic(EveService.Characteristics.TotalConsumption);
+ outletService.addCharacteristic(EveService.Characteristics.ResetTotal);
+ accessory.context = {
+ ...accessory.context,
+ ...{
+ extraPersistedData: {},
+ lastReset: 0,
+ totalEnergy: 0,
+ totalEnergyTemp: 0,
+ },
+ };
+ }
}
outletService
.getCharacteristic(Characteristic.On)
.on("set", (value, callback) => this.internalOutletUpdate(accessory, value, callback));
- accessory.log = this.log;
- accessory.eveLogger = new EveHistoryService("energy", accessory, {
- storage: "fs",
- minutes: 5,
- path: this.eveLogPath,
- });
- corrInterval.setCorrectingInterval(() => {
- let isOn = outletService.getCharacteristic(Characteristic.On).value,
- currentWatt = isOn
- ? outletService.getCharacteristic(EveService.Characteristics.CurrentConsumption)
- .value
- : 0;
- if (accessory.eveLogger.isHistoryLoaded()) {
- accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData();
- if (accessory.context.extraPersistedData !== undefined) {
- accessory.context.totalEnergy =
- accessory.context.extraPersistedData.totalenergy +
- accessory.context.totalEnergyTemp +
- (currentWatt * 10) / 3600 / 1000;
- accessory.eveLogger.setExtraPersistedData({
- totalenergy: accessory.context.totalEnergy,
- lastReset: accessory.context.extraPersistedData.lastReset,
- });
+ if (accessory.context.eweModel !== "S26" && !(this.config.disableEveLogging || false)) {
+ accessory.log = this.log;
+ accessory.eveLogger = new EveHistoryService("energy", accessory, {
+ storage: "fs",
+ minutes: 5,
+ path: this.eveLogPath,
+ });
+ corrInterval.setCorrectingInterval(() => {
+ let isOn = outletService.getCharacteristic(Characteristic.On).value,
+ currentWatt = isOn
+ ? outletService.getCharacteristic(EveService.Characteristics.CurrentConsumption)
+ .value
+ : 0;
+ if (accessory.eveLogger.isHistoryLoaded()) {
+ accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData();
+ if (accessory.context.extraPersistedData !== undefined) {
+ accessory.context.totalEnergy =
+ accessory.context.extraPersistedData.totalenergy +
+ accessory.context.totalEnergyTemp +
+ (currentWatt * 10) / 3600 / 1000;
+ accessory.eveLogger.setExtraPersistedData({
+ totalenergy: accessory.context.totalEnergy,
+ lastReset: accessory.context.extraPersistedData.lastReset,
+ });
+ } else {
+ accessory.context.totalEnergy =
+ accessory.context.totalEnergyTemp + (currentWatt * 10) / 3600 / 1000;
+ accessory.eveLogger.setExtraPersistedData({
+ totalenergy: accessory.context.totalEnergy,
+ lastReset: 0,
+ });
+ }
+ accessory.context.totalEnergytemp = 0;
} else {
- accessory.context.totalEnergy =
- accessory.context.totalEnergyTemp + (currentWatt * 10) / 3600 / 1000;
+ accessory.context.totalEnergyTemp += (currentWatt * 10) / 3600 / 1000;
+ accessory.context.totalEnergy = accessory.context.totalEnergyTemp;
+ }
+ accessory.eveLogger.addEntry({
+ time: Date.now(),
+ power: currentWatt,
+ });
+ }, 300000);
+ outletService
+ .getCharacteristic(EveService.Characteristics.TotalConsumption)
+ .on("get", callback => {
+ accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData();
+ if (accessory.context.extraPersistedData !== undefined) {
+ accessory.context.totalEnergy = accessory.context.extraPersistedData.totalPower;
+ }
+ callback(null, accessory.context.totalEnergy);
+ });
+ outletService
+ .getCharacteristic(EveService.Characteristics.ResetTotal)
+ .on("set", (value, callback) => {
+ accessory.context.totalEnergy = 0;
+ accessory.context.lastReset = value;
accessory.eveLogger.setExtraPersistedData({
- totalenergy: accessory.context.totalEnergy,
- lastReset: 0,
+ totalPower: 0,
+ lastReset: value,
});
- }
- accessory.context.totalEnergytemp = 0;
- } else {
- accessory.context.totalEnergyTemp += (currentWatt * 10) / 3600 / 1000;
- accessory.context.totalEnergy = accessory.context.totalEnergyTemp;
- }
- accessory.eveLogger.addEntry({
- time: Date.now(),
- power: currentWatt,
- });
- }, 300000);
- outletService
- .getCharacteristic(EveService.Characteristics.TotalConsumption)
- .on("get", callback => {
- accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData();
- if (accessory.context.extraPersistedData !== undefined) {
- accessory.context.totalEnergy = accessory.context.extraPersistedData.totalPower;
- }
- callback(null, accessory.context.totalEnergy);
- });
- outletService
- .getCharacteristic(EveService.Characteristics.ResetTotal)
- .on("set", (value, callback) => {
- accessory.context.totalEnergy = 0;
- accessory.context.lastReset = value;
- accessory.eveLogger.setExtraPersistedData({
- totalPower: 0,
- lastReset: value,
+ callback();
+ })
+ .on("get", callback => {
+ accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData();
+ if (accessory.context.extraPersistedData !== undefined) {
+ accessory.context.lastReset = accessory.context.extraPersistedData.lastReset;
+ }
+ callback(null, accessory.context.lastReset);
});
- callback();
- })
- .on("get", callback => {
- accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData();
- if (accessory.context.extraPersistedData !== undefined) {
- accessory.context.lastReset = accessory.context.extraPersistedData.lastReset;
- }
- callback(null, accessory.context.lastReset);
- });
+ }
break;
case "usb":
let usbService =
@@ -1514,8 +1518,9 @@ class eWeLink {
}
return this.sendDeviceUpdate(accessory, params);
})
- .then(() =>
- Promise(resolve => setTimeout(resolve, parseInt(garageConfig.operationTime) * 100))
+ .then(
+ () =>
+ new Promise(resolve => setTimeout(resolve, parseInt(garageConfig.operationTime) * 100))
)
.then(() => {
if (!sAccessory) {
@@ -1904,6 +1909,9 @@ class eWeLink {
let outletService = accessory.getService(Service.Outlet);
if (params.hasOwnProperty("switch")) {
outletService.updateCharacteristic(Characteristic.On, params.switch === "on");
+ if (accessory.context.eweModel === "S26" || this.config.disableEveLogging || false) {
+ outletService.updateCharacteristic(Characteristic.OutletInUse, params.switch === "on");
+ }
}
if (params.hasOwnProperty("power")) {
outletService.updateCharacteristic(
diff --git a/lib/eWeLinkWS.js b/lib/eWeLinkWS.js
index 6f30b2ea..bdfae75d 100644
--- a/lib/eWeLinkWS.js
+++ b/lib/eWeLinkWS.js
@@ -237,7 +237,7 @@ module.exports = class eWeLinkWS {
resolve();
break;
default:
- throw "Unknown response";
+ reject("Unknown response");
}
})
.catch(err => reject("Device update failed [" + err + "]."));
From 68a1cd2e04e02e7b919e93bb2cdd4c64b22cb530 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Fri, 25 Sep 2020 05:48:34 +0100
Subject: [PATCH 0211/3183] Update eWeLinkLAN.js
---
lib/eWeLinkLAN.js | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/lib/eWeLinkLAN.js b/lib/eWeLinkLAN.js
index 647e2c1c..09c6f749 100644
--- a/lib/eWeLinkLAN.js
+++ b/lib/eWeLinkLAN.js
@@ -174,8 +174,9 @@ module.exports = class eWeLinkLAN {
.then(res => {
if (res.data.hasOwnProperty("error") && res.data.error === 0) {
resolve();
+ } else {
+ throw res.data;
}
- reject(res.data);
})
.catch(err => reject(err));
}
From 92005bcec9cbfb121f1d8eb6927b4b7179192a18 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Fri, 25 Sep 2020 05:48:37 +0100
Subject: [PATCH 0212/3183] Update eWeLinkWS.js
---
lib/eWeLinkWS.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/eWeLinkWS.js b/lib/eWeLinkWS.js
index bdfae75d..6f30b2ea 100644
--- a/lib/eWeLinkWS.js
+++ b/lib/eWeLinkWS.js
@@ -237,7 +237,7 @@ module.exports = class eWeLinkWS {
resolve();
break;
default:
- reject("Unknown response");
+ throw "Unknown response";
}
})
.catch(err => reject("Device update failed [" + err + "]."));
From aa319b12a02da919af83ae6bf93667b7116b2012 Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Fri, 25 Sep 2020 06:12:46 +0100
Subject: [PATCH 0213/3183] Create discord.md
---
lib/discord.md | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
create mode 100644 lib/discord.md
diff --git a/lib/discord.md b/lib/discord.md
new file mode 100644
index 00000000..c53fcd66
--- /dev/null
+++ b/lib/discord.md
@@ -0,0 +1,26 @@
+Situation: I am trying to control a smart plug which itself is not plugged in.
+`Characteristic.On` calls `internalOutletUpdate()` for it's `.on("set")` event.
+When trying to turn the outlet on I receive the warning at the end of this file.
+
+
+Code can be seen at:
+https://github.com/bwp91/homebridge-ewelink/tree/master/lib
+
+In a nutshell:
+
+* /eWeLink.js line 1078 `internalOutletUpdate()`, which calls
+* /eWeLink.js line 1310 `sendDeviceUpdate()`, which calls
+ * /eWeLinkLAN.js line 125 `sendUpdate()`, and if this fails,
+ * /eWeLinkWS.js line 208 `sendUpdate()`
+
+```
+(node:1229) UnhandledPromiseRejectionWarning: it is unreachable
+ at emitUnhandledRejectionWarning (internal/process/promises.js:170:15)
+ at processPromiseRejections (internal/process/promises.js:247:11)
+ at processTicksAndRejections (internal/process/task_queues.js:94:32)
+(node:1229) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 3)
+(node:1229) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
+ at emitDeprecationWarning (internal/process/promises.js:180:11)
+ at processPromiseRejections (internal/process/promises.js:249:13)
+ at processTicksAndRejections (internal/process/task_queues.js:94:32)
+```
From 93861cae2fa9a97ff780145508c9168e32b1c485 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Fri, 25 Sep 2020 10:29:40 +0100
Subject: [PATCH 0214/3183] fix catch errors
---
lib/eWeLink.js | 210 ++++++++++---------------------------------------
1 file changed, 41 insertions(+), 169 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 08ece724..1edf88c3 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -1096,7 +1096,7 @@ class eWeLink {
.then(() => resolve())
.catch(err => reject(err));
} else {
- reject("it is unreachable");
+ reject("it is unreachable. I's status will be corrected once it is reachable");
}
});
});
@@ -1183,6 +1183,16 @@ class eWeLink {
}
}
}
+ requestDeviceRefresh(accessory, err) {
+ this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ if (accessory.context.reachableWAN) {
+ this.wsClient.requestUpdate(accessory).catch(() => {});
+ this.log.warn(
+ "[%s] requesting previous state to revert Homebridge status.",
+ accessory.displayName
+ );
+ }
+ }
internalValveUpdate(accessory, valve, value, callback) {
callback();
try {
@@ -1229,18 +1239,9 @@ class eWeLink {
break;
}
})
- .catch(err => {
- throw err;
- });
+ .catch(err => this.requestDeviceRefresh(accessory, err));
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- if (accessory.context.reachableWAN) {
- this.wsClient.requestUpdate(accessory).catch(() => {});
- this.log.warn(
- "[%s] requesting previous state to revert Homebridge status.",
- accessory.displayName
- );
- }
+ this.requestDeviceRefresh(accessory, err);
}
}
externalValveUpdate(accessory, params) {
@@ -1289,18 +1290,9 @@ class eWeLink {
.updateCharacteristic(Characteristic.PositionState, newPos > prevPos ? 1 : 0);
accessory.context.cacheCurrentPosition = newPos;
})
- .catch(err => {
- throw err;
- });
+ .catch(err => this.requestDeviceRefresh(accessory, err));
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- if (accessory.context.reachableWAN) {
- this.wsClient.requestUpdate(accessory).catch(() => {});
- this.log.warn(
- "[%s] requesting previous state to revert Homebridge status.",
- accessory.displayName
- );
- }
+ this.requestDeviceRefresh(accessory, err);
}
}
externalCurtainUpdate(accessory, params) {
@@ -1394,19 +1386,9 @@ class eWeLink {
accessory.context.cachePositionState = 2;
accessory.context.inUse = false;
})
- .catch(err => {
- throw err;
- });
+ .catch(err => this.requestDeviceRefresh(accessory, err));
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- accessory.context.inUse = false;
- if (accessory.context.reachableWAN) {
- this.wsClient.requestUpdate(accessory).catch(() => {});
- this.log.warn(
- "[%s] requesting previous state to revert Homebridge status.",
- accessory.displayName
- );
- }
+ this.requestDeviceRefresh(accessory, err);
}
}
externalBlindUpdate(accessory, params) {
@@ -1529,19 +1511,9 @@ class eWeLink {
}
accessory.context.inUse = false;
})
- .catch(err => {
- throw err;
- });
+ .catch(err => this.requestDeviceRefresh(accessory, err));
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- accessory.context.inUse = false;
- if (accessory.context.reachableWAN) {
- this.wsClient.requestUpdate(accessory).catch(() => {});
- this.log.warn(
- "[%s] requesting previous state to revert Homebridge status.",
- accessory.displayName
- );
- }
+ this.requestDeviceRefresh(accessory, err);
}
}
externalGarageUpdate(accessory, params) {
@@ -1624,19 +1596,9 @@ class eWeLink {
accessory.context.inUse = false;
}, parseInt(lockConfig.operationTime) * 100);
})
- .catch(err => {
- throw err;
- });
+ .catch(err => this.requestDeviceRefresh(accessory, err));
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- accessory.context.inUse = false;
- if (accessory.context.reachableWAN) {
- this.wsClient.requestUpdate(accessory).catch(() => {});
- this.log.warn(
- "[%s] requesting previous state to revert Homebridge status.",
- accessory.displayName
- );
- }
+ this.requestDeviceRefresh(accessory, err);
}
}
externalLockUpdate(accessory, params) {
@@ -1751,18 +1713,9 @@ class eWeLink {
.updateCharacteristic(Characteristic.Active, newPower)
.updateCharacteristic(Characteristic.RotationSpeed, newSpeed);
})
- .catch(err => {
- throw err;
- });
+ .catch(err => this.requestDeviceRefresh(accessory, err));
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- if (accessory.context.reachableWAN) {
- this.wsClient.requestUpdate(accessory).catch(() => {});
- this.log.warn(
- "[%s] requesting previous state to revert Homebridge status.",
- accessory.displayName
- );
- }
+ this.requestDeviceRefresh(accessory, err);
}
}
externalFanUpdate(accessory, params) {
@@ -1822,18 +1775,9 @@ class eWeLink {
.then(() => {
switchService.updateCharacteristic(Characteristic.On, value);
})
- .catch(err => {
- throw err;
- });
+ .catch(err => this.requestDeviceRefresh(accessory, err));
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- if (accessory.context.reachableWAN) {
- this.wsClient.requestUpdate(accessory).catch(() => {});
- this.log.warn(
- "[%s] requesting previous state to revert Homebridge status.",
- accessory.displayName
- );
- }
+ this.requestDeviceRefresh(accessory, err);
}
}
externalThermostatUpdate(accessory, params) {
@@ -1890,18 +1834,9 @@ class eWeLink {
.then(() => {
outletService.updateCharacteristic(Characteristic.On, value);
})
- .catch(err => {
- throw err;
- });
+ .catch(err => this.requestDeviceRefresh(accessory, err));
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- if (accessory.context.reachableWAN) {
- this.wsClient.requestUpdate(accessory).catch(() => {});
- this.log.warn(
- "[%s] requesting previous state to revert Homebridge status.",
- accessory.displayName
- );
- }
+ this.requestDeviceRefresh(accessory, err);
}
}
externalOutletUpdate(accessory, params) {
@@ -1956,18 +1891,9 @@ class eWeLink {
.then(() => {
outletService.updateCharacteristic(Characteristic.On, value);
})
- .catch(err => {
- throw err;
- });
+ .catch(err => this.requestDeviceRefresh(accessory, err));
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- if (accessory.context.reachableWAN) {
- this.wsClient.requestUpdate(accessory).catch(() => {});
- this.log.warn(
- "[%s] requesting previous state to revert Homebridge status.",
- accessory.displayName
- );
- }
+ this.requestDeviceRefresh(accessory, err);
}
}
externalUSBUpdate(accessory, params) {
@@ -1991,18 +1917,9 @@ class eWeLink {
.then(() => {
switchService.updateCharacteristic(Characteristic.On, value);
})
- .catch(err => {
- throw err;
- });
+ .catch(err => this.requestDeviceRefresh(accessory, err));
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- if (accessory.context.reachableWAN) {
- this.wsClient.requestUpdate(accessory).catch(() => {});
- this.log.warn(
- "[%s] requesting previous state to revert Homebridge status.",
- accessory.displayName
- );
- }
+ this.requestDeviceRefresh(accessory, err);
}
}
externalSCMUpdate(accessory, params) {
@@ -2096,18 +2013,9 @@ class eWeLink {
break;
}
})
- .catch(err => {
- throw err;
- });
+ .catch(err => this.requestDeviceRefresh(accessory, err));
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- if (accessory.context.reachableWAN) {
- this.wsClient.requestUpdate(accessory).catch(() => {});
- this.log.warn(
- "[%s] requesting previous state to revert Homebridge status.",
- accessory.displayName
- );
- }
+ this.requestDeviceRefresh(accessory, err);
}
}
internalBrightnessUpdate(accessory, value, callback) {
@@ -2141,18 +2049,9 @@ class eWeLink {
lightService.updateCharacteristic(Characteristic.Brightness, value);
}
})
- .catch(err => {
- throw err;
- });
+ .catch(err => this.requestDeviceRefresh(accessory, err));
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- if (accessory.context.reachableWAN) {
- this.wsClient.requestUpdate(accessory).catch(() => {});
- this.log.warn(
- "[%s] requesting previous state to revert Homebridge status.",
- accessory.displayName
- );
- }
+ this.requestDeviceRefresh(accessory, err);
}
}
internalHSBUpdate(accessory, type, value, callback) {
@@ -2227,18 +2126,9 @@ class eWeLink {
break;
}
})
- .catch(err => {
- throw err;
- });
+ .catch(err => this.requestDeviceRefresh(accessory, err));
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- if (accessory.context.reachableWAN) {
- this.wsClient.requestUpdate(accessory).catch(() => {});
- this.log.warn(
- "[%s] requesting previous state to revert Homebridge status.",
- accessory.displayName
- );
- }
+ this.requestDeviceRefresh(accessory, err);
}
}
externalSingleLightUpdate(accessory, params) {
@@ -2415,18 +2305,9 @@ class eWeLink {
break;
}
})
- .catch(err => {
- throw err;
- });
+ .catch(err => this.requestDeviceRefresh(accessory, err));
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- if (accessory.context.reachableWAN) {
- this.wsClient.requestUpdate(accessory).catch(() => {});
- this.log.warn(
- "[%s] requesting previous state to revert Homebridge status.",
- accessory.displayName
- );
- }
+ this.requestDeviceRefresh(accessory, err);
}
}
externalSingleSwitchUpdate(accessory, params) {
@@ -2473,18 +2354,9 @@ class eWeLink {
rfService.updateCharacteristic(Characteristic.On, true);
setTimeout(() => rfService.updateCharacteristic(Characteristic.On, false), 3000);
})
- .catch(err => {
- throw err;
- });
+ .catch(err => this.requestDeviceRefresh(accessory, err));
} catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- if (accessory.context.reachableWAN) {
- this.wsClient.requestUpdate(accessory).catch(() => {});
- this.log.warn(
- "[%s] requesting previous state to revert Homebridge status.",
- accessory.displayName
- );
- }
+ this.requestDeviceRefresh(accessory, err);
}
}
externalRFUpdate(accessory, params) {
From 56d51191ee3b7085fd669f86bce8263a6450e156 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Fri, 25 Sep 2020 10:35:44 +0100
Subject: [PATCH 0215/3183] 3.0.1
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 88ddc263..24611c34 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.0.1-2",
+ "version": "3.0.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 91e793dc..82cf0b07 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.0.1-2",
+ "version": "3.0.1",
"author": "bwp91",
"contributors": [
"gbro115",
From b206f415ffe4adb4904b642e7b32b685bd9e41e0 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Fri, 25 Sep 2020 14:45:56 +0100
Subject: [PATCH 0216/3183] async/awaits
---
lib/discord.md | 26 --
lib/eWeLink.js | 751 +++++++++++++++++++++------------------------
lib/eWeLinkHTTP.js | 348 +++++++++++----------
lib/eWeLinkLAN.js | 158 +++++-----
lib/eWeLinkWS.js | 196 ++++++------
lib/utils.js | 7 +
package-lock.json | 5 +
package.json | 1 +
8 files changed, 706 insertions(+), 786 deletions(-)
delete mode 100644 lib/discord.md
create mode 100644 lib/utils.js
diff --git a/lib/discord.md b/lib/discord.md
deleted file mode 100644
index c53fcd66..00000000
--- a/lib/discord.md
+++ /dev/null
@@ -1,26 +0,0 @@
-Situation: I am trying to control a smart plug which itself is not plugged in.
-`Characteristic.On` calls `internalOutletUpdate()` for it's `.on("set")` event.
-When trying to turn the outlet on I receive the warning at the end of this file.
-
-
-Code can be seen at:
-https://github.com/bwp91/homebridge-ewelink/tree/master/lib
-
-In a nutshell:
-
-* /eWeLink.js line 1078 `internalOutletUpdate()`, which calls
-* /eWeLink.js line 1310 `sendDeviceUpdate()`, which calls
- * /eWeLinkLAN.js line 125 `sendUpdate()`, and if this fails,
- * /eWeLinkWS.js line 208 `sendUpdate()`
-
-```
-(node:1229) UnhandledPromiseRejectionWarning: it is unreachable
- at emitUnhandledRejectionWarning (internal/process/promises.js:170:15)
- at processPromiseRejections (internal/process/promises.js:247:11)
- at processTicksAndRejections (internal/process/task_queues.js:94:32)
-(node:1229) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 3)
-(node:1229) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
- at emitDeprecationWarning (internal/process/promises.js:180:11)
- at processPromiseRejections (internal/process/promises.js:249:13)
- at processTicksAndRejections (internal/process/task_queues.js:94:32)
-```
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 1edf88c3..d66cbdaf 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -8,7 +8,9 @@ const cns = require("./constants"),
eWeLinkWS = require("./eWeLinkWS"),
eWeLinkLAN = require("./eWeLinkLAN"),
fakegato = require("fakegato-history"),
- hbLib = require("homebridge-lib");
+ hbLib = require("homebridge-lib"),
+ promInterval = require("interval-promise"),
+ utils = require("./utils");
class eWeLink {
constructor(log, config, api) {
if (!log || !api || !config) return;
@@ -28,89 +30,89 @@ class eWeLink {
this.cusS = new Map();
this.hiddenMasters = [];
this.eveLogPath = this.api.user.storagePath() + "/homebridge-ewelink/";
+ this.wsRefreshFlag = true;
this.api
.on("didFinishLaunching", () => this.eWeLinkSync())
.on("shutdown", () => {
if (this.lanClient) this.lanClient.closeConnection();
if (this.wsClient) this.wsClient.closeConnection();
- if (this.wsRefresh) clearInterval(this.wsRefresh);
+ this.wsRefreshFlag = false;
});
}
- eWeLinkSync() {
- this.log("Plugin has finished initialising. Synching with eWeLink.");
- this.httpClient = new eWeLinkHTTP(this.config, this.log);
- this.httpClient
- .getHost()
- .then(() => this.httpClient.login())
- .then(res => {
- this.authData = res;
- return this.httpClient.getDevices();
- })
- .then(res => {
- res.forEach(device => this.devicesInEW.set(device.deviceid, device));
- this.wsClient = new eWeLinkWS(this.config, this.log, this.authData);
- this.lanClient = new eWeLinkLAN(this.config, this.log, res);
- return this.wsClient.getHost();
- })
- .then(() => {
- this.wsClient.login();
- this.wsRefresh = setInterval(() => {
- if (this.wsClient) {
- this.wsClient
- .getHost()
- .then(() => this.wsClient.closeConnection())
- .then(() => new Promise(resolve => setTimeout(resolve, 250)))
- .then(() => this.wsClient.login())
- .catch(err => this.log.warn(err));
- }
- }, 1800000);
- return this.lanClient.getHosts();
- })
- .then(res => {
- this.lanDevices = res;
- return this.lanClient.startMonitor();
- })
- .then(() => {
- (() => {
- //*** Make a map of custom groups from Homebridge config ***\\
- if (Object.keys(this.config.groups || []).length > 0) {
- this.config.groups
- .filter(g => g.hasOwnProperty("type") && cns.allowedGroups.includes(g.type))
- .filter(g => g.hasOwnProperty("deviceId") && this.devicesInEW.has(g.deviceId))
- .forEach(g => this.cusG.set(g.deviceId + "SWX", g));
- }
- //*** Make a map of RF Bridge custom sensors from Homebridge config ***\\
- if (Object.keys(this.config.bridgeSensors || []).length > 0) {
- this.config.bridgeSensors
- .filter(s => s.hasOwnProperty("deviceId") && this.devicesInEW.has(s.deviceId))
- .forEach(s => this.cusS.set(s.fullDeviceId, s));
+ async eWeLinkSync() {
+ try {
+ this.log("Plugin has finished initialising. Synching with eWeLink.");
+ this.httpClient = new eWeLinkHTTP(this.config, this.log);
+ await this.httpClient.getHost();
+ this.authData = await this.httpClient.login();
+ let deviceList = await this.httpClient.getDevices();
+ deviceList.forEach(device => this.devicesInEW.set(device.deviceid, device));
+ this.wsClient = new eWeLinkWS(this.config, this.log, this.authData);
+ this.lanClient = new eWeLinkLAN(this.config, this.log, deviceList);
+ await this.wsClient.getHost();
+ this.wsClient.login();
+ this.lanDevices = await this.lanClient.getHosts();
+ await this.lanClient.startMonitor();
+ (() => {
+ //*** Make a map of custom groups from Homebridge config ***\\
+ if (Object.keys(this.config.groups || []).length > 0) {
+ this.config.groups
+ .filter(g => g.hasOwnProperty("type") && cns.allowedGroups.includes(g.type))
+ .filter(g => g.hasOwnProperty("deviceId") && this.devicesInEW.has(g.deviceId))
+ .forEach(g => this.cusG.set(g.deviceId + "SWX", g));
+ }
+ //*** Make a map of RF Bridge custom sensors from Homebridge config ***\\
+ if (Object.keys(this.config.bridgeSensors || []).length > 0) {
+ this.config.bridgeSensors
+ .filter(s => s.hasOwnProperty("deviceId") && this.devicesInEW.has(s.deviceId))
+ .forEach(s => this.cusS.set(s.fullDeviceId, s));
+ }
+ //*** Logging always helps to see if everything is okay so far ***\\
+ this.log("[%s] eWeLink devices loaded from the Homebridge cache.", this.devicesInHB.size);
+ this.log("[%s] primary devices loaded from your eWeLink account.", this.devicesInEW.size);
+ //*** Remove Homebridge accessories that don't appear in eWeLink ***\\
+ this.devicesInHB.forEach(a => {
+ if (!this.devicesInEW.has(a.context.eweDeviceId)) {
+ this.removeAccessory(a);
}
- //*** Logging always helps to see if everything is okay so far ***\\
- this.log("[%s] eWeLink devices loaded from the Homebridge cache.", this.devicesInHB.size);
- this.log("[%s] primary devices loaded from your eWeLink account.", this.devicesInEW.size);
- //*** Remove Homebridge accessories that don't appear in eWeLink ***\\
- this.devicesInHB.forEach(a => {
- if (!this.devicesInEW.has(a.context.eweDeviceId)) {
- this.removeAccessory(a);
+ });
+ //*** Synchronise devices between eWeLink and Homebridge and set up ws/lan listeners ***\\
+ this.devicesInEW.forEach(d => this.initialiseDevice(d));
+ this.wsClient.receiveUpdate(d => this.receiveDeviceUpdate(d));
+ this.lanClient.receiveUpdate(d => this.receiveDeviceUpdate(d));
+ this.wsRefresh = promInterval(
+ async () => {
+ if (this.wsRefreshFlag) {
+ try {
+ if (this.wsClient) {
+ await this.wsClient.getHost();
+ await this.wsClient.closeConnection();
+ await utils.sleep(250);
+ await this.wsClient.login();
+ }
+ } catch (err) {
+ this.log.warn(err);
+ }
}
- });
- //*** Synchronise devices between eWeLink and Homebridge and set up ws/lan listeners ***\\
- this.devicesInEW.forEach(d => this.initialiseDevice(d));
- this.wsClient.receiveUpdate(d => this.receiveDeviceUpdate(d));
- this.lanClient.receiveUpdate(d => this.receiveDeviceUpdate(d));
- this.log("eWeLink sync complete. Don't forget to âī¸ this plugin on GitHub!");
- if (this.config.debugReqRes || false) {
- this.log.warn("Note: 'Request & Response Logging' is not advised for long-term use.");
+ },
+ 1800000,
+ {
+ stopOnError: false,
}
- })();
- })
- .catch(err => {
- this.log.error("************** Cannot load homebridge-ewelink **************");
- this.log.error(err);
- this.log.error("************************************************************");
- if (this.lanClient) this.lanClient.closeConnection();
- if (this.wsClient) this.wsClient.closeConnection();
- });
+ );
+ this.log("eWeLink sync complete. Don't forget to âī¸ this plugin on GitHub!");
+ if (this.config.debugReqRes || false) {
+ this.log.warn("Note: 'Request & Response Logging' is not advised for long-term use.");
+ }
+ })();
+ } catch (err) {
+ this.log.error("************** Cannot load homebridge-ewelink **************");
+ this.log.error(err);
+ this.log.error("************************************************************");
+ if (this.lanClient) this.lanClient.closeConnection();
+ if (this.wsClient) this.wsClient.closeConnection();
+ this.wsRefreshFlag = false;
+ }
}
initialiseDevice(device) {
let accessory;
@@ -664,22 +666,24 @@ class eWeLink {
this.internalThermostatUpdate(accessory, value, callback)
);
}
- accessory.log = this.log;
- accessory.eveLogger = new EveHistoryService("weather", accessory, {
- storage: "fs",
- minutes: 5,
- path: this.eveLogPath,
- });
- corrInterval.setCorrectingInterval(() => {
- let dataToAdd = {
- time: Date.now(),
- temp: tempService.getCharacteristic(Characteristic.CurrentTemperature).value,
- };
- if (humiService) {
- humiService.getCharacteristic(Characteristic.CurrentRelativeHumidity).value;
- }
- accessory.eveLogger.addEntry(dataToAdd);
- }, 300000);
+ if (!(this.config.disableEveLogging || false)) {
+ accessory.log = this.log;
+ accessory.eveLogger = new EveHistoryService("weather", accessory, {
+ storage: "fs",
+ minutes: 5,
+ path: this.eveLogPath,
+ });
+ corrInterval.setCorrectingInterval(() => {
+ let dataToAdd = {
+ time: Date.now(),
+ temp: tempService.getCharacteristic(Characteristic.CurrentTemperature).value,
+ };
+ if (humiService) {
+ humiService.getCharacteristic(Characteristic.CurrentRelativeHumidity).value;
+ }
+ accessory.eveLogger.addEntry(dataToAdd);
+ }, 300000);
+ }
break;
case "outlet":
let outletService;
@@ -1076,32 +1080,34 @@ class eWeLink {
}
}
sendDeviceUpdate(accessory, params) {
- return new Promise((resolve, reject) => {
+ return new Promise(async (resolve, reject) => {
let payload = {
- apikey: accessory.context.eweApiKey,
- deviceid: accessory.context.eweDeviceId,
- params,
- },
- delayPromise = new Promise(resolve => setTimeout(resolve, Math.random() * 100 + 200));
- delayPromise
- .then(() => this.lanClient.sendUpdate(payload))
- .then(() => resolve())
- .catch(err => {
- if (accessory.context.reachableWAN) {
- if (this.debug) {
- this.log.warn("[%s] Reverting to web socket as %s.", accessory.displayName, err);
- }
- this.wsClient
- .sendUpdate(payload)
- .then(() => resolve())
- .catch(err => reject(err));
- } else {
- reject("it is unreachable. I's status will be corrected once it is reachable");
+ apikey: accessory.context.eweApiKey,
+ deviceid: accessory.context.eweDeviceId,
+ params,
+ };
+ try {
+ await utils.sleep(Math.random() * 100 + 200);
+ await this.lanClient.sendUpdate(payload);
+ resolve();
+ } catch (err) {
+ if (accessory.context.reachableWAN) {
+ if (this.debug) {
+ this.log.warn("[%s] Reverting to web socket as %s.", accessory.displayName, err);
}
- });
+ try {
+ await this.wsClient.sendUpdate(payload);
+ resolve();
+ } catch (err) {
+ reject(err);
+ }
+ } else {
+ reject("it is unreachable. I's status will be corrected once it is reachable");
+ }
+ }
});
}
- receiveDeviceUpdate(device) {
+ async receiveDeviceUpdate(device) {
let accessory,
deviceId = device.deviceid,
reachableChange = false;
@@ -1167,33 +1173,33 @@ class eWeLink {
deviceId,
device.params.updateSource
);
- this.httpClient
- .getDevice(deviceId)
- .then(device => {
- this.initialiseDevice(device);
- this.lanClient.addDeviceToMap(device);
- })
- .catch(err => {
- this.log.error("[%s] error getting info [%s]", deviceId, err);
- this.log.error(
- "[%s] Please try restarting Homebridge so this device is added.",
- deviceId
- );
- });
+ try {
+ let device = await this.httpClient.getDevice(deviceId);
+ this.initialiseDevice(device);
+ this.lanClient.addDeviceToMap(device);
+ } catch (err) {
+ this.log.error("[%s] error getting info [%s]", deviceId, err);
+ this.log.error(
+ "[%s] Please try restarting Homebridge so this device is added.",
+ deviceId
+ );
+ }
}
}
}
- requestDeviceRefresh(accessory, err) {
+ async requestDeviceRefresh(accessory, err) {
this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
if (accessory.context.reachableWAN) {
- this.wsClient.requestUpdate(accessory).catch(() => {});
- this.log.warn(
- "[%s] requesting previous state to revert Homebridge status.",
- accessory.displayName
- );
+ try {
+ await this.wsClient.requestUpdate(accessory);
+ this.log.warn(
+ "[%s] requesting previous state to revert Homebridge status.",
+ accessory.displayName
+ );
+ } catch (err) {}
}
}
- internalValveUpdate(accessory, valve, value, callback) {
+ async internalValveUpdate(accessory, valve, value, callback) {
callback();
try {
let params = {},
@@ -1219,27 +1225,24 @@ class eWeLink {
}
params.switches[2].switch = "off";
params.switches[3].switch = "off";
- this.sendDeviceUpdate(accessory, params)
- .then(() => {
- serviceValve
- .updateCharacteristic(Characteristic.Active, value)
- .updateCharacteristic(Characteristic.InUse, value);
- switch (value) {
- case 0:
- serviceValve.updateCharacteristic(Characteristic.RemainingDuration, 0);
- clearTimeout(accessory.getService(valve).timer);
- break;
- case 1:
- let timer = serviceValve.getCharacteristic(Characteristic.SetDuration).value;
- serviceValve.updateCharacteristic(Characteristic.RemainingDuration, timer);
- serviceValve.timer = setTimeout(
- () => serviceValve.setCharacteristic(Characteristic.Active, 0),
- timer * 1000
- );
- break;
- }
- })
- .catch(err => this.requestDeviceRefresh(accessory, err));
+ await this.sendDeviceUpdate(accessory, params);
+ serviceValve
+ .updateCharacteristic(Characteristic.Active, value)
+ .updateCharacteristic(Characteristic.InUse, value);
+ switch (value) {
+ case 0:
+ serviceValve.updateCharacteristic(Characteristic.RemainingDuration, 0);
+ clearTimeout(accessory.getService(valve).timer);
+ break;
+ case 1:
+ let timer = serviceValve.getCharacteristic(Characteristic.SetDuration).value;
+ serviceValve.updateCharacteristic(Characteristic.RemainingDuration, timer);
+ serviceValve.timer = setTimeout(
+ () => serviceValve.setCharacteristic(Characteristic.Active, 0),
+ timer * 1000
+ );
+ break;
+ }
} catch (err) {
this.requestDeviceRefresh(accessory, err);
}
@@ -1266,7 +1269,7 @@ class eWeLink {
this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
- internalCurtainUpdate(accessory, value, callback) {
+ async internalCurtainUpdate(accessory, value, callback) {
callback();
try {
let params,
@@ -1283,14 +1286,11 @@ class eWeLink {
setclose: Math.abs(100 - newPos),
};
}
- this.sendDeviceUpdate(accessory, params)
- .then(() => {
- cService
- .updateCharacteristic(Characteristic.TargetPosition, newPos)
- .updateCharacteristic(Characteristic.PositionState, newPos > prevPos ? 1 : 0);
- accessory.context.cacheCurrentPosition = newPos;
- })
- .catch(err => this.requestDeviceRefresh(accessory, err));
+ await this.sendDeviceUpdate(accessory, params);
+ cService
+ .updateCharacteristic(Characteristic.TargetPosition, newPos)
+ .updateCharacteristic(Characteristic.PositionState, newPos > prevPos ? 1 : 0);
+ accessory.context.cacheCurrentPosition = newPos;
} catch (err) {
this.requestDeviceRefresh(accessory, err);
}
@@ -1311,7 +1311,7 @@ class eWeLink {
this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
- internalBlindUpdate(accessory, value, callback) {
+ async internalBlindUpdate(accessory, value, callback) {
callback();
try {
let blindConfig,
@@ -1346,7 +1346,6 @@ class eWeLink {
outlet: 3,
},
];
- let logger = str => this.log.warn("[%s] %s.", accessory.displayName, str);
accessory.context.inUse = true;
if (prevState !== 2) {
this.log.warn(
@@ -1368,25 +1367,18 @@ class eWeLink {
accessory.context.targetTimestamp = timeNow + duration;
params.switches[0].switch = moveUp ? "on" : "off";
params.switches[1].switch = moveUp ? "off" : "on";
- this.sendDeviceUpdate(accessory, params)
- .then(() => {
- wcService.updateCharacteristic(Characteristic.PositionState, moveUp ? 0 : 1);
- accessory.context.cachePositionState = moveUp ? 0 : 1;
- return new Promise(resolve => setTimeout(resolve, duration));
- })
- .then(() => {
- params.switches[0].switch = "off";
- params.switches[1].switch = "off";
- return this.sendDeviceUpdate(accessory, params);
- })
- .then(() => {
- wcService.updateCharacteristic(Characteristic.PositionState, 2);
- wcService.updateCharacteristic(Characteristic.CurrentPosition, newTarget);
- accessory.context.cacheCurrentPosition = newTarget;
- accessory.context.cachePositionState = 2;
- accessory.context.inUse = false;
- })
- .catch(err => this.requestDeviceRefresh(accessory, err));
+ await this.sendDeviceUpdate(accessory, params);
+ wcService.updateCharacteristic(Characteristic.PositionState, moveUp ? 0 : 1);
+ accessory.context.cachePositionState = moveUp ? 0 : 1;
+ await utils.sleep(duration);
+ params.switches[0].switch = "off";
+ params.switches[1].switch = "off";
+ await this.sendDeviceUpdate(accessory, params);
+ wcService.updateCharacteristic(Characteristic.PositionState, 2);
+ wcService.updateCharacteristic(Characteristic.CurrentPosition, newTarget);
+ accessory.context.cacheCurrentPosition = newTarget;
+ accessory.context.cachePositionState = 2;
+ accessory.context.inUse = false;
} catch (err) {
this.requestDeviceRefresh(accessory, err);
}
@@ -1438,7 +1430,7 @@ class eWeLink {
this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
- internalGarageUpdate(accessory, value, callback) {
+ async internalGarageUpdate(accessory, value, callback) {
callback();
try {
let garageConfig;
@@ -1480,38 +1472,29 @@ class eWeLink {
delay = 1500;
}
if (accessory.context.state !== newPos) return;
- let delayPromise = new Promise(resolve => setTimeout(resolve, delay));
- delayPromise
- .then(() => {
- gdService
- .updateCharacteristic(Characteristic.TargetDoorState, newPos)
- .updateCharacteristic(Characteristic.CurrentDoorState, newPos + 2);
- accessory.context.cacheTargetDoorState = newPos;
- accessory.context.cacheCurrentDoorState = newPos + 2;
- switch (garageConfig.setup) {
- case "oneSwitch":
- params.switch = "on";
- break;
- case "twoSwitch":
- params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
- params.switches[0].switch = newPos === 0 ? "on" : "off";
- params.switches[1].switch = newPos === 1 ? "on" : "off";
- break;
- }
- return this.sendDeviceUpdate(accessory, params);
- })
- .then(
- () =>
- new Promise(resolve => setTimeout(resolve, parseInt(garageConfig.operationTime) * 100))
- )
- .then(() => {
- if (!sAccessory) {
- gdService.updateCharacteristic(Characteristic.CurrentDoorState, newPos);
- accessory.context.cacheCurrentDoorState = newPos;
- }
- accessory.context.inUse = false;
- })
- .catch(err => this.requestDeviceRefresh(accessory, err));
+ await utils.sleep(delay);
+ gdService
+ .updateCharacteristic(Characteristic.TargetDoorState, newPos)
+ .updateCharacteristic(Characteristic.CurrentDoorState, newPos + 2);
+ accessory.context.cacheTargetDoorState = newPos;
+ accessory.context.cacheCurrentDoorState = newPos + 2;
+ switch (garageConfig.setup) {
+ case "oneSwitch":
+ params.switch = "on";
+ break;
+ case "twoSwitch":
+ params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
+ params.switches[0].switch = newPos === 0 ? "on" : "off";
+ params.switches[1].switch = newPos === 1 ? "on" : "off";
+ break;
+ }
+ await this.sendDeviceUpdate(accessory, params);
+ await utils.sleep(garageConfig.operationTime * 100);
+ if (!sAccessory) {
+ gdService.updateCharacteristic(Characteristic.CurrentDoorState, newPos);
+ accessory.context.cacheCurrentDoorState = newPos;
+ }
+ accessory.context.inUse = false;
} catch (err) {
this.requestDeviceRefresh(accessory, err);
}
@@ -1569,7 +1552,7 @@ class eWeLink {
this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
- internalLockUpdate(accessory, value, callback) {
+ async internalLockUpdate(accessory, value, callback) {
callback();
try {
let lockConfig,
@@ -1584,19 +1567,15 @@ class eWeLink {
throw "improper configuration";
}
accessory.context.inUse = true;
- this.sendDeviceUpdate(accessory, params)
- .then(() => {
- lmService
- .updateCharacteristic(Characteristic.LockTargetState, 0)
- .updateCharacteristic(Characteristic.LockCurrentState, 0);
- setTimeout(() => {
- lmService
- .updateCharacteristic(Characteristic.LockTargetState, 1)
- .updateCharacteristic(Characteristic.LockCurrentState, 1);
- accessory.context.inUse = false;
- }, parseInt(lockConfig.operationTime) * 100);
- })
- .catch(err => this.requestDeviceRefresh(accessory, err));
+ await this.sendDeviceUpdate(accessory, params);
+ lmService
+ .updateCharacteristic(Characteristic.LockTargetState, 0)
+ .updateCharacteristic(Characteristic.LockCurrentState, 0);
+ await utils.sleep(lockConfig.operationTime * 100);
+ lmService
+ .updateCharacteristic(Characteristic.LockTargetState, 1)
+ .updateCharacteristic(Characteristic.LockCurrentState, 1);
+ accessory.context.inUse = false;
} catch (err) {
this.requestDeviceRefresh(accessory, err);
}
@@ -1674,7 +1653,7 @@ class eWeLink {
this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
- internalFanUpdate(accessory, type, value, callback) {
+ async internalFanUpdate(accessory, type, value, callback) {
callback();
try {
let newPower,
@@ -1706,14 +1685,11 @@ class eWeLink {
params.switches[1].switch = newPower === 1 && newSpeed >= 33 ? "on" : "off";
params.switches[2].switch = newPower === 1 && newSpeed >= 66 && newSpeed < 99 ? "on" : "off";
params.switches[3].switch = newPower === 1 && newSpeed >= 99 ? "on" : "off";
- this.sendDeviceUpdate(accessory, params)
- .then(() => {
- lightService.updateCharacteristic(Characteristic.On, newLight);
- fanService
- .updateCharacteristic(Characteristic.Active, newPower)
- .updateCharacteristic(Characteristic.RotationSpeed, newSpeed);
- })
- .catch(err => this.requestDeviceRefresh(accessory, err));
+ await this.sendDeviceUpdate(accessory, params);
+ lightService.updateCharacteristic(Characteristic.On, newLight);
+ fanService
+ .updateCharacteristic(Characteristic.Active, newPower)
+ .updateCharacteristic(Characteristic.RotationSpeed, newSpeed);
} catch (err) {
this.requestDeviceRefresh(accessory, err);
}
@@ -1763,7 +1739,7 @@ class eWeLink {
this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
- internalThermostatUpdate(accessory, value, callback) {
+ async internalThermostatUpdate(accessory, value, callback) {
callback();
try {
let params = {
@@ -1771,11 +1747,8 @@ class eWeLink {
mainSwitch: value ? "on" : "off",
},
switchService = accessory.getService(Service.Switch);
- this.sendDeviceUpdate(accessory, params)
- .then(() => {
- switchService.updateCharacteristic(Characteristic.On, value);
- })
- .catch(err => this.requestDeviceRefresh(accessory, err));
+ await this.sendDeviceUpdate(accessory, params);
+ switchService.updateCharacteristic(Characteristic.On, value);
} catch (err) {
this.requestDeviceRefresh(accessory, err);
}
@@ -1792,49 +1765,48 @@ class eWeLink {
switchService = accessory.getService(Service.Switch);
switchService.updateCharacteristic(Characteristic.On, newState);
}
- let eveLog = {
- time: Date.now(),
- };
- if (
- params.hasOwnProperty("currentTemperature") &&
- accessory.getService(Service.TemperatureSensor)
- ) {
- let currentTemp =
- params.currentTemperature !== "unavailable" ? params.currentTemperature : 0;
- accessory
- .getService(Service.TemperatureSensor)
- .updateCharacteristic(Characteristic.CurrentTemperature, currentTemp);
- eveLog.temp = parseFloat(currentTemp);
- }
- if (
- params.hasOwnProperty("currentHumidity") &&
- accessory.getService(Service.HumiditySensor)
- ) {
- let currentHumi = params.currentHumidity !== "unavailable" ? params.currentHumidity : 0;
- accessory
- .getService(Service.HumiditySensor)
- .updateCharacteristic(Characteristic.CurrentRelativeHumidity, currentHumi);
- eveLog.humidity = parseFloat(currentHumi);
- }
- if (eveLog.hasOwnProperty("temp") || eveLog.hasOwnProperty("humidity")) {
- accessory.eveLogger.addEntry(eveLog);
+ if (!(this.config.disableEveLogging || false)) {
+ let eveLog = {
+ time: Date.now(),
+ };
+ if (
+ params.hasOwnProperty("currentTemperature") &&
+ accessory.getService(Service.TemperatureSensor)
+ ) {
+ let currentTemp =
+ params.currentTemperature !== "unavailable" ? params.currentTemperature : 0;
+ accessory
+ .getService(Service.TemperatureSensor)
+ .updateCharacteristic(Characteristic.CurrentTemperature, currentTemp);
+ eveLog.temp = parseFloat(currentTemp);
+ }
+ if (
+ params.hasOwnProperty("currentHumidity") &&
+ accessory.getService(Service.HumiditySensor)
+ ) {
+ let currentHumi = params.currentHumidity !== "unavailable" ? params.currentHumidity : 0;
+ accessory
+ .getService(Service.HumiditySensor)
+ .updateCharacteristic(Characteristic.CurrentRelativeHumidity, currentHumi);
+ eveLog.humidity = parseFloat(currentHumi);
+ }
+ if (eveLog.hasOwnProperty("temp") || eveLog.hasOwnProperty("humidity")) {
+ accessory.eveLogger.addEntry(eveLog);
+ }
}
} catch (err) {
this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
- internalOutletUpdate(accessory, value, callback) {
+ async internalOutletUpdate(accessory, value, callback) {
callback();
try {
let params = {
switch: value ? "on" : "off",
},
outletService = accessory.getService(Service.Outlet);
- this.sendDeviceUpdate(accessory, params)
- .then(() => {
- outletService.updateCharacteristic(Characteristic.On, value);
- })
- .catch(err => this.requestDeviceRefresh(accessory, err));
+ await this.sendDeviceUpdate(accessory, params);
+ outletService.updateCharacteristic(Characteristic.On, value);
} catch (err) {
this.requestDeviceRefresh(accessory, err);
}
@@ -1879,7 +1851,7 @@ class eWeLink {
this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
- internalUSBUpdate(accessory, value, callback) {
+ async internalUSBUpdate(accessory, value, callback) {
callback();
try {
let params = {
@@ -1887,11 +1859,8 @@ class eWeLink {
},
outletService = accessory.getService(Service.Outlet);
params.switches[0].switch = value ? "on" : "off";
- this.sendDeviceUpdate(accessory, params)
- .then(() => {
- outletService.updateCharacteristic(Characteristic.On, value);
- })
- .catch(err => this.requestDeviceRefresh(accessory, err));
+ await this.sendDeviceUpdate(accessory, params);
+ outletService.updateCharacteristic(Characteristic.On, value);
} catch (err) {
this.requestDeviceRefresh(accessory, err);
}
@@ -1905,7 +1874,7 @@ class eWeLink {
this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
- internalSCMUpdate(accessory, value, callback) {
+ async internalSCMUpdate(accessory, value, callback) {
callback();
try {
let params = {
@@ -1913,11 +1882,8 @@ class eWeLink {
},
switchService = accessory.getService(Service.Switch);
params.switches[0].switch = value ? "on" : "off";
- this.sendDeviceUpdate(accessory, params)
- .then(() => {
- switchService.updateCharacteristic(Characteristic.On, value);
- })
- .catch(err => this.requestDeviceRefresh(accessory, err));
+ await this.sendDeviceUpdate(accessory, params);
+ switchService.updateCharacteristic(Characteristic.On, value);
} catch (err) {
this.requestDeviceRefresh(accessory, err);
}
@@ -1931,7 +1897,7 @@ class eWeLink {
this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
- internalLightbulbUpdate(accessory, value, callback) {
+ async internalLightbulbUpdate(accessory, value, callback) {
callback();
try {
let oAccessory,
@@ -1973,52 +1939,48 @@ class eWeLink {
}
break;
}
- this.sendDeviceUpdate(accessory, params)
- .then(() => {
- switch (accessory.context.switchNumber) {
- case "X":
- lightService.updateCharacteristic(Characteristic.On, value);
- break;
- case "0":
- for (let i = 0; i <= 4; i++) {
- if ((oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
- oAccessory
- .getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.On, value);
- }
- }
- break;
- case "1":
- case "2":
- case "3":
- case "4":
- lightService.updateCharacteristic(Characteristic.On, value);
- let masterState = "off";
- for (let i = 1; i <= 4; i++) {
- if ((oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
- if (
- oAccessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On)
- .value
- ) {
- masterState = "on";
- }
- }
- }
- if (!this.hiddenMasters.includes(accessory.context.eweDeviceId)) {
- oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
- oAccessory
- .getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.On, masterState === "on");
+ await this.sendDeviceUpdate(accessory, params);
+ switch (accessory.context.switchNumber) {
+ case "X":
+ lightService.updateCharacteristic(Characteristic.On, value);
+ break;
+ case "0":
+ for (let i = 0; i <= 4; i++) {
+ if ((oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
+ oAccessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.On, value);
+ }
+ }
+ break;
+ case "1":
+ case "2":
+ case "3":
+ case "4":
+ lightService.updateCharacteristic(Characteristic.On, value);
+ let masterState = "off";
+ for (let i = 1; i <= 4; i++) {
+ if ((oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
+ if (
+ oAccessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value
+ ) {
+ masterState = "on";
}
- break;
+ }
+ }
+ if (!this.hiddenMasters.includes(accessory.context.eweDeviceId)) {
+ oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
+ oAccessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.On, masterState === "on");
}
- })
- .catch(err => this.requestDeviceRefresh(accessory, err));
+ break;
+ }
} catch (err) {
this.requestDeviceRefresh(accessory, err);
}
}
- internalBrightnessUpdate(accessory, value, callback) {
+ async internalBrightnessUpdate(accessory, value, callback) {
callback();
try {
let params = {},
@@ -2039,22 +2001,18 @@ class eWeLink {
break;
}
}
- let delayPromise = new Promise(resolve => setTimeout(resolve, 250));
- delayPromise
- .then(() => this.sendDeviceUpdate(accessory, params))
- .then(() => {
- if (value === 0) {
- lightService.updateCharacteristic(Characteristic.On, false);
- } else {
- lightService.updateCharacteristic(Characteristic.Brightness, value);
- }
- })
- .catch(err => this.requestDeviceRefresh(accessory, err));
+ await utils.sleep(250);
+ await this.sendDeviceUpdate(accessory, params);
+ if (value === 0) {
+ lightService.updateCharacteristic(Characteristic.On, false);
+ } else {
+ lightService.updateCharacteristic(Characteristic.Brightness, value);
+ }
} catch (err) {
this.requestDeviceRefresh(accessory, err);
}
}
- internalHSBUpdate(accessory, type, value, callback) {
+ async internalHSBUpdate(accessory, type, value, callback) {
callback();
try {
if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
@@ -2113,20 +2071,16 @@ class eWeLink {
}
break;
}
- let delayPromise = new Promise(resolve => setTimeout(resolve, 250));
- delayPromise
- .then(() => this.sendDeviceUpdate(accessory, params))
- .then(() => {
- switch (type) {
- case "hue":
- lightService.updateCharacteristic(Characteristic.Hue, value);
- break;
- case "bri":
- lightService.updateCharacteristic(Characteristic.Brightness, value);
- break;
- }
- })
- .catch(err => this.requestDeviceRefresh(accessory, err));
+ await utils.sleep(250);
+ await this.sendDeviceUpdate(accessory, params);
+ switch (type) {
+ case "hue":
+ lightService.updateCharacteristic(Characteristic.Hue, value);
+ break;
+ case "bri":
+ lightService.updateCharacteristic(Characteristic.Brightness, value);
+ break;
+ }
} catch (err) {
this.requestDeviceRefresh(accessory, err);
}
@@ -2229,7 +2183,7 @@ class eWeLink {
this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
- internalSwitchUpdate(accessory, value, callback) {
+ async internalSwitchUpdate(accessory, value, callback) {
callback();
try {
let oAccessory,
@@ -2266,46 +2220,41 @@ class eWeLink {
}
break;
}
- this.sendDeviceUpdate(accessory, params)
- .then(() => {
- switch (accessory.context.switchNumber) {
- case "X":
- switchService.updateCharacteristic(Characteristic.On, value);
- break;
- case "0":
- for (let i = 0; i <= 4; i++) {
- if ((oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
- oAccessory
- .getService(Service.Switch)
- .updateCharacteristic(Characteristic.On, value);
- }
- }
- break;
- case "1":
- case "2":
- case "3":
- case "4":
- switchService.updateCharacteristic(Characteristic.On, value);
- let masterState = "off";
- for (let i = 1; i <= 4; i++) {
- if ((oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
- if (
- oAccessory.getService(Service.Switch).getCharacteristic(Characteristic.On).value
- ) {
- masterState = "on";
- }
- }
- }
- if (!this.hiddenMasters.includes(accessory.context.eweDeviceId)) {
- oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
- oAccessory
- .getService(Service.Switch)
- .updateCharacteristic(Characteristic.On, masterState === "on");
+ await this.sendDeviceUpdate(accessory, params);
+ switch (accessory.context.switchNumber) {
+ case "X":
+ switchService.updateCharacteristic(Characteristic.On, value);
+ break;
+ case "0":
+ for (let i = 0; i <= 4; i++) {
+ if ((oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
+ oAccessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
+ }
+ }
+ break;
+ case "1":
+ case "2":
+ case "3":
+ case "4":
+ switchService.updateCharacteristic(Characteristic.On, value);
+ let masterState = "off";
+ for (let i = 1; i <= 4; i++) {
+ if ((oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
+ if (
+ oAccessory.getService(Service.Switch).getCharacteristic(Characteristic.On).value
+ ) {
+ masterState = "on";
}
- break;
+ }
+ }
+ if (!this.hiddenMasters.includes(accessory.context.eweDeviceId)) {
+ oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
+ oAccessory
+ .getService(Service.Switch)
+ .updateCharacteristic(Characteristic.On, masterState === "on");
}
- })
- .catch(err => this.requestDeviceRefresh(accessory, err));
+ break;
+ }
} catch (err) {
this.requestDeviceRefresh(accessory, err);
}
@@ -2341,7 +2290,7 @@ class eWeLink {
this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
}
- internalRFUpdate(accessory, rfChl, service, callback) {
+ async internalRFUpdate(accessory, rfChl, service, callback) {
callback();
try {
let params = {
@@ -2349,12 +2298,10 @@ class eWeLink {
rfChl: parseInt(rfChl),
},
rfService = accessory.getService(service);
- this.sendDeviceUpdate(accessory, params)
- .then(() => {
- rfService.updateCharacteristic(Characteristic.On, true);
- setTimeout(() => rfService.updateCharacteristic(Characteristic.On, false), 3000);
- })
- .catch(err => this.requestDeviceRefresh(accessory, err));
+ await this.sendDeviceUpdate(accessory, params);
+ rfService.updateCharacteristic(Characteristic.On, true);
+ await utils.sleep(3000);
+ rfService.updateCharacteristic(Characteristic.On, false);
} catch (err) {
this.requestDeviceRefresh(accessory, err);
}
diff --git a/lib/eWeLinkHTTP.js b/lib/eWeLinkHTTP.js
index 36d099cf..4076d982 100644
--- a/lib/eWeLinkHTTP.js
+++ b/lib/eWeLinkHTTP.js
@@ -2,7 +2,8 @@
"use strict";
const axios = require("axios"),
constants = require("./constants"),
- crypto = require("crypto");
+ crypto = require("crypto"),
+ utils = require("./utils");
module.exports = class eWeLinkHTTP {
constructor(config, log) {
this.log = log;
@@ -14,7 +15,7 @@ module.exports = class eWeLinkHTTP {
this.cCode = "+" + config.countryCode.toString().replace("+", "").replace(" ", "");
}
getHost() {
- return new Promise((resolve, reject) => {
+ return new Promise(async (resolve, reject) => {
let params = {
appid: constants.appId,
country_code: this.cCode,
@@ -23,92 +24,91 @@ module.exports = class eWeLinkHTTP {
version: 8,
},
dataToSign = [];
- Object.keys(params).forEach(k => {
- dataToSign.push({
- key: k,
- value: params.k,
+ try {
+ Object.keys(params).forEach(k => {
+ dataToSign.push({
+ key: k,
+ value: params.k,
+ });
});
- });
- dataToSign.sort((a, b) => (a.key < b.key ? -1 : 1));
- dataToSign = dataToSign.map(k => k.key + "=" + k.value).join("&");
- dataToSign = crypto
- .createHmac("sha256", constants.appSecret)
- .update(dataToSign)
- .digest("base64");
- if (this.debugReqRes) {
- this.log.warn(
- "Sending HTTP getHost request. This text is yellow for clarity.\n%s",
- JSON.stringify(params, null, 2)
- );
- } else if (this.debug) {
- this.log("Sending HTTP getHost request.");
- }
- axios
- .get("https://api.coolkit.cc:8080/api/user/region", {
+ dataToSign.sort((a, b) => (a.key < b.key ? -1 : 1));
+ dataToSign = dataToSign.map(k => k.key + "=" + k.value).join("&");
+ dataToSign = crypto
+ .createHmac("sha256", constants.appSecret)
+ .update(dataToSign)
+ .digest("base64");
+ if (this.debugReqRes) {
+ this.log.warn(
+ "Sending HTTP getHost request. This text is yellow for clarity.\n%s",
+ JSON.stringify(params, null, 2)
+ );
+ } else if (this.debug) {
+ this.log("Sending HTTP getHost request.");
+ }
+ let res = await axios.get("https://api.coolkit.cc:8080/api/user/region", {
headers: {
Authorization: "Sign " + dataToSign,
"Content-Type": "application/json",
},
params,
- })
- .then(res => {
- let body = res.data;
- if (!body.region) {
- throw "Server did not respond with a region.\n" + JSON.stringify(body, null, 2);
- }
- switch (body.region) {
- case "eu":
- case "us":
- case "as":
- this.httpHost = body.region + "-apia.coolkit.cc";
- break;
- case "cn":
- this.httpHost = "cn-apia.coolkit.cn";
- break;
- default:
- throw "No valid region received - [" + body.region + "].";
- }
- if (this.debug) {
- this.log("HTTP API host received [%s].", this.httpHost);
- }
- resolve(this.httpHost);
- })
- .catch(err => {
- if (
- err.hasOwnProperty("code") &&
- ["ENOTFOUND", "ETIMEDOUT", "EAI_AGAIN"].includes(err.code)
- ) {
- this.log.warn("Unable to reach eWeLink. Retrying in 30 seconds.");
- this.delay().then(() => resolve(this.getHost()));
- } else {
- reject(err.message || err);
- }
});
+ let body = res.data;
+ if (!body.region) {
+ throw "Server did not respond with a region.\n" + JSON.stringify(body, null, 2);
+ }
+ switch (body.region) {
+ case "eu":
+ case "us":
+ case "as":
+ this.httpHost = body.region + "-apia.coolkit.cc";
+ break;
+ case "cn":
+ this.httpHost = "cn-apia.coolkit.cn";
+ break;
+ default:
+ throw "No valid region received - [" + body.region + "].";
+ }
+ if (this.debug) {
+ this.log("HTTP API host received [%s].", this.httpHost);
+ }
+ resolve(this.httpHost);
+ } catch (err) {
+ if (
+ err.hasOwnProperty("code") &&
+ ["ENOTFOUND", "ETIMEDOUT", "EAI_AGAIN"].includes(err.code)
+ ) {
+ this.log.warn("Unable to reach eWeLink. Retrying in 30 seconds.");
+ await utils.sleep(30000);
+ resolve(this.getHost());
+ } else {
+ reject(err.message || err);
+ }
+ }
});
}
login() {
- return new Promise((resolve, reject) => {
+ return new Promise(async (resolve, reject) => {
let data = {
countryCode: this.cCode,
password: this.password,
};
- this.username.includes("@")
- ? (data.email = this.username)
- : (data.phoneNumber = this.username);
- if (this.debugReqRes) {
- let msg = JSON.stringify(data, null, 2)
- .replace(this.password, "**hidden**")
- .replace(this.username, "**hidden**");
- this.log.warn("Sending HTTP login request. This text is yellow for clarity.\n%s", msg);
- } else if (this.debug) {
- this.log("Sending HTTP login request.");
- }
- let dataToSign = crypto
- .createHmac("sha256", constants.appSecret)
- .update(JSON.stringify(data))
- .digest("base64");
- axios
- .post("https://" + this.httpHost + "/v2/user/login", data, {
+ try {
+ this.username.includes("@")
+ ? (data.email = this.username)
+ : (data.phoneNumber = this.username);
+ if (this.debugReqRes) {
+ let msg = JSON.stringify(data, null, 2)
+ .replace(this.password, "**hidden**")
+ .replace(this.username, "**hidden**");
+ this.log.warn("Sending HTTP login request. This text is yellow for clarity.\n%s", msg);
+ } else if (this.debug) {
+ this.log("Sending HTTP login request.");
+ }
+ let dataToSign = crypto
+ .createHmac("sha256", constants.appSecret)
+ .update(JSON.stringify(data))
+ .digest("base64");
+ let res = await axios.post("https://" + this.httpHost + "/v2/user/login", data, {
headers: {
Authorization: "Sign " + dataToSign,
"Content-Type": "application/json",
@@ -116,58 +116,59 @@ module.exports = class eWeLinkHTTP {
"X-CK-Appid": constants.appId,
"X-CK-Nonce": Math.random().toString(36).substr(2, 8),
},
- })
- .then(res => {
- let body = res.data;
- if (
- body.hasOwnProperty("error") &&
- body.error === 10004 &&
- body.hasOwnProperty("data") &&
- body.data.hasOwnProperty("region")
- ) {
- let givenRegion = body.data.region;
- switch (givenRegion) {
- case "eu":
- case "us":
- case "as":
- this.httpHost = givenRegion + "-apia.coolkit.cc";
- break;
- case "cn":
- this.httpHost = "cn-apia.coolkit.cn";
- break;
- default:
- throw "No valid region received - [" + givenRegion + "].";
- }
- if (this.debug) {
- this.log("New HTTP API host received [%s].", this.httpHost);
- }
- resolve(this.login());
- return;
+ });
+ let body = res.data;
+ if (
+ body.hasOwnProperty("error") &&
+ body.error === 10004 &&
+ body.hasOwnProperty("data") &&
+ body.data.hasOwnProperty("region")
+ ) {
+ let givenRegion = body.data.region;
+ switch (givenRegion) {
+ case "eu":
+ case "us":
+ case "as":
+ this.httpHost = givenRegion + "-apia.coolkit.cc";
+ break;
+ case "cn":
+ this.httpHost = "cn-apia.coolkit.cn";
+ break;
+ default:
+ throw "No valid region received - [" + givenRegion + "].";
+ }
+ if (this.debug) {
+ this.log("New HTTP API host received [%s].", this.httpHost);
}
- if (body.data.at) {
- this.aToken = body.data.at;
- this.apiKey = body.data.user.apikey;
- resolve({
- aToken: this.aToken,
- apiKey: this.apiKey,
- httpHost: this.httpHost,
- });
+ resolve(this.login());
+ return;
+ }
+ if (body.data.at) {
+ this.aToken = body.data.at;
+ this.apiKey = body.data.user.apikey;
+ resolve({
+ aToken: this.aToken,
+ apiKey: this.apiKey,
+ httpHost: this.httpHost,
+ });
+ } else {
+ if (body.error === 500) {
+ this.log.warn("An eWeLink error [500] occured. Retrying in 30 seconds.");
+ await utils.sleep(30000);
+ resolve(this.login());
} else {
- if (body.error === 500) {
- this.log.warn("An eWeLink error [500] occured. Retrying in 30 seconds.");
- this.delay().then(() => resolve(this.login()));
- } else {
- throw "No auth token received.\n" + JSON.stringify(body, null, 2);
- }
+ throw "No auth token received.\n" + JSON.stringify(body, null, 2);
}
- })
- .catch(err => reject(err.message || err));
+ }
+ } catch (err) {
+ reject(err.message || err);
+ }
});
}
getDevices() {
- return new Promise((resolve, reject) => {
- axios
- .get("https://" + this.httpHost + "/v2/device/thing", {
+ return new Promise(async (resolve, reject) => {
+ try {
+ let res = await axios.get("https://" + this.httpHost + "/v2/device/thing", {
headers: {
Authorization: "Bearer " + this.aToken,
"Content-Type": "application/json",
@@ -175,39 +176,38 @@ module.exports = class eWeLinkHTTP {
"X-CK-Appid": constants.appId,
"X-CK-Nonce": Math.random().toString(36).substr(2, 8),
},
- })
- .then(res => {
- let body = res.data;
- if (
- !body.hasOwnProperty("data") ||
- !body.hasOwnProperty("error") ||
- (body.hasOwnProperty("error") && body.error !== 0)
- ) {
- throw JSON.stringify(body, null, 2);
- }
- let deviceList = [];
- if (body.data.thingList && body.data.thingList.length > 0) {
- body.data.thingList.forEach(device => deviceList.push(device.itemData));
- }
- deviceList
- .filter(d => d.hasOwnProperty("extra") && d.extra.hasOwnProperty("uiid"))
- .filter(d => !this.hideDevFromHB.includes(d.deviceid));
- resolve(deviceList);
- })
- .catch(err => {
- if (err.hasOwnProperty("code") && ["ENOTFOUND", "ETIMEDOUT"].includes(err.code)) {
- this.log.warn("Unable to reach eWeLink. Retrying in 30 seconds.");
- this.delay().then(() => resolve(this.getDevices()));
- } else {
- reject(err.message || err);
- }
});
+ let body = res.data;
+ if (
+ !body.hasOwnProperty("data") ||
+ !body.hasOwnProperty("error") ||
+ (body.hasOwnProperty("error") && body.error !== 0)
+ ) {
+ throw JSON.stringify(body, null, 2);
+ }
+ let deviceList = [];
+ if (body.data.thingList && body.data.thingList.length > 0) {
+ body.data.thingList.forEach(device => deviceList.push(device.itemData));
+ }
+ deviceList
+ .filter(d => d.hasOwnProperty("extra") && d.extra.hasOwnProperty("uiid"))
+ .filter(d => !this.hideDevFromHB.includes(d.deviceid));
+ resolve(deviceList);
+ } catch (err) {
+ if (err.hasOwnProperty("code") && ["ENOTFOUND", "ETIMEDOUT"].includes(err.code)) {
+ this.log.warn("Unable to reach eWeLink. Retrying in 30 seconds.");
+ await utils.sleep(30000);
+ resolve(this.getDevices());
+ } else {
+ reject(err.message || err);
+ }
+ }
});
}
getDevice(deviceId) {
- return new Promise((resolve, reject) => {
- axios
- .post(
+ return new Promise(async (resolve, reject) => {
+ try {
+ let res = await axios.post(
"https://" + this.httpHost + "/v2/device/thing",
{
thingList: [
@@ -226,33 +226,29 @@ module.exports = class eWeLinkHTTP {
"X-CK-Nonce": Math.random().toString(36).substr(2, 8),
},
}
- )
- .then(res => {
- let body = res.data;
- if (
- !body.hasOwnProperty("data") ||
- !body.hasOwnProperty("error") ||
- (body.hasOwnProperty("error") && body.error !== 0)
- ) {
- throw JSON.stringify(body, null, 2);
- }
- if (body.data.thingList && body.data.thingList.length === 1) {
- resolve(body.data.thingList[0].itemData);
- } else {
- throw "device not found in eWeLink";
- }
- })
- .catch(err => {
- if (err.hasOwnProperty("code") && ["ENOTFOUND", "ETIMEDOUT"].includes(err.code)) {
- this.log.warn("Unable to reach eWeLink. Retrying in 30 seconds.");
- this.delay().then(() => resolve(this.getDevice(deviceId)));
- } else {
- reject(err.message || err);
- }
- });
+ );
+ let body = res.data;
+ if (
+ !body.hasOwnProperty("data") ||
+ !body.hasOwnProperty("error") ||
+ (body.hasOwnProperty("error") && body.error !== 0)
+ ) {
+ throw JSON.stringify(body, null, 2);
+ }
+ if (body.data.thingList && body.data.thingList.length === 1) {
+ resolve(body.data.thingList[0].itemData);
+ } else {
+ throw "device not found in eWeLink";
+ }
+ } catch (err) {
+ if (err.hasOwnProperty("code") && ["ENOTFOUND", "ETIMEDOUT"].includes(err.code)) {
+ this.log.warn("Unable to reach eWeLink. Retrying in 30 seconds.");
+ await utils.sleep(30000);
+ resolve(this.getDevice(deviceId));
+ } else {
+ reject(err.message || err);
+ }
+ }
});
}
- delay() {
- return new Promise(resolve => setTimeout(resolve, 30000));
- }
};
diff --git a/lib/eWeLinkLAN.js b/lib/eWeLinkLAN.js
index 09c6f749..b046db46 100644
--- a/lib/eWeLinkLAN.js
+++ b/lib/eWeLinkLAN.js
@@ -25,28 +25,28 @@ module.exports = class eWeLinkLAN {
this.emitter = new eventemitter();
}
getHosts() {
- return new Promise((resolve, reject) => {
- dns
- .discover({
+ return new Promise(async (resolve, reject) => {
+ try {
+ let res = await dns.discover({
name: "_ewelink._tcp.local",
- })
- .then(res => {
- res.forEach(device => {
- let d,
- deviceId = device.fqdn.replace("._ewelink._tcp.local", "").replace("eWeLink_", "");
- if ((d = this.deviceMap.get(deviceId))) {
- if (!this.ipOverrides.hasOwnProperty(deviceId)) {
- this.deviceMap.set(deviceId, {
- apiKey: d.apiKey,
- online: true,
- ip: device.address,
- });
- }
+ });
+ res.forEach(device => {
+ let d,
+ deviceId = device.fqdn.replace("._ewelink._tcp.local", "").replace("eWeLink_", "");
+ if ((d = this.deviceMap.get(deviceId))) {
+ if (!this.ipOverrides.hasOwnProperty(deviceId)) {
+ this.deviceMap.set(deviceId, {
+ apiKey: d.apiKey,
+ online: true,
+ ip: device.address,
+ });
}
- });
- resolve(this.deviceMap);
- })
- .catch(err => reject(err));
+ }
+ });
+ resolve(this.deviceMap);
+ } catch (err) {
+ reject(err);
+ }
});
}
startMonitor() {
@@ -115,70 +115,66 @@ module.exports = class eWeLinkLAN {
});
}
};
- return new Promise((resolve, reject) => {
- dns
- .startMonitoring()
- .then(() => resolve())
- .catch(err => reject(err));
- });
+ dns.startMonitoring();
}
sendUpdate(json) {
- return new Promise((resolve, reject) => {
- if (!this.deviceMap.get(json.deviceid).online) {
- throw "device isn't reachable via LAN mode";
- }
- let apiKey,
- suffix,
- params = {};
- if (json.params.hasOwnProperty("switches")) {
- params.switches = json.params.switches;
- suffix = "switches";
- } else if (json.params.hasOwnProperty("switch")) {
- params.switch = json.params.switch;
- suffix = "switch";
- } else {
- throw "device isn't reachable via LAN mode";
- }
- if ((apiKey = this.deviceMap.get(json.deviceid).apiKey)) {
- let key = crypto.createHash("md5").update(Buffer.from(apiKey, "utf8")).digest(),
- iv = crypto.randomBytes(16),
- enc = crypto.createCipheriv("aes-128-cbc", key, iv),
- data = {
- data: Buffer.concat([enc.update(JSON.stringify(params)), enc.final()]).toString(
- "base64"
- ),
- deviceid: json.deviceid,
- encrypt: true,
- iv: iv.toString("base64"),
- selfApikey: "123",
- sequence: Date.now().toString(),
- };
- if (this.debugReqRes) {
- let msg = JSON.stringify(json, null, 2)
- .replace(json.apikey, "**hidden**")
- .replace(json.apikey, "**hidden**")
- .replace(json.deviceid, "**hidden**");
- this.log.warn("LAN message sent. This text is yellow for clarity.\n%s", msg);
- } else if (this.debug) {
- this.log("LAN message sent.");
+ return new Promise(async (resolve, reject) => {
+ try {
+ if (!this.deviceMap.get(json.deviceid).online) {
+ throw "device isn't reachable via LAN mode";
}
- axios({
- method: "post",
- url: "http://" + this.deviceMap.get(json.deviceid).ip + ":8081/zeroconf/" + suffix,
- headers: {
- Accept: "application/json",
- "Content-Type": "application/json",
- },
- data,
- })
- .then(res => {
- if (res.data.hasOwnProperty("error") && res.data.error === 0) {
- resolve();
- } else {
- throw res.data;
- }
- })
- .catch(err => reject(err));
+ let apiKey,
+ suffix,
+ params = {};
+ if (json.params.hasOwnProperty("switches")) {
+ params.switches = json.params.switches;
+ suffix = "switches";
+ } else if (json.params.hasOwnProperty("switch")) {
+ params.switch = json.params.switch;
+ suffix = "switch";
+ } else {
+ throw "device isn't reachable via LAN mode";
+ }
+ if ((apiKey = this.deviceMap.get(json.deviceid).apiKey)) {
+ let key = crypto.createHash("md5").update(Buffer.from(apiKey, "utf8")).digest(),
+ iv = crypto.randomBytes(16),
+ enc = crypto.createCipheriv("aes-128-cbc", key, iv),
+ data = {
+ data: Buffer.concat([enc.update(JSON.stringify(params)), enc.final()]).toString(
+ "base64"
+ ),
+ deviceid: json.deviceid,
+ encrypt: true,
+ iv: iv.toString("base64"),
+ selfApikey: "123",
+ sequence: Date.now().toString(),
+ };
+ if (this.debugReqRes) {
+ let msg = JSON.stringify(json, null, 2)
+ .replace(json.apikey, "**hidden**")
+ .replace(json.apikey, "**hidden**")
+ .replace(json.deviceid, "**hidden**");
+ this.log.warn("LAN message sent. This text is yellow for clarity.\n%s", msg);
+ } else if (this.debug) {
+ this.log("LAN message sent.");
+ }
+ let res = await axios({
+ method: "post",
+ url: "http://" + this.deviceMap.get(json.deviceid).ip + ":8081/zeroconf/" + suffix,
+ headers: {
+ Accept: "application/json",
+ "Content-Type": "application/json",
+ },
+ data,
+ });
+ if (res.data.hasOwnProperty("error") && res.data.error === 0) {
+ resolve();
+ } else {
+ throw res.data;
+ }
+ }
+ } catch (err) {
+ reject(err);
}
});
}
diff --git a/lib/eWeLinkWS.js b/lib/eWeLinkWS.js
index 6f30b2ea..f6a63e26 100644
--- a/lib/eWeLinkWS.js
+++ b/lib/eWeLinkWS.js
@@ -3,6 +3,7 @@
const axios = require("axios"),
cns = require("./constants"),
eventemitter = require("events"),
+ utils = require("./utils"),
ws = require("ws"),
wsp = require("websocket-as-promised");
module.exports = class eWeLinkWS {
@@ -19,40 +20,40 @@ module.exports = class eWeLinkWS {
this.delaySend = 0;
}
getHost() {
- return new Promise((resolve, reject) => {
- axios({
- method: "post",
- url: "https://" + this.httpHost.replace("-api", "-disp") + "/dispatch/app",
- headers: {
- Authorization: "Bearer " + this.aToken,
- "Content-Type": "application/json",
- },
- data: {
- appid: cns.appId,
- nonce: Math.random().toString(36).substr(2, 8),
- ts: Math.floor(new Date().getTime() / 1000),
- version: 8,
- },
- })
- .then(res => {
- let body = res.data;
- if (!body.domain) {
- throw "Server did not respond with a web socket host.";
- }
- if (this.debug) {
- this.log("Web socket host received [%s].", body.domain);
- }
- this.wsHost = body.domain;
- resolve(body.domain);
- })
- .catch(err => {
- if (err.hasOwnProperty("code") && ["ENOTFOUND", "ETIMEDOUT"].includes(err.code)) {
- this.log.warn("Unable to reach eWeLink. Retrying in 30 seconds.");
- this.delay().then(() => resolve(this.getDevices()));
- } else {
- reject(err.message || err);
- }
+ return new Promise(async (resolve, reject) => {
+ try {
+ let res = await axios({
+ method: "post",
+ url: "https://" + this.httpHost.replace("-api", "-disp") + "/dispatch/app",
+ headers: {
+ Authorization: "Bearer " + this.aToken,
+ "Content-Type": "application/json",
+ },
+ data: {
+ appid: cns.appId,
+ nonce: Math.random().toString(36).substr(2, 8),
+ ts: Math.floor(new Date().getTime() / 1000),
+ version: 8,
+ },
});
+ let body = res.data;
+ if (!body.domain) {
+ throw "Server did not respond with a web socket host.";
+ }
+ if (this.debug) {
+ this.log("Web socket host received [%s].", body.domain);
+ }
+ this.wsHost = body.domain;
+ resolve(body.domain);
+ } catch (err) {
+ if (err.hasOwnProperty("code") && ["ENOTFOUND", "ETIMEDOUT"].includes(err.code)) {
+ this.log.warn("Unable to reach eWeLink. Retrying in 30 seconds.");
+ await utils.sleep(30000);
+ resolve(this.getDevices());
+ } else {
+ reject(err.message || err);
+ }
+ }
});
}
login() {
@@ -73,7 +74,7 @@ module.exports = class eWeLinkWS {
},
});
this.wsp.open();
- this.wsp.onOpen.addListener(() => {
+ this.wsp.onOpen.addListener(async () => {
this.wsIsOpen = true;
let sequence = Math.floor(new Date()).toString(),
payload = {
@@ -95,27 +96,25 @@ module.exports = class eWeLinkWS {
} else if (this.debug) {
this.log("Sending WS login request.");
}
- this.wsp
- .sendRequest(payload, {
+ try {
+ let res = await this.wsp.sendRequest(payload, {
requestId: sequence,
- })
- .then(res => {
- if (
- res.hasOwnProperty("config") &&
- res.config.hb &&
- res.config.hbInterval &&
- !this.hbInterval
- ) {
- this.hbInterval = setInterval(() => {
- this.wsp.send("ping");
- }, (res.config.hbInterval + 7) * 1000);
- } else {
- throw "Unknown parameters received";
- }
- })
- .catch(err => {
- this.log.error("WS login failed [%s].", err);
});
+ if (
+ res.hasOwnProperty("config") &&
+ res.config.hb &&
+ res.config.hbInterval &&
+ !this.hbInterval
+ ) {
+ this.hbInterval = setInterval(() => {
+ this.wsp.send("ping");
+ }, (res.config.hbInterval + 7) * 1000);
+ } else {
+ throw "Unknown parameters received";
+ }
+ } catch (err) {
+ this.log.error("WS login failed [%s].", err);
+ }
});
this.wsp.onUnpackedMessage.addListener(device => {
if (device === "pong") return;
@@ -206,7 +205,7 @@ module.exports = class eWeLinkWS {
});
}
sendUpdate(json) {
- return new Promise((resolve, reject) => {
+ return new Promise(async (resolve, reject) => {
let sequence = Math.floor(new Date()).toString(),
jsonToSend = {
...json,
@@ -217,37 +216,36 @@ module.exports = class eWeLinkWS {
},
};
if (this.wsp && this.wsIsOpen) {
- this.wsp
- .sendRequest(jsonToSend, {
+ try {
+ let device = await this.wsp.sendRequest(jsonToSend, {
requestId: sequence,
- })
- .then(device => {
- if (this.debugReqRes) {
- let msg = JSON.stringify(json, null, 2)
- .replace(json.apikey, "**hidden**")
- .replace(json.apiKey, "**hidden**")
- .replace(json.deviceid, "**hidden**");
- this.log.warn("WS message sent. This text is yellow for clarity.\n%s", msg);
- } else if (this.debug) {
- this.log("WS message sent.");
- }
- device.error = device.hasOwnProperty("error") ? device.error : 504; // mimic ewelink device offline
- switch (device.error) {
- case 0:
- resolve();
- break;
- default:
- throw "Unknown response";
- }
- })
- .catch(err => reject("Device update failed [" + err + "]."));
- } else {
- this.delay(2500).then(() => {
- if (this.debug) {
- this.log.warn("Will resend command when WS is reconnected.");
+ });
+ if (this.debugReqRes) {
+ let msg = JSON.stringify(json, null, 2)
+ .replace(json.apikey, "**hidden**")
+ .replace(json.apiKey, "**hidden**")
+ .replace(json.deviceid, "**hidden**");
+ this.log.warn("WS message sent. This text is yellow for clarity.\n%s", msg);
+ } else if (this.debug) {
+ this.log("WS message sent.");
}
- resolve(this.sendUpdate(json));
- });
+ device.error = device.hasOwnProperty("error") ? device.error : 504; // mimic ewelink device offline
+ switch (device.error) {
+ case 0:
+ resolve();
+ break;
+ default:
+ throw "Unknown response";
+ }
+ } catch (err) {
+ reject("Device update failed [" + err + "].");
+ }
+ } else {
+ if (this.debug) {
+ this.log.warn("Command will be resent when WS is reconnected.");
+ }
+ await utils.sleep(30000);
+ resolve(this.sendUpdate(json));
}
});
}
@@ -275,16 +273,15 @@ module.exports = class eWeLinkWS {
this.log("WS message sent.");
}
},
- checkToSend = () => {
+ checkToSend = async () => {
if (this.wsp && this.wsIsOpen) {
sendOperation();
} else {
- this.delay(2500).then(() => {
- if (this.debug) {
- this.log.warn("Will resend command when WS is reconnected.");
- }
- checkToSend();
- });
+ await utils.sleep(2500);
+ if (this.debug) {
+ this.log.warn("Will resend command when WS is reconnected.");
+ }
+ checkToSend();
}
};
checkToSend();
@@ -294,20 +291,17 @@ module.exports = class eWeLinkWS {
this.emitter.addListener("update", f);
}
closeConnection() {
- return new Promise((resolve, reject) => {
+ return new Promise(async (resolve, reject) => {
if (this.wsp && this.wsIsOpen) {
- this.wsp
- .close()
- .then(() => {
- this.log("Web socket gracefully closed.");
- resolve();
- })
- .catch(err => reject(err));
+ try {
+ await this.wsp.close();
+ this.log("Web socket gracefully closed.");
+ resolve();
+ } catch (err) {
+ reject(err);
+ }
}
resolve();
});
}
- delay(ms) {
- return new Promise(resolve => setTimeout(resolve, ms));
- }
};
diff --git a/lib/utils.js b/lib/utils.js
new file mode 100644
index 00000000..5cb638ad
--- /dev/null
+++ b/lib/utils.js
@@ -0,0 +1,7 @@
+/* jshint esversion: 9, -W014, -W030, node: true */
+"use strict";
+module.exports = {
+ sleep: ms => {
+ return new Promise(resolve => setTimeout(resolve, ms));
+ },
+};
diff --git a/package-lock.json b/package-lock.json
index 24611c34..4560d366 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -405,6 +405,11 @@
}
}
},
+ "interval-promise": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/interval-promise/-/interval-promise-1.4.0.tgz",
+ "integrity": "sha512-PUwEmGqUglJhb6M01JNvMDvxr4DA8FCeYoYCLHPEcBBZiq/8yOpCchfs1VJui7fXj69l170gAxzF1FeSA0nSlg=="
+ },
"ip": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
diff --git a/package.json b/package.json
index 82cf0b07..46a2e2e3 100644
--- a/package.json
+++ b/package.json
@@ -63,6 +63,7 @@
"correcting-interval": "2.0.0",
"fakegato-history": "0.5.6",
"homebridge-lib": "4.7.15",
+ "interval-promise": "1.4.0",
"node-dns-sd": "0.4.1",
"websocket-as-promised": "1.0.1",
"ws": "7.3.1"
From 07c13122da42c915959bbeeccd1bc481a8521e3e Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Fri, 25 Sep 2020 15:44:08 +0100
Subject: [PATCH 0217/3183] requestUpdate bugfix
---
lib/eWeLinkWS.js | 47 +++++++++++++++++++++--------------------------
1 file changed, 21 insertions(+), 26 deletions(-)
diff --git a/lib/eWeLinkWS.js b/lib/eWeLinkWS.js
index f6a63e26..a9df48ca 100644
--- a/lib/eWeLinkWS.js
+++ b/lib/eWeLinkWS.js
@@ -238,7 +238,7 @@ module.exports = class eWeLinkWS {
throw "Unknown response";
}
} catch (err) {
- reject("Device update failed [" + err + "].");
+ reject("device update failed [" + err + "]");
}
} else {
if (this.debug) {
@@ -250,7 +250,7 @@ module.exports = class eWeLinkWS {
});
}
requestUpdate(accessory) {
- return new Promise(resolve => {
+ return new Promise(async resolve => {
let sequence = Math.floor(new Date()).toString(),
json = {
action: "query",
@@ -260,31 +260,26 @@ module.exports = class eWeLinkWS {
sequence,
ts: 0,
userAgent: "app",
- },
- sendOperation = () => {
- this.wsp.send(json);
- if (this.debugReqRes) {
- let msg = JSON.stringify(json, null, 2)
- .replace(json.apikey, "**hidden**")
- .replace(json.apiKey, "**hidden**")
- .replace(json.deviceid, "**hidden**");
- this.log.warn("WS message sent. This text is yellow for clarity.\n%s", msg);
- } else if (this.debug) {
- this.log("WS message sent.");
- }
- },
- checkToSend = async () => {
- if (this.wsp && this.wsIsOpen) {
- sendOperation();
- } else {
- await utils.sleep(2500);
- if (this.debug) {
- this.log.warn("Will resend command when WS is reconnected.");
- }
- checkToSend();
- }
};
- checkToSend();
+
+ if (this.wsp && this.wsIsOpen) {
+ this.wsp.send(JSON.stringify(json));
+ if (this.debugReqRes) {
+ let msg = JSON.stringify(json, null, 2)
+ .replace(json.apikey, "**hidden**")
+ .replace(json.apiKey, "**hidden**")
+ .replace(json.deviceid, "**hidden**");
+ this.log.warn("WS message sent. This text is yellow for clarity.\n%s", msg);
+ } else if (this.debug) {
+ this.log("WS message sent.");
+ }
+ } else {
+ if (this.debug) {
+ this.log.warn("Command will be resent when WS is reconnected.");
+ }
+ await utils.sleep(30000);
+ resolve(this.requestUpdate(accessory));
+ }
});
}
receiveUpdate(f) {
From 78ddb14eee5db355bc7f15d058750a9b8f48f781 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Fri, 25 Sep 2020 15:44:24 +0100
Subject: [PATCH 0218/3183] improved logging
---
lib/eWeLink.js | 23 ++++++++++++++++-------
1 file changed, 16 insertions(+), 7 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index d66cbdaf..7bc0cc34 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -1193,10 +1193,15 @@ class eWeLink {
try {
await this.wsClient.requestUpdate(accessory);
this.log.warn(
- "[%s] requesting previous state to revert Homebridge status.",
+ "[%s] requesting previous state to revert Homebridge state.",
accessory.displayName
);
} catch (err) {}
+ } else {
+ this.log.warn(
+ "[%s] Homebridge state will be synced once the device comes back online.",
+ accessory.displayName
+ );
}
}
async internalValveUpdate(accessory, valve, value, callback) {
@@ -1346,19 +1351,23 @@ class eWeLink {
outlet: 3,
},
];
- accessory.context.inUse = true;
- if (prevState !== 2) {
+
+ if (prevState !== 2 || accessory.context.inUse) {
+ await utils.sleep(500);
this.log.warn(
"[%s] tried to move the blinds to [%s%] but they are already moving.",
accessory.displayName,
newTarget
);
- wcService.updateCharacteristic(
- Characteristic.TargetPosition,
- accessory.context.cacheTargetPosition
- );
+ wcService
+ .updateCharacteristic(
+ Characteristic.TargetPosition,
+ accessory.context.cacheTargetPosition
+ )
+ .updateCharacteristic(Characteristic.PositionState, accessory.context.cachePositionState);
return;
}
+ accessory.context.inUse = true;
wcService.updateCharacteristic(Characteristic.TargetPosition, newTarget);
accessory.context.cacheTargetPosition = newTarget;
let moveUp = newTarget > prevPos,
From 8436eb28f7924ee36979af6b642f5150a395a2ff Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Fri, 25 Sep 2020 15:45:28 +0100
Subject: [PATCH 0219/3183] 3.0.2
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 4560d366..16b95537 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.0.1",
+ "version": "3.0.2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 46a2e2e3..cf8c488f 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.0.1",
+ "version": "3.0.2",
"author": "bwp91",
"contributors": [
"gbro115",
From fe636c6ad2a1f6b3d1c5f1d7874f9fd36189d6d1 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sat, 26 Sep 2020 17:49:41 +0100
Subject: [PATCH 0220/3183] blinds relative %
---
.prettierrc.json | 2 +-
lib/constants.js | 41 ++--
lib/eWeLink.js | 584 ++++++++++++++-------------------------------
lib/eWeLinkHTTP.js | 19 +-
lib/eWeLinkLAN.js | 22 +-
lib/eWeLinkWS.js | 21 +-
6 files changed, 209 insertions(+), 480 deletions(-)
diff --git a/.prettierrc.json b/.prettierrc.json
index 87f5e5e8..163a0a7e 100644
--- a/.prettierrc.json
+++ b/.prettierrc.json
@@ -1,4 +1,4 @@
{
"arrowParens": "avoid",
- "printWidth": 100
+ "printWidth": 120
}
diff --git a/lib/constants.js b/lib/constants.js
index 9e1ce0d4..555488c5 100644
--- a/lib/constants.js
+++ b/lib/constants.js
@@ -12,18 +12,7 @@ module.exports = {
devicesSingleSwitchOutlet: ["Sonoff Pow", "S26"],
devicesMultiSwitch: [2, 3, 4, 7, 8, 9, 29, 30, 31, 34, 41],
devicesMultiSwitchParams: ["switches"],
- devicesSingleSwitchLight: [
- "T1 1C",
- "L1",
- "B1",
- "B1_R2",
- "TX1C",
- "D1",
- "D1R1",
- "KING-M4",
- "Slampher",
- "GTTA59",
- ],
+ devicesSingleSwitchLight: ["T1 1C", "L1", "B1", "B1_R2", "TX1C", "D1", "D1R1", "KING-M4", "Slampher", "GTTA59"],
devicesSingleSwitchLightParams: [
"switch",
"state",
@@ -56,15 +45,7 @@ module.exports = {
devicesRFBridge: [28],
devicesRFBridgeParams: ["cmd"],
devicesZBBridge: [66],
- devicesZBBridgeParams: [
- "key",
- "temperature",
- "humidity",
- "motion",
- "lock",
- "trigTime",
- "battery",
- ],
+ devicesZBBridgeParams: ["key", "temperature", "humidity", "motion", "lock", "trigTime", "battery"],
devicesZB: [1000, 1770, 2026, 3026],
devicesValveParams: ["switches"],
devicesBlindParams: ["switch", "switches"],
@@ -108,6 +89,24 @@ module.exports = {
"voltage",
"zyx_mode",
],
+ defaultMultiSwitchOff: [
+ {
+ switch: "off",
+ outlet: 0,
+ },
+ {
+ switch: "off",
+ outlet: 1,
+ },
+ {
+ switch: "off",
+ outlet: 2,
+ },
+ {
+ switch: "off",
+ outlet: 3,
+ },
+ ],
chansFromUiid: {
1: 1, // "SOCKET" \\ 20, MINI, BASIC, S26
2: 2, // "SOCKET_2" \\
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 7bc0cc34..57e64c9d 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -116,18 +116,9 @@ class eWeLink {
}
initialiseDevice(device) {
let accessory;
- //*** IRRIGATION VALVES ***\\
- if (
- device.extra.uiid === 2 &&
- device.brandName === "coolkit" &&
- device.productModel === "0285"
- ) {
- accessory = this.devicesInHB.has(device.deviceid + "SWX")
- ? this.devicesInHB.get(device.deviceid + "SWX")
- : this.addAccessory(device, device.deviceid + "SWX", "valve");
- }
+
//*** CURTAINS ***\\
- else if (cns.devicesCurtain.includes(device.extra.uiid)) {
+ if (cns.devicesCurtain.includes(device.extra.uiid)) {
accessory = this.devicesInHB.has(device.deviceid + "SWX")
? this.devicesInHB.get(device.deviceid + "SWX")
: this.addAccessory(device, device.deviceid + "SWX", "curtain", false, {
@@ -145,10 +136,7 @@ class eWeLink {
}
}
//*** WINDOW BLINDS ***\\
- else if (
- this.cusG.has(device.deviceid + "SWX") &&
- this.cusG.get(device.deviceid + "SWX").type === "blind"
- ) {
+ else if (this.cusG.has(device.deviceid + "SWX") && this.cusG.get(device.deviceid + "SWX").type === "blind") {
accessory = this.devicesInHB.has(device.deviceid + "SWX")
? this.devicesInHB.get(device.deviceid + "SWX")
: this.addAccessory(device, device.deviceid + "SWX", "blind", false, {
@@ -165,10 +153,7 @@ class eWeLink {
//*** @ENDUPGRADE ***\\
}
//*** GARAGE DOORS ***\\
- else if (
- this.cusG.has(device.deviceid + "SWX") &&
- this.cusG.get(device.deviceid + "SWX").type === "garage"
- ) {
+ else if (this.cusG.has(device.deviceid + "SWX") && this.cusG.get(device.deviceid + "SWX").type === "garage") {
accessory = this.devicesInHB.has(device.deviceid + "SWX")
? this.devicesInHB.get(device.deviceid + "SWX")
: this.addAccessory(device, device.deviceid + "SWX", "garage", false, {
@@ -182,14 +167,11 @@ class eWeLink {
}
//*** @ENDUPGRADE ***\\
}
- //*** LOCKS ***\\
- else if (
- this.cusG.has(device.deviceid + "SWX") &&
- this.cusG.get(device.deviceid + "SWX").type === "lock"
- ) {
- accessory = this.devicesInHB.has(device.deviceid + "SWX")
+ //*** SINGLE LOCKS ***\\
+ else if (this.cusG.has(device.deviceid + "SWX") && this.cusG.get(device.deviceid + "SWX").type === "lock") {
+ let lockConfig = (accessory = this.devicesInHB.has(device.deviceid + "SWX")
? this.devicesInHB.get(device.deviceid + "SWX")
- : this.addAccessory(device, device.deviceid + "SWX", "lock");
+ : this.addAccessory(device, device.deviceid + "SWX", "lock"));
}
//*** SENSORS (DW2) ***\\
else if (cns.devicesSensor.includes(device.extra.uiid)) {
@@ -197,6 +179,12 @@ class eWeLink {
? this.devicesInHB.get(device.deviceid + "SWX")
: this.addAccessory(device, device.deviceid + "SWX", "sensor");
}
+ //*** IRRIGATION VALVES ***\\
+ else if (device.extra.uiid === 2 && device.brandName === "coolkit" && device.productModel === "0285") {
+ accessory = this.devicesInHB.has(device.deviceid + "SWX")
+ ? this.devicesInHB.get(device.deviceid + "SWX")
+ : this.addAccessory(device, device.deviceid + "SWX", "valve");
+ }
//*** FANS ***\\
else if (cns.devicesFan.includes(device.extra.uiid)) {
accessory = this.devicesInHB.has(device.deviceid + "SWX")
@@ -368,22 +356,13 @@ class eWeLink {
swNumber,
};
if ((subAccessory = this.devicesInHB.get(device.deviceid + "SW" + swNumber))) {
- if (
- subAccessory.context.subType !== subType ||
- subAccessory.context.swNumber !== swNumber
- ) {
+ if (subAccessory.context.subType !== subType || subAccessory.context.swNumber !== swNumber) {
this.removeAccessory(subAccessory);
}
}
subAccessory = this.devicesInHB.has(device.deviceid + "SW" + swNumber)
? this.devicesInHB.get(device.deviceid + "SW" + swNumber)
- : this.addAccessory(
- device,
- device.deviceid + "SW" + swNumber,
- "rf_sub",
- false,
- subExtraContext
- );
+ : this.addAccessory(device, device.deviceid + "SW" + swNumber, "rf_sub", false, subExtraContext);
subAccessory
.getService(Service.AccessoryInformation)
.setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion);
@@ -485,19 +464,13 @@ class eWeLink {
newDeviceName = this.config.nameOverride[hbDeviceId];
}
try {
- const accessory = new Accessory(
- newDeviceName,
- this.api.hap.uuid.generate(hbDeviceId).toString()
- );
+ const accessory = new Accessory(newDeviceName, this.api.hap.uuid.generate(hbDeviceId).toString());
if (!hidden) {
accessory
.getService(Service.AccessoryInformation)
.setCharacteristic(Characteristic.SerialNumber, hbDeviceId)
.setCharacteristic(Characteristic.Manufacturer, device.brandName)
- .setCharacteristic(
- Characteristic.Model,
- device.productModel + " (" + device.extra.model + ")"
- )
+ .setCharacteristic(Characteristic.Model, device.productModel + " (" + device.extra.model + ")")
.setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion)
.setCharacteristic(Characteristic.Identify, false);
}
@@ -546,21 +519,17 @@ class eWeLink {
}
valveService
.getCharacteristic(Characteristic.Active)
- .on("set", (value, callback) =>
- this.internalValveUpdate(accessory, "Valve " + v, value, callback)
- );
- valveService
- .getCharacteristic(Characteristic.SetDuration)
- .on("set", (value, callback) => {
- if (valveService.getCharacteristic(Characteristic.InUse).value) {
- valveService.updateCharacteristic(Characteristic.RemainingDuration, value);
- clearTimeout(valveService.timer);
- valveService.timer = setTimeout(() => {
- valveService.setCharacteristic(Characteristic.Active, 0);
- }, value * 1000);
- }
- callback();
- });
+ .on("set", (value, callback) => this.internalValveUpdate(accessory, "Valve " + v, value, callback));
+ valveService.getCharacteristic(Characteristic.SetDuration).on("set", (value, callback) => {
+ if (valveService.getCharacteristic(Characteristic.InUse).value) {
+ valveService.updateCharacteristic(Characteristic.RemainingDuration, value);
+ clearTimeout(valveService.timer);
+ valveService.timer = setTimeout(() => {
+ valveService.setCharacteristic(Characteristic.Active, 0);
+ }, value * 1000);
+ }
+ callback();
+ });
});
break;
case "curtain":
@@ -606,65 +575,47 @@ class eWeLink {
.on("set", (value, callback) => this.internalGarageUpdate(accessory, value, callback));
break;
case "lock":
- let lmService =
- accessory.getService(Service.LockMechanism) ||
- accessory.addService(Service.LockMechanism);
+ let lmService = accessory.getService(Service.LockMechanism) || accessory.addService(Service.LockMechanism);
lmService
.getCharacteristic(Characteristic.LockTargetState)
.on("set", (value, callback) => this.internalLockUpdate(accessory, value, callback));
break;
case "sensor":
- accessory.getService(Service.ContactSensor) ||
- accessory.addService(Service.ContactSensor);
- accessory.getService(Service.BatteryService) ||
- accessory.addService(Service.BatteryService);
+ accessory.getService(Service.ContactSensor) || accessory.addService(Service.ContactSensor);
+ accessory.getService(Service.BatteryService) || accessory.addService(Service.BatteryService);
break;
case "fan":
- let fanService =
- accessory.getService(Service.Fanv2) || accessory.addService(Service.Fanv2),
- fanLightService =
- accessory.getService(Service.Lightbulb) || accessory.addService(Service.Lightbulb);
+ let fanService = accessory.getService(Service.Fanv2) || accessory.addService(Service.Fanv2),
+ fanLightService = accessory.getService(Service.Lightbulb) || accessory.addService(Service.Lightbulb);
fanService
.getCharacteristic(Characteristic.Active)
- .on("set", (value, callback) =>
- this.internalFanUpdate(accessory, "power", value, callback)
- );
+ .on("set", (value, callback) => this.internalFanUpdate(accessory, "power", value, callback));
fanService
.getCharacteristic(Characteristic.RotationSpeed)
- .on("set", (value, callback) =>
- this.internalFanUpdate(accessory, "speed", value, callback)
- )
+ .on("set", (value, callback) => this.internalFanUpdate(accessory, "speed", value, callback))
.setProps({
minStep: 33,
});
fanLightService
.getCharacteristic(Characteristic.On)
- .on("set", (value, callback) =>
- this.internalFanUpdate(accessory, "light", value, callback)
- );
+ .on("set", (value, callback) => this.internalFanUpdate(accessory, "light", value, callback));
break;
case "thermostat":
let tempService =
- accessory.getService(Service.TemperatureSensor) ||
- accessory.addService(Service.TemperatureSensor),
+ accessory.getService(Service.TemperatureSensor) || accessory.addService(Service.TemperatureSensor),
humiService = false;
if (accessory.context.sensorType !== "DS18B20") {
- humiService =
- accessory.getService(Service.HumiditySensor) ||
- accessory.addService(Service.HumiditySensor);
+ humiService = accessory.getService(Service.HumiditySensor) || accessory.addService(Service.HumiditySensor);
} else {
if (accessory.getService(Service.HumiditySensor)) {
accessory.removeService(Service.HumiditySensor);
}
}
if (!this.config.hideTHSwitch) {
- let switchService =
- accessory.getService(Service.Switch) || accessory.addService(Service.Switch);
+ let switchService = accessory.getService(Service.Switch) || accessory.addService(Service.Switch);
switchService
.getCharacteristic(Characteristic.On)
- .on("set", (value, callback) =>
- this.internalThermostatUpdate(accessory, value, callback)
- );
+ .on("set", (value, callback) => this.internalThermostatUpdate(accessory, value, callback));
}
if (!(this.config.disableEveLogging || false)) {
accessory.log = this.log;
@@ -720,8 +671,7 @@ class eWeLink {
corrInterval.setCorrectingInterval(() => {
let isOn = outletService.getCharacteristic(Characteristic.On).value,
currentWatt = isOn
- ? outletService.getCharacteristic(EveService.Characteristics.CurrentConsumption)
- .value
+ ? outletService.getCharacteristic(EveService.Characteristics.CurrentConsumption).value
: 0;
if (accessory.eveLogger.isHistoryLoaded()) {
accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData();
@@ -735,8 +685,7 @@ class eWeLink {
lastReset: accessory.context.extraPersistedData.lastReset,
});
} else {
- accessory.context.totalEnergy =
- accessory.context.totalEnergyTemp + (currentWatt * 10) / 3600 / 1000;
+ accessory.context.totalEnergy = accessory.context.totalEnergyTemp + (currentWatt * 10) / 3600 / 1000;
accessory.eveLogger.setExtraPersistedData({
totalenergy: accessory.context.totalEnergy,
lastReset: 0,
@@ -752,15 +701,13 @@ class eWeLink {
power: currentWatt,
});
}, 300000);
- outletService
- .getCharacteristic(EveService.Characteristics.TotalConsumption)
- .on("get", callback => {
- accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData();
- if (accessory.context.extraPersistedData !== undefined) {
- accessory.context.totalEnergy = accessory.context.extraPersistedData.totalPower;
- }
- callback(null, accessory.context.totalEnergy);
- });
+ outletService.getCharacteristic(EveService.Characteristics.TotalConsumption).on("get", callback => {
+ accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData();
+ if (accessory.context.extraPersistedData !== undefined) {
+ accessory.context.totalEnergy = accessory.context.extraPersistedData.totalPower;
+ }
+ callback(null, accessory.context.totalEnergy);
+ });
outletService
.getCharacteristic(EveService.Characteristics.ResetTotal)
.on("set", (value, callback) => {
@@ -782,70 +729,56 @@ class eWeLink {
}
break;
case "usb":
- let usbService =
- accessory.getService(Service.Outlet) || accessory.addService(Service.Outlet);
+ let usbService = accessory.getService(Service.Outlet) || accessory.addService(Service.Outlet);
usbService
.getCharacteristic(Characteristic.On)
.on("set", (value, callback) => this.internalUSBUpdate(accessory, value, callback));
break;
case "scm":
- let scmService =
- accessory.getService(Service.Switch) || accessory.addService(Service.Switch);
+ let scmService = accessory.getService(Service.Switch) || accessory.addService(Service.Switch);
scmService
.getCharacteristic(Characteristic.On)
.on("set", (value, callback) => this.internalSCMUpdate(accessory, value, callback));
break;
case "light":
- let lightService =
- accessory.getService(Service.Lightbulb) || accessory.addService(Service.Lightbulb);
+ let lightService = accessory.getService(Service.Lightbulb) || accessory.addService(Service.Lightbulb);
lightService
.getCharacteristic(Characteristic.On)
- .on("set", (value, callback) =>
- this.internalLightbulbUpdate(accessory, value, callback)
- );
+ .on("set", (value, callback) => this.internalLightbulbUpdate(accessory, value, callback));
if (cns.devicesBrightable.includes(accessory.context.eweUIID)) {
- lightService
- .getCharacteristic(Characteristic.Brightness)
- .on("set", (value, callback) => {
- if (value > 0) {
- if (!lightService.getCharacteristic(Characteristic.On).value) {
- this.internalLightbulbUpdate(accessory, true, function () {
- return;
- });
- }
- this.internalBrightnessUpdate(accessory, value, callback);
- } else {
- this.internalLightbulbUpdate(accessory, false, callback);
+ lightService.getCharacteristic(Characteristic.Brightness).on("set", (value, callback) => {
+ if (value > 0) {
+ if (!lightService.getCharacteristic(Characteristic.On).value) {
+ this.internalLightbulbUpdate(accessory, true, function () {
+ return;
+ });
}
- });
+ this.internalBrightnessUpdate(accessory, value, callback);
+ } else {
+ this.internalLightbulbUpdate(accessory, false, callback);
+ }
+ });
} else if (cns.devicesColourable.includes(accessory.context.eweUIID)) {
- lightService
- .getCharacteristic(Characteristic.Brightness)
- .on("set", (value, callback) => {
- if (value > 0) {
- if (!lightService.getCharacteristic(Characteristic.On).value) {
- this.internalLightbulbUpdate(accessory, true, function () {
- return;
- });
- }
- this.internalHSBUpdate(accessory, "bri", value, callback);
- } else {
- this.internalLightbulbUpdate(accessory, false, callback);
+ lightService.getCharacteristic(Characteristic.Brightness).on("set", (value, callback) => {
+ if (value > 0) {
+ if (!lightService.getCharacteristic(Characteristic.On).value) {
+ this.internalLightbulbUpdate(accessory, true, function () {
+ return;
+ });
}
- });
+ this.internalHSBUpdate(accessory, "bri", value, callback);
+ } else {
+ this.internalLightbulbUpdate(accessory, false, callback);
+ }
+ });
lightService
.getCharacteristic(Characteristic.Hue)
- .on("set", (value, callback) =>
- this.internalHSBUpdate(accessory, "hue", value, callback)
- );
- lightService
- .getCharacteristic(Characteristic.Saturation)
- .on("set", (value, callback) => callback());
+ .on("set", (value, callback) => this.internalHSBUpdate(accessory, "hue", value, callback));
+ lightService.getCharacteristic(Characteristic.Saturation).on("set", (value, callback) => callback());
}
break;
case "switch":
- let switchService =
- accessory.getService(Service.Switch) || accessory.addService(Service.Switch);
+ let switchService = accessory.getService(Service.Switch) || accessory.addService(Service.Switch);
switchService
.getCharacteristic(Characteristic.On)
.on("set", (value, callback) => this.internalSwitchUpdate(accessory, value, callback));
@@ -857,33 +790,26 @@ class eWeLink {
break;
case "fire":
case "smoke":
- accessory.getService(Service.SmokeSensor) ||
- accessory.addService(Service.SmokeSensor);
+ accessory.getService(Service.SmokeSensor) || accessory.addService(Service.SmokeSensor);
break;
case "co":
- accessory.getService(Service.CarbonMonoxideSensor) ||
- accessory.addService(Service.CarbonMonoxideSensor);
+ accessory.getService(Service.CarbonMonoxideSensor) || accessory.addService(Service.CarbonMonoxideSensor);
break;
case "co2":
- accessory.getService(Service.CarbonDioxideSensor) ||
- accessory.addService(Service.CarbonDioxideSensor);
+ accessory.getService(Service.CarbonDioxideSensor) || accessory.addService(Service.CarbonDioxideSensor);
break;
case "contact":
- accessory.getService(Service.ContactSensor) ||
- accessory.addService(Service.ContactSensor);
+ accessory.getService(Service.ContactSensor) || accessory.addService(Service.ContactSensor);
break;
case "occupancy":
- accessory.getService(Service.OccupancySensor) ||
- accessory.addService(Service.OccupancySensor);
+ accessory.getService(Service.OccupancySensor) || accessory.addService(Service.OccupancySensor);
break;
default:
- accessory.getService(Service.MotionSensor) ||
- accessory.addService(Service.MotionSensor);
+ accessory.getService(Service.MotionSensor) || accessory.addService(Service.MotionSensor);
break;
case "button":
Object.entries(accessory.context.buttons).forEach(([chan, name]) => {
- accessory.getService(name) ||
- accessory.addService(Service.Switch, name, "switch" + chan);
+ accessory.getService(name) || accessory.addService(Service.Switch, name, "switch" + chan);
accessory.getService(name).updateCharacteristic(Characteristic.On, false);
accessory
.getService(name)
@@ -896,8 +822,7 @@ class eWeLink {
}
break;
case "zb_dev": //*** credit @tasict ***\\
- accessory.getService(Service.BatteryService) ||
- accessory.addService(Service.BatteryService);
+ accessory.getService(Service.BatteryService) || accessory.addService(Service.BatteryService);
switch (accessory.context.eweUIID) {
case 1000:
let zbspsService =
@@ -911,11 +836,9 @@ class eWeLink {
break;
case 1770:
let zbTempService =
- accessory.getService(Service.TemperatureSensor) ||
- accessory.addService(Service.TemperatureSensor);
+ accessory.getService(Service.TemperatureSensor) || accessory.addService(Service.TemperatureSensor);
let zbHumiService =
- accessory.getService(Service.HumiditySensor) ||
- accessory.addService(Service.HumiditySensor);
+ accessory.getService(Service.HumiditySensor) || accessory.addService(Service.HumiditySensor);
accessory.log = this.log;
accessory.eveLogger = new EveHistoryService("weather", accessory, {
storage: "fs",
@@ -926,19 +849,16 @@ class eWeLink {
let dataToAdd = {
time: Date.now(),
temp: zbTempService.getCharacteristic(Characteristic.CurrentTemperature).value,
- humidity: zbHumiService.getCharacteristic(Characteristic.CurrentRelativeHumidity)
- .value,
+ humidity: zbHumiService.getCharacteristic(Characteristic.CurrentRelativeHumidity).value,
};
accessory.eveLogger.addEntry(dataToAdd);
}, 300000);
break;
case 2026:
- accessory.getService(Service.MotionSensor) ||
- accessory.addService(Service.MotionSensor);
+ accessory.getService(Service.MotionSensor) || accessory.addService(Service.MotionSensor);
break;
case 3026:
- accessory.getService(Service.ContactSensor) ||
- accessory.addService(Service.ContactSensor);
+ accessory.getService(Service.ContactSensor) || accessory.addService(Service.ContactSensor);
break;
}
break;
@@ -951,10 +871,7 @@ class eWeLink {
refreshAccessory(accessory, newParams) {
switch (accessory.context.type) {
case "valve":
- if (
- Object.keys(newParams).some(v => cns.devicesValveParams.includes(v)) &&
- Array.isArray(newParams.switches)
- ) {
+ if (Object.keys(newParams).some(v => cns.devicesValveParams.includes(v)) && Array.isArray(newParams.switches)) {
this.externalValveUpdate(accessory, newParams);
}
return true;
@@ -964,10 +881,7 @@ class eWeLink {
}
return true;
case "blind":
- if (
- Object.keys(newParams).some(v => cns.devicesBlindParams.includes(v)) &&
- Array.isArray(newParams.switches)
- ) {
+ if (Object.keys(newParams).some(v => cns.devicesBlindParams.includes(v)) && Array.isArray(newParams.switches)) {
this.externalBlindUpdate(accessory, newParams);
}
return true;
@@ -1005,18 +919,12 @@ class eWeLink {
}
return true;
case "usb":
- if (
- Object.keys(newParams).some(v => cns.devicesUSBParams.includes(v)) &&
- Array.isArray(newParams.switches)
- ) {
+ if (Object.keys(newParams).some(v => cns.devicesUSBParams.includes(v)) && Array.isArray(newParams.switches)) {
this.externalUSBUpdate(accessory, newParams);
}
return true;
case "scm":
- if (
- Object.keys(newParams).some(v => cns.devicesSCMParams.includes(v)) &&
- Array.isArray(newParams.switches)
- ) {
+ if (Object.keys(newParams).some(v => cns.devicesSCMParams.includes(v)) && Array.isArray(newParams.switches)) {
this.externalSCMUpdate(accessory, newParams);
}
return true;
@@ -1111,16 +1019,13 @@ class eWeLink {
let accessory,
deviceId = device.deviceid,
reachableChange = false;
- if (
- (accessory = this.devicesInHB.get(deviceId + "SWX") || this.devicesInHB.get(deviceId + "SW0"))
- ) {
+ if ((accessory = this.devicesInHB.get(deviceId + "SWX") || this.devicesInHB.get(deviceId + "SW0"))) {
let isX = accessory.context.hbDeviceId.substr(-1) === "X";
if (device.params.updateSource === "WS") {
if (device.params.online != accessory.context.reachableWAN) {
accessory.context.reachableWAN = device.params.online;
this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
- if (accessory.context.reachableWAN)
- this.wsClient.requestUpdate(accessory).catch(() => {});
+ if (accessory.context.reachableWAN) this.wsClient.requestUpdate(accessory).catch(() => {});
reachableChange = true;
this.log.warn(
"[%s] has been reported [%s] via [WS].",
@@ -1179,10 +1084,7 @@ class eWeLink {
this.lanClient.addDeviceToMap(device);
} catch (err) {
this.log.error("[%s] error getting info [%s]", deviceId, err);
- this.log.error(
- "[%s] Please try restarting Homebridge so this device is added.",
- deviceId
- );
+ this.log.error("[%s] Please try restarting Homebridge so this device is added.", deviceId);
}
}
}
@@ -1192,16 +1094,10 @@ class eWeLink {
if (accessory.context.reachableWAN) {
try {
await this.wsClient.requestUpdate(accessory);
- this.log.warn(
- "[%s] requesting previous state to revert Homebridge state.",
- accessory.displayName
- );
+ this.log.warn("[%s] requesting previous state to revert Homebridge state.", accessory.displayName);
} catch (err) {}
} else {
- this.log.warn(
- "[%s] Homebridge state will be synced once the device comes back online.",
- accessory.displayName
- );
+ this.log.warn("[%s] Homebridge state will be synced once the device comes back online.", accessory.displayName);
}
}
async internalValveUpdate(accessory, valve, value, callback) {
@@ -1213,16 +1109,12 @@ class eWeLink {
switch (valve) {
case "Valve A":
params.switches[0].switch = value ? "on" : "off";
- params.switches[1].switch = accessory
- .getService("Valve B")
- .getCharacteristic(Characteristic.Active).value
+ params.switches[1].switch = accessory.getService("Valve B").getCharacteristic(Characteristic.Active).value
? "on"
: "off";
break;
case "Valve B":
- params.switches[0].switch = accessory
- .getService("Valve A")
- .getCharacteristic(Characteristic.Active).value
+ params.switches[0].switch = accessory.getService("Valve A").getCharacteristic(Characteristic.Active).value
? "on"
: "off";
params.switches[1].switch = value ? "on" : "off";
@@ -1231,9 +1123,7 @@ class eWeLink {
params.switches[2].switch = "off";
params.switches[3].switch = "off";
await this.sendDeviceUpdate(accessory, params);
- serviceValve
- .updateCharacteristic(Characteristic.Active, value)
- .updateCharacteristic(Characteristic.InUse, value);
+ serviceValve.updateCharacteristic(Characteristic.Active, value).updateCharacteristic(Characteristic.InUse, value);
switch (value) {
case 0:
serviceValve.updateCharacteristic(Characteristic.RemainingDuration, 0);
@@ -1242,10 +1132,7 @@ class eWeLink {
case 1:
let timer = serviceValve.getCharacteristic(Characteristic.SetDuration).value;
serviceValve.updateCharacteristic(Characteristic.RemainingDuration, timer);
- serviceValve.timer = setTimeout(
- () => serviceValve.setCharacteristic(Characteristic.Active, 0),
- timer * 1000
- );
+ serviceValve.timer = setTimeout(() => serviceValve.setCharacteristic(Characteristic.Active, 0), timer * 1000);
break;
}
} catch (err) {
@@ -1323,118 +1210,63 @@ class eWeLink {
params = {},
wcService = accessory.getService(Service.WindowCovering),
prevState = accessory.context.cachePositionState,
- prevPos = accessory.context.cacheCurrentPosition,
+ prevPosition = accessory.context.cacheCurrentPosition,
+ prevTarget = accessory.context.cacheTargetPosition,
newTarget = value,
- timeNow = Date.now();
+ updateKey = Math.random().toString(36).substr(2, 8);
if (!(blindConfig = this.cusG.get(accessory.context.hbDeviceId))) {
throw "group config missing";
}
if (blindConfig.type !== "blind" || blindConfig.setup !== "twoSwitch") {
throw "improper configuration";
}
- if (newTarget === prevPos) return;
- params.switches = [
- {
- switch: "off",
- outlet: 0,
- },
- {
- switch: "off",
- outlet: 1,
- },
- {
- switch: "off",
- outlet: 2,
- },
- {
- switch: "off",
- outlet: 3,
- },
- ];
-
- if (prevState !== 2 || accessory.context.inUse) {
- await utils.sleep(500);
- this.log.warn(
- "[%s] tried to move the blinds to [%s%] but they are already moving.",
- accessory.displayName,
- newTarget
- );
- wcService
- .updateCharacteristic(
- Characteristic.TargetPosition,
- accessory.context.cacheTargetPosition
- )
- .updateCharacteristic(Characteristic.PositionState, accessory.context.cachePositionState);
- return;
- }
- accessory.context.inUse = true;
- wcService.updateCharacteristic(Characteristic.TargetPosition, newTarget);
- accessory.context.cacheTargetPosition = newTarget;
- let moveUp = newTarget > prevPos,
- duration = Math.round(Math.abs(newTarget - prevPos) * blindConfig.operationTime);
- accessory.context.startTimestamp = timeNow;
- accessory.context.targetTimestamp = timeNow + duration;
- params.switches[0].switch = moveUp ? "on" : "off";
- params.switches[1].switch = moveUp ? "off" : "on";
- await this.sendDeviceUpdate(accessory, params);
- wcService.updateCharacteristic(Characteristic.PositionState, moveUp ? 0 : 1);
- accessory.context.cachePositionState = moveUp ? 0 : 1;
- await utils.sleep(duration);
- params.switches[0].switch = "off";
- params.switches[1].switch = "off";
+ if (newTarget === prevPosition) return;
+ params.switches = cns.defaultMultiSwitchOff;
+ accessory.context.updateKey = updateKey;
+ let percentStepPerDecisecond = blindConfig.operationTime / 100;
+ if (prevState !== 2) {
+ await this.sendDeviceUpdate(accessory, params);
+ let beenMovingAlreadyFor = Math.floor(Date.now() / 100) - accessory.context.cacheLastStartTime;
+ let positionPercentChange = Math.round(beenMovingAlreadyFor * percentStepPerDecisecond);
+ if (prevState === 1) {
+ prevPosition = prevPosition + positionPercentChange;
+ } else {
+ prevPosition = prevPosition - positionPercentChange;
+ }
+ wcService.updateCharacteristic(Characteristic.CurrentPosition, prevPosition);
+ accessory.context.cacheCurrentPosition = prevPosition;
+ }
+ let diffPosition = newTarget - prevPosition;
+ let setToMoveUp = diffPosition > 0;
+ let decisecondsToMove = Math.round(Math.abs(diffPosition) * percentStepPerDecisecond);
+ params.switches[0].switch = setToMoveUp ? "on" : "off";
+ params.switches[1].switch = setToMoveUp ? "off" : "on";
await this.sendDeviceUpdate(accessory, params);
- wcService.updateCharacteristic(Characteristic.PositionState, 2);
- wcService.updateCharacteristic(Characteristic.CurrentPosition, newTarget);
- accessory.context.cacheCurrentPosition = newTarget;
- accessory.context.cachePositionState = 2;
- accessory.context.inUse = false;
+ wcService
+ .updateCharacteristic(Characteristic.TargetPosition, newTarget)
+ .updateCharacteristic(Characteristic.PositionState, setToMoveUp);
+ accessory.context.cacheTargetPosition = newTarget;
+ accessory.context.cachePositionState = setToMoveUp;
+ accessory.context.cacheLastStartTime = Math.floor(Date.now() / 100);
+ this.log.warn(decisecondsToMove + " movement time in deciseconds");
+ await utils.sleep(decisecondsToMove * 100);
+ if (accessory.context.updateKey === updateKey) {
+ params.switches[0].switch = "off";
+ params.switches[1].switch = "off";
+ await this.sendDeviceUpdate(accessory, params);
+ wcService.updateCharacteristic(Characteristic.PositionState, 2);
+ wcService.updateCharacteristic(Characteristic.CurrentPosition, newTarget);
+ accessory.context.cachePositionState = 2;
+ accessory.context.cacheCurrentPosition = newTarget;
+ accessory.context.inUse = false;
+ }
} catch (err) {
this.requestDeviceRefresh(accessory, err);
}
}
externalBlindUpdate(accessory, params) {
try {
- let blindConfig,
- newPosition,
- wcService = accessory.getService(Service.WindowCovering);
- if (!(blindConfig = this.cusG.get(accessory.context.hbDeviceId))) {
- throw "group config missing";
- }
- if (blindConfig.type !== "blind" || blindConfig.setup !== "twoSwitch") {
- throw "improper configuration";
- }
- if (!params.hasOwnProperty("updateSource")) {
- wcService
- .updateCharacteristic(Characteristic.PositionState, accessory.context.cachePositionState)
- .updateCharacteristic(
- Characteristic.TargetPosition,
- accessory.context.cacheTargetPosition
- )
- .updateCharacteristic(
- Characteristic.CurrentPosition,
- accessory.context.cacheCurrentPosition
- );
- return;
- }
- if (accessory.context.inUse) return;
- if (params.switches[0].switch === "off" && params.switches[1].switch === "off") {
- return;
- }
- let switchUp = params.switches[0].switch === "on" ? -1 : 0, // matrix of numbers to get
- switchDown = params.switches[1].switch === "on" ? 0 : 2; // ... the correct HomeKit value
- newPosition = switchUp + switchDown;
- wcService
- .updateCharacteristic(Characteristic.PositionState, newPosition)
- .updateCharacteristic(Characteristic.TargetPosition, newPosition * 100);
- accessory.context.cachePositionState = newPosition;
- accessory.context.cacheTargetPosition = newPosition * 100;
- setTimeout(() => {
- wcService
- .updateCharacteristic(Characteristic.PositionState, 2)
- .updateCharacteristic(Characteristic.CurrentPosition, newPosition * 100);
- accessory.context.cachePositionState = 2;
- accessory.context.cacheCurrentPosition = newPosition * 100;
- }, parseInt(blindConfig.operationTime) * 100);
+ //
} catch (err) {
this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
@@ -1446,10 +1278,7 @@ class eWeLink {
if (!(garageConfig = this.cusG.get(accessory.context.hbDeviceId))) {
throw "group config missing";
}
- if (
- garageConfig.type !== "garage" ||
- !["oneSwitch", "twoSwitch"].includes(garageConfig.setup)
- ) {
+ if (garageConfig.type !== "garage" || !["oneSwitch", "twoSwitch"].includes(garageConfig.setup)) {
throw "improper configuration";
}
let sensorDefinition = garageConfig.sensorId || false,
@@ -1466,9 +1295,7 @@ class eWeLink {
throw "defined DW2 sensor isn't a sensor";
}
prevState = sAccessory
- ? sAccessory
- .getService(Service.ContactSensor)
- .getCharacteristic(Characteristic.ContactSensorState).value === 0
+ ? sAccessory.getService(Service.ContactSensor).getCharacteristic(Characteristic.ContactSensorState).value === 0
? 1
: 0
: accessory.context.cacheCurrentDoorState;
@@ -1517,10 +1344,7 @@ class eWeLink {
if (!(garageConfig = this.cusG.get(accessory.context.hbDeviceId))) {
throw "group config missing";
}
- if (
- garageConfig.type !== "garage" ||
- !["oneSwitch", "twoSwitch"].includes(garageConfig.setup)
- ) {
+ if (garageConfig.type !== "garage" || !["oneSwitch", "twoSwitch"].includes(garageConfig.setup)) {
throw "improper configuration";
}
if (accessory.context.inUse || garageConfig.sensorId) {
@@ -1621,8 +1445,7 @@ class eWeLink {
try {
if (params.hasOwnProperty("battery")) {
let batteryService =
- accessory.getService(Service.BatteryService) ||
- accessory.addService(Service.BatteryService),
+ accessory.getService(Service.BatteryService) || accessory.addService(Service.BatteryService),
scaledBattery = Math.round(params.battery * 33.3);
batteryService.updateCharacteristic(Characteristic.BatteryLevel, scaledBattery);
batteryService.updateCharacteristic(
@@ -1729,11 +1552,7 @@ class eWeLink {
status = 1;
speed = 99;
}
- } else if (
- params.hasOwnProperty("light") &&
- params.hasOwnProperty("fan") &&
- params.hasOwnProperty("speed")
- ) {
+ } else if (params.hasOwnProperty("light") && params.hasOwnProperty("fan") && params.hasOwnProperty("speed")) {
light = params.light === "on";
status = params.fan === "on" ? 1 : 0;
speed = params.speed * 33 * status;
@@ -1764,13 +1583,8 @@ class eWeLink {
}
externalThermostatUpdate(accessory, params) {
try {
- if (
- !this.config.hideTHSwitch &&
- (params.hasOwnProperty("switch") || params.hasOwnProperty("mainSwitch"))
- ) {
- let newState = params.hasOwnProperty("switch")
- ? params.switch === "on"
- : params.mainSwitch === "on",
+ if (!this.config.hideTHSwitch && (params.hasOwnProperty("switch") || params.hasOwnProperty("mainSwitch"))) {
+ let newState = params.hasOwnProperty("switch") ? params.switch === "on" : params.mainSwitch === "on",
switchService = accessory.getService(Service.Switch);
switchService.updateCharacteristic(Characteristic.On, newState);
}
@@ -1778,21 +1592,14 @@ class eWeLink {
let eveLog = {
time: Date.now(),
};
- if (
- params.hasOwnProperty("currentTemperature") &&
- accessory.getService(Service.TemperatureSensor)
- ) {
- let currentTemp =
- params.currentTemperature !== "unavailable" ? params.currentTemperature : 0;
+ if (params.hasOwnProperty("currentTemperature") && accessory.getService(Service.TemperatureSensor)) {
+ let currentTemp = params.currentTemperature !== "unavailable" ? params.currentTemperature : 0;
accessory
.getService(Service.TemperatureSensor)
.updateCharacteristic(Characteristic.CurrentTemperature, currentTemp);
eveLog.temp = parseFloat(currentTemp);
}
- if (
- params.hasOwnProperty("currentHumidity") &&
- accessory.getService(Service.HumiditySensor)
- ) {
+ if (params.hasOwnProperty("currentHumidity") && accessory.getService(Service.HumiditySensor)) {
let currentHumi = params.currentHumidity !== "unavailable" ? params.currentHumidity : 0;
accessory
.getService(Service.HumiditySensor)
@@ -1830,10 +1637,7 @@ class eWeLink {
}
}
if (params.hasOwnProperty("power")) {
- outletService.updateCharacteristic(
- EveService.Characteristics.CurrentConsumption,
- parseFloat(params.power)
- );
+ outletService.updateCharacteristic(EveService.Characteristics.CurrentConsumption, parseFloat(params.power));
outletService.updateCharacteristic(
Characteristic.OutletInUse,
parseFloat(params.power) > (this.config.inUsePowerThreshold || 0)
@@ -1845,16 +1649,10 @@ class eWeLink {
});
}
if (params.hasOwnProperty("voltage")) {
- outletService.updateCharacteristic(
- EveService.Characteristics.Voltage,
- parseFloat(params.voltage)
- );
+ outletService.updateCharacteristic(EveService.Characteristics.Voltage, parseFloat(params.voltage));
}
if (params.hasOwnProperty("current")) {
- outletService.updateCharacteristic(
- EveService.Characteristics.ElectricCurrent,
- parseFloat(params.current)
- );
+ outletService.updateCharacteristic(EveService.Characteristics.ElectricCurrent, parseFloat(params.current));
}
} catch (err) {
this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
@@ -1876,9 +1674,7 @@ class eWeLink {
}
externalUSBUpdate(accessory, params) {
try {
- accessory
- .getService(Service.Outlet)
- .updateCharacteristic(Characteristic.On, params.switches[0].switch === "on");
+ accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, params.switches[0].switch === "on");
} catch (err) {
this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
@@ -1899,9 +1695,7 @@ class eWeLink {
}
externalSCMUpdate(accessory, params) {
try {
- accessory
- .getService(Service.Switch)
- .updateCharacteristic(Characteristic.On, params.switches[0].switch === "on");
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, params.switches[0].switch === "on");
} catch (err) {
this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
@@ -1956,9 +1750,7 @@ class eWeLink {
case "0":
for (let i = 0; i <= 4; i++) {
if ((oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
- oAccessory
- .getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.On, value);
+ oAccessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
}
}
break;
@@ -1970,18 +1762,14 @@ class eWeLink {
let masterState = "off";
for (let i = 1; i <= 4; i++) {
if ((oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
- if (
- oAccessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value
- ) {
+ if (oAccessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value) {
masterState = "on";
}
}
}
if (!this.hiddenMasters.includes(accessory.context.eweDeviceId)) {
oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
- oAccessory
- .getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.On, masterState === "on");
+ oAccessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, masterState === "on");
}
break;
}
@@ -2124,10 +1912,7 @@ class eWeLink {
case 22: // B1
if (params.hasOwnProperty("zyx_mode")) {
mode = parseInt(params.zyx_mode);
- } else if (
- params.hasOwnProperty("channel0") &&
- parseInt(params.channel0) + parseInt(params.channel1) > 0
- ) {
+ } else if (params.hasOwnProperty("channel0") && parseInt(params.channel0) + parseInt(params.channel1) > 0) {
mode = 1;
} else {
mode = 2;
@@ -2184,9 +1969,7 @@ class eWeLink {
}
}
if (!this.hiddenMasters.includes(accessory.context.eweDeviceId)) {
- accessory
- .getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.On, primaryState);
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, primaryState);
}
} catch (err) {
this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
@@ -2249,18 +2032,14 @@ class eWeLink {
let masterState = "off";
for (let i = 1; i <= 4; i++) {
if ((oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
- if (
- oAccessory.getService(Service.Switch).getCharacteristic(Characteristic.On).value
- ) {
+ if (oAccessory.getService(Service.Switch).getCharacteristic(Characteristic.On).value) {
masterState = "on";
}
}
}
if (!this.hiddenMasters.includes(accessory.context.eweDeviceId)) {
oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
- oAccessory
- .getService(Service.Switch)
- .updateCharacteristic(Characteristic.On, masterState === "on");
+ oAccessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, masterState === "on");
}
break;
}
@@ -2270,9 +2049,7 @@ class eWeLink {
}
externalSingleSwitchUpdate(accessory, params) {
try {
- accessory
- .getService(Service.Switch)
- .updateCharacteristic(Characteristic.On, params.switch === "on");
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, params.switch === "on");
} catch (err) {
this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
@@ -2320,11 +2097,7 @@ class eWeLink {
if (!params.hasOwnProperty("updateSource")) return;
let timeNow = new Date(),
oAccessory = false;
- if (
- params.hasOwnProperty("cmd") &&
- params.cmd === "transmit" &&
- params.hasOwnProperty("rfChl")
- ) {
+ if (params.hasOwnProperty("cmd") && params.cmd === "transmit" && params.hasOwnProperty("rfChl")) {
//*** RF Button ***\\
// the device needed is SW% corresponding to params.rfChl
this.devicesInHB.forEach(acc => {
@@ -2336,9 +2109,7 @@ class eWeLink {
}
});
if (oAccessory) {
- oAccessory
- .getService(oAccessory.context.buttons[params.rfChl])
- .updateCharacteristic(Characteristic.On, 1);
+ oAccessory.getService(oAccessory.context.buttons[params.rfChl]).updateCharacteristic(Characteristic.On, 1);
setTimeout(
() =>
oAccessory
@@ -2406,11 +2177,7 @@ class eWeLink {
oAccessory.getService(serv).updateCharacteristic(char, 0);
}, (this.config.sensorTimeLength || 2) * 1000);
if (this.debug) {
- this.log(
- "[%s] has detected [%s].",
- oAccessory.displayName,
- oAccessory.context.sensorType
- );
+ this.log("[%s] has detected [%s].", oAccessory.displayName, oAccessory.context.sensorType);
}
}
}
@@ -2428,8 +2195,7 @@ class eWeLink {
params.battery *= 10;
}
let batteryService =
- accessory.getService(Service.BatteryService) ||
- accessory.addService(Service.BatteryService);
+ accessory.getService(Service.BatteryService) || accessory.addService(Service.BatteryService);
batteryService.updateCharacteristic(Characteristic.BatteryLevel, params.battery);
batteryService.updateCharacteristic(
Characteristic.StatusLowBattery,
diff --git a/lib/eWeLinkHTTP.js b/lib/eWeLinkHTTP.js
index 4076d982..03e24b06 100644
--- a/lib/eWeLinkHTTP.js
+++ b/lib/eWeLinkHTTP.js
@@ -33,10 +33,7 @@ module.exports = class eWeLinkHTTP {
});
dataToSign.sort((a, b) => (a.key < b.key ? -1 : 1));
dataToSign = dataToSign.map(k => k.key + "=" + k.value).join("&");
- dataToSign = crypto
- .createHmac("sha256", constants.appSecret)
- .update(dataToSign)
- .digest("base64");
+ dataToSign = crypto.createHmac("sha256", constants.appSecret).update(dataToSign).digest("base64");
if (this.debugReqRes) {
this.log.warn(
"Sending HTTP getHost request. This text is yellow for clarity.\n%s",
@@ -73,10 +70,7 @@ module.exports = class eWeLinkHTTP {
}
resolve(this.httpHost);
} catch (err) {
- if (
- err.hasOwnProperty("code") &&
- ["ENOTFOUND", "ETIMEDOUT", "EAI_AGAIN"].includes(err.code)
- ) {
+ if (err.hasOwnProperty("code") && ["ENOTFOUND", "ETIMEDOUT", "EAI_AGAIN"].includes(err.code)) {
this.log.warn("Unable to reach eWeLink. Retrying in 30 seconds.");
await utils.sleep(30000);
resolve(this.getHost());
@@ -93,9 +87,7 @@ module.exports = class eWeLinkHTTP {
password: this.password,
};
try {
- this.username.includes("@")
- ? (data.email = this.username)
- : (data.phoneNumber = this.username);
+ this.username.includes("@") ? (data.email = this.username) : (data.phoneNumber = this.username);
if (this.debugReqRes) {
let msg = JSON.stringify(data, null, 2)
.replace(this.password, "**hidden**")
@@ -104,10 +96,7 @@ module.exports = class eWeLinkHTTP {
} else if (this.debug) {
this.log("Sending HTTP login request.");
}
- let dataToSign = crypto
- .createHmac("sha256", constants.appSecret)
- .update(JSON.stringify(data))
- .digest("base64");
+ let dataToSign = crypto.createHmac("sha256", constants.appSecret).update(JSON.stringify(data)).digest("base64");
let res = await axios.post("https://" + this.httpHost + "/v2/user/login", data, {
headers: {
Authorization: "Sign " + dataToSign,
diff --git a/lib/eWeLinkLAN.js b/lib/eWeLinkLAN.js
index b046db46..70d0c13c 100644
--- a/lib/eWeLinkLAN.js
+++ b/lib/eWeLinkLAN.js
@@ -15,9 +15,7 @@ module.exports = class eWeLinkLAN {
this.deviceMap.set(device.deviceid, {
apiKey: device.devicekey,
online: this.ipOverrides.hasOwnProperty(device.deviceid) ? true : false,
- ip: this.ipOverrides.hasOwnProperty(device.deviceid)
- ? this.ipOverrides[device.deviceid]
- : null,
+ ip: this.ipOverrides.hasOwnProperty(device.deviceid) ? this.ipOverrides[device.deviceid] : null,
});
});
this.debug = config.debug || false;
@@ -64,15 +62,9 @@ module.exports = class eWeLinkLAN {
(rdata.hasOwnProperty("data2") ? rdata.data2 : "") +
(rdata.hasOwnProperty("data3") ? rdata.data3 : "") +
(rdata.hasOwnProperty("data4") ? rdata.data4 : ""),
- key = crypto
- .createHash("md5")
- .update(Buffer.from(deviceInfo.apiKey, "utf8"))
- .digest(),
+ key = crypto.createHash("md5").update(Buffer.from(deviceInfo.apiKey, "utf8")).digest(),
dText = crypto.createDecipheriv("aes-128-cbc", key, Buffer.from(rdata.iv, "base64")),
- pText = Buffer.concat([
- dText.update(Buffer.from(data, "base64")),
- dText.final(),
- ]).toString("utf8"),
+ pText = Buffer.concat([dText.update(Buffer.from(data, "base64")), dText.final()]).toString("utf8"),
params;
if (packet.address !== deviceInfo.ip && !this.ipOverrides.hasOwnProperty(rdata.id)) {
this.deviceMap.set(rdata.id, {
@@ -140,9 +132,7 @@ module.exports = class eWeLinkLAN {
iv = crypto.randomBytes(16),
enc = crypto.createCipheriv("aes-128-cbc", key, iv),
data = {
- data: Buffer.concat([enc.update(JSON.stringify(params)), enc.final()]).toString(
- "base64"
- ),
+ data: Buffer.concat([enc.update(JSON.stringify(params)), enc.final()]).toString("base64"),
deviceid: json.deviceid,
encrypt: true,
iv: iv.toString("base64"),
@@ -185,9 +175,7 @@ module.exports = class eWeLinkLAN {
this.deviceMap.set(device.deviceid, {
apiKey: device.devicekey,
online: this.ipOverrides.hasOwnProperty(device.deviceid) ? true : false,
- ip: this.ipOverrides.hasOwnProperty(device.deviceid)
- ? this.ipOverrides[device.deviceid]
- : null,
+ ip: this.ipOverrides.hasOwnProperty(device.deviceid) ? this.ipOverrides[device.deviceid] : null,
});
}
closeConnection() {
diff --git a/lib/eWeLinkWS.js b/lib/eWeLinkWS.js
index a9df48ca..c3201325 100644
--- a/lib/eWeLinkWS.js
+++ b/lib/eWeLinkWS.js
@@ -100,12 +100,7 @@ module.exports = class eWeLinkWS {
let res = await this.wsp.sendRequest(payload, {
requestId: sequence,
});
- if (
- res.hasOwnProperty("config") &&
- res.config.hb &&
- res.config.hbInterval &&
- !this.hbInterval
- ) {
+ if (res.hasOwnProperty("config") && res.config.hb && res.config.hbInterval && !this.hbInterval) {
this.hbInterval = setInterval(() => {
this.wsp.send("ping");
}, (res.config.hbInterval + 7) * 1000);
@@ -146,10 +141,7 @@ module.exports = class eWeLinkWS {
params: device.params,
};
if (this.debugReqRes) {
- let msg = JSON.stringify(returnTemplate, null, 2).replace(
- device.deviceid,
- "**hidden**"
- );
+ let msg = JSON.stringify(returnTemplate, null, 2).replace(device.deviceid, "**hidden**");
this.log("WS message received.\n%s", msg);
} else if (this.debug) {
this.log("WS message received.");
@@ -160,10 +152,7 @@ module.exports = class eWeLinkWS {
case "reportSubDevice":
return;
default:
- this.log.warn(
- "[%s] WS message has unknown action.\n" + JSON.stringify(device, null, 2),
- device.deviceid
- );
+ this.log.warn("[%s] WS message has unknown action.\n" + JSON.stringify(device, null, 2), device.deviceid);
return;
}
} else if (device.hasOwnProperty("error") && device.error === 0) {
@@ -194,9 +183,7 @@ module.exports = class eWeLinkWS {
this.wsp.onError.addListener(e => {
this.log.error("Web socket error - [%s].", e);
if (e.code === "ECONNREFUSED") {
- this.log.warn(
- "Web socket will try to reconnect in five seconds then try the command again."
- );
+ this.log.warn("Web socket will try to reconnect in five seconds then try the command again.");
this.wsp.removeAllListeners();
setTimeout(() => this.login(), 5000);
} else {
From 11ae9127ac5266b2b30311fb5ab8389270089594 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sat, 26 Sep 2020 17:51:24 +0100
Subject: [PATCH 0221/3183] 3.0.3-0
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 16b95537..0f7c5732 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.0.2",
+ "version": "3.0.3-0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index cf8c488f..761b4ca3 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.0.2",
+ "version": "3.0.3-0",
"author": "bwp91",
"contributors": [
"gbro115",
From a6e3b516f5a167d9d171185361f58e8a24adf6ed Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sat, 26 Sep 2020 18:55:39 +0100
Subject: [PATCH 0222/3183] blinds rel % fix
---
lib/eWeLink.js | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 57e64c9d..53bc6241 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -1211,7 +1211,6 @@ class eWeLink {
wcService = accessory.getService(Service.WindowCovering),
prevState = accessory.context.cachePositionState,
prevPosition = accessory.context.cacheCurrentPosition,
- prevTarget = accessory.context.cacheTargetPosition,
newTarget = value,
updateKey = Math.random().toString(36).substr(2, 8);
if (!(blindConfig = this.cusG.get(accessory.context.hbDeviceId))) {
@@ -1226,12 +1225,13 @@ class eWeLink {
let percentStepPerDecisecond = blindConfig.operationTime / 100;
if (prevState !== 2) {
await this.sendDeviceUpdate(accessory, params);
- let beenMovingAlreadyFor = Math.floor(Date.now() / 100) - accessory.context.cacheLastStartTime;
- let positionPercentChange = Math.round(beenMovingAlreadyFor * percentStepPerDecisecond);
- if (prevState === 1) {
- prevPosition = prevPosition + positionPercentChange;
+ let positionPercentChange = Math.round(
+ Math.floor(Date.now() / 100) - accessory.context.cacheLastStartTime * percentStepPerDecisecond
+ );
+ if ((prevState === 0 && newTarget > prevPosition) || (prevState === 1 && newTarget < prevPosition)) {
+ prevPosition += positionPercentChange;
} else {
- prevPosition = prevPosition - positionPercentChange;
+ prevPosition -= positionPercentChange;
}
wcService.updateCharacteristic(Characteristic.CurrentPosition, prevPosition);
accessory.context.cacheCurrentPosition = prevPosition;
@@ -1258,7 +1258,6 @@ class eWeLink {
wcService.updateCharacteristic(Characteristic.CurrentPosition, newTarget);
accessory.context.cachePositionState = 2;
accessory.context.cacheCurrentPosition = newTarget;
- accessory.context.inUse = false;
}
} catch (err) {
this.requestDeviceRefresh(accessory, err);
@@ -1266,7 +1265,6 @@ class eWeLink {
}
externalBlindUpdate(accessory, params) {
try {
- //
} catch (err) {
this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
}
From f6ca880243168b4db2ac15f275b377e3d90a02b0 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sat, 26 Sep 2020 18:56:15 +0100
Subject: [PATCH 0223/3183] 3.0.3-1
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 0f7c5732..cf967598 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.0.3-0",
+ "version": "3.0.3-1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 761b4ca3..a50beb2b 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.0.3-0",
+ "version": "3.0.3-1",
"author": "bwp91",
"contributors": [
"gbro115",
From 825bfbcded98d7ae5953cae6eef3a13e3d10c814 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sat, 26 Sep 2020 20:54:39 +0100
Subject: [PATCH 0224/3183] separate devices
---
lib/constants.js | 1 -
lib/device/blind.js | 73 +++
lib/device/curtain.js | 52 ++
lib/device/fan.js | 92 +++
lib/device/garage.js | 125 ++++
lib/device/light.js | 287 +++++++++
lib/device/lock.js | 67 ++
lib/device/outlet.js | 56 ++
lib/device/rf-sub.js | 122 ++++
lib/device/scm.js | 32 +
lib/device/sensor.js | 54 ++
lib/device/switch.js | 111 ++++
lib/device/thermostat.js | 58 ++
lib/device/usb.js | 31 +
lib/device/valve.js | 71 ++
lib/device/zb-dev.js | 82 +++
lib/eWeLink.js | 1327 +++-----------------------------------
17 files changed, 1412 insertions(+), 1229 deletions(-)
create mode 100644 lib/device/blind.js
create mode 100644 lib/device/curtain.js
create mode 100644 lib/device/fan.js
create mode 100644 lib/device/garage.js
create mode 100644 lib/device/light.js
create mode 100644 lib/device/lock.js
create mode 100644 lib/device/outlet.js
create mode 100644 lib/device/rf-sub.js
create mode 100644 lib/device/scm.js
create mode 100644 lib/device/sensor.js
create mode 100644 lib/device/switch.js
create mode 100644 lib/device/thermostat.js
create mode 100644 lib/device/usb.js
create mode 100644 lib/device/valve.js
create mode 100644 lib/device/zb-dev.js
diff --git a/lib/constants.js b/lib/constants.js
index 555488c5..803a3423 100644
--- a/lib/constants.js
+++ b/lib/constants.js
@@ -48,7 +48,6 @@ module.exports = {
devicesZBBridgeParams: ["key", "temperature", "humidity", "motion", "lock", "trigTime", "battery"],
devicesZB: [1000, 1770, 2026, 3026],
devicesValveParams: ["switches"],
- devicesBlindParams: ["switch", "switches"],
devicesGarageParams: ["switch", "switches"],
devicesLockParams: ["switch"],
allowedGroups: ["blind", "garage", "lock"],
diff --git a/lib/device/blind.js b/lib/device/blind.js
new file mode 100644
index 00000000..8057a852
--- /dev/null
+++ b/lib/device/blind.js
@@ -0,0 +1,73 @@
+/* jshint esversion: 9, -W014, -W030, node: true */
+"use strict";
+let Characteristic, Service;
+const cns = require("./../constants"),
+ utils = require("./../utils");
+module.exports = class deviceBlind {
+ constructor(platform) {
+ this.platform = platform;
+ Service = platform.api.hap.Service;
+ Characteristic = platform.api.hap.Characteristic;
+ }
+
+ async internalBlindUpdate(accessory, value, callback) {
+ callback();
+ try {
+ let blindConfig,
+ params = {},
+ wcService = accessory.getService(Service.WindowCovering),
+ prevState = accessory.context.cachePositionState,
+ prevPosition = accessory.context.cacheCurrentPosition,
+ newTarget = value,
+ updateKey = Math.random().toString(36).substr(2, 8);
+ if (!(blindConfig = this.cusG.get(accessory.context.hbDeviceId))) {
+ throw "group config missing";
+ }
+ if (blindConfig.type !== "blind" || blindConfig.setup !== "twoSwitch") {
+ throw "improper configuration";
+ }
+ if (newTarget === prevPosition) return;
+ params.switches = cns.defaultMultiSwitchOff;
+ accessory.context.updateKey = updateKey;
+ let percentStepPerDecisecond = blindConfig.operationTime / 100;
+ if (prevState !== 2) {
+ await this.platform.sendDeviceUpdate(accessory, params);
+ let positionPercentChange = Math.round(
+ Math.floor(Date.now() / 100) - accessory.context.cacheLastStartTime * percentStepPerDecisecond
+ );
+ if ((prevState === 0 && newTarget > prevPosition) || (prevState === 1 && newTarget < prevPosition)) {
+ prevPosition += positionPercentChange;
+ } else {
+ prevPosition -= positionPercentChange;
+ }
+ wcService.updateCharacteristic(Characteristic.CurrentPosition, prevPosition);
+ accessory.context.cacheCurrentPosition = prevPosition;
+ }
+ let diffPosition = newTarget - prevPosition;
+ let setToMoveUp = diffPosition > 0;
+ let decisecondsToMove = Math.round(Math.abs(diffPosition) * percentStepPerDecisecond);
+ params.switches[0].switch = setToMoveUp ? "on" : "off";
+ params.switches[1].switch = setToMoveUp ? "off" : "on";
+ await this.platform.sendDeviceUpdate(accessory, params);
+ wcService
+ .updateCharacteristic(Characteristic.TargetPosition, newTarget)
+ .updateCharacteristic(Characteristic.PositionState, setToMoveUp);
+ accessory.context.cacheTargetPosition = newTarget;
+ accessory.context.cachePositionState = setToMoveUp;
+ accessory.context.cacheLastStartTime = Math.floor(Date.now() / 100);
+ this.platform.log.warn(decisecondsToMove + " movement time in deciseconds");
+ await utils.sleep(decisecondsToMove * 100);
+ if (accessory.context.updateKey === updateKey) {
+ params.switches[0].switch = "off";
+ params.switches[1].switch = "off";
+ await this.platform.sendDeviceUpdate(accessory, params);
+ wcService.updateCharacteristic(Characteristic.PositionState, 2);
+ wcService.updateCharacteristic(Characteristic.CurrentPosition, newTarget);
+ accessory.context.cachePositionState = 2;
+ accessory.context.cacheCurrentPosition = newTarget;
+ }
+ } catch (err) {
+ this.platform.requestDeviceRefresh(accessory, err);
+ }
+ }
+};
diff --git a/lib/device/curtain.js b/lib/device/curtain.js
new file mode 100644
index 00000000..d7a8cf8a
--- /dev/null
+++ b/lib/device/curtain.js
@@ -0,0 +1,52 @@
+/* jshint esversion: 9, -W014, -W030, node: true */
+"use strict";
+let Characteristic, Service;
+module.exports = class deviceCurtain {
+ constructor(platform) {
+ this.platform = platform;
+ Service = platform.api.hap.Service;
+ Characteristic = platform.api.hap.Characteristic;
+ }
+ async internalCurtainUpdate(accessory, value, callback) {
+ callback();
+ try {
+ let params,
+ cService = accessory.getService(Service.WindowCovering),
+ prevPos = accessory.context.cacheCurrentPosition,
+ newPos = value;
+ if (newPos === prevPos) return;
+ if (newPos === 0 || newPos === 100) {
+ params = {
+ switch: newPos === 100 ? "on" : "off",
+ };
+ } else {
+ params = {
+ setclose: Math.abs(100 - newPos),
+ };
+ }
+ await this.platform.sendDeviceUpdate(accessory, params);
+ cService
+ .updateCharacteristic(Characteristic.TargetPosition, newPos)
+ .updateCharacteristic(Characteristic.PositionState, newPos > prevPos ? 1 : 0);
+ accessory.context.cacheCurrentPosition = newPos;
+ } catch (err) {
+ this.platform.requestDeviceRefresh(accessory, err);
+ }
+ }
+ externalCurtainUpdate(accessory, params) {
+ try {
+ let cService = accessory.getService(Service.WindowCovering);
+ if (params.hasOwnProperty("switch") && params.hasOwnProperty("setclose")) {
+ let newPos = Math.abs(100 - parseInt(params.setclose));
+ cService
+ .updateCharacteristic(Characteristic.TargetPosition, newPos)
+ .updateCharacteristic(Characteristic.CurrentPosition, newPos)
+ .updateCharacteristic(Characteristic.PositionState, 2);
+ accessory.context.cacheCurrentPosition = newPos;
+ return;
+ }
+ } catch (err) {
+ this.platform.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
+};
diff --git a/lib/device/fan.js b/lib/device/fan.js
new file mode 100644
index 00000000..2c12a5e7
--- /dev/null
+++ b/lib/device/fan.js
@@ -0,0 +1,92 @@
+/* jshint esversion: 9, -W014, -W030, node: true */
+"use strict";
+let Characteristic, Service;
+module.exports = class deviceFan {
+ constructor(platform) {
+ this.platform = platform;
+ Service = platform.api.hap.Service;
+ Characteristic = platform.api.hap.Characteristic;
+ }
+ async internalFanUpdate(accessory, type, value, callback) {
+ callback();
+ try {
+ let newPower,
+ newSpeed,
+ newLight,
+ lightService = accessory.getService(Service.Lightbulb),
+ fanService = accessory.getService(Service.Fanv2);
+ switch (type) {
+ case "power":
+ newPower = value;
+ newSpeed = value ? 33 : 0;
+ newLight = lightService.getCharacteristic(Characteristic.On).value;
+ break;
+ case "speed":
+ newPower = value >= 33 ? 1 : 0;
+ newSpeed = value;
+ newLight = lightService.getCharacteristic(Characteristic.On).value;
+ break;
+ case "light":
+ newPower = fanService.getCharacteristic(Characteristic.Active).value;
+ newSpeed = fanService.getCharacteristic(Characteristic.RotationSpeed).value;
+ newLight = value;
+ break;
+ }
+ let params = {
+ switches: this.platform.devicesInEW.get(accessory.context.eweDeviceId).params.switches,
+ };
+ params.switches[0].switch = newLight ? "on" : "off";
+ params.switches[1].switch = newPower === 1 && newSpeed >= 33 ? "on" : "off";
+ params.switches[2].switch = newPower === 1 && newSpeed >= 66 && newSpeed < 99 ? "on" : "off";
+ params.switches[3].switch = newPower === 1 && newSpeed >= 99 ? "on" : "off";
+ await this.platform.sendDeviceUpdate(accessory, params);
+ lightService.updateCharacteristic(Characteristic.On, newLight);
+ fanService
+ .updateCharacteristic(Characteristic.Active, newPower)
+ .updateCharacteristic(Characteristic.RotationSpeed, newSpeed);
+ } catch (err) {
+ this.platform.requestDeviceRefresh(accessory, err);
+ }
+ }
+ externalFanUpdate(accessory, params) {
+ try {
+ let light,
+ status,
+ speed,
+ lightService = accessory.getService(Service.Lightbulb),
+ fanService = accessory.getService(Service.Fanv2);
+ if (Array.isArray(params.switches)) {
+ light = params.switches[0].switch === "on";
+ switch (params.switches[1].switch + params.switches[2].switch + params.switches[3].switch) {
+ default:
+ status = 0;
+ speed = 0;
+ break;
+ case "onoffoff":
+ status = 1;
+ speed = 33;
+ break;
+ case "ononoff":
+ status = 1;
+ speed = 66;
+ break;
+ case "onoffon":
+ status = 1;
+ speed = 99;
+ }
+ } else if (params.hasOwnProperty("light") && params.hasOwnProperty("fan") && params.hasOwnProperty("speed")) {
+ light = params.light === "on";
+ status = params.fan === "on" ? 1 : 0;
+ speed = params.speed * 33 * status;
+ } else {
+ throw "unknown parameters received";
+ }
+ lightService.updateCharacteristic(Characteristic.On, light);
+ fanService
+ .updateCharacteristic(Characteristic.Active, status)
+ .updateCharacteristic(Characteristic.RotationSpeed, speed);
+ } catch (err) {
+ this.platform.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
+};
diff --git a/lib/device/garage.js b/lib/device/garage.js
new file mode 100644
index 00000000..e888c551
--- /dev/null
+++ b/lib/device/garage.js
@@ -0,0 +1,125 @@
+/* jshint esversion: 9, -W014, -W030, node: true */
+"use strict";
+let Characteristic, Service;
+const utils = require("./../utils");
+module.exports = class deviceGarage {
+ constructor(platform) {
+ this.platform = platform;
+ Service = platform.api.hap.Service;
+ Characteristic = platform.api.hap.Characteristic;
+ }
+ async internalGarageUpdate(accessory, value, callback) {
+ callback();
+ try {
+ let garageConfig;
+ if (!(garageConfig = this.platform.cusG.get(accessory.context.hbDeviceId))) {
+ throw "group config missing";
+ }
+ if (garageConfig.type !== "garage" || !["oneSwitch", "twoSwitch"].includes(garageConfig.setup)) {
+ throw "improper configuration";
+ }
+ let sensorDefinition = garageConfig.sensorId || false,
+ sAccessory = false,
+ prevState,
+ newPos = value,
+ params = {},
+ delay = 0,
+ gdService = accessory.getService(Service.GarageDoorOpener);
+ if (sensorDefinition && !(sAccessory = this.platform.devicesInHB.get(garageConfig.sensorId + "SWX"))) {
+ throw "defined DW2 sensor doesn't exist";
+ }
+ if (sensorDefinition && sAccessory.context.type !== "sensor") {
+ throw "defined DW2 sensor isn't a sensor";
+ }
+ prevState = sAccessory
+ ? sAccessory.getService(Service.ContactSensor).getCharacteristic(Characteristic.ContactSensorState).value === 0
+ ? 1
+ : 0
+ : accessory.context.cacheCurrentDoorState;
+ if (newPos === prevState % 2) return;
+ accessory.context.inUse = true;
+ accessory.context.state = value;
+ if (garageConfig.setup === "oneSwitch" && [2, 3].includes(prevState)) {
+ gdService.updateCharacteristic(Characteristic.CurrentDoorState, ((prevState * 2) % 3) + 2);
+ accessory.context.cacheCurrentDoorState = ((prevState * 2) % 3) + 2;
+ delay = 1500;
+ }
+ if (accessory.context.state !== newPos) return;
+ await utils.sleep(delay);
+ gdService
+ .updateCharacteristic(Characteristic.TargetDoorState, newPos)
+ .updateCharacteristic(Characteristic.CurrentDoorState, newPos + 2);
+ accessory.context.cacheTargetDoorState = newPos;
+ accessory.context.cacheCurrentDoorState = newPos + 2;
+ switch (garageConfig.setup) {
+ case "oneSwitch":
+ params.switch = "on";
+ break;
+ case "twoSwitch":
+ params.switches = this.platform.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
+ params.switches[0].switch = newPos === 0 ? "on" : "off";
+ params.switches[1].switch = newPos === 1 ? "on" : "off";
+ break;
+ }
+ await this.platform.sendDeviceUpdate(accessory, params);
+ await utils.sleep(garageConfig.operationTime * 100);
+ if (!sAccessory) {
+ gdService.updateCharacteristic(Characteristic.CurrentDoorState, newPos);
+ accessory.context.cacheCurrentDoorState = newPos;
+ }
+ accessory.context.inUse = false;
+ } catch (err) {
+ this.platform.requestDeviceRefresh(accessory, err);
+ }
+ }
+ externalGarageUpdate(accessory, params) {
+ try {
+ let garageConfig,
+ gcService = accessory.getService(Service.GarageDoorOpener),
+ prevState = accessory.context.cacheCurrentDoorState,
+ newPos = [0, 2].includes(prevState) ? 3 : 2;
+ if (!(garageConfig = this.platform.cusG.get(accessory.context.hbDeviceId))) {
+ throw "group config missing";
+ }
+ if (garageConfig.type !== "garage" || !["oneSwitch", "twoSwitch"].includes(garageConfig.setup)) {
+ throw "improper configuration";
+ }
+ if (accessory.context.inUse || garageConfig.sensorId) {
+ return;
+ }
+ switch (garageConfig.setup) {
+ case "oneSwitch":
+ if (params.switch === "off") {
+ return;
+ }
+ break;
+ case "twoSwitch":
+ if (
+ params.switches[0].switch === params.switches[1].switch ||
+ params.switches[prevState % 2].switch === "on"
+ ) {
+ return;
+ }
+ break;
+ }
+ accessory.context.inUse = true;
+ if (!garageConfig.sensorId) {
+ gcService
+ .updateCharacteristic(Characteristic.CurrentDoorState, newPos)
+ .updateCharacteristic(Characteristic.TargetDoorState, newPos - 2);
+ accessory.context.cacheCurrentDoorState = newPos;
+ accessory.context.cacheTargetDoorState = newPos - 2;
+ setTimeout(() => {
+ gcService.updateCharacteristic(Characteristic.CurrentDoorState, newPos - 2);
+ accessory.context.cacheCurrentDoorState = newPos - 2;
+ }, parseInt(garageConfig.operationTime) * 100);
+ }
+ setTimeout(() => {
+ accessory.context.inUse = false;
+ }, parseInt(garageConfig.operationTime) * 100);
+ } catch (err) {
+ accessory.context.inUse = false;
+ this.platform.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
+};
diff --git a/lib/device/light.js b/lib/device/light.js
new file mode 100644
index 00000000..ac838310
--- /dev/null
+++ b/lib/device/light.js
@@ -0,0 +1,287 @@
+/* jshint esversion: 9, -W014, -W030, node: true */
+"use strict";
+let Characteristic, Service;
+const convert = require("color-convert"),
+ utils = require("./../utils");
+module.exports = class deviceLight {
+ constructor(platform) {
+ this.platform = platform;
+ Service = platform.api.hap.Service;
+ Characteristic = platform.api.hap.Characteristic;
+ }
+ async internalLightbulbUpdate(accessory, value, callback) {
+ callback();
+ try {
+ let oAccessory,
+ params = {},
+ lightService = accessory.getService(Service.Lightbulb);
+ switch (accessory.context.switchNumber) {
+ case "X":
+ if (accessory.context.eweUIID === 22) {
+ //*** B1 ***\\
+ params.state = value ? "on" : "off";
+ } else {
+ params.switch = value ? "on" : "off";
+ }
+ break;
+ case "0":
+ params.switches = this.platform.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
+ params.switches[0].switch = value ? "on" : "off";
+ params.switches[1].switch = value ? "on" : "off";
+ params.switches[2].switch = value ? "on" : "off";
+ params.switches[3].switch = value ? "on" : "off";
+ break;
+ case "1":
+ case "2":
+ case "3":
+ case "4":
+ params.switches = this.platform.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
+ for (let i = 1; i <= 4; i++) {
+ if ((oAccessory = this.platform.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
+ i === parseInt(accessory.context.switchNumber)
+ ? (params.switches[i - 1].switch = value ? "on" : "off")
+ : (params.switches[i - 1].switch = oAccessory
+ .getService(Service.Lightbulb)
+ .getCharacteristic(Characteristic.On).value
+ ? "on"
+ : "off");
+ } else {
+ params.switches[i - 1].switch = "off";
+ }
+ }
+ break;
+ }
+ await this.platform.sendDeviceUpdate(accessory, params);
+ switch (accessory.context.switchNumber) {
+ case "X":
+ lightService.updateCharacteristic(Characteristic.On, value);
+ break;
+ case "0":
+ for (let i = 0; i <= 4; i++) {
+ if ((oAccessory = this.platform.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
+ oAccessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
+ }
+ }
+ break;
+ case "1":
+ case "2":
+ case "3":
+ case "4":
+ lightService.updateCharacteristic(Characteristic.On, value);
+ let masterState = "off";
+ for (let i = 1; i <= 4; i++) {
+ if ((oAccessory = this.platform.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
+ if (oAccessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value) {
+ masterState = "on";
+ }
+ }
+ }
+ if (!this.platform.hiddenMasters.includes(accessory.context.eweDeviceId)) {
+ oAccessory = this.platform.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
+ oAccessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, masterState === "on");
+ }
+ break;
+ }
+ } catch (err) {
+ this.platform.requestDeviceRefresh(accessory, err);
+ }
+ }
+ async internalBrightnessUpdate(accessory, value, callback) {
+ callback();
+ try {
+ let params = {},
+ lightService = accessory.getService(Service.Lightbulb);
+ if (value === 0) {
+ params.switch = "off";
+ } else {
+ if (!lightService.getCharacteristic(Characteristic.On).value) {
+ params.switch = "on";
+ }
+ switch (accessory.context.eweUIID) {
+ case 36: //*** KING-M4 ***\\
+ params.bright = Math.round((value * 9) / 10 + 10);
+ break;
+ case 44: //*** D1 ***\\
+ params.brightness = value;
+ params.mode = 0;
+ break;
+ }
+ }
+ await utils.sleep(250);
+ await this.platform.sendDeviceUpdate(accessory, params);
+ if (value === 0) {
+ lightService.updateCharacteristic(Characteristic.On, false);
+ } else {
+ lightService.updateCharacteristic(Characteristic.Brightness, value);
+ }
+ } catch (err) {
+ this.platform.requestDeviceRefresh(accessory, err);
+ }
+ }
+ async internalHSBUpdate(accessory, type, value, callback) {
+ callback();
+ try {
+ if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
+ throw "it is currently offline";
+ }
+ let newRGB,
+ params = {},
+ lightService = accessory.getService(Service.Lightbulb),
+ curHue = lightService.getCharacteristic(Characteristic.Hue).value,
+ curSat = lightService.getCharacteristic(Characteristic.Saturation).value;
+ switch (type) {
+ case "hue":
+ newRGB = convert.hsv.rgb(value, curSat, 100);
+ switch (accessory.context.eweUIID) {
+ case 22: //*** B1 ***\\
+ params = {
+ zyx_mode: 2,
+ type: "middle",
+ channel0: "0",
+ channel1: "0",
+ channel2: newRGB[0].toString(),
+ channel3: newRGB[1].toString(),
+ channel4: newRGB[2].toString(),
+ };
+ break;
+ case 59: //*** L1 ***\\
+ params = {
+ mode: 1,
+ colorR: newRGB[0],
+ colorG: newRGB[1],
+ colorB: newRGB[2],
+ };
+ break;
+ }
+ break;
+ case "bri":
+ switch (accessory.context.eweUIID) {
+ case 22: //*** B1 ***\\
+ newRGB = convert.hsv.rgb(curHue, curSat, value);
+ params = {
+ zyx_mode: 2,
+ type: "middle",
+ channel0: "0",
+ channel1: "0",
+ channel2: newRGB[0].toString(),
+ channel3: newRGB[1].toString(),
+ channel4: newRGB[2].toString(),
+ };
+ break;
+ case 59: //*** L1 ***\\
+ params = {
+ mode: 1,
+ bright: value,
+ };
+ break;
+ }
+ break;
+ }
+ await utils.sleep(250);
+ await this.platform.sendDeviceUpdate(accessory, params);
+ switch (type) {
+ case "hue":
+ lightService.updateCharacteristic(Characteristic.Hue, value);
+ break;
+ case "bri":
+ lightService.updateCharacteristic(Characteristic.Brightness, value);
+ break;
+ }
+ } catch (err) {
+ this.platform.requestDeviceRefresh(accessory, err);
+ }
+ }
+ externalSingleLightUpdate(accessory, params) {
+ try {
+ let newColour,
+ mode,
+ isOn = false,
+ lightService = accessory.getService(Service.Lightbulb);
+ if (accessory.context.eweUIID === 22 && params.hasOwnProperty("state")) {
+ isOn = params.state === "on";
+ } else if (accessory.context.eweUIID !== 22 && params.hasOwnProperty("switch")) {
+ isOn = params.switch === "on";
+ } else {
+ isOn = lightService.getCharacteristic(Characteristic.On).value;
+ }
+ if (isOn) {
+ lightService.updateCharacteristic(Characteristic.On, true);
+ switch (accessory.context.eweUIID) {
+ case 36: // KING-M4
+ if (params.hasOwnProperty("bright")) {
+ let nb = Math.round(((params.bright - 10) * 10) / 9); // eWeLink scale is 10-100 and HomeKit scale is 0-100.
+ lightService.updateCharacteristic(Characteristic.Brightness, nb);
+ }
+ break;
+ case 44: // D1
+ if (params.hasOwnProperty("brightness")) {
+ lightService.updateCharacteristic(Characteristic.Brightness, params.brightness);
+ }
+ break;
+ case 22: // B1
+ if (params.hasOwnProperty("zyx_mode")) {
+ mode = parseInt(params.zyx_mode);
+ } else if (params.hasOwnProperty("channel0") && parseInt(params.channel0) + parseInt(params.channel1) > 0) {
+ mode = 1;
+ } else {
+ mode = 2;
+ }
+ if (mode === 2) {
+ lightService.updateCharacteristic(Characteristic.On, true);
+ newColour = convert.rgb.hsv(
+ parseInt(params.channel2),
+ parseInt(params.channel3),
+ parseInt(params.channel4)
+ );
+ lightService
+ .updateCharacteristic(Characteristic.Hue, newColour[0])
+ .updateCharacteristic(Characteristic.Saturation, 100)
+ .updateCharacteristic(Characteristic.Brightness, 100);
+ } else if (mode === 1) {
+ throw "has been set to white mode which is not supported";
+ }
+ break;
+ case 59: // L1
+ if (params.hasOwnProperty("bright")) {
+ lightService.updateCharacteristic(Characteristic.Brightness, params.bright);
+ }
+ if (params.hasOwnProperty("colorR")) {
+ newColour = convert.rgb.hsv(params.colorR, params.colorG, params.colorB);
+ lightService
+ .updateCharacteristic(Characteristic.Hue, newColour[0])
+ .updateCharacteristic(Characteristic.Saturation, newColour[1]);
+ }
+ break;
+ default:
+ return;
+ }
+ } else {
+ lightService.updateCharacteristic(Characteristic.On, false);
+ }
+ } catch (err) {
+ this.platform.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
+ externalMultiLightUpdate(accessory, params) {
+ try {
+ let idToCheck = accessory.context.hbDeviceId.slice(0, -1),
+ primaryState = false;
+ for (let i = 1; i <= accessory.context.channelCount; i++) {
+ if (this.platform.devicesInHB.has(idToCheck + i)) {
+ let oAccessory = this.platform.devicesInHB.get(idToCheck + i);
+ oAccessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.On, params.switches[i - 1].switch === "on");
+ if (params.switches[i - 1].switch === "on") {
+ primaryState = true;
+ }
+ }
+ }
+ if (!this.platform.hiddenMasters.includes(accessory.context.eweDeviceId)) {
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, primaryState);
+ }
+ } catch (err) {
+ this.platform.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
+};
diff --git a/lib/device/lock.js b/lib/device/lock.js
new file mode 100644
index 00000000..ac74af5e
--- /dev/null
+++ b/lib/device/lock.js
@@ -0,0 +1,67 @@
+/* jshint esversion: 9, -W014, -W030, node: true */
+"use strict";
+let Characteristic, Service;
+const utils = require("./../utils");
+module.exports = class deviceLock {
+ constructor(platform) {
+ this.platform = platform;
+ Service = platform.api.hap.Service;
+ Characteristic = platform.api.hap.Characteristic;
+ }
+ async internalLockUpdate(accessory, value, callback) {
+ callback();
+ try {
+ let lockConfig,
+ params = {
+ switch: "on",
+ },
+ lmService = accessory.getService(Service.LockMechanism);
+ if (!(lockConfig = this.platform.cusG.get(accessory.context.hbDeviceId))) {
+ throw "group config missing";
+ }
+ if (lockConfig.type !== "lock") {
+ throw "improper configuration";
+ }
+ accessory.context.inUse = true;
+ await this.platform.sendDeviceUpdate(accessory, params);
+ lmService
+ .updateCharacteristic(Characteristic.LockTargetState, 0)
+ .updateCharacteristic(Characteristic.LockCurrentState, 0);
+ await utils.sleep(lockConfig.operationTime * 100);
+ lmService
+ .updateCharacteristic(Characteristic.LockTargetState, 1)
+ .updateCharacteristic(Characteristic.LockCurrentState, 1);
+ accessory.context.inUse = false;
+ } catch (err) {
+ this.platform.requestDeviceRefresh(accessory, err);
+ }
+ }
+ externalLockUpdate(accessory, params) {
+ try {
+ let lockConfig,
+ lmService = accessory.getService(Service.LockMechanism);
+ if (!(lockConfig = this.platform.cusG.get(accessory.context.hbDeviceId))) {
+ throw "group config missing";
+ }
+ if (lockConfig.type !== "lock") {
+ throw "improper configuration";
+ }
+ if (params.switch === "off" || accessory.context.inUse) {
+ return;
+ }
+ accessory.context.inUse = true;
+ lmService
+ .updateCharacteristic(Characteristic.LockCurrentState, 0)
+ .updateCharacteristic(Characteristic.LockTargetState, 0);
+ setTimeout(() => {
+ lmService
+ .updateCharacteristic(Characteristic.LockCurrentState, 1)
+ .updateCharacteristic(Characteristic.LockTargetState, 1);
+ accessory.context.inUse = false;
+ }, parseInt(lockConfig.operationTime) * 100);
+ } catch (err) {
+ accessory.context.inUse = false;
+ this.platform.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
+};
diff --git a/lib/device/outlet.js b/lib/device/outlet.js
new file mode 100644
index 00000000..a1d7145b
--- /dev/null
+++ b/lib/device/outlet.js
@@ -0,0 +1,56 @@
+/* jshint esversion: 9, -W014, -W030, node: true */
+"use strict";
+let Characteristic, EveService, Service;
+const hbLib = require("homebridge-lib");
+module.exports = class deviceOutlet {
+ constructor(platform, homebridge) {
+ this.platform = platform;
+ Service = platform.api.hap.Service;
+ Characteristic = platform.api.hap.Characteristic;
+ EveService = new hbLib.EveHomeKitTypes(platform.api);
+ }
+ async internalOutletUpdate(accessory, value, callback) {
+ callback();
+ try {
+ let params = {
+ switch: value ? "on" : "off",
+ },
+ outletService = accessory.getService(Service.Outlet);
+ await this.platform.sendDeviceUpdate(accessory, params);
+ outletService.updateCharacteristic(Characteristic.On, value);
+ } catch (err) {
+ this.platform.requestDeviceRefresh(accessory, err);
+ }
+ }
+ externalOutletUpdate(accessory, params) {
+ try {
+ let outletService = accessory.getService(Service.Outlet);
+ if (params.hasOwnProperty("switch")) {
+ outletService.updateCharacteristic(Characteristic.On, params.switch === "on");
+ if (accessory.context.eweModel === "S26" || this.platform.config.disableEveLogging || false) {
+ outletService.updateCharacteristic(Characteristic.OutletInUse, params.switch === "on");
+ }
+ }
+ if (params.hasOwnProperty("power")) {
+ outletService.updateCharacteristic(EveService.Characteristics.CurrentConsumption, parseFloat(params.power));
+ outletService.updateCharacteristic(
+ Characteristic.OutletInUse,
+ parseFloat(params.power) > (this.platform.config.inUsePowerThreshold || 0)
+ );
+ let isOn = accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On).value;
+ accessory.eveLogger.addEntry({
+ time: Date.now(),
+ power: isOn ? parseFloat(params.power) : 0,
+ });
+ }
+ if (params.hasOwnProperty("voltage")) {
+ outletService.updateCharacteristic(EveService.Characteristics.Voltage, parseFloat(params.voltage));
+ }
+ if (params.hasOwnProperty("current")) {
+ outletService.updateCharacteristic(EveService.Characteristics.ElectricCurrent, parseFloat(params.current));
+ }
+ } catch (err) {
+ this.platform.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
+};
diff --git a/lib/device/rf-sub.js b/lib/device/rf-sub.js
new file mode 100644
index 00000000..59dcfb06
--- /dev/null
+++ b/lib/device/rf-sub.js
@@ -0,0 +1,122 @@
+/* jshint esversion: 9, -W014, -W030, node: true */
+"use strict";
+let Characteristic, Service;
+const utils = require("./../utils");
+module.exports = class deviceRFSub {
+ constructor(platform) {
+ this.platform = platform;
+ Service = platform.api.hap.Service;
+ Characteristic = platform.api.hap.Characteristic;
+ }
+ async internalRFUpdate(accessory, rfChl, service, callback) {
+ callback();
+ try {
+ let params = {
+ cmd: "transmit",
+ rfChl: parseInt(rfChl),
+ },
+ rfService = accessory.getService(service);
+ await this.platform.sendDeviceUpdate(accessory, params);
+ rfService.updateCharacteristic(Characteristic.On, true);
+ await utils.sleep(3000);
+ rfService.updateCharacteristic(Characteristic.On, false);
+ } catch (err) {
+ this.platform.requestDeviceRefresh(accessory, err);
+ }
+ }
+ externalRFUpdate(accessory, params) {
+ try {
+ if (!params.hasOwnProperty("updateSource")) return;
+ let timeNow = new Date(),
+ oAccessory = false;
+ if (params.hasOwnProperty("cmd") && params.cmd === "transmit" && params.hasOwnProperty("rfChl")) {
+ //*** RF Button ***\\
+ // the device needed is SW% corresponding to params.rfChl
+ this.platform.devicesInHB.forEach(acc => {
+ if (
+ acc.context.eweDeviceId === accessory.context.eweDeviceId &&
+ acc.context.buttons.hasOwnProperty(params.rfChl.toString())
+ ) {
+ oAccessory = acc;
+ }
+ });
+ if (oAccessory) {
+ oAccessory.getService(oAccessory.context.buttons[params.rfChl]).updateCharacteristic(Characteristic.On, 1);
+ setTimeout(
+ () =>
+ oAccessory
+ .getService(oAccessory.context.buttons[params.rfChl])
+ .updateCharacteristic(Characteristic.On, 0),
+ 3000
+ );
+ } else {
+ throw "rf button not found in Homebridge";
+ }
+ } else if (params.hasOwnProperty("cmd") && params.cmd === "trigger") {
+ //*** RF Sensor ***\\
+ Object.keys(params)
+ .filter(name => /rfTrig/.test(name))
+ .forEach(chan => {
+ this.platform.devicesInHB.forEach(acc => {
+ if (
+ acc.context.eweDeviceId === accessory.context.eweDeviceId &&
+ acc.context.buttons.hasOwnProperty(chan.substr(-1).toString())
+ ) {
+ oAccessory = acc;
+ }
+ });
+ if (oAccessory) {
+ let timeOfMotion = new Date(params[chan]),
+ diff = (timeNow.getTime() - timeOfMotion.getTime()) / 1000,
+ serv,
+ char;
+ if (diff < (this.platform.config.sensorTimeDifference || 120)) {
+ switch (oAccessory.context.sensorType) {
+ case "button":
+ break;
+ case "water":
+ serv = Service.LeakSensor;
+ char = Characteristic.LeakDetected;
+ break;
+ case "fire":
+ case "smoke":
+ serv = Service.SmokeSensor;
+ char = Characteristic.LeakDetected;
+ break;
+ case "co":
+ serv = Service.CarbonMonoxideSensor;
+ char = Characteristic.CarbonMonoxideDetected;
+ break;
+ case "co2":
+ serv = Service.CarbonDioxideSensor;
+ char = Characteristic.CarbonDioxideDetected;
+ break;
+ case "contact":
+ serv = Service.ContactSensor;
+ char = Characteristic.ContactSensorState;
+ break;
+ case "occupancy":
+ serv = Service.OccupancySensor;
+ char = Characteristic.OccupancyDetected;
+ break;
+ default:
+ serv = Service.MotionSensor;
+ char = Characteristic.MotionDetected;
+ break;
+ }
+ oAccessory.getService(serv).updateCharacteristic(char, 1);
+ setTimeout(() => {
+ oAccessory.getService(serv).updateCharacteristic(char, 0);
+ }, (this.platform.config.sensorTimeLength || 2) * 1000);
+ if (this.platform.debug) {
+ this.platform.log("[%s] has detected [%s].", oAccessory.displayName, oAccessory.context.sensorType);
+ }
+ }
+ }
+ });
+ }
+ } catch (err) {
+ this.platform.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
+};
diff --git a/lib/device/scm.js b/lib/device/scm.js
new file mode 100644
index 00000000..e424e8eb
--- /dev/null
+++ b/lib/device/scm.js
@@ -0,0 +1,32 @@
+/* jshint esversion: 9, -W014, -W030, node: true */
+"use strict";
+let Characteristic, Service;
+module.exports = class deviceSCM {
+ constructor(platform) {
+ this.platform = platform;
+ Service = platform.api.hap.Service;
+ Characteristic = platform.api.hap.Characteristic;
+ }
+
+ async internalSCMUpdate(accessory, value, callback) {
+ callback();
+ try {
+ let params = {
+ switches: this.platform.devicesInEW.get(accessory.context.eweDeviceId).params.switches,
+ },
+ switchService = accessory.getService(Service.Switch);
+ params.switches[0].switch = value ? "on" : "off";
+ await this.platform.sendDeviceUpdate(accessory, params);
+ switchService.updateCharacteristic(Characteristic.On, value);
+ } catch (err) {
+ this.platform.requestDeviceRefresh(accessory, err);
+ }
+ }
+ externalSCMUpdate(accessory, params) {
+ try {
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, params.switches[0].switch === "on");
+ } catch (err) {
+ this.platform.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
+};
diff --git a/lib/device/sensor.js b/lib/device/sensor.js
new file mode 100644
index 00000000..391d7f08
--- /dev/null
+++ b/lib/device/sensor.js
@@ -0,0 +1,54 @@
+/* jshint esversion: 9, -W014, -W030, node: true */
+"use strict";
+let Characteristic, Service;
+module.exports = class deviceSensor {
+ constructor(platform) {
+ this.platform = platform;
+ Service = platform.api.hap.Service;
+ Characteristic = platform.api.hap.Characteristic;
+ }
+ externalSensorUpdate(accessory, params) {
+ try {
+ if (params.hasOwnProperty("battery")) {
+ let batteryService =
+ accessory.getService(Service.BatteryService) || accessory.addService(Service.BatteryService),
+ scaledBattery = Math.round(params.battery * 33.3);
+ batteryService.updateCharacteristic(Characteristic.BatteryLevel, scaledBattery);
+ batteryService.updateCharacteristic(
+ Characteristic.StatusLowBattery,
+ scaledBattery < (this.platform.config.lowBattThreshold || 25)
+ );
+ }
+ let newState = params.switch === "on" ? 1 : 0,
+ oAccessory = false,
+ contactService = accessory.getService(Service.ContactSensor);
+ contactService.updateCharacteristic(Characteristic.ContactSensorState, newState);
+ this.platform.cusG.forEach(group => {
+ if (group.sensorId === accessory.context.eweDeviceId && group.type === "garage") {
+ if ((oAccessory = this.platform.devicesInHB.get(group.deviceId + "SWX"))) {
+ switch (newState) {
+ case 0:
+ oAccessory
+ .getService(Service.GarageDoorOpener)
+ .updateCharacteristic(Characteristic.TargetDoorState, 1)
+ .updateCharacteristic(Characteristic.CurrentDoorState, 1);
+ break;
+ case 1:
+ setTimeout(() => {
+ oAccessory
+ .getService(Service.GarageDoorOpener)
+ .updateCharacteristic(Characteristic.TargetDoorState, 0)
+ .updateCharacteristic(Characteristic.CurrentDoorState, 0);
+ }, group.operationTime * 100);
+ break;
+ default:
+ throw "unknown sensor status received [" + newState + "]";
+ }
+ }
+ }
+ });
+ } catch (err) {
+ this.platform.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
+};
diff --git a/lib/device/switch.js b/lib/device/switch.js
new file mode 100644
index 00000000..e446492a
--- /dev/null
+++ b/lib/device/switch.js
@@ -0,0 +1,111 @@
+/* jshint esversion: 9, -W014, -W030, node: true */
+"use strict";
+let Characteristic, Service;
+module.exports = class deviceSwitch {
+ constructor(platform) {
+ this.platform = platform;
+ Service = platform.api.hap.Service;
+ Characteristic = platform.api.hap.Characteristic;
+ }
+ async internalSwitchUpdate(accessory, value, callback) {
+ callback();
+ try {
+ let oAccessory,
+ params = {},
+ switchService = accessory.getService(Service.Switch);
+ switch (accessory.context.switchNumber) {
+ case "X":
+ params.switch = value ? "on" : "off";
+ break;
+ case "0":
+ params.switches = this.platform.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
+ params.switches[0].switch = value ? "on" : "off";
+ params.switches[1].switch = value ? "on" : "off";
+ params.switches[2].switch = value ? "on" : "off";
+ params.switches[3].switch = value ? "on" : "off";
+ break;
+ case "1":
+ case "2":
+ case "3":
+ case "4":
+ params.switches = this.platform.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
+ for (let i = 1; i <= 4; i++) {
+ if ((oAccessory = this.platform.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
+ i === parseInt(accessory.context.switchNumber)
+ ? (params.switches[i - 1].switch = value ? "on" : "off")
+ : (params.switches[i - 1].switch = oAccessory
+ .getService(Service.Switch)
+ .getCharacteristic(Characteristic.On).value
+ ? "on"
+ : "off");
+ } else {
+ params.switches[i - 1].switch = "off";
+ }
+ }
+ break;
+ }
+ await this.platform.sendDeviceUpdate(accessory, params);
+ switch (accessory.context.switchNumber) {
+ case "X":
+ switchService.updateCharacteristic(Characteristic.On, value);
+ break;
+ case "0":
+ for (let i = 0; i <= 4; i++) {
+ if ((oAccessory = this.platform.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
+ oAccessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
+ }
+ }
+ break;
+ case "1":
+ case "2":
+ case "3":
+ case "4":
+ switchService.updateCharacteristic(Characteristic.On, value);
+ let masterState = "off";
+ for (let i = 1; i <= 4; i++) {
+ if ((oAccessory = this.platform.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
+ if (oAccessory.getService(Service.Switch).getCharacteristic(Characteristic.On).value) {
+ masterState = "on";
+ }
+ }
+ }
+ if (!this.platform.hiddenMasters.includes(accessory.context.eweDeviceId)) {
+ oAccessory = this.platform.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
+ oAccessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, masterState === "on");
+ }
+ break;
+ }
+ } catch (err) {
+ this.platform.requestDeviceRefresh(accessory, err);
+ }
+ }
+ externalSingleSwitchUpdate(accessory, params) {
+ try {
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, params.switch === "on");
+ } catch (err) {
+ this.platform.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
+ externalMultiSwitchUpdate(accessory, params) {
+ try {
+ let idToCheck = accessory.context.hbDeviceId.slice(0, -1),
+ primaryState = false;
+ for (let i = 1; i <= accessory.context.channelCount; i++) {
+ if (this.platform.devicesInHB.has(idToCheck + i)) {
+ let oAccessory = this.platform.devicesInHB.get(idToCheck + i);
+ oAccessory
+ .getService(Service.Switch)
+ .updateCharacteristic(Characteristic.On, params.switches[i - 1].switch === "on");
+ if (params.switches[i - 1].switch === "on") {
+ primaryState = true;
+ }
+ }
+ }
+ if (!this.platform.hiddenMasters.includes(accessory.context.eweDeviceId)) {
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, primaryState);
+ }
+ } catch (err) {
+ this.platform.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
+};
diff --git a/lib/device/thermostat.js b/lib/device/thermostat.js
new file mode 100644
index 00000000..dfc0baec
--- /dev/null
+++ b/lib/device/thermostat.js
@@ -0,0 +1,58 @@
+/* jshint esversion: 9, -W014, -W030, node: true */
+"use strict";
+let Characteristic, Service;
+module.exports = class deviceThermostat {
+ constructor(platform, homebridge) {
+ this.platform = platform;
+ }
+ async internalThermostatUpdate(accessory, value, callback) {
+ callback();
+ try {
+ let params = {
+ switch: value ? "on" : "off",
+ mainSwitch: value ? "on" : "off",
+ },
+ switchService = accessory.getService(Service.Switch);
+ await this.platform.sendDeviceUpdate(accessory, params);
+ switchService.updateCharacteristic(Characteristic.On, value);
+ } catch (err) {
+ this.platform.requestDeviceRefresh(accessory, err);
+ }
+ }
+ externalThermostatUpdate(accessory, params) {
+ try {
+ if (
+ !this.platform.config.hideTHSwitch &&
+ (params.hasOwnProperty("switch") || params.hasOwnProperty("mainSwitch"))
+ ) {
+ let newState = params.hasOwnProperty("switch") ? params.switch === "on" : params.mainSwitch === "on",
+ switchService = accessory.getService(Service.Switch);
+ switchService.updateCharacteristic(Characteristic.On, newState);
+ }
+ if (!(this.platform.config.disableEveLogging || false)) {
+ let eveLog = {
+ time: Date.now(),
+ };
+ if (params.hasOwnProperty("currentTemperature") && accessory.getService(Service.TemperatureSensor)) {
+ let currentTemp = params.currentTemperature !== "unavailable" ? params.currentTemperature : 0;
+ accessory
+ .getService(Service.TemperatureSensor)
+ .updateCharacteristic(Characteristic.CurrentTemperature, currentTemp);
+ eveLog.temp = parseFloat(currentTemp);
+ }
+ if (params.hasOwnProperty("currentHumidity") && accessory.getService(Service.HumiditySensor)) {
+ let currentHumi = params.currentHumidity !== "unavailable" ? params.currentHumidity : 0;
+ accessory
+ .getService(Service.HumiditySensor)
+ .updateCharacteristic(Characteristic.CurrentRelativeHumidity, currentHumi);
+ eveLog.humidity = parseFloat(currentHumi);
+ }
+ if (eveLog.hasOwnProperty("temp") || eveLog.hasOwnProperty("humidity")) {
+ accessory.eveLogger.addEntry(eveLog);
+ }
+ }
+ } catch (err) {
+ this.platform.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
+};
diff --git a/lib/device/usb.js b/lib/device/usb.js
new file mode 100644
index 00000000..7d6e244f
--- /dev/null
+++ b/lib/device/usb.js
@@ -0,0 +1,31 @@
+/* jshint esversion: 9, -W014, -W030, node: true */
+"use strict";
+let Characteristic, Service;
+module.exports = class deviceUSB {
+ constructor(platform) {
+ this.platform = platform;
+ Service = platform.api.hap.Service;
+ Characteristic = platform.api.hap.Characteristic;
+ }
+ async internalUSBUpdate(accessory, value, callback) {
+ callback();
+ try {
+ let params = {
+ switches: this.platform.devicesInEW.get(accessory.context.eweDeviceId).params.switches,
+ },
+ outletService = accessory.getService(Service.Outlet);
+ params.switches[0].switch = value ? "on" : "off";
+ await this.platform.sendDeviceUpdate(accessory, params);
+ outletService.updateCharacteristic(Characteristic.On, value);
+ } catch (err) {
+ this.platform.requestDeviceRefresh(accessory, err);
+ }
+ }
+ externalUSBUpdate(accessory, params) {
+ try {
+ accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, params.switches[0].switch === "on");
+ } catch (err) {
+ this.platform.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
+};
diff --git a/lib/device/valve.js b/lib/device/valve.js
new file mode 100644
index 00000000..6336871d
--- /dev/null
+++ b/lib/device/valve.js
@@ -0,0 +1,71 @@
+/* jshint esversion: 9, -W014, -W030, node: true */
+"use strict";
+let Characteristic, Service;
+module.exports = class deviceValve {
+ constructor(platform) {
+ this.platform = platform;
+ Service = platform.api.hap.Service;
+ Characteristic = platform.api.hap.Characteristic;
+ }
+ async internalValveUpdate(accessory, valve, value, callback) {
+ callback();
+ try {
+ let params = {},
+ serviceValve = accessory.getService(valve);
+ params.switches = this.platform.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
+ switch (valve) {
+ case "Valve A":
+ params.switches[0].switch = value ? "on" : "off";
+ params.switches[1].switch = accessory.getService("Valve B").getCharacteristic(Characteristic.Active).value
+ ? "on"
+ : "off";
+ break;
+ case "Valve B":
+ params.switches[0].switch = accessory.getService("Valve A").getCharacteristic(Characteristic.Active).value
+ ? "on"
+ : "off";
+ params.switches[1].switch = value ? "on" : "off";
+ break;
+ }
+ params.switches[2].switch = "off";
+ params.switches[3].switch = "off";
+ await this.platform.sendDeviceUpdate(accessory, params);
+ serviceValve.updateCharacteristic(Characteristic.Active, value).updateCharacteristic(Characteristic.InUse, value);
+ switch (value) {
+ case 0:
+ serviceValve.updateCharacteristic(Characteristic.RemainingDuration, 0);
+ clearTimeout(accessory.getService(valve).timer);
+ break;
+ case 1:
+ let timer = serviceValve.getCharacteristic(Characteristic.SetDuration).value;
+ serviceValve.updateCharacteristic(Characteristic.RemainingDuration, timer);
+ serviceValve.timer = setTimeout(() => serviceValve.setCharacteristic(Characteristic.Active, 0), timer * 1000);
+ break;
+ }
+ } catch (err) {
+ this.platform.requestDeviceRefresh(accessory, err);
+ }
+ }
+ externalValveUpdate(accessory, params) {
+ try {
+ ["A", "B"].forEach((v, k) => {
+ let valveService = accessory.getService("Valve " + v);
+ valveService
+ .updateCharacteristic(Characteristic.Active, params.switches[k].switch === "on")
+ .updateCharacteristic(Characteristic.InUse, params.switches[k].switch === "on");
+ if (params.switches[k].switch === "on") {
+ let timer = valveService.getCharacteristic(Characteristic.SetDuration).value;
+ valveService.updateCharacteristic(Characteristic.RemainingDuration, timer);
+ valveService.timer = setTimeout(() => {
+ valveService.setCharacteristic(Characteristic.Active, 0);
+ }, timer * 1000);
+ } else {
+ valveService.updateCharacteristic(Characteristic.RemainingDuration, 0);
+ clearTimeout(valveService.timer);
+ }
+ });
+ } catch (err) {
+ this.platform.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
+};
diff --git a/lib/device/zb-dev.js b/lib/device/zb-dev.js
new file mode 100644
index 00000000..07e64a8f
--- /dev/null
+++ b/lib/device/zb-dev.js
@@ -0,0 +1,82 @@
+/* jshint esversion: 9, -W014, -W030, node: true */
+"use strict";
+let Characteristic, Service;
+module.exports = class deviceZBDev {
+ constructor(platform) {
+ this.platform = platform;
+ Service = platform.api.hap.Service;
+ Characteristic = platform.api.hap.Characteristic;
+ }
+ externalZBUpdate(accessory, params) {
+ try {
+ //*** credit @tasict ***\\
+ if (params.hasOwnProperty("battery")) {
+ if (accessory.context.eweUIID === 3026 && (this.platform.config.ZBDWBatt || false)) {
+ params.battery *= 10;
+ }
+ let batteryService =
+ accessory.getService(Service.BatteryService) || accessory.addService(Service.BatteryService);
+ batteryService.updateCharacteristic(Characteristic.BatteryLevel, params.battery);
+ batteryService.updateCharacteristic(
+ Characteristic.StatusLowBattery,
+ params.battery < (this.platform.config.lowBattThreshold || 25)
+ );
+ }
+ switch (accessory.context.eweUIID) {
+ case 1000:
+ if (params.hasOwnProperty("key") && [0, 1, 2].includes(params.key)) {
+ accessory
+ .getService(Service.StatelessProgrammableSwitch)
+ .updateCharacteristic(Characteristic.ProgrammableSwitchEvent, params.key);
+ }
+ break;
+ case 1770:
+ let eveLog = {
+ time: Date.now(),
+ };
+ if (params.hasOwnProperty("temperature")) {
+ let currentTemp = parseInt(params.temperature) / 100;
+ accessory
+ .getService(Service.TemperatureSensor)
+ .updateCharacteristic(Characteristic.CurrentTemperature, currentTemp);
+ eveLog.temp = parseFloat(currentTemp);
+ }
+ if (params.hasOwnProperty("humidity")) {
+ let currentHumi = parseInt(params.humidity) / 100;
+ accessory
+ .getService(Service.HumiditySensor)
+ .updateCharacteristic(Characteristic.CurrentRelativeHumidity, currentHumi);
+ eveLog.humidity = parseFloat(currentHumi);
+ }
+ if (eveLog.hasOwnProperty("temp") || eveLog.hasOwnProperty("humidity")) {
+ accessory.eveLogger.addEntry(eveLog);
+ }
+ break;
+ case 2026:
+ if (params.hasOwnProperty("motion") && params.hasOwnProperty("trigTime")) {
+ let timeNow = new Date(),
+ diff = (timeNow.getTime() - params.trigTime) / 1000;
+ accessory
+ .getService(Service.MotionSensor)
+ .updateCharacteristic(
+ Characteristic.MotionDetected,
+ params.hasOwnProperty("updateSource") &&
+ params.motion === 1 &&
+ diff < (this.platform.config.sensorTimeDifference || 120)
+ );
+ break;
+ }
+ break;
+ case 3026:
+ if (params.hasOwnProperty("lock") && [0, 1].includes(params.lock)) {
+ accessory
+ .getService(Service.ContactSensor)
+ .updateCharacteristic(Characteristic.ContactSensorState, params.lock);
+ }
+ break;
+ }
+ } catch (err) {
+ this.platform.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ }
+ }
+};
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 53bc6241..f5ca8134 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -2,8 +2,22 @@
"use strict";
let Accessory, Characteristic, EveService, EveHistoryService, Service;
const cns = require("./constants"),
- convert = require("color-convert"),
corrInterval = require("correcting-interval"),
+ deviceCurtain = require("./device/curtain"),
+ deviceBlind = require("./device/blind"),
+ deviceGarage = require("./device/garage"),
+ deviceLock = require("./device/lock"),
+ deviceValve = require("./device/valve"),
+ deviceSensor = require("./device/sensor"),
+ deviceFan = require("./device/fan"),
+ deviceThermostat = require("./device/thermostat"),
+ deviceOutlet = require("./device/outlet"),
+ deviceUSB = require("./device/usb"),
+ deviceSCM = require("./device/scm"),
+ deviceLight = require("./device/light"),
+ deviceSwitch = require("./device/switch"),
+ deviceRFSub = require("./device/rf-sub"),
+ deviceZBDev = require("./device/zb-dev"),
eWeLinkHTTP = require("./eWeLinkHTTP"),
eWeLinkWS = require("./eWeLinkWS"),
eWeLinkLAN = require("./eWeLinkLAN"),
@@ -169,9 +183,9 @@ class eWeLink {
}
//*** SINGLE LOCKS ***\\
else if (this.cusG.has(device.deviceid + "SWX") && this.cusG.get(device.deviceid + "SWX").type === "lock") {
- let lockConfig = (accessory = this.devicesInHB.has(device.deviceid + "SWX")
+ accessory = this.devicesInHB.has(device.deviceid + "SWX")
? this.devicesInHB.get(device.deviceid + "SWX")
- : this.addAccessory(device, device.deviceid + "SWX", "lock"));
+ : this.addAccessory(device, device.deviceid + "SWX", "lock");
}
//*** SENSORS (DW2) ***\\
else if (cns.devicesSensor.includes(device.extra.uiid)) {
@@ -504,35 +518,8 @@ class eWeLink {
accessory.context.reachableWAN = true;
accessory.context.reachableLAN = true;
switch (accessory.context.type) {
- case "valve":
- ["A", "B"].forEach(v => {
- let valveService;
- if (!(valveService = accessory.getService("Valve " + v))) {
- accessory
- .addService(Service.Valve, "Valve " + v, "valve" + v.toLowerCase())
- .setCharacteristic(Characteristic.Active, 0)
- .setCharacteristic(Characteristic.InUse, 0)
- .setCharacteristic(Characteristic.ValveType, 1)
- .setCharacteristic(Characteristic.SetDuration, this.config.valveTimeLength || 120)
- .addCharacteristic(Characteristic.RemainingDuration);
- valveService = accessory.getService("Valve " + v);
- }
- valveService
- .getCharacteristic(Characteristic.Active)
- .on("set", (value, callback) => this.internalValveUpdate(accessory, "Valve " + v, value, callback));
- valveService.getCharacteristic(Characteristic.SetDuration).on("set", (value, callback) => {
- if (valveService.getCharacteristic(Characteristic.InUse).value) {
- valveService.updateCharacteristic(Characteristic.RemainingDuration, value);
- clearTimeout(valveService.timer);
- valveService.timer = setTimeout(() => {
- valveService.setCharacteristic(Characteristic.Active, 0);
- }, value * 1000);
- }
- callback();
- });
- });
- break;
case "curtain":
+ accessory.control = new deviceCurtain(this);
let cService;
if (!(cService = accessory.getService(Service.WindowCovering))) {
accessory
@@ -544,9 +531,10 @@ class eWeLink {
}
cService
.getCharacteristic(Characteristic.TargetPosition)
- .on("set", (value, callback) => this.internalCurtainUpdate(accessory, value, callback));
+ .on("set", (value, callback) => accessory.control.internalCurtainUpdate(accessory, value, callback));
break;
case "blind":
+ accessory.control = new deviceBlind(this);
let wcService;
if (!(wcService = accessory.getService(Service.WindowCovering))) {
accessory
@@ -558,9 +546,10 @@ class eWeLink {
}
wcService
.getCharacteristic(Characteristic.TargetPosition)
- .on("set", (value, callback) => this.internalBlindUpdate(accessory, value, callback));
+ .on("set", (value, callback) => accessory.control.internalBlindUpdate(accessory, value, callback));
break;
case "garage":
+ accessory.control = new deviceGarage(this);
let gdService;
if (!(gdService = accessory.getService(Service.GarageDoorOpener))) {
accessory
@@ -572,35 +561,70 @@ class eWeLink {
}
gdService
.getCharacteristic(Characteristic.TargetDoorState)
- .on("set", (value, callback) => this.internalGarageUpdate(accessory, value, callback));
+ .on("set", (value, callback) => accessory.control.internalGarageUpdate(accessory, value, callback));
break;
case "lock":
+ accessory.control = new deviceLock(this);
let lmService = accessory.getService(Service.LockMechanism) || accessory.addService(Service.LockMechanism);
lmService
.getCharacteristic(Characteristic.LockTargetState)
- .on("set", (value, callback) => this.internalLockUpdate(accessory, value, callback));
+ .on("set", (value, callback) => accessory.control.internalLockUpdate(accessory, value, callback));
+ break;
+ case "valve":
+ accessory.control = new deviceValve(this);
+ ["A", "B"].forEach(v => {
+ let valveService;
+ if (!(valveService = accessory.getService("Valve " + v))) {
+ accessory
+ .addService(Service.Valve, "Valve " + v, "valve" + v.toLowerCase())
+ .setCharacteristic(Characteristic.Active, 0)
+ .setCharacteristic(Characteristic.InUse, 0)
+ .setCharacteristic(Characteristic.ValveType, 1)
+ .setCharacteristic(Characteristic.SetDuration, this.config.valveTimeLength || 120)
+ .addCharacteristic(Characteristic.RemainingDuration);
+ valveService = accessory.getService("Valve " + v);
+ }
+ valveService
+ .getCharacteristic(Characteristic.Active)
+ .on("set", (value, callback) =>
+ accessory.control.internalValveUpdate(accessory, "Valve " + v, value, callback)
+ );
+ valveService.getCharacteristic(Characteristic.SetDuration).on("set", (value, callback) => {
+ if (valveService.getCharacteristic(Characteristic.InUse).value) {
+ valveService.updateCharacteristic(Characteristic.RemainingDuration, value);
+ clearTimeout(valveService.timer);
+ valveService.timer = setTimeout(() => {
+ valveService.setCharacteristic(Characteristic.Active, 0);
+ }, value * 1000);
+ }
+ callback();
+ });
+ });
break;
case "sensor":
+ accessory.control = new deviceSensor(this);
accessory.getService(Service.ContactSensor) || accessory.addService(Service.ContactSensor);
accessory.getService(Service.BatteryService) || accessory.addService(Service.BatteryService);
break;
case "fan":
+ accessory.control = new deviceFan(this);
let fanService = accessory.getService(Service.Fanv2) || accessory.addService(Service.Fanv2),
fanLightService = accessory.getService(Service.Lightbulb) || accessory.addService(Service.Lightbulb);
fanService
.getCharacteristic(Characteristic.Active)
- .on("set", (value, callback) => this.internalFanUpdate(accessory, "power", value, callback));
+ .on("set", (value, callback) => accessory.control.internalFanUpdate(accessory, "power", value, callback));
fanService
.getCharacteristic(Characteristic.RotationSpeed)
- .on("set", (value, callback) => this.internalFanUpdate(accessory, "speed", value, callback))
+ .on("set", (value, callback) => accessory.control.internalFanUpdate(accessory, "speed", value, callback))
.setProps({
minStep: 33,
});
fanLightService
.getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => this.internalFanUpdate(accessory, "light", value, callback));
+ .on("set", (value, callback) => accessory.control.internalFanUpdate(accessory, "light", value, callback));
break;
case "thermostat":
+ accessory.control = new deviceThermostat(this);
let tempService =
accessory.getService(Service.TemperatureSensor) || accessory.addService(Service.TemperatureSensor),
humiService = false;
@@ -615,7 +639,7 @@ class eWeLink {
let switchService = accessory.getService(Service.Switch) || accessory.addService(Service.Switch);
switchService
.getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => this.internalThermostatUpdate(accessory, value, callback));
+ .on("set", (value, callback) => accessory.control.internalThermostatUpdate(accessory, value, callback));
}
if (!(this.config.disableEveLogging || false)) {
accessory.log = this.log;
@@ -637,6 +661,7 @@ class eWeLink {
}
break;
case "outlet":
+ accessory.control = new deviceOutlet(this);
let outletService;
if (!(outletService = accessory.getService(Service.Outlet))) {
accessory.addService(Service.Outlet);
@@ -660,7 +685,7 @@ class eWeLink {
}
outletService
.getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => this.internalOutletUpdate(accessory, value, callback));
+ .on("set", (value, callback) => accessory.control.internalOutletUpdate(accessory, value, callback));
if (accessory.context.eweModel !== "S26" && !(this.config.disableEveLogging || false)) {
accessory.log = this.log;
accessory.eveLogger = new EveHistoryService("energy", accessory, {
@@ -729,61 +754,66 @@ class eWeLink {
}
break;
case "usb":
+ accessory.control = new deviceUSB(this);
let usbService = accessory.getService(Service.Outlet) || accessory.addService(Service.Outlet);
usbService
.getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => this.internalUSBUpdate(accessory, value, callback));
+ .on("set", (value, callback) => accessory.control.internalUSBUpdate(accessory, value, callback));
break;
case "scm":
+ accessory.control = new deviceSCM(this);
let scmService = accessory.getService(Service.Switch) || accessory.addService(Service.Switch);
scmService
.getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => this.internalSCMUpdate(accessory, value, callback));
+ .on("set", (value, callback) => accessory.control.internalSCMUpdate(accessory, value, callback));
break;
case "light":
+ accessory.control = new deviceLight(this);
let lightService = accessory.getService(Service.Lightbulb) || accessory.addService(Service.Lightbulb);
lightService
.getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => this.internalLightbulbUpdate(accessory, value, callback));
+ .on("set", (value, callback) => accessory.control.internalLightbulbUpdate(accessory, value, callback));
if (cns.devicesBrightable.includes(accessory.context.eweUIID)) {
lightService.getCharacteristic(Characteristic.Brightness).on("set", (value, callback) => {
if (value > 0) {
if (!lightService.getCharacteristic(Characteristic.On).value) {
- this.internalLightbulbUpdate(accessory, true, function () {
+ accessory.control.internalLightbulbUpdate(accessory, true, function () {
return;
});
}
- this.internalBrightnessUpdate(accessory, value, callback);
+ accessory.control.internalBrightnessUpdate(accessory, value, callback);
} else {
- this.internalLightbulbUpdate(accessory, false, callback);
+ accessory.control.internalLightbulbUpdate(accessory, false, callback);
}
});
} else if (cns.devicesColourable.includes(accessory.context.eweUIID)) {
lightService.getCharacteristic(Characteristic.Brightness).on("set", (value, callback) => {
if (value > 0) {
if (!lightService.getCharacteristic(Characteristic.On).value) {
- this.internalLightbulbUpdate(accessory, true, function () {
+ accessory.control.internalLightbulbUpdate(accessory, true, function () {
return;
});
}
- this.internalHSBUpdate(accessory, "bri", value, callback);
+ accessory.control.internalHSBUpdate(accessory, "bri", value, callback);
} else {
- this.internalLightbulbUpdate(accessory, false, callback);
+ accessory.control.internalLightbulbUpdate(accessory, false, callback);
}
});
lightService
.getCharacteristic(Characteristic.Hue)
- .on("set", (value, callback) => this.internalHSBUpdate(accessory, "hue", value, callback));
+ .on("set", (value, callback) => accessory.control.internalHSBUpdate(accessory, "hue", value, callback));
lightService.getCharacteristic(Characteristic.Saturation).on("set", (value, callback) => callback());
}
break;
case "switch":
+ accessory.control = new deviceSwitch(this);
let switchService = accessory.getService(Service.Switch) || accessory.addService(Service.Switch);
switchService
.getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => this.internalSwitchUpdate(accessory, value, callback));
+ .on("set", (value, callback) => accessory.control.internalSwitchUpdate(accessory, value, callback));
break;
case "rf_sub":
+ accessory.control = new deviceRFSub(this);
switch (accessory.context.subType) {
case "water":
accessory.getService(Service.LeakSensor) || accessory.addService(Service.LeakSensor);
@@ -815,13 +845,14 @@ class eWeLink {
.getService(name)
.getCharacteristic(Characteristic.On)
.on("set", (value, callback) => {
- value ? this.internalRFUpdate(accessory, chan, name, callback) : callback();
+ value ? accessory.control.internalRFUpdate(accessory, chan, name, callback) : callback();
});
});
break;
}
break;
case "zb_dev": //*** credit @tasict ***\\
+ accessory.control = new deviceZBDev(this);
accessory.getService(Service.BatteryService) || accessory.addService(Service.BatteryService);
switch (accessory.context.eweUIID) {
case 1000:
@@ -872,60 +903,57 @@ class eWeLink {
switch (accessory.context.type) {
case "valve":
if (Object.keys(newParams).some(v => cns.devicesValveParams.includes(v)) && Array.isArray(newParams.switches)) {
- this.externalValveUpdate(accessory, newParams);
+ accessory.control.externalValveUpdate(accessory, newParams);
}
return true;
case "curtain":
if (Object.keys(newParams).some(v => cns.devicesCurtainParams.includes(v))) {
- this.externalCurtainUpdate(accessory, newParams);
+ accessory.control.externalCurtainUpdate(accessory, newParams);
}
return true;
case "blind":
- if (Object.keys(newParams).some(v => cns.devicesBlindParams.includes(v)) && Array.isArray(newParams.switches)) {
- this.externalBlindUpdate(accessory, newParams);
- }
return true;
case "garage":
if (
Object.keys(newParams).some(v => cns.devicesGarageParams.includes(v)) &&
Array.isArray(newParams.switches)
) {
- this.externalGarageUpdate(accessory, newParams);
+ accessory.control.externalGarageUpdate(accessory, newParams);
}
return true;
case "lock":
if (Object.keys(newParams).some(v => cns.devicesLockParams.includes(v))) {
- this.externalLockUpdate(accessory, newParams);
+ accessory.control.externalLockUpdate(accessory, newParams);
}
return true;
case "sensor":
if (Object.keys(newParams).some(v => cns.devicesSensorParams.includes(v))) {
- this.externalSensorUpdate(accessory, newParams);
+ accessory.control.externalSensorUpdate(accessory, newParams);
}
return true;
case "fan":
if (Object.keys(newParams).some(v => cns.devicesFanParams.includes(v))) {
- this.externalFanUpdate(accessory, newParams);
+ accessory.control.externalFanUpdate(accessory, newParams);
}
return true;
case "thermostat":
if (Object.keys(newParams).some(v => cns.devicesThermostatParams.includes(v))) {
- this.externalThermostatUpdate(accessory, newParams);
+ accessory.control.externalThermostatUpdate(accessory, newParams);
}
return true;
case "outlet":
if (Object.keys(newParams).some(v => cns.devicesOutletParams.includes(v))) {
- this.externalOutletUpdate(accessory, newParams);
+ accessory.control.externalOutletUpdate(accessory, newParams);
}
return true;
case "usb":
if (Object.keys(newParams).some(v => cns.devicesUSBParams.includes(v)) && Array.isArray(newParams.switches)) {
- this.externalUSBUpdate(accessory, newParams);
+ accessory.control.externalUSBUpdate(accessory, newParams);
}
return true;
case "scm":
if (Object.keys(newParams).some(v => cns.devicesSCMParams.includes(v)) && Array.isArray(newParams.switches)) {
- this.externalSCMUpdate(accessory, newParams);
+ accessory.control.externalSCMUpdate(accessory, newParams);
}
return true;
case "light":
@@ -934,7 +962,7 @@ class eWeLink {
cns.devicesSingleSwitchLight.includes(accessory.context.eweModel)
) {
if (Object.keys(newParams).some(v => cns.devicesSingleSwitchLightParams.includes(v))) {
- this.externalSingleLightUpdate(accessory, newParams);
+ accessory.control.externalSingleLightUpdate(accessory, newParams);
}
} else if (
cns.devicesMultiSwitch.includes(accessory.context.eweUIID) &&
@@ -944,34 +972,34 @@ class eWeLink {
Object.keys(newParams).some(v => cns.devicesMultiSwitchLightParams.includes(v)) &&
Array.isArray(newParams.switches)
) {
- this.externalMultiLightUpdate(accessory, newParams);
+ accessory.control.externalMultiLightUpdate(accessory, newParams);
}
}
return true;
case "switch":
if (cns.devicesSingleSwitch.includes(accessory.context.eweUIID)) {
if (Object.keys(newParams).some(v => cns.devicesSingleSwitchParams.includes(v))) {
- this.externalSingleSwitchUpdate(accessory, newParams);
+ accessory.control.externalSingleSwitchUpdate(accessory, newParams);
}
} else if (cns.devicesMultiSwitch.includes(accessory.context.eweUIID)) {
if (
Object.keys(newParams).some(v => cns.devicesMultiSwitchParams.includes(v)) &&
Array.isArray(newParams.switches)
) {
- this.externalMultiSwitchUpdate(accessory, newParams);
+ accessory.control.externalMultiSwitchUpdate(accessory, newParams);
}
}
return true;
case "rf_pri":
if (Object.keys(newParams).some(v => cns.devicesRFBridgeParams.includes(v))) {
- this.externalRFUpdate(accessory, newParams);
+ accessory.control.externalRFUpdate(accessory, newParams);
}
return true;
case "rf_sub":
return true;
case "zb_dev":
if (Object.keys(newParams).some(v => cns.devicesZBBridgeParams.includes(v))) {
- this.externalZBUpdate(accessory, newParams);
+ accessory.control.externalZBUpdate(accessory, newParams);
}
return true;
default:
@@ -1100,1163 +1128,6 @@ class eWeLink {
this.log.warn("[%s] Homebridge state will be synced once the device comes back online.", accessory.displayName);
}
}
- async internalValveUpdate(accessory, valve, value, callback) {
- callback();
- try {
- let params = {},
- serviceValve = accessory.getService(valve);
- params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
- switch (valve) {
- case "Valve A":
- params.switches[0].switch = value ? "on" : "off";
- params.switches[1].switch = accessory.getService("Valve B").getCharacteristic(Characteristic.Active).value
- ? "on"
- : "off";
- break;
- case "Valve B":
- params.switches[0].switch = accessory.getService("Valve A").getCharacteristic(Characteristic.Active).value
- ? "on"
- : "off";
- params.switches[1].switch = value ? "on" : "off";
- break;
- }
- params.switches[2].switch = "off";
- params.switches[3].switch = "off";
- await this.sendDeviceUpdate(accessory, params);
- serviceValve.updateCharacteristic(Characteristic.Active, value).updateCharacteristic(Characteristic.InUse, value);
- switch (value) {
- case 0:
- serviceValve.updateCharacteristic(Characteristic.RemainingDuration, 0);
- clearTimeout(accessory.getService(valve).timer);
- break;
- case 1:
- let timer = serviceValve.getCharacteristic(Characteristic.SetDuration).value;
- serviceValve.updateCharacteristic(Characteristic.RemainingDuration, timer);
- serviceValve.timer = setTimeout(() => serviceValve.setCharacteristic(Characteristic.Active, 0), timer * 1000);
- break;
- }
- } catch (err) {
- this.requestDeviceRefresh(accessory, err);
- }
- }
- externalValveUpdate(accessory, params) {
- try {
- ["A", "B"].forEach((v, k) => {
- let valveService = accessory.getService("Valve " + v);
- valveService
- .updateCharacteristic(Characteristic.Active, params.switches[k].switch === "on")
- .updateCharacteristic(Characteristic.InUse, params.switches[k].switch === "on");
- if (params.switches[k].switch === "on") {
- let timer = valveService.getCharacteristic(Characteristic.SetDuration).value;
- valveService.updateCharacteristic(Characteristic.RemainingDuration, timer);
- valveService.timer = setTimeout(() => {
- valveService.setCharacteristic(Characteristic.Active, 0);
- }, timer * 1000);
- } else {
- valveService.updateCharacteristic(Characteristic.RemainingDuration, 0);
- clearTimeout(valveService.timer);
- }
- });
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- async internalCurtainUpdate(accessory, value, callback) {
- callback();
- try {
- let params,
- cService = accessory.getService(Service.WindowCovering),
- prevPos = accessory.context.cacheCurrentPosition,
- newPos = value;
- if (newPos === prevPos) return;
- if (newPos === 0 || newPos === 100) {
- params = {
- switch: newPos === 100 ? "on" : "off",
- };
- } else {
- params = {
- setclose: Math.abs(100 - newPos),
- };
- }
- await this.sendDeviceUpdate(accessory, params);
- cService
- .updateCharacteristic(Characteristic.TargetPosition, newPos)
- .updateCharacteristic(Characteristic.PositionState, newPos > prevPos ? 1 : 0);
- accessory.context.cacheCurrentPosition = newPos;
- } catch (err) {
- this.requestDeviceRefresh(accessory, err);
- }
- }
- externalCurtainUpdate(accessory, params) {
- try {
- let cService = accessory.getService(Service.WindowCovering);
- if (params.hasOwnProperty("switch") && params.hasOwnProperty("setclose")) {
- let newPos = Math.abs(100 - parseInt(params.setclose));
- cService
- .updateCharacteristic(Characteristic.TargetPosition, newPos)
- .updateCharacteristic(Characteristic.CurrentPosition, newPos)
- .updateCharacteristic(Characteristic.PositionState, 2);
- accessory.context.cacheCurrentPosition = newPos;
- return;
- }
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- async internalBlindUpdate(accessory, value, callback) {
- callback();
- try {
- let blindConfig,
- params = {},
- wcService = accessory.getService(Service.WindowCovering),
- prevState = accessory.context.cachePositionState,
- prevPosition = accessory.context.cacheCurrentPosition,
- newTarget = value,
- updateKey = Math.random().toString(36).substr(2, 8);
- if (!(blindConfig = this.cusG.get(accessory.context.hbDeviceId))) {
- throw "group config missing";
- }
- if (blindConfig.type !== "blind" || blindConfig.setup !== "twoSwitch") {
- throw "improper configuration";
- }
- if (newTarget === prevPosition) return;
- params.switches = cns.defaultMultiSwitchOff;
- accessory.context.updateKey = updateKey;
- let percentStepPerDecisecond = blindConfig.operationTime / 100;
- if (prevState !== 2) {
- await this.sendDeviceUpdate(accessory, params);
- let positionPercentChange = Math.round(
- Math.floor(Date.now() / 100) - accessory.context.cacheLastStartTime * percentStepPerDecisecond
- );
- if ((prevState === 0 && newTarget > prevPosition) || (prevState === 1 && newTarget < prevPosition)) {
- prevPosition += positionPercentChange;
- } else {
- prevPosition -= positionPercentChange;
- }
- wcService.updateCharacteristic(Characteristic.CurrentPosition, prevPosition);
- accessory.context.cacheCurrentPosition = prevPosition;
- }
- let diffPosition = newTarget - prevPosition;
- let setToMoveUp = diffPosition > 0;
- let decisecondsToMove = Math.round(Math.abs(diffPosition) * percentStepPerDecisecond);
- params.switches[0].switch = setToMoveUp ? "on" : "off";
- params.switches[1].switch = setToMoveUp ? "off" : "on";
- await this.sendDeviceUpdate(accessory, params);
- wcService
- .updateCharacteristic(Characteristic.TargetPosition, newTarget)
- .updateCharacteristic(Characteristic.PositionState, setToMoveUp);
- accessory.context.cacheTargetPosition = newTarget;
- accessory.context.cachePositionState = setToMoveUp;
- accessory.context.cacheLastStartTime = Math.floor(Date.now() / 100);
- this.log.warn(decisecondsToMove + " movement time in deciseconds");
- await utils.sleep(decisecondsToMove * 100);
- if (accessory.context.updateKey === updateKey) {
- params.switches[0].switch = "off";
- params.switches[1].switch = "off";
- await this.sendDeviceUpdate(accessory, params);
- wcService.updateCharacteristic(Characteristic.PositionState, 2);
- wcService.updateCharacteristic(Characteristic.CurrentPosition, newTarget);
- accessory.context.cachePositionState = 2;
- accessory.context.cacheCurrentPosition = newTarget;
- }
- } catch (err) {
- this.requestDeviceRefresh(accessory, err);
- }
- }
- externalBlindUpdate(accessory, params) {
- try {
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- async internalGarageUpdate(accessory, value, callback) {
- callback();
- try {
- let garageConfig;
- if (!(garageConfig = this.cusG.get(accessory.context.hbDeviceId))) {
- throw "group config missing";
- }
- if (garageConfig.type !== "garage" || !["oneSwitch", "twoSwitch"].includes(garageConfig.setup)) {
- throw "improper configuration";
- }
- let sensorDefinition = garageConfig.sensorId || false,
- sAccessory = false,
- prevState,
- newPos = value,
- params = {},
- delay = 0,
- gdService = accessory.getService(Service.GarageDoorOpener);
- if (sensorDefinition && !(sAccessory = this.devicesInHB.get(garageConfig.sensorId + "SWX"))) {
- throw "defined DW2 sensor doesn't exist";
- }
- if (sensorDefinition && sAccessory.context.type !== "sensor") {
- throw "defined DW2 sensor isn't a sensor";
- }
- prevState = sAccessory
- ? sAccessory.getService(Service.ContactSensor).getCharacteristic(Characteristic.ContactSensorState).value === 0
- ? 1
- : 0
- : accessory.context.cacheCurrentDoorState;
- if (newPos === prevState % 2) return;
- accessory.context.inUse = true;
- accessory.context.state = value;
- if (garageConfig.setup === "oneSwitch" && [2, 3].includes(prevState)) {
- gdService.updateCharacteristic(Characteristic.CurrentDoorState, ((prevState * 2) % 3) + 2);
- accessory.context.cacheCurrentDoorState = ((prevState * 2) % 3) + 2;
- delay = 1500;
- }
- if (accessory.context.state !== newPos) return;
- await utils.sleep(delay);
- gdService
- .updateCharacteristic(Characteristic.TargetDoorState, newPos)
- .updateCharacteristic(Characteristic.CurrentDoorState, newPos + 2);
- accessory.context.cacheTargetDoorState = newPos;
- accessory.context.cacheCurrentDoorState = newPos + 2;
- switch (garageConfig.setup) {
- case "oneSwitch":
- params.switch = "on";
- break;
- case "twoSwitch":
- params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
- params.switches[0].switch = newPos === 0 ? "on" : "off";
- params.switches[1].switch = newPos === 1 ? "on" : "off";
- break;
- }
- await this.sendDeviceUpdate(accessory, params);
- await utils.sleep(garageConfig.operationTime * 100);
- if (!sAccessory) {
- gdService.updateCharacteristic(Characteristic.CurrentDoorState, newPos);
- accessory.context.cacheCurrentDoorState = newPos;
- }
- accessory.context.inUse = false;
- } catch (err) {
- this.requestDeviceRefresh(accessory, err);
- }
- }
- externalGarageUpdate(accessory, params) {
- try {
- let garageConfig,
- gcService = accessory.getService(Service.GarageDoorOpener),
- prevState = accessory.context.cacheCurrentDoorState,
- newPos = [0, 2].includes(prevState) ? 3 : 2;
- if (!(garageConfig = this.cusG.get(accessory.context.hbDeviceId))) {
- throw "group config missing";
- }
- if (garageConfig.type !== "garage" || !["oneSwitch", "twoSwitch"].includes(garageConfig.setup)) {
- throw "improper configuration";
- }
- if (accessory.context.inUse || garageConfig.sensorId) {
- return;
- }
- switch (garageConfig.setup) {
- case "oneSwitch":
- if (params.switch === "off") {
- return;
- }
- break;
- case "twoSwitch":
- if (
- params.switches[0].switch === params.switches[1].switch ||
- params.switches[prevState % 2].switch === "on"
- ) {
- return;
- }
- break;
- }
- accessory.context.inUse = true;
- if (!garageConfig.sensorId) {
- gcService
- .updateCharacteristic(Characteristic.CurrentDoorState, newPos)
- .updateCharacteristic(Characteristic.TargetDoorState, newPos - 2);
- accessory.context.cacheCurrentDoorState = newPos;
- accessory.context.cacheTargetDoorState = newPos - 2;
- setTimeout(() => {
- gcService.updateCharacteristic(Characteristic.CurrentDoorState, newPos - 2);
- accessory.context.cacheCurrentDoorState = newPos - 2;
- }, parseInt(garageConfig.operationTime) * 100);
- }
- setTimeout(() => {
- accessory.context.inUse = false;
- }, parseInt(garageConfig.operationTime) * 100);
- } catch (err) {
- accessory.context.inUse = false;
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- async internalLockUpdate(accessory, value, callback) {
- callback();
- try {
- let lockConfig,
- params = {
- switch: "on",
- },
- lmService = accessory.getService(Service.LockMechanism);
- if (!(lockConfig = this.cusG.get(accessory.context.hbDeviceId))) {
- throw "group config missing";
- }
- if (lockConfig.type !== "lock") {
- throw "improper configuration";
- }
- accessory.context.inUse = true;
- await this.sendDeviceUpdate(accessory, params);
- lmService
- .updateCharacteristic(Characteristic.LockTargetState, 0)
- .updateCharacteristic(Characteristic.LockCurrentState, 0);
- await utils.sleep(lockConfig.operationTime * 100);
- lmService
- .updateCharacteristic(Characteristic.LockTargetState, 1)
- .updateCharacteristic(Characteristic.LockCurrentState, 1);
- accessory.context.inUse = false;
- } catch (err) {
- this.requestDeviceRefresh(accessory, err);
- }
- }
- externalLockUpdate(accessory, params) {
- try {
- let lockConfig,
- lmService = accessory.getService(Service.LockMechanism);
- if (!(lockConfig = this.cusG.get(accessory.context.hbDeviceId))) {
- throw "group config missing";
- }
- if (lockConfig.type !== "lock") {
- throw "improper configuration";
- }
- if (params.switch === "off" || accessory.context.inUse) {
- return;
- }
- accessory.context.inUse = true;
- lmService
- .updateCharacteristic(Characteristic.LockCurrentState, 0)
- .updateCharacteristic(Characteristic.LockTargetState, 0);
- setTimeout(() => {
- lmService
- .updateCharacteristic(Characteristic.LockCurrentState, 1)
- .updateCharacteristic(Characteristic.LockTargetState, 1);
- accessory.context.inUse = false;
- }, parseInt(lockConfig.operationTime) * 100);
- } catch (err) {
- accessory.context.inUse = false;
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- externalSensorUpdate(accessory, params) {
- try {
- if (params.hasOwnProperty("battery")) {
- let batteryService =
- accessory.getService(Service.BatteryService) || accessory.addService(Service.BatteryService),
- scaledBattery = Math.round(params.battery * 33.3);
- batteryService.updateCharacteristic(Characteristic.BatteryLevel, scaledBattery);
- batteryService.updateCharacteristic(
- Characteristic.StatusLowBattery,
- scaledBattery < (this.config.lowBattThreshold || 25)
- );
- }
- let newState = params.switch === "on" ? 1 : 0,
- oAccessory = false,
- contactService = accessory.getService(Service.ContactSensor);
- contactService.updateCharacteristic(Characteristic.ContactSensorState, newState);
- this.cusG.forEach(group => {
- if (group.sensorId === accessory.context.eweDeviceId && group.type === "garage") {
- if ((oAccessory = this.devicesInHB.get(group.deviceId + "SWX"))) {
- switch (newState) {
- case 0:
- oAccessory
- .getService(Service.GarageDoorOpener)
- .updateCharacteristic(Characteristic.TargetDoorState, 1)
- .updateCharacteristic(Characteristic.CurrentDoorState, 1);
- break;
- case 1:
- setTimeout(() => {
- oAccessory
- .getService(Service.GarageDoorOpener)
- .updateCharacteristic(Characteristic.TargetDoorState, 0)
- .updateCharacteristic(Characteristic.CurrentDoorState, 0);
- }, group.operationTime * 100);
- break;
- default:
- throw "unknown sensor status received [" + newState + "]";
- }
- }
- }
- });
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- async internalFanUpdate(accessory, type, value, callback) {
- callback();
- try {
- let newPower,
- newSpeed,
- newLight,
- lightService = accessory.getService(Service.Lightbulb),
- fanService = accessory.getService(Service.Fanv2);
- switch (type) {
- case "power":
- newPower = value;
- newSpeed = value ? 33 : 0;
- newLight = lightService.getCharacteristic(Characteristic.On).value;
- break;
- case "speed":
- newPower = value >= 33 ? 1 : 0;
- newSpeed = value;
- newLight = lightService.getCharacteristic(Characteristic.On).value;
- break;
- case "light":
- newPower = fanService.getCharacteristic(Characteristic.Active).value;
- newSpeed = fanService.getCharacteristic(Characteristic.RotationSpeed).value;
- newLight = value;
- break;
- }
- let params = {
- switches: this.devicesInEW.get(accessory.context.eweDeviceId).params.switches,
- };
- params.switches[0].switch = newLight ? "on" : "off";
- params.switches[1].switch = newPower === 1 && newSpeed >= 33 ? "on" : "off";
- params.switches[2].switch = newPower === 1 && newSpeed >= 66 && newSpeed < 99 ? "on" : "off";
- params.switches[3].switch = newPower === 1 && newSpeed >= 99 ? "on" : "off";
- await this.sendDeviceUpdate(accessory, params);
- lightService.updateCharacteristic(Characteristic.On, newLight);
- fanService
- .updateCharacteristic(Characteristic.Active, newPower)
- .updateCharacteristic(Characteristic.RotationSpeed, newSpeed);
- } catch (err) {
- this.requestDeviceRefresh(accessory, err);
- }
- }
- externalFanUpdate(accessory, params) {
- try {
- let light,
- status,
- speed,
- lightService = accessory.getService(Service.Lightbulb),
- fanService = accessory.getService(Service.Fanv2);
- if (Array.isArray(params.switches)) {
- light = params.switches[0].switch === "on";
- switch (params.switches[1].switch + params.switches[2].switch + params.switches[3].switch) {
- default:
- status = 0;
- speed = 0;
- break;
- case "onoffoff":
- status = 1;
- speed = 33;
- break;
- case "ononoff":
- status = 1;
- speed = 66;
- break;
- case "onoffon":
- status = 1;
- speed = 99;
- }
- } else if (params.hasOwnProperty("light") && params.hasOwnProperty("fan") && params.hasOwnProperty("speed")) {
- light = params.light === "on";
- status = params.fan === "on" ? 1 : 0;
- speed = params.speed * 33 * status;
- } else {
- throw "unknown parameters received";
- }
- lightService.updateCharacteristic(Characteristic.On, light);
- fanService
- .updateCharacteristic(Characteristic.Active, status)
- .updateCharacteristic(Characteristic.RotationSpeed, speed);
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- async internalThermostatUpdate(accessory, value, callback) {
- callback();
- try {
- let params = {
- switch: value ? "on" : "off",
- mainSwitch: value ? "on" : "off",
- },
- switchService = accessory.getService(Service.Switch);
- await this.sendDeviceUpdate(accessory, params);
- switchService.updateCharacteristic(Characteristic.On, value);
- } catch (err) {
- this.requestDeviceRefresh(accessory, err);
- }
- }
- externalThermostatUpdate(accessory, params) {
- try {
- if (!this.config.hideTHSwitch && (params.hasOwnProperty("switch") || params.hasOwnProperty("mainSwitch"))) {
- let newState = params.hasOwnProperty("switch") ? params.switch === "on" : params.mainSwitch === "on",
- switchService = accessory.getService(Service.Switch);
- switchService.updateCharacteristic(Characteristic.On, newState);
- }
- if (!(this.config.disableEveLogging || false)) {
- let eveLog = {
- time: Date.now(),
- };
- if (params.hasOwnProperty("currentTemperature") && accessory.getService(Service.TemperatureSensor)) {
- let currentTemp = params.currentTemperature !== "unavailable" ? params.currentTemperature : 0;
- accessory
- .getService(Service.TemperatureSensor)
- .updateCharacteristic(Characteristic.CurrentTemperature, currentTemp);
- eveLog.temp = parseFloat(currentTemp);
- }
- if (params.hasOwnProperty("currentHumidity") && accessory.getService(Service.HumiditySensor)) {
- let currentHumi = params.currentHumidity !== "unavailable" ? params.currentHumidity : 0;
- accessory
- .getService(Service.HumiditySensor)
- .updateCharacteristic(Characteristic.CurrentRelativeHumidity, currentHumi);
- eveLog.humidity = parseFloat(currentHumi);
- }
- if (eveLog.hasOwnProperty("temp") || eveLog.hasOwnProperty("humidity")) {
- accessory.eveLogger.addEntry(eveLog);
- }
- }
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- async internalOutletUpdate(accessory, value, callback) {
- callback();
- try {
- let params = {
- switch: value ? "on" : "off",
- },
- outletService = accessory.getService(Service.Outlet);
- await this.sendDeviceUpdate(accessory, params);
- outletService.updateCharacteristic(Characteristic.On, value);
- } catch (err) {
- this.requestDeviceRefresh(accessory, err);
- }
- }
- externalOutletUpdate(accessory, params) {
- try {
- let outletService = accessory.getService(Service.Outlet);
- if (params.hasOwnProperty("switch")) {
- outletService.updateCharacteristic(Characteristic.On, params.switch === "on");
- if (accessory.context.eweModel === "S26" || this.config.disableEveLogging || false) {
- outletService.updateCharacteristic(Characteristic.OutletInUse, params.switch === "on");
- }
- }
- if (params.hasOwnProperty("power")) {
- outletService.updateCharacteristic(EveService.Characteristics.CurrentConsumption, parseFloat(params.power));
- outletService.updateCharacteristic(
- Characteristic.OutletInUse,
- parseFloat(params.power) > (this.config.inUsePowerThreshold || 0)
- );
- let isOn = accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On).value;
- accessory.eveLogger.addEntry({
- time: Date.now(),
- power: isOn ? parseFloat(params.power) : 0,
- });
- }
- if (params.hasOwnProperty("voltage")) {
- outletService.updateCharacteristic(EveService.Characteristics.Voltage, parseFloat(params.voltage));
- }
- if (params.hasOwnProperty("current")) {
- outletService.updateCharacteristic(EveService.Characteristics.ElectricCurrent, parseFloat(params.current));
- }
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- async internalUSBUpdate(accessory, value, callback) {
- callback();
- try {
- let params = {
- switches: this.devicesInEW.get(accessory.context.eweDeviceId).params.switches,
- },
- outletService = accessory.getService(Service.Outlet);
- params.switches[0].switch = value ? "on" : "off";
- await this.sendDeviceUpdate(accessory, params);
- outletService.updateCharacteristic(Characteristic.On, value);
- } catch (err) {
- this.requestDeviceRefresh(accessory, err);
- }
- }
- externalUSBUpdate(accessory, params) {
- try {
- accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, params.switches[0].switch === "on");
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- async internalSCMUpdate(accessory, value, callback) {
- callback();
- try {
- let params = {
- switches: this.devicesInEW.get(accessory.context.eweDeviceId).params.switches,
- },
- switchService = accessory.getService(Service.Switch);
- params.switches[0].switch = value ? "on" : "off";
- await this.sendDeviceUpdate(accessory, params);
- switchService.updateCharacteristic(Characteristic.On, value);
- } catch (err) {
- this.requestDeviceRefresh(accessory, err);
- }
- }
- externalSCMUpdate(accessory, params) {
- try {
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, params.switches[0].switch === "on");
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- async internalLightbulbUpdate(accessory, value, callback) {
- callback();
- try {
- let oAccessory,
- params = {},
- lightService = accessory.getService(Service.Lightbulb);
- switch (accessory.context.switchNumber) {
- case "X":
- if (accessory.context.eweUIID === 22) {
- //*** B1 ***\\
- params.state = value ? "on" : "off";
- } else {
- params.switch = value ? "on" : "off";
- }
- break;
- case "0":
- params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
- params.switches[0].switch = value ? "on" : "off";
- params.switches[1].switch = value ? "on" : "off";
- params.switches[2].switch = value ? "on" : "off";
- params.switches[3].switch = value ? "on" : "off";
- break;
- case "1":
- case "2":
- case "3":
- case "4":
- params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
- for (let i = 1; i <= 4; i++) {
- if ((oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
- i === parseInt(accessory.context.switchNumber)
- ? (params.switches[i - 1].switch = value ? "on" : "off")
- : (params.switches[i - 1].switch = oAccessory
- .getService(Service.Lightbulb)
- .getCharacteristic(Characteristic.On).value
- ? "on"
- : "off");
- } else {
- params.switches[i - 1].switch = "off";
- }
- }
- break;
- }
- await this.sendDeviceUpdate(accessory, params);
- switch (accessory.context.switchNumber) {
- case "X":
- lightService.updateCharacteristic(Characteristic.On, value);
- break;
- case "0":
- for (let i = 0; i <= 4; i++) {
- if ((oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
- oAccessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
- }
- }
- break;
- case "1":
- case "2":
- case "3":
- case "4":
- lightService.updateCharacteristic(Characteristic.On, value);
- let masterState = "off";
- for (let i = 1; i <= 4; i++) {
- if ((oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
- if (oAccessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value) {
- masterState = "on";
- }
- }
- }
- if (!this.hiddenMasters.includes(accessory.context.eweDeviceId)) {
- oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
- oAccessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, masterState === "on");
- }
- break;
- }
- } catch (err) {
- this.requestDeviceRefresh(accessory, err);
- }
- }
- async internalBrightnessUpdate(accessory, value, callback) {
- callback();
- try {
- let params = {},
- lightService = accessory.getService(Service.Lightbulb);
- if (value === 0) {
- params.switch = "off";
- } else {
- if (!lightService.getCharacteristic(Characteristic.On).value) {
- params.switch = "on";
- }
- switch (accessory.context.eweUIID) {
- case 36: //*** KING-M4 ***\\
- params.bright = Math.round((value * 9) / 10 + 10);
- break;
- case 44: //*** D1 ***\\
- params.brightness = value;
- params.mode = 0;
- break;
- }
- }
- await utils.sleep(250);
- await this.sendDeviceUpdate(accessory, params);
- if (value === 0) {
- lightService.updateCharacteristic(Characteristic.On, false);
- } else {
- lightService.updateCharacteristic(Characteristic.Brightness, value);
- }
- } catch (err) {
- this.requestDeviceRefresh(accessory, err);
- }
- }
- async internalHSBUpdate(accessory, type, value, callback) {
- callback();
- try {
- if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
- throw "it is currently offline";
- }
- let newRGB,
- params = {},
- lightService = accessory.getService(Service.Lightbulb),
- curHue = lightService.getCharacteristic(Characteristic.Hue).value,
- curSat = lightService.getCharacteristic(Characteristic.Saturation).value;
- switch (type) {
- case "hue":
- newRGB = convert.hsv.rgb(value, curSat, 100);
- switch (accessory.context.eweUIID) {
- case 22: //*** B1 ***\\
- params = {
- zyx_mode: 2,
- type: "middle",
- channel0: "0",
- channel1: "0",
- channel2: newRGB[0].toString(),
- channel3: newRGB[1].toString(),
- channel4: newRGB[2].toString(),
- };
- break;
- case 59: //*** L1 ***\\
- params = {
- mode: 1,
- colorR: newRGB[0],
- colorG: newRGB[1],
- colorB: newRGB[2],
- };
- break;
- }
- break;
- case "bri":
- switch (accessory.context.eweUIID) {
- case 22: //*** B1 ***\\
- newRGB = convert.hsv.rgb(curHue, curSat, value);
- params = {
- zyx_mode: 2,
- type: "middle",
- channel0: "0",
- channel1: "0",
- channel2: newRGB[0].toString(),
- channel3: newRGB[1].toString(),
- channel4: newRGB[2].toString(),
- };
- break;
- case 59: //*** L1 ***\\
- params = {
- mode: 1,
- bright: value,
- };
- break;
- }
- break;
- }
- await utils.sleep(250);
- await this.sendDeviceUpdate(accessory, params);
- switch (type) {
- case "hue":
- lightService.updateCharacteristic(Characteristic.Hue, value);
- break;
- case "bri":
- lightService.updateCharacteristic(Characteristic.Brightness, value);
- break;
- }
- } catch (err) {
- this.requestDeviceRefresh(accessory, err);
- }
- }
- externalSingleLightUpdate(accessory, params) {
- try {
- let newColour,
- mode,
- isOn = false,
- lightService = accessory.getService(Service.Lightbulb);
- if (accessory.context.eweUIID === 22 && params.hasOwnProperty("state")) {
- isOn = params.state === "on";
- } else if (accessory.context.eweUIID !== 22 && params.hasOwnProperty("switch")) {
- isOn = params.switch === "on";
- } else {
- isOn = lightService.getCharacteristic(Characteristic.On).value;
- }
- if (isOn) {
- lightService.updateCharacteristic(Characteristic.On, true);
- switch (accessory.context.eweUIID) {
- case 36: // KING-M4
- if (params.hasOwnProperty("bright")) {
- let nb = Math.round(((params.bright - 10) * 10) / 9); // eWeLink scale is 10-100 and HomeKit scale is 0-100.
- lightService.updateCharacteristic(Characteristic.Brightness, nb);
- }
- break;
- case 44: // D1
- if (params.hasOwnProperty("brightness")) {
- lightService.updateCharacteristic(Characteristic.Brightness, params.brightness);
- }
- break;
- case 22: // B1
- if (params.hasOwnProperty("zyx_mode")) {
- mode = parseInt(params.zyx_mode);
- } else if (params.hasOwnProperty("channel0") && parseInt(params.channel0) + parseInt(params.channel1) > 0) {
- mode = 1;
- } else {
- mode = 2;
- }
- if (mode === 2) {
- lightService.updateCharacteristic(Characteristic.On, true);
- newColour = convert.rgb.hsv(
- parseInt(params.channel2),
- parseInt(params.channel3),
- parseInt(params.channel4)
- );
- lightService
- .updateCharacteristic(Characteristic.Hue, newColour[0])
- .updateCharacteristic(Characteristic.Saturation, 100)
- .updateCharacteristic(Characteristic.Brightness, 100);
- } else if (mode === 1) {
- throw "has been set to white mode which is not supported";
- }
- break;
- case 59: // L1
- if (params.hasOwnProperty("bright")) {
- lightService.updateCharacteristic(Characteristic.Brightness, params.bright);
- }
- if (params.hasOwnProperty("colorR")) {
- newColour = convert.rgb.hsv(params.colorR, params.colorG, params.colorB);
- lightService
- .updateCharacteristic(Characteristic.Hue, newColour[0])
- .updateCharacteristic(Characteristic.Saturation, newColour[1]);
- }
- break;
- default:
- return;
- }
- } else {
- lightService.updateCharacteristic(Characteristic.On, false);
- }
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- externalMultiLightUpdate(accessory, params) {
- try {
- let idToCheck = accessory.context.hbDeviceId.slice(0, -1),
- primaryState = false;
- for (let i = 1; i <= accessory.context.channelCount; i++) {
- if (this.devicesInHB.has(idToCheck + i)) {
- let oAccessory = this.devicesInHB.get(idToCheck + i);
- oAccessory
- .getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.On, params.switches[i - 1].switch === "on");
- if (params.switches[i - 1].switch === "on") {
- primaryState = true;
- }
- }
- }
- if (!this.hiddenMasters.includes(accessory.context.eweDeviceId)) {
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, primaryState);
- }
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- async internalSwitchUpdate(accessory, value, callback) {
- callback();
- try {
- let oAccessory,
- params = {},
- switchService = accessory.getService(Service.Switch);
- switch (accessory.context.switchNumber) {
- case "X":
- params.switch = value ? "on" : "off";
- break;
- case "0":
- params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
- params.switches[0].switch = value ? "on" : "off";
- params.switches[1].switch = value ? "on" : "off";
- params.switches[2].switch = value ? "on" : "off";
- params.switches[3].switch = value ? "on" : "off";
- break;
- case "1":
- case "2":
- case "3":
- case "4":
- params.switches = this.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
- for (let i = 1; i <= 4; i++) {
- if ((oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
- i === parseInt(accessory.context.switchNumber)
- ? (params.switches[i - 1].switch = value ? "on" : "off")
- : (params.switches[i - 1].switch = oAccessory
- .getService(Service.Switch)
- .getCharacteristic(Characteristic.On).value
- ? "on"
- : "off");
- } else {
- params.switches[i - 1].switch = "off";
- }
- }
- break;
- }
- await this.sendDeviceUpdate(accessory, params);
- switch (accessory.context.switchNumber) {
- case "X":
- switchService.updateCharacteristic(Characteristic.On, value);
- break;
- case "0":
- for (let i = 0; i <= 4; i++) {
- if ((oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
- oAccessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
- }
- }
- break;
- case "1":
- case "2":
- case "3":
- case "4":
- switchService.updateCharacteristic(Characteristic.On, value);
- let masterState = "off";
- for (let i = 1; i <= 4; i++) {
- if ((oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
- if (oAccessory.getService(Service.Switch).getCharacteristic(Characteristic.On).value) {
- masterState = "on";
- }
- }
- }
- if (!this.hiddenMasters.includes(accessory.context.eweDeviceId)) {
- oAccessory = this.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
- oAccessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, masterState === "on");
- }
- break;
- }
- } catch (err) {
- this.requestDeviceRefresh(accessory, err);
- }
- }
- externalSingleSwitchUpdate(accessory, params) {
- try {
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, params.switch === "on");
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- externalMultiSwitchUpdate(accessory, params) {
- try {
- let idToCheck = accessory.context.hbDeviceId.slice(0, -1),
- primaryState = false;
- for (let i = 1; i <= accessory.context.channelCount; i++) {
- if (this.devicesInHB.has(idToCheck + i)) {
- let oAccessory = this.devicesInHB.get(idToCheck + i);
- oAccessory
- .getService(Service.Switch)
- .updateCharacteristic(Characteristic.On, params.switches[i - 1].switch === "on");
- if (params.switches[i - 1].switch === "on") {
- primaryState = true;
- }
- }
- }
- if (!this.hiddenMasters.includes(accessory.context.eweDeviceId)) {
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, primaryState);
- }
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- async internalRFUpdate(accessory, rfChl, service, callback) {
- callback();
- try {
- let params = {
- cmd: "transmit",
- rfChl: parseInt(rfChl),
- },
- rfService = accessory.getService(service);
- await this.sendDeviceUpdate(accessory, params);
- rfService.updateCharacteristic(Characteristic.On, true);
- await utils.sleep(3000);
- rfService.updateCharacteristic(Characteristic.On, false);
- } catch (err) {
- this.requestDeviceRefresh(accessory, err);
- }
- }
- externalRFUpdate(accessory, params) {
- try {
- if (!params.hasOwnProperty("updateSource")) return;
- let timeNow = new Date(),
- oAccessory = false;
- if (params.hasOwnProperty("cmd") && params.cmd === "transmit" && params.hasOwnProperty("rfChl")) {
- //*** RF Button ***\\
- // the device needed is SW% corresponding to params.rfChl
- this.devicesInHB.forEach(acc => {
- if (
- acc.context.eweDeviceId === accessory.context.eweDeviceId &&
- acc.context.buttons.hasOwnProperty(params.rfChl.toString())
- ) {
- oAccessory = acc;
- }
- });
- if (oAccessory) {
- oAccessory.getService(oAccessory.context.buttons[params.rfChl]).updateCharacteristic(Characteristic.On, 1);
- setTimeout(
- () =>
- oAccessory
- .getService(oAccessory.context.buttons[params.rfChl])
- .updateCharacteristic(Characteristic.On, 0),
- 3000
- );
- } else {
- throw "rf button not found in Homebridge";
- }
- } else if (params.hasOwnProperty("cmd") && params.cmd === "trigger") {
- //*** RF Sensor ***\\
- Object.keys(params)
- .filter(name => /rfTrig/.test(name))
- .forEach(chan => {
- this.devicesInHB.forEach(acc => {
- if (
- acc.context.eweDeviceId === accessory.context.eweDeviceId &&
- acc.context.buttons.hasOwnProperty(chan.substr(-1).toString())
- ) {
- oAccessory = acc;
- }
- });
- if (oAccessory) {
- let timeOfMotion = new Date(params[chan]),
- diff = (timeNow.getTime() - timeOfMotion.getTime()) / 1000,
- serv,
- char;
- if (diff < (this.config.sensorTimeDifference || 120)) {
- switch (oAccessory.context.sensorType) {
- case "button":
- break;
- case "water":
- serv = Service.LeakSensor;
- char = Characteristic.LeakDetected;
- break;
- case "fire":
- case "smoke":
- serv = Service.SmokeSensor;
- char = Characteristic.LeakDetected;
- break;
- case "co":
- serv = Service.CarbonMonoxideSensor;
- char = Characteristic.CarbonMonoxideDetected;
- break;
- case "co2":
- serv = Service.CarbonDioxideSensor;
- char = Characteristic.CarbonDioxideDetected;
- break;
- case "contact":
- serv = Service.ContactSensor;
- char = Characteristic.ContactSensorState;
- break;
- case "occupancy":
- serv = Service.OccupancySensor;
- char = Characteristic.OccupancyDetected;
- break;
- default:
- serv = Service.MotionSensor;
- char = Characteristic.MotionDetected;
- break;
- }
- oAccessory.getService(serv).updateCharacteristic(char, 1);
- setTimeout(() => {
- oAccessory.getService(serv).updateCharacteristic(char, 0);
- }, (this.config.sensorTimeLength || 2) * 1000);
- if (this.debug) {
- this.log("[%s] has detected [%s].", oAccessory.displayName, oAccessory.context.sensorType);
- }
- }
- }
- });
- }
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
- externalZBUpdate(accessory, params) {
- try {
- //*** credit @tasict ***\\
- if (params.hasOwnProperty("battery")) {
- if (accessory.context.eweUIID === 3026 && (this.config.ZBDWBatt || false)) {
- params.battery *= 10;
- }
- let batteryService =
- accessory.getService(Service.BatteryService) || accessory.addService(Service.BatteryService);
- batteryService.updateCharacteristic(Characteristic.BatteryLevel, params.battery);
- batteryService.updateCharacteristic(
- Characteristic.StatusLowBattery,
- params.battery < (this.config.lowBattThreshold || 25)
- );
- }
- switch (accessory.context.eweUIID) {
- case 1000:
- if (params.hasOwnProperty("key") && [0, 1, 2].includes(params.key)) {
- accessory
- .getService(Service.StatelessProgrammableSwitch)
- .updateCharacteristic(Characteristic.ProgrammableSwitchEvent, params.key);
- }
- break;
- case 1770:
- let eveLog = {
- time: Date.now(),
- };
- if (params.hasOwnProperty("temperature")) {
- let currentTemp = parseInt(params.temperature) / 100;
- accessory
- .getService(Service.TemperatureSensor)
- .updateCharacteristic(Characteristic.CurrentTemperature, currentTemp);
- eveLog.temp = parseFloat(currentTemp);
- }
- if (params.hasOwnProperty("humidity")) {
- let currentHumi = parseInt(params.humidity) / 100;
- accessory
- .getService(Service.HumiditySensor)
- .updateCharacteristic(Characteristic.CurrentRelativeHumidity, currentHumi);
- eveLog.humidity = parseFloat(currentHumi);
- }
- if (eveLog.hasOwnProperty("temp") || eveLog.hasOwnProperty("humidity")) {
- accessory.eveLogger.addEntry(eveLog);
- }
- break;
- case 2026:
- if (params.hasOwnProperty("motion") && params.hasOwnProperty("trigTime")) {
- let timeNow = new Date(),
- diff = (timeNow.getTime() - params.trigTime) / 1000;
- accessory
- .getService(Service.MotionSensor)
- .updateCharacteristic(
- Characteristic.MotionDetected,
- params.hasOwnProperty("updateSource") &&
- params.motion === 1 &&
- diff < (this.config.sensorTimeDifference || 120)
- );
- break;
- }
- break;
- case 3026:
- if (params.hasOwnProperty("lock") && [0, 1].includes(params.lock)) {
- accessory
- .getService(Service.ContactSensor)
- .updateCharacteristic(Characteristic.ContactSensorState, params.lock);
- }
- break;
- }
- } catch (err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
- }
- }
}
module.exports = function (homebridge) {
Accessory = homebridge.platformAccessory;
From 7e33edf6faeaa3bccc1148526823dda000bcb171 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sat, 26 Sep 2020 22:19:23 +0100
Subject: [PATCH 0225/3183] blinds
---
lib/device/blind.js | 87 ++++++++++++++++++++++++++++++++++++++-------
1 file changed, 74 insertions(+), 13 deletions(-)
diff --git a/lib/device/blind.js b/lib/device/blind.js
index 8057a852..bb9b5725 100644
--- a/lib/device/blind.js
+++ b/lib/device/blind.js
@@ -18,9 +18,12 @@ module.exports = class deviceBlind {
wcService = accessory.getService(Service.WindowCovering),
prevState = accessory.context.cachePositionState,
prevPosition = accessory.context.cacheCurrentPosition,
+ prevFixedPosition = accessory.context.cacheLastFixedPosition,
newTarget = value,
updateKey = Math.random().toString(36).substr(2, 8);
- if (!(blindConfig = this.cusG.get(accessory.context.hbDeviceId))) {
+ if (
+ !(blindConfig = this.platform.cusG.get(accessory.context.hbDeviceId))
+ ) {
throw "group config missing";
}
if (blindConfig.type !== "blind" || blindConfig.setup !== "twoSwitch") {
@@ -30,41 +33,99 @@ module.exports = class deviceBlind {
params.switches = cns.defaultMultiSwitchOff;
accessory.context.updateKey = updateKey;
let percentStepPerDecisecond = blindConfig.operationTime / 100;
+
+ //
+ //
+
+ this.platform.log("============================");
+ this.platform.log("============================");
+ this.platform.log("Starting main calculation...");
+ this.platform.log("Moving from [%s%] to [%s%].", prevPosition, newTarget);
+
+ //
+ //
+
if (prevState !== 2) {
- await this.platform.sendDeviceUpdate(accessory, params);
+ // await this.platform.sendDeviceUpdate(accessory, params);
let positionPercentChange = Math.round(
- Math.floor(Date.now() / 100) - accessory.context.cacheLastStartTime * percentStepPerDecisecond
+ (Math.floor(Date.now() / 100) -
+ accessory.context.cacheLastStartTime) *
+ percentStepPerDecisecond
);
- if ((prevState === 0 && newTarget > prevPosition) || (prevState === 1 && newTarget < prevPosition)) {
- prevPosition += positionPercentChange;
+ if (
+ (prevState === 0 && newTarget < prevPosition) ||
+ (prevState === 1 && newTarget > prevPosition)
+ ) {
+ prevPosition = Math.abs(prevPosition - positionPercentChange);
} else {
- prevPosition -= positionPercentChange;
+ prevPosition = Math.abs(prevPosition + positionPercentChange);
}
- wcService.updateCharacteristic(Characteristic.CurrentPosition, prevPosition);
+ wcService.updateCharacteristic(
+ Characteristic.CurrentPosition,
+ prevPosition
+ );
+ this.platform.log.warn("But...");
+ this.platform.log.warn(
+ "Blind was already moving %s when it was changed and was probably around %s%",
+ prevState === 1 ? "up" : "down",
+ prevPosition
+ );
+ this.platform.log.warn(
+ "Blind was already moving from time %s when it was changed at %s time",
+ accessory.context.cacheLastStartTime,
+ Math.floor(Date.now() / 100)
+ );
+ this.platform.log.warn(
+ "Giving a difference of %s seconds",
+ (Math.floor(Date.now() / 100) -
+ accessory.context.cacheLastStartTime) /
+ 10
+ );
+ this.platform.log.warn(
+ "This works out as a position change of %s%",
+ positionPercentChange
+ );
+
accessory.context.cacheCurrentPosition = prevPosition;
}
+
let diffPosition = newTarget - prevPosition;
let setToMoveUp = diffPosition > 0;
- let decisecondsToMove = Math.round(Math.abs(diffPosition) * percentStepPerDecisecond);
+ let decisecondsToMove = Math.round(
+ Math.abs(diffPosition) * percentStepPerDecisecond
+ );
+ this.platform.log(
+ "So we need to move %s from the previous state of %s for about %s seconds",
+ setToMoveUp ? "up" : "down",
+ prevState === 0
+ ? "moving down"
+ : prevState === 1
+ ? "moving up"
+ : "stopped",
+ decisecondsToMove / 10
+ );
params.switches[0].switch = setToMoveUp ? "on" : "off";
params.switches[1].switch = setToMoveUp ? "off" : "on";
- await this.platform.sendDeviceUpdate(accessory, params);
+ // await this.platform.sendDeviceUpdate(accessory, params);
wcService
.updateCharacteristic(Characteristic.TargetPosition, newTarget)
.updateCharacteristic(Characteristic.PositionState, setToMoveUp);
accessory.context.cacheTargetPosition = newTarget;
- accessory.context.cachePositionState = setToMoveUp;
+ accessory.context.cachePositionState = setToMoveUp ? 1 : 0;
accessory.context.cacheLastStartTime = Math.floor(Date.now() / 100);
- this.platform.log.warn(decisecondsToMove + " movement time in deciseconds");
await utils.sleep(decisecondsToMove * 100);
if (accessory.context.updateKey === updateKey) {
params.switches[0].switch = "off";
params.switches[1].switch = "off";
- await this.platform.sendDeviceUpdate(accessory, params);
+ // await this.platform.sendDeviceUpdate(accessory, params);
wcService.updateCharacteristic(Characteristic.PositionState, 2);
- wcService.updateCharacteristic(Characteristic.CurrentPosition, newTarget);
+ wcService.updateCharacteristic(
+ Characteristic.CurrentPosition,
+ newTarget
+ );
accessory.context.cachePositionState = 2;
accessory.context.cacheCurrentPosition = newTarget;
+ accessory.context.cacheLastFixedPosition = newTarget;
}
} catch (err) {
this.platform.requestDeviceRefresh(accessory, err);
From a322e981c076fefff52296283324cef28f3013e3 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sat, 26 Sep 2020 22:20:01 +0100
Subject: [PATCH 0226/3183] formatting
---
lib/device/blind.js | 42 +++++++++---------------------------------
1 file changed, 9 insertions(+), 33 deletions(-)
diff --git a/lib/device/blind.js b/lib/device/blind.js
index bb9b5725..73615c4e 100644
--- a/lib/device/blind.js
+++ b/lib/device/blind.js
@@ -21,9 +21,7 @@ module.exports = class deviceBlind {
prevFixedPosition = accessory.context.cacheLastFixedPosition,
newTarget = value,
updateKey = Math.random().toString(36).substr(2, 8);
- if (
- !(blindConfig = this.platform.cusG.get(accessory.context.hbDeviceId))
- ) {
+ if (!(blindConfig = this.platform.cusG.get(accessory.context.hbDeviceId))) {
throw "group config missing";
}
if (blindConfig.type !== "blind" || blindConfig.setup !== "twoSwitch") {
@@ -48,22 +46,14 @@ module.exports = class deviceBlind {
if (prevState !== 2) {
// await this.platform.sendDeviceUpdate(accessory, params);
let positionPercentChange = Math.round(
- (Math.floor(Date.now() / 100) -
- accessory.context.cacheLastStartTime) *
- percentStepPerDecisecond
+ (Math.floor(Date.now() / 100) - accessory.context.cacheLastStartTime) * percentStepPerDecisecond
);
- if (
- (prevState === 0 && newTarget < prevPosition) ||
- (prevState === 1 && newTarget > prevPosition)
- ) {
+ if ((prevState === 0 && newTarget < prevPosition) || (prevState === 1 && newTarget > prevPosition)) {
prevPosition = Math.abs(prevPosition - positionPercentChange);
} else {
prevPosition = Math.abs(prevPosition + positionPercentChange);
}
- wcService.updateCharacteristic(
- Characteristic.CurrentPosition,
- prevPosition
- );
+ wcService.updateCharacteristic(Characteristic.CurrentPosition, prevPosition);
this.platform.log.warn("But...");
this.platform.log.warn(
"Blind was already moving %s when it was changed and was probably around %s%",
@@ -77,31 +67,20 @@ module.exports = class deviceBlind {
);
this.platform.log.warn(
"Giving a difference of %s seconds",
- (Math.floor(Date.now() / 100) -
- accessory.context.cacheLastStartTime) /
- 10
- );
- this.platform.log.warn(
- "This works out as a position change of %s%",
- positionPercentChange
+ (Math.floor(Date.now() / 100) - accessory.context.cacheLastStartTime) / 10
);
+ this.platform.log.warn("This works out as a position change of %s%", positionPercentChange);
accessory.context.cacheCurrentPosition = prevPosition;
}
let diffPosition = newTarget - prevPosition;
let setToMoveUp = diffPosition > 0;
- let decisecondsToMove = Math.round(
- Math.abs(diffPosition) * percentStepPerDecisecond
- );
+ let decisecondsToMove = Math.round(Math.abs(diffPosition) * percentStepPerDecisecond);
this.platform.log(
"So we need to move %s from the previous state of %s for about %s seconds",
setToMoveUp ? "up" : "down",
- prevState === 0
- ? "moving down"
- : prevState === 1
- ? "moving up"
- : "stopped",
+ prevState === 0 ? "moving down" : prevState === 1 ? "moving up" : "stopped",
decisecondsToMove / 10
);
params.switches[0].switch = setToMoveUp ? "on" : "off";
@@ -119,10 +98,7 @@ module.exports = class deviceBlind {
params.switches[1].switch = "off";
// await this.platform.sendDeviceUpdate(accessory, params);
wcService.updateCharacteristic(Characteristic.PositionState, 2);
- wcService.updateCharacteristic(
- Characteristic.CurrentPosition,
- newTarget
- );
+ wcService.updateCharacteristic(Characteristic.CurrentPosition, newTarget);
accessory.context.cachePositionState = 2;
accessory.context.cacheCurrentPosition = newTarget;
accessory.context.cacheLastFixedPosition = newTarget;
From fc49a009ea9ce229050cb192cbafbbb486cd54c6 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sat, 26 Sep 2020 22:20:43 +0100
Subject: [PATCH 0227/3183] 3.0.3-2
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index cf967598..4325215d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.0.3-1",
+ "version": "3.0.3-2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index a50beb2b..71511ffd 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.0.3-1",
+ "version": "3.0.3-2",
"author": "bwp91",
"contributors": [
"gbro115",
From aff2c9e5626a9b7d6f66dfc70494e665e2d83bf5 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sat, 26 Sep 2020 22:30:00 +0100
Subject: [PATCH 0228/3183] Update blind.js
---
lib/device/blind.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/lib/device/blind.js b/lib/device/blind.js
index 73615c4e..9d36d708 100644
--- a/lib/device/blind.js
+++ b/lib/device/blind.js
@@ -44,7 +44,7 @@ module.exports = class deviceBlind {
//
if (prevState !== 2) {
- // await this.platform.sendDeviceUpdate(accessory, params);
+ await this.platform.sendDeviceUpdate(accessory, params);
let positionPercentChange = Math.round(
(Math.floor(Date.now() / 100) - accessory.context.cacheLastStartTime) * percentStepPerDecisecond
);
@@ -85,7 +85,7 @@ module.exports = class deviceBlind {
);
params.switches[0].switch = setToMoveUp ? "on" : "off";
params.switches[1].switch = setToMoveUp ? "off" : "on";
- // await this.platform.sendDeviceUpdate(accessory, params);
+ await this.platform.sendDeviceUpdate(accessory, params);
wcService
.updateCharacteristic(Characteristic.TargetPosition, newTarget)
.updateCharacteristic(Characteristic.PositionState, setToMoveUp);
@@ -96,7 +96,7 @@ module.exports = class deviceBlind {
if (accessory.context.updateKey === updateKey) {
params.switches[0].switch = "off";
params.switches[1].switch = "off";
- // await this.platform.sendDeviceUpdate(accessory, params);
+ await this.platform.sendDeviceUpdate(accessory, params);
wcService.updateCharacteristic(Characteristic.PositionState, 2);
wcService.updateCharacteristic(Characteristic.CurrentPosition, newTarget);
accessory.context.cachePositionState = 2;
From 22833940e95044673193ad94de8c8820f2e500fa Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sat, 26 Sep 2020 22:31:28 +0100
Subject: [PATCH 0229/3183] 3.0.3-3
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 4325215d..8937010e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.0.3-2",
+ "version": "3.0.3-3",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 71511ffd..2b7e84c0 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.0.3-2",
+ "version": "3.0.3-3",
"author": "bwp91",
"contributors": [
"gbro115",
From 55172e1f222e12ef9f4916c7c10bf573724628b6 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 27 Sep 2020 00:13:38 +0100
Subject: [PATCH 0230/3183] Update blind.js
---
lib/device/blind.js | 57 +++++++++++++++++----------------------------
1 file changed, 22 insertions(+), 35 deletions(-)
diff --git a/lib/device/blind.js b/lib/device/blind.js
index 9d36d708..4e205161 100644
--- a/lib/device/blind.js
+++ b/lib/device/blind.js
@@ -9,7 +9,6 @@ module.exports = class deviceBlind {
Service = platform.api.hap.Service;
Characteristic = platform.api.hap.Characteristic;
}
-
async internalBlindUpdate(accessory, value, callback) {
callback();
try {
@@ -18,7 +17,6 @@ module.exports = class deviceBlind {
wcService = accessory.getService(Service.WindowCovering),
prevState = accessory.context.cachePositionState,
prevPosition = accessory.context.cacheCurrentPosition,
- prevFixedPosition = accessory.context.cacheLastFixedPosition,
newTarget = value,
updateKey = Math.random().toString(36).substr(2, 8);
if (!(blindConfig = this.platform.cusG.get(accessory.context.hbDeviceId))) {
@@ -31,49 +29,39 @@ module.exports = class deviceBlind {
params.switches = cns.defaultMultiSwitchOff;
accessory.context.updateKey = updateKey;
let percentStepPerDecisecond = blindConfig.operationTime / 100;
-
//
//
-
this.platform.log("============================");
this.platform.log("============================");
this.platform.log("Starting main calculation...");
- this.platform.log("Moving from [%s%] to [%s%].", prevPosition, newTarget);
-
//
//
-
if (prevState !== 2) {
await this.platform.sendDeviceUpdate(accessory, params);
- let positionPercentChange = Math.round(
- (Math.floor(Date.now() / 100) - accessory.context.cacheLastStartTime) * percentStepPerDecisecond
- );
- if ((prevState === 0 && newTarget < prevPosition) || (prevState === 1 && newTarget > prevPosition)) {
- prevPosition = Math.abs(prevPosition - positionPercentChange);
+ let positionPercentChange = Math.floor(Date.now() / 100) - accessory.context.cacheLastStartTime;
+ positionPercentChange = Math.floor(percentStepPerDecisecond * positionPercentChange);
+ if (prevState === 0) {
+ // moving down
+ prevPosition -= positionPercentChange;
} else {
- prevPosition = Math.abs(prevPosition + positionPercentChange);
+ prevPosition += positionPercentChange;
}
wcService.updateCharacteristic(Characteristic.CurrentPosition, prevPosition);
- this.platform.log.warn("But...");
+ accessory.context.cacheCurrentPosition = prevPosition;
+ this.platform.log.warn("Moving from [%s%] to [%s]", prevPosition, newTarget);
this.platform.log.warn(
"Blind was already moving %s when it was changed and was probably around %s%",
prevState === 1 ? "up" : "down",
prevPosition
);
this.platform.log.warn(
- "Blind was already moving from time %s when it was changed at %s time",
- accessory.context.cacheLastStartTime,
- Math.floor(Date.now() / 100)
- );
- this.platform.log.warn(
- "Giving a difference of %s seconds",
- (Math.floor(Date.now() / 100) - accessory.context.cacheLastStartTime) / 10
+ "Giving a difference of %s seconds - a position change of %s%",
+ (Math.floor(Date.now() / 100) - accessory.context.cacheLastStartTime) / 10,
+ positionPercentChange
);
- this.platform.log.warn("This works out as a position change of %s%", positionPercentChange);
-
- accessory.context.cacheCurrentPosition = prevPosition;
+ } else {
+ this.platform.log("Moving from [%s%] to [%s%].", prevPosition, newTarget);
}
-
let diffPosition = newTarget - prevPosition;
let setToMoveUp = diffPosition > 0;
let decisecondsToMove = Math.round(Math.abs(diffPosition) * percentStepPerDecisecond);
@@ -92,17 +80,16 @@ module.exports = class deviceBlind {
accessory.context.cacheTargetPosition = newTarget;
accessory.context.cachePositionState = setToMoveUp ? 1 : 0;
accessory.context.cacheLastStartTime = Math.floor(Date.now() / 100);
+ if (accessory.context.updateKey !== updateKey) return;
await utils.sleep(decisecondsToMove * 100);
- if (accessory.context.updateKey === updateKey) {
- params.switches[0].switch = "off";
- params.switches[1].switch = "off";
- await this.platform.sendDeviceUpdate(accessory, params);
- wcService.updateCharacteristic(Characteristic.PositionState, 2);
- wcService.updateCharacteristic(Characteristic.CurrentPosition, newTarget);
- accessory.context.cachePositionState = 2;
- accessory.context.cacheCurrentPosition = newTarget;
- accessory.context.cacheLastFixedPosition = newTarget;
- }
+ if (accessory.context.updateKey !== updateKey) return;
+ params.switches[0].switch = "off";
+ params.switches[1].switch = "off";
+ await this.platform.sendDeviceUpdate(accessory, params);
+ wcService.updateCharacteristic(Characteristic.PositionState, 2);
+ wcService.updateCharacteristic(Characteristic.CurrentPosition, newTarget);
+ accessory.context.cachePositionState = 2;
+ accessory.context.cacheCurrentPosition = newTarget;
} catch (err) {
this.platform.requestDeviceRefresh(accessory, err);
}
From 996850df5f75fa4a585e3c14b98ada50de64b0f7 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 27 Sep 2020 00:14:08 +0100
Subject: [PATCH 0231/3183] Update blind.js
---
lib/device/blind.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/device/blind.js b/lib/device/blind.js
index 4e205161..377fb763 100644
--- a/lib/device/blind.js
+++ b/lib/device/blind.js
@@ -48,7 +48,7 @@ module.exports = class deviceBlind {
}
wcService.updateCharacteristic(Characteristic.CurrentPosition, prevPosition);
accessory.context.cacheCurrentPosition = prevPosition;
- this.platform.log.warn("Moving from [%s%] to [%s]", prevPosition, newTarget);
+ this.platform.log.warn("Moving from [%s%] to [%s%]", prevPosition, newTarget);
this.platform.log.warn(
"Blind was already moving %s when it was changed and was probably around %s%",
prevState === 1 ? "up" : "down",
From 5879e1b7a61a42691c3931988618c3b1afca09ee Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 27 Sep 2020 00:14:51 +0100
Subject: [PATCH 0232/3183] 3.0.3-4
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 8937010e..a05cbda3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.0.3-3",
+ "version": "3.0.3-4",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 2b7e84c0..81643c16 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.0.3-3",
+ "version": "3.0.3-4",
"author": "bwp91",
"contributors": [
"gbro115",
From cba99517e8c2d66a27602cdc767116bf9261ef12 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 27 Sep 2020 02:20:59 +0100
Subject: [PATCH 0233/3183] Update README.md
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 79d92ff6..d8a98c3f 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@
[![verified-by-homebridge](https://badgen.net/badge/homebridge/verified/purple)](https://github.com/homebridge/homebridge/wiki/Verified-Plugins)
[![Discord](https://img.shields.io/discord/432663330281226270?color=728ED5&logo=discord&label=discord)](https://discord.com/channels/432663330281226270/742733745743855627)
- [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/prettier/prettier)
+ [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)
[![npm](https://img.shields.io/npm/v/homebridge-ewelink/latest?label=release)](https://www.npmjs.com/package/homebridge-ewelink)
[![npm](https://img.shields.io/npm/v/homebridge-ewelink/beta?label=beta)](https://www.npmjs.com/package/homebridge-ewelink)
[![npm](https://img.shields.io/npm/dt/homebridge-ewelink)](https://www.npmjs.com/package/homebridge-ewelink)
From 9da0ed7433bf951a59a9ca80bdbd2fe6e6ce2437 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 27 Sep 2020 02:24:39 +0100
Subject: [PATCH 0234/3183] standard js
---
.prettier.ignore | 5 -
.prettierrc.json | 4 -
config.schema.json | 62 +-
index.js | 9 +-
lib/constants.js | 137 ++---
lib/eWeLink.js | 1456 ++++++++++++++++++++++----------------------
lib/eWeLinkHTTP.js | 460 +++++++-------
lib/eWeLinkLAN.js | 287 ++++-----
lib/eWeLinkWS.js | 492 ++++++++-------
lib/utils.js | 9 +-
package-lock.json | 6 -
package.json | 3 -
12 files changed, 1462 insertions(+), 1468 deletions(-)
delete mode 100644 .prettier.ignore
delete mode 100644 .prettierrc.json
diff --git a/.prettier.ignore b/.prettier.ignore
deleted file mode 100644
index 45fb205e..00000000
--- a/.prettier.ignore
+++ /dev/null
@@ -1,5 +0,0 @@
-.DS_Store
-.nova
-.github
-.npm
-node_modules/
\ No newline at end of file
diff --git a/.prettierrc.json b/.prettierrc.json
deleted file mode 100644
index 163a0a7e..00000000
--- a/.prettierrc.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "arrowParens": "avoid",
- "printWidth": 120
-}
diff --git a/config.schema.json b/config.schema.json
index f1e23146..037b6c42 100644
--- a/config.schema.json
+++ b/config.schema.json
@@ -136,15 +136,21 @@
"oneOf": [
{
"title": "Blind",
- "enum": ["blind"]
+ "enum": [
+ "blind"
+ ]
},
{
"title": "Garage Door",
- "enum": ["garage"]
+ "enum": [
+ "garage"
+ ]
},
{
"title": "Lock",
- "enum": ["lock"]
+ "enum": [
+ "lock"
+ ]
}
]
},
@@ -156,11 +162,15 @@
"oneOf": [
{
"title": "One Switch - for up and down",
- "enum": ["oneSwitch"]
+ "enum": [
+ "oneSwitch"
+ ]
},
{
"title": "Two Switches - one for up and one for down",
- "enum": ["twoSwitch"]
+ "enum": [
+ "twoSwitch"
+ ]
}
]
},
@@ -205,31 +215,45 @@
"oneOf": [
{
"title": "Motion",
- "enum": ["motion"]
+ "enum": [
+ "motion"
+ ]
},
{
"title": "Smoke/Fire",
- "enum": ["smoke"]
+ "enum": [
+ "smoke"
+ ]
},
{
"title": "Water/Leak",
- "enum": ["water"]
+ "enum": [
+ "water"
+ ]
},
{
"title": "Carbon Monoxide",
- "enum": ["co"]
+ "enum": [
+ "co"
+ ]
},
{
"title": "Carbon Dioxide",
- "enum": ["co2"]
+ "enum": [
+ "co2"
+ ]
},
{
"title": "Occupancy",
- "enum": ["occupancy"]
+ "enum": [
+ "occupancy"
+ ]
},
{
"title": "Contact",
- "enum": ["contact"]
+ "enum": [
+ "contact"
+ ]
}
]
}
@@ -237,14 +261,22 @@
}
}
},
- "required": ["countryCode", "username", "password"]
+ "required": [
+ "countryCode",
+ "username",
+ "password"
+ ]
},
"layout": [
{
"type": "fieldset",
"title": "Required Settings",
"description": "These are the basic settings that are required for this plugin to work.",
- "items": ["countryCode", "username", "password"]
+ "items": [
+ "countryCode",
+ "username",
+ "password"
+ ]
},
{
"type": "fieldset",
@@ -312,4 +344,4 @@
]
}
]
-}
+}
\ No newline at end of file
diff --git a/index.js b/index.js
index 01e13ba7..bff9ae59 100644
--- a/index.js
+++ b/index.js
@@ -1,6 +1,5 @@
-/* jshint esversion: 9, -W014, -W030, node: true */
-"use strict";
+'use strict'
module.exports = function (homebridge) {
- const eWeLink = require("./lib/eWeLink.js")(homebridge);
- homebridge.registerPlatform("homebridge-ewelink", "eWeLink", eWeLink, true);
-};
+ const eWeLink = require('./lib/eWeLink.js')(homebridge)
+ homebridge.registerPlatform('homebridge-ewelink', 'eWeLink', eWeLink, true)
+}
diff --git a/lib/constants.js b/lib/constants.js
index 803a3423..1ec671bc 100644
--- a/lib/constants.js
+++ b/lib/constants.js
@@ -1,110 +1,61 @@
-/* jshint esversion: 9, -W014, -W030, node: true */
-"use strict";
+'use strict'
module.exports = {
- // appId: "Uw83EKZFxdif7XFXEsrpduz5YyjP7nTl",
- appId: "oeVkj2lYFGnJu5XUtWisfW4utiN4u9Mq",
- // appSecret: "mXLOjea0woSMvK9gw7Fjsy7YlFO4iSu6",
- appSecret: "6Nz4n0xA8s8qdxQf2GqurZj2Fs55FUvM",
- devicesHideable: ["switch", "light"],
+ appId: 'oeVkj2lYFGnJu5XUtWisfW4utiN4u9Mq',
+ appSecret: '6Nz4n0xA8s8qdxQf2GqurZj2Fs55FUvM',
+ devicesHideable: ['switch', 'light'],
devicesNonLAN: [22, 28, 59, 102],
devicesSingleSwitch: [1, 5, 6, 14, 15, 22, 24, 27, 32, 36, 44, 59],
- devicesSingleSwitchParams: ["switch"],
- devicesSingleSwitchOutlet: ["Sonoff Pow", "S26"],
+ devicesSingleSwitchParams: ['switch'],
+ devicesSingleSwitchOutlet: ['Sonoff Pow', 'S26'],
devicesMultiSwitch: [2, 3, 4, 7, 8, 9, 29, 30, 31, 34, 41],
- devicesMultiSwitchParams: ["switches"],
- devicesSingleSwitchLight: ["T1 1C", "L1", "B1", "B1_R2", "TX1C", "D1", "D1R1", "KING-M4", "Slampher", "GTTA59"],
- devicesSingleSwitchLightParams: [
- "switch",
- "state",
- "bright",
- "colorR",
- "brightness",
- "channel0",
- "channel2",
- "xyz_mode",
- ],
- devicesMultiSwitchLight: ["T1 2C", "T1 3C", "TX2C", "TX3C"],
- devicesMultiSwitchLightParams: ["switches"],
+ devicesMultiSwitchParams: ['switches'],
+ devicesSingleSwitchLight: ['T1 1C', 'L1', 'B1', 'B1_R2', 'TX1C', 'D1', 'D1R1', 'KING-M4', 'Slampher', 'GTTA59'],
+ devicesSingleSwitchLightParams: ['switch', 'state', 'bright', 'colorR', 'brightness', 'channel0', 'channel2', 'xyz_mode'],
+ devicesMultiSwitchLight: ['T1 2C', 'T1 3C', 'TX2C', 'TX3C'],
+ devicesMultiSwitchLightParams: ['switches'],
devicesBrightable: [36, 44],
devicesColourable: [22, 59],
devicesCurtain: [11],
- devicesCurtainParams: ["switch", "setclose"],
+ devicesCurtainParams: ['switch', 'setclose'],
devicesSensor: [102],
- devicesSensorParams: ["switch", "battery"],
+ devicesSensorParams: ['switch', 'battery'],
devicesThermostat: [15],
- devicesThermostatParams: ["currentTemperature", "currentHumidity", "switch", "masterSwitch"],
+ devicesThermostatParams: ['currentTemperature', 'currentHumidity', 'switch', 'masterSwitch'],
devicesFan: [34],
- devicesFanParams: ["switches", "light", "fan", "speed"],
+ devicesFanParams: ['switches', 'light', 'fan', 'speed'],
devicesOutlet: [32],
- devicesOutletParams: ["switch", "power", "voltage", "current"],
+ devicesOutletParams: ['switch', 'power', 'voltage', 'current'],
devicesCamera: [87],
devicesUSB: [77],
- devicesUSBParams: ["switches"],
+ devicesUSBParams: ['switches'],
devicesSCM: [78],
- devicesSCMParams: ["switches"],
+ devicesSCMParams: ['switches'],
devicesRFBridge: [28],
- devicesRFBridgeParams: ["cmd"],
+ devicesRFBridgeParams: ['cmd'],
devicesZBBridge: [66],
- devicesZBBridgeParams: ["key", "temperature", "humidity", "motion", "lock", "trigTime", "battery"],
+ devicesZBBridgeParams: ['key', 'temperature', 'humidity', 'motion', 'lock', 'trigTime', 'battery'],
devicesZB: [1000, 1770, 2026, 3026],
- devicesValveParams: ["switches"],
- devicesGarageParams: ["switch", "switches"],
- devicesLockParams: ["switch"],
- allowedGroups: ["blind", "garage", "lock"],
- paramsToKeep: [
- "battery",
- "bright",
- "brightness",
- "channel",
- "cmd",
- "colorB",
- "colorG",
- "colorR",
- "current",
- "currentHumidity",
- "currentTemperature",
- "fan",
- "humidity",
- "key",
- "light",
- "lock",
- "mainSwitch",
- "mode",
- "motion",
- "online",
- "power",
- "rfChl",
- "rfList",
- "rfTrig",
- "sensorType",
- "setclose",
- "speed",
- "state",
- "switch",
- "switches",
- "temperature",
- "trigTime",
- "type",
- "voltage",
- "zyx_mode",
- ],
- defaultMultiSwitchOff: [
- {
- switch: "off",
- outlet: 0,
- },
- {
- switch: "off",
- outlet: 1,
- },
- {
- switch: "off",
- outlet: 2,
- },
- {
- switch: "off",
- outlet: 3,
- },
+ devicesValveParams: ['switches'],
+ devicesGarageParams: ['switch', 'switches'],
+ devicesLockParams: ['switch'],
+ allowedGroups: ['blind', 'garage', 'lock'],
+ paramsToKeep: ['battery', 'bright', 'brightness', 'channel', 'cmd', 'colorB', 'colorG', 'colorR', 'current', 'currentHumidity', 'currentTemperature', 'fan', 'humidity', 'key', 'light', 'lock', 'mainSwitch', 'mode', 'motion', 'online', 'power', 'rfChl', 'rfList', 'rfTrig', 'sensorType', 'setclose', 'speed', 'state', 'switch', 'switches', 'temperature', 'trigTime', 'type', 'voltage', 'zyx_mode'],
+ defaultMultiSwitchOff: [{
+ switch: 'off',
+ outlet: 0
+ },
+ {
+ switch: 'off',
+ outlet: 1
+ },
+ {
+ switch: 'off',
+ outlet: 2
+ },
+ {
+ switch: 'off',
+ outlet: 3
+ }
],
chansFromUiid: {
1: 1, // "SOCKET" \\ 20, MINI, BASIC, S26
@@ -200,6 +151,6 @@ module.exports = {
3026: 1, // "ZIGBEE_DOOR_AND_WINDOW_SENSOR" \\
3256: 3, // "ZIGBEE_SWITCH_3" \\
4026: 1, // "ZIGBEE_WATER_SENSOR" \\
- 4256: 4, // "ZIGBEE_SWITCH_4" \\
- },
-};
+ 4256: 4 // "ZIGBEE_SWITCH_4" \\
+ }
+}
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index f5ca8134..7ea7569b 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -1,492 +1,453 @@
-/* jshint esversion: 9, -W014, -W030, node: true */
-"use strict";
-let Accessory, Characteristic, EveService, EveHistoryService, Service;
-const cns = require("./constants"),
- corrInterval = require("correcting-interval"),
- deviceCurtain = require("./device/curtain"),
- deviceBlind = require("./device/blind"),
- deviceGarage = require("./device/garage"),
- deviceLock = require("./device/lock"),
- deviceValve = require("./device/valve"),
- deviceSensor = require("./device/sensor"),
- deviceFan = require("./device/fan"),
- deviceThermostat = require("./device/thermostat"),
- deviceOutlet = require("./device/outlet"),
- deviceUSB = require("./device/usb"),
- deviceSCM = require("./device/scm"),
- deviceLight = require("./device/light"),
- deviceSwitch = require("./device/switch"),
- deviceRFSub = require("./device/rf-sub"),
- deviceZBDev = require("./device/zb-dev"),
- eWeLinkHTTP = require("./eWeLinkHTTP"),
- eWeLinkWS = require("./eWeLinkWS"),
- eWeLinkLAN = require("./eWeLinkLAN"),
- fakegato = require("fakegato-history"),
- hbLib = require("homebridge-lib"),
- promInterval = require("interval-promise"),
- utils = require("./utils");
+'use strict'
+let Accessory, Characteristic, EveService, EveHistoryService, Service
+const cns = require('./constants')
+const corrInterval = require('correcting-interval')
+const DeviceCurtain = require('./device/curtain')
+const DeviceBlind = require('./device/blind')
+const DeviceGarage = require('./device/garage')
+const DeviceLock = require('./device/lock')
+const DeviceValve = require('./device/valve')
+const DeviceSensor = require('./device/sensor')
+const DeviceFan = require('./device/fan')
+const DeviceThermostat = require('./device/thermostat')
+const DeviceOutlet = require('./device/outlet')
+const DeviceUSB = require('./device/usb')
+const DeviceSCM = require('./device/scm')
+const DeviceLight = require('./device/light')
+const DeviceSwitch = require('./device/switch')
+const DeviceRFSub = require('./device/rf-sub')
+const DeviceZBDev = require('./device/zb-dev')
+const EWeLinkHTTP = require('./eWeLinkHTTP')
+const EWeLinkWS = require('./eWeLinkWS')
+const EWeLinkLAN = require('./eWeLinkLAN')
+const fakegato = require('fakegato-history')
+const hbLib = require('homebridge-lib')
+const promInterval = require('interval-promise')
+const utils = require('./utils')
class eWeLink {
- constructor(log, config, api) {
- if (!log || !api || !config) return;
+ constructor (log, config, api) {
+ if (!log || !api || !config) return
if (!config.username || !config.password || !config.countryCode) {
- log.error("*********** Cannot load homebridge-ewelink ***********");
- log.error("eWeLink credentials missing from the Homebridge config.");
- log.error("*******************************************************");
- return;
+ log.error('*********** Cannot load homebridge-ewelink ***********')
+ log.error('eWeLink credentials missing from the Homebridge config.')
+ log.error('*******************************************************')
+ return
}
- this.log = log;
- this.config = config;
- this.api = api;
- this.debug = this.config.debug || false;
- this.devicesInHB = new Map();
- this.devicesInEW = new Map();
- this.cusG = new Map();
- this.cusS = new Map();
- this.hiddenMasters = [];
- this.eveLogPath = this.api.user.storagePath() + "/homebridge-ewelink/";
- this.wsRefreshFlag = true;
+ this.log = log
+ this.config = config
+ this.api = api
+ this.debug = this.config.debug || false
+ this.devicesInHB = new Map()
+ this.devicesInEW = new Map()
+ this.cusG = new Map()
+ this.cusS = new Map()
+ this.hiddenMasters = []
+ this.eveLogPath = this.api.user.storagePath() + '/homebridge-ewelink/'
+ this.wsRefreshFlag = true
this.api
- .on("didFinishLaunching", () => this.eWeLinkSync())
- .on("shutdown", () => {
- if (this.lanClient) this.lanClient.closeConnection();
- if (this.wsClient) this.wsClient.closeConnection();
- this.wsRefreshFlag = false;
- });
+ .on('didFinishLaunching', () => this.eWeLinkSync())
+ .on('shutdown', () => {
+ if (this.lanClient) this.lanClient.closeConnection()
+ if (this.wsClient) this.wsClient.closeConnection()
+ this.wsRefreshFlag = false
+ })
}
- async eWeLinkSync() {
+
+ async eWeLinkSync () {
try {
- this.log("Plugin has finished initialising. Synching with eWeLink.");
- this.httpClient = new eWeLinkHTTP(this.config, this.log);
- await this.httpClient.getHost();
- this.authData = await this.httpClient.login();
- let deviceList = await this.httpClient.getDevices();
- deviceList.forEach(device => this.devicesInEW.set(device.deviceid, device));
- this.wsClient = new eWeLinkWS(this.config, this.log, this.authData);
- this.lanClient = new eWeLinkLAN(this.config, this.log, deviceList);
- await this.wsClient.getHost();
- this.wsClient.login();
- this.lanDevices = await this.lanClient.getHosts();
+ this.log('Plugin has finished initialising. Synching with eWeLink.')
+ this.httpClient = new EWeLinkHTTP(this.config, this.log)
+ await this.httpClient.getHost()
+ this.authData = await this.httpClient.login()
+ const deviceList = await this.httpClient.getDevices()
+ deviceList.forEach(device => this.devicesInEW.set(device.deviceid, device))
+ this.wsClient = new EWeLinkWS(this.config, this.log, this.authData)
+ this.lanClient = new EWeLinkLAN(this.config, this.log, deviceList)
+ await this.wsClient.getHost()
+ this.wsClient.login()
+ this.lanDevices = await this.lanClient.getHosts()
await this.lanClient.startMonitor();
(() => {
- //*** Make a map of custom groups from Homebridge config ***\\
+ //* ** Make a map of custom groups from Homebridge config ***\\
if (Object.keys(this.config.groups || []).length > 0) {
this.config.groups
- .filter(g => g.hasOwnProperty("type") && cns.allowedGroups.includes(g.type))
- .filter(g => g.hasOwnProperty("deviceId") && this.devicesInEW.has(g.deviceId))
- .forEach(g => this.cusG.set(g.deviceId + "SWX", g));
+ .filter(g => Object.prototype.hasOwnProperty.call(g, 'type') && cns.allowedGroups.includes(g.type))
+ .filter(g => Object.prototype.hasOwnProperty.call(g, 'deviceId') && this.devicesInEW.has(g.deviceId))
+ .forEach(g => this.cusG.set(g.deviceId + 'SWX', g))
}
- //*** Make a map of RF Bridge custom sensors from Homebridge config ***\\
+ //* ** Make a map of RF Bridge custom sensors from Homebridge config ***\\
if (Object.keys(this.config.bridgeSensors || []).length > 0) {
this.config.bridgeSensors
- .filter(s => s.hasOwnProperty("deviceId") && this.devicesInEW.has(s.deviceId))
- .forEach(s => this.cusS.set(s.fullDeviceId, s));
+ .filter(s => Object.prototype.hasOwnProperty.call(s, 'deviceId') && this.devicesInEW.has(s.deviceId))
+ .forEach(s => this.cusS.set(s.fullDeviceId, s))
}
- //*** Logging always helps to see if everything is okay so far ***\\
- this.log("[%s] eWeLink devices loaded from the Homebridge cache.", this.devicesInHB.size);
- this.log("[%s] primary devices loaded from your eWeLink account.", this.devicesInEW.size);
- //*** Remove Homebridge accessories that don't appear in eWeLink ***\\
+ //* ** Logging always helps to see if everything is okay so far ***\\
+ this.log('[%s] eWeLink devices loaded from the Homebridge cache.', this.devicesInHB.size)
+ this.log('[%s] primary devices loaded from your eWeLink account.', this.devicesInEW.size)
+ //* ** Remove Homebridge accessories that don't appear in eWeLink ***\\
this.devicesInHB.forEach(a => {
if (!this.devicesInEW.has(a.context.eweDeviceId)) {
- this.removeAccessory(a);
+ this.removeAccessory(a)
}
- });
- //*** Synchronise devices between eWeLink and Homebridge and set up ws/lan listeners ***\\
- this.devicesInEW.forEach(d => this.initialiseDevice(d));
- this.wsClient.receiveUpdate(d => this.receiveDeviceUpdate(d));
- this.lanClient.receiveUpdate(d => this.receiveDeviceUpdate(d));
+ })
+ //* ** Synchronise devices between eWeLink and Homebridge and set up ws/lan listeners ***\\
+ this.devicesInEW.forEach(d => this.initialiseDevice(d))
+ this.wsClient.receiveUpdate(d => this.receiveDeviceUpdate(d))
+ this.lanClient.receiveUpdate(d => this.receiveDeviceUpdate(d))
this.wsRefresh = promInterval(
async () => {
if (this.wsRefreshFlag) {
try {
if (this.wsClient) {
- await this.wsClient.getHost();
- await this.wsClient.closeConnection();
- await utils.sleep(250);
- await this.wsClient.login();
+ await this.wsClient.getHost()
+ await this.wsClient.closeConnection()
+ await utils.sleep(250)
+ await this.wsClient.login()
}
} catch (err) {
- this.log.warn(err);
+ this.log.warn(err)
}
}
},
- 1800000,
- {
- stopOnError: false,
+ 1800000, {
+ stopOnError: false
}
- );
- this.log("eWeLink sync complete. Don't forget to âī¸ this plugin on GitHub!");
+ )
+ this.log("eWeLink sync complete. Don't forget to âī¸ this plugin on GitHub!")
if (this.config.debugReqRes || false) {
- this.log.warn("Note: 'Request & Response Logging' is not advised for long-term use.");
+ this.log.warn("Note: 'Request & Response Logging' is not advised for long-term use.")
}
- })();
+ })()
} catch (err) {
- this.log.error("************** Cannot load homebridge-ewelink **************");
- this.log.error(err);
- this.log.error("************************************************************");
- if (this.lanClient) this.lanClient.closeConnection();
- if (this.wsClient) this.wsClient.closeConnection();
- this.wsRefreshFlag = false;
+ this.log.error('************** Cannot load homebridge-ewelink **************')
+ this.log.error(err)
+ this.log.error('************************************************************')
+ if (this.lanClient) this.lanClient.closeConnection()
+ if (this.wsClient) this.wsClient.closeConnection()
+ this.wsRefreshFlag = false
}
}
- initialiseDevice(device) {
- let accessory;
- //*** CURTAINS ***\\
+ initialiseDevice (device) {
+ let accessory
+ //* ** CURTAINS ***\\
if (cns.devicesCurtain.includes(device.extra.uiid)) {
- accessory = this.devicesInHB.has(device.deviceid + "SWX")
- ? this.devicesInHB.get(device.deviceid + "SWX")
- : this.addAccessory(device, device.deviceid + "SWX", "curtain", false, {
- cacheCurrentPosition: 0,
- });
- //*** @UPGRADE from v2 -> v3 23.09.2020 ***\\
- if (accessory.context.hasOwnProperty("prevPos")) {
- accessory.context.cacheCurrentPosition = accessory.context.prevPos;
- delete accessory.context.prevPos;
- //*** @ENDUPGRADE ***\\
+ accessory = this.devicesInHB.has(device.deviceid + 'SWX')
+ ? this.devicesInHB.get(device.deviceid + 'SWX')
+ : this.addAccessory(device, device.deviceid + 'SWX', 'curtain', false, {
+ cacheCurrentPosition: 0
+ })
+ //* ** @UPGRADE from v2 -> v3 23.09.2020 ***\\
+ if (Object.prototype.hasOwnProperty.call(accessory.context, 'prevPos')) {
+ accessory.context.cacheCurrentPosition = accessory.context.prevPos
+ delete accessory.context.prevPos
+ //* ** @ENDUPGRADE ***\\
}
- if (!accessory.context.hasOwnProperty("cacheCurrentPosition")) {
- accessory.context.cacheCurrentPosition = 0;
- //*** @ENDUPGRADE ***\\
+ if (!Object.prototype.hasOwnProperty.call(accessory.context, 'cacheCurrentPosition')) {
+ accessory.context.cacheCurrentPosition = 0
+ //* ** @ENDUPGRADE ***\\
}
- }
- //*** WINDOW BLINDS ***\\
- else if (this.cusG.has(device.deviceid + "SWX") && this.cusG.get(device.deviceid + "SWX").type === "blind") {
- accessory = this.devicesInHB.has(device.deviceid + "SWX")
- ? this.devicesInHB.get(device.deviceid + "SWX")
- : this.addAccessory(device, device.deviceid + "SWX", "blind", false, {
- cacheCurrentPosition: 0,
- cachePositionState: 2,
- cacheTargetPosition: 0,
- });
- //*** @UPGRADE from v2 -> v3 23.09.2020 ***\\
- if (!accessory.context.hasOwnProperty("cacheCurrentPosition")) {
- accessory.context.cacheCurrentPosition = 0;
- accessory.context.cachePositionState = 2;
- accessory.context.cacheTargetPosition = 0;
+ } else if (this.cusG.has(device.deviceid + 'SWX') && this.cusG.get(device.deviceid + 'SWX').type === 'blind') {
+ accessory = this.devicesInHB.has(device.deviceid + 'SWX')
+ ? this.devicesInHB.get(device.deviceid + 'SWX')
+ : this.addAccessory(device, device.deviceid + 'SWX', 'blind', false, {
+ cacheCurrentPosition: 0,
+ cachePositionState: 2,
+ cacheTargetPosition: 0
+ })
+ //* ** @UPGRADE from v2 -> v3 23.09.2020 ***\\
+ if (!Object.prototype.hasOwnProperty.call(accessory.context, 'cacheCurrentPosition')) {
+ accessory.context.cacheCurrentPosition = 0
+ accessory.context.cachePositionState = 2
+ accessory.context.cacheTargetPosition = 0
}
- //*** @ENDUPGRADE ***\\
- }
- //*** GARAGE DOORS ***\\
- else if (this.cusG.has(device.deviceid + "SWX") && this.cusG.get(device.deviceid + "SWX").type === "garage") {
- accessory = this.devicesInHB.has(device.deviceid + "SWX")
- ? this.devicesInHB.get(device.deviceid + "SWX")
- : this.addAccessory(device, device.deviceid + "SWX", "garage", false, {
- cacheCurrentDoorState: 1,
- cacheTargetDoorState: 1,
- });
- //*** @UPGRADE from v2 -> v3 23.09.2020 ***\\
- if (!accessory.context.hasOwnProperty("cacheCurrentDoorState")) {
- accessory.context.cacheCurrentDoorState = 1;
- accessory.context.cacheTargetDoorState = 1;
+ //* ** @ENDUPGRADE ***\\
+ } else if (this.cusG.has(device.deviceid + 'SWX') && this.cusG.get(device.deviceid + 'SWX').type === 'garage') {
+ accessory = this.devicesInHB.has(device.deviceid + 'SWX')
+ ? this.devicesInHB.get(device.deviceid + 'SWX')
+ : this.addAccessory(device, device.deviceid + 'SWX', 'garage', false, {
+ cacheCurrentDoorState: 1,
+ cacheTargetDoorState: 1
+ })
+ //* ** @UPGRADE from v2 -> v3 23.09.2020 ***\\
+ if (!Object.prototype.hasOwnProperty.call(accessory.context, 'cacheCurrentDoorState')) {
+ accessory.context.cacheCurrentDoorState = 1
+ accessory.context.cacheTargetDoorState = 1
}
- //*** @ENDUPGRADE ***\\
- }
- //*** SINGLE LOCKS ***\\
- else if (this.cusG.has(device.deviceid + "SWX") && this.cusG.get(device.deviceid + "SWX").type === "lock") {
- accessory = this.devicesInHB.has(device.deviceid + "SWX")
- ? this.devicesInHB.get(device.deviceid + "SWX")
- : this.addAccessory(device, device.deviceid + "SWX", "lock");
- }
- //*** SENSORS (DW2) ***\\
- else if (cns.devicesSensor.includes(device.extra.uiid)) {
- accessory = this.devicesInHB.has(device.deviceid + "SWX")
- ? this.devicesInHB.get(device.deviceid + "SWX")
- : this.addAccessory(device, device.deviceid + "SWX", "sensor");
- }
- //*** IRRIGATION VALVES ***\\
- else if (device.extra.uiid === 2 && device.brandName === "coolkit" && device.productModel === "0285") {
- accessory = this.devicesInHB.has(device.deviceid + "SWX")
- ? this.devicesInHB.get(device.deviceid + "SWX")
- : this.addAccessory(device, device.deviceid + "SWX", "valve");
- }
- //*** FANS ***\\
- else if (cns.devicesFan.includes(device.extra.uiid)) {
- accessory = this.devicesInHB.has(device.deviceid + "SWX")
- ? this.devicesInHB.get(device.deviceid + "SWX")
- : this.addAccessory(device, device.deviceid + "SWX", "fan");
- }
- //*** THERMOSTATS ***\\
- else if (cns.devicesThermostat.includes(device.extra.uiid)) {
- accessory = this.devicesInHB.has(device.deviceid + "SWX")
- ? this.devicesInHB.get(device.deviceid + "SWX")
- : this.addAccessory(device, device.deviceid + "SWX", "thermostat", false, {
- sensorType: device.params.sensorType,
- });
- //*** @UPGRADE from v2 -> v3 23.09.2020 ***\\
- if (!accessory.context.hasOwnProperty("sensorType")) {
- accessory.context.sensorType = device.params.sensorType;
+ //* ** @ENDUPGRADE ***\\
+ } else if (this.cusG.has(device.deviceid + 'SWX') && this.cusG.get(device.deviceid + 'SWX').type === 'lock') {
+ accessory = this.devicesInHB.has(device.deviceid + 'SWX')
+ ? this.devicesInHB.get(device.deviceid + 'SWX')
+ : this.addAccessory(device, device.deviceid + 'SWX', 'lock')
+ } else if (cns.devicesSensor.includes(device.extra.uiid)) {
+ accessory = this.devicesInHB.has(device.deviceid + 'SWX')
+ ? this.devicesInHB.get(device.deviceid + 'SWX')
+ : this.addAccessory(device, device.deviceid + 'SWX', 'sensor')
+ } else if (device.extra.uiid === 2 && device.brandName === 'coolkit' && device.productModel === '0285') {
+ accessory = this.devicesInHB.has(device.deviceid + 'SWX')
+ ? this.devicesInHB.get(device.deviceid + 'SWX')
+ : this.addAccessory(device, device.deviceid + 'SWX', 'valve')
+ } else if (cns.devicesFan.includes(device.extra.uiid)) {
+ accessory = this.devicesInHB.has(device.deviceid + 'SWX')
+ ? this.devicesInHB.get(device.deviceid + 'SWX')
+ : this.addAccessory(device, device.deviceid + 'SWX', 'fan')
+ } else if (cns.devicesThermostat.includes(device.extra.uiid)) {
+ accessory = this.devicesInHB.has(device.deviceid + 'SWX')
+ ? this.devicesInHB.get(device.deviceid + 'SWX')
+ : this.addAccessory(device, device.deviceid + 'SWX', 'thermostat', false, {
+ sensorType: device.params.sensorType
+ })
+ //* ** @UPGRADE from v2 -> v3 23.09.2020 ***\\
+ if (!Object.prototype.hasOwnProperty.call(accessory.context, 'sensorType')) {
+ accessory.context.sensorType = device.params.sensorType
}
- //*** @ENDUPGRADE ***\\
+ //* ** @ENDUPGRADE ***\\
if (accessory.context.sensorType !== device.params.sensorType) {
- accessory.context.sensorType = device.params.sensorType;
- this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
+ accessory.context.sensorType = device.params.sensorType
+ this.devicesInHB.set(accessory.context.hbDeviceId, accessory)
}
- }
- //*** OUTLETS ***\\
- else if (
+ } else if (
cns.devicesOutlet.includes(device.extra.uiid) ||
(cns.devicesSingleSwitch.includes(device.extra.uiid) &&
cns.devicesSingleSwitchOutlet.includes(device.productModel))
) {
- accessory = this.devicesInHB.has(device.deviceid + "SWX")
- ? this.devicesInHB.get(device.deviceid + "SWX")
- : this.addAccessory(device, device.deviceid + "SWX", "outlet");
- }
- //*** USB OUTLETS ***\\
- else if (cns.devicesUSB.includes(device.extra.uiid)) {
- accessory = this.devicesInHB.has(device.deviceid + "SWX")
- ? this.devicesInHB.get(device.deviceid + "SWX")
- : this.addAccessory(device, device.deviceid + "SWX", "usb");
- }
- //*** SINGLE CHANNEL [MULTI CHANNEL HARDWARE] ***\\
- else if (cns.devicesSCM.includes(device.extra.uiid)) {
- accessory = this.devicesInHB.has(device.deviceid + "SWX")
- ? this.devicesInHB.get(device.deviceid + "SWX")
- : this.addAccessory(device, device.deviceid + "SWX", "scm");
- }
- //*** SINGLE CHANNEL LIGHTS ***\\
- else if (
+ accessory = this.devicesInHB.has(device.deviceid + 'SWX')
+ ? this.devicesInHB.get(device.deviceid + 'SWX')
+ : this.addAccessory(device, device.deviceid + 'SWX', 'outlet')
+ } else if (cns.devicesUSB.includes(device.extra.uiid)) {
+ accessory = this.devicesInHB.has(device.deviceid + 'SWX')
+ ? this.devicesInHB.get(device.deviceid + 'SWX')
+ : this.addAccessory(device, device.deviceid + 'SWX', 'usb')
+ } else if (cns.devicesSCM.includes(device.extra.uiid)) {
+ accessory = this.devicesInHB.has(device.deviceid + 'SWX')
+ ? this.devicesInHB.get(device.deviceid + 'SWX')
+ : this.addAccessory(device, device.deviceid + 'SWX', 'scm')
+ } else if (
cns.devicesSingleSwitch.includes(device.extra.uiid) &&
cns.devicesSingleSwitchLight.includes(device.productModel)
) {
- accessory = this.devicesInHB.has(device.deviceid + "SWX")
- ? this.devicesInHB.get(device.deviceid + "SWX")
- : this.addAccessory(device, device.deviceid + "SWX", "light");
- }
- //*** MULTI CHANNEL LIGHTS ***\\
- else if (
+ accessory = this.devicesInHB.has(device.deviceid + 'SWX')
+ ? this.devicesInHB.get(device.deviceid + 'SWX')
+ : this.addAccessory(device, device.deviceid + 'SWX', 'light')
+ } else if (
cns.devicesMultiSwitch.includes(device.extra.uiid) &&
cns.devicesMultiSwitchLight.includes(device.productModel)
) {
if (this.config.hideMasters) {
- if (this.devicesInHB.has(device.deviceid + "SW0")) {
- this.removeAccessory(this.devicesInHB.get(device.deviceid + "SW0"));
+ if (this.devicesInHB.has(device.deviceid + 'SW0')) {
+ this.removeAccessory(this.devicesInHB.get(device.deviceid + 'SW0'))
}
- this.hiddenMasters.push(device.deviceid);
- accessory = this.addAccessory(device, device.deviceid + "SW0", "light", true);
+ this.hiddenMasters.push(device.deviceid)
+ accessory = this.addAccessory(device, device.deviceid + 'SW0', 'light', true)
} else {
- accessory = this.devicesInHB.has(device.deviceid + "SW0")
- ? this.devicesInHB.get(device.deviceid + "SW0")
- : this.addAccessory(device, device.deviceid + "SW0", "light");
+ accessory = this.devicesInHB.has(device.deviceid + 'SW0')
+ ? this.devicesInHB.get(device.deviceid + 'SW0')
+ : this.addAccessory(device, device.deviceid + 'SW0', 'light')
}
for (let i = 1; i <= cns.chansFromUiid[device.extra.uiid]; i++) {
- if ((this.config.hideFromHB || "").includes(device.deviceid + "SW" + i)) {
- if (this.devicesInHB.has(device.deviceid + "SW" + i)) {
- this.removeAccessory(this.devicesInHB.get(device.deviceid + "SW" + i));
+ if ((this.config.hideFromHB || '').includes(device.deviceid + 'SW' + i)) {
+ if (this.devicesInHB.has(device.deviceid + 'SW' + i)) {
+ this.removeAccessory(this.devicesInHB.get(device.deviceid + 'SW' + i))
}
} else {
- let oAccessory = this.devicesInHB.has(device.deviceid + "SW" + i)
- ? this.devicesInHB.get(device.deviceid + "SW" + i)
- : this.addAccessory(device, device.deviceid + "SW" + i, "light");
+ const oAccessory = this.devicesInHB.has(device.deviceid + 'SW' + i)
+ ? this.devicesInHB.get(device.deviceid + 'SW' + i)
+ : this.addAccessory(device, device.deviceid + 'SW' + i, 'light')
oAccessory
.getService(Service.AccessoryInformation)
- .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion);
- oAccessory.context.reachableWAN = device.online;
- oAccessory.context.reachableLAN = this.lanDevices.get(device.deviceid).online || false;
- this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory);
+ .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion)
+ oAccessory.context.reachableWAN = device.online
+ oAccessory.context.reachableLAN = this.lanDevices.get(device.deviceid).online || false
+ this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory)
}
}
- }
- //*** SINGLE CHANNEL SWITCHES ***\\
- else if (cns.devicesSingleSwitch.includes(device.extra.uiid)) {
- accessory = this.devicesInHB.has(device.deviceid + "SWX")
- ? this.devicesInHB.get(device.deviceid + "SWX")
- : this.addAccessory(device, device.deviceid + "SWX", "switch");
- }
- //*** MULTI CHANNEL SWITCHES ***\\
- else if (cns.devicesMultiSwitch.includes(device.extra.uiid)) {
+ } else if (cns.devicesSingleSwitch.includes(device.extra.uiid)) {
+ accessory = this.devicesInHB.has(device.deviceid + 'SWX')
+ ? this.devicesInHB.get(device.deviceid + 'SWX')
+ : this.addAccessory(device, device.deviceid + 'SWX', 'switch')
+ } else if (cns.devicesMultiSwitch.includes(device.extra.uiid)) {
if (this.config.hideMasters) {
- if (this.devicesInHB.has(device.deviceid + "SW0")) {
- this.removeAccessory(this.devicesInHB.get(device.deviceid + "SW0"));
+ if (this.devicesInHB.has(device.deviceid + 'SW0')) {
+ this.removeAccessory(this.devicesInHB.get(device.deviceid + 'SW0'))
}
- this.hiddenMasters.push(device.deviceid);
- accessory = this.addAccessory(device, device.deviceid + "SW0", "switch", true);
+ this.hiddenMasters.push(device.deviceid)
+ accessory = this.addAccessory(device, device.deviceid + 'SW0', 'switch', true)
} else {
- accessory = this.devicesInHB.has(device.deviceid + "SW0")
- ? this.devicesInHB.get(device.deviceid + "SW0")
- : this.addAccessory(device, device.deviceid + "SW0", "switch");
+ accessory = this.devicesInHB.has(device.deviceid + 'SW0')
+ ? this.devicesInHB.get(device.deviceid + 'SW0')
+ : this.addAccessory(device, device.deviceid + 'SW0', 'switch')
}
for (let i = 1; i <= cns.chansFromUiid[device.extra.uiid]; i++) {
- if ((this.config.hideFromHB || "").includes(device.deviceid + "SW" + i)) {
- if (this.devicesInHB.has(device.deviceid + "SW" + i)) {
- this.removeAccessory(this.devicesInHB.get(device.deviceid + "SW" + i));
+ if ((this.config.hideFromHB || '').includes(device.deviceid + 'SW' + i)) {
+ if (this.devicesInHB.has(device.deviceid + 'SW' + i)) {
+ this.removeAccessory(this.devicesInHB.get(device.deviceid + 'SW' + i))
}
} else {
- let oAccessory = this.devicesInHB.has(device.deviceid + "SW" + i)
- ? this.devicesInHB.get(device.deviceid + "SW" + i)
- : this.addAccessory(device, device.deviceid + "SW" + i, "switch");
+ const oAccessory = this.devicesInHB.has(device.deviceid + 'SW' + i)
+ ? this.devicesInHB.get(device.deviceid + 'SW' + i)
+ : this.addAccessory(device, device.deviceid + 'SW' + i, 'switch')
oAccessory
.getService(Service.AccessoryInformation)
- .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion);
- oAccessory.context.reachableWAN = device.online;
- oAccessory.context.reachableLAN = this.lanDevices.get(device.deviceid).online || false;
- this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory);
+ .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion)
+ oAccessory.context.reachableWAN = device.online
+ oAccessory.context.reachableLAN = this.lanDevices.get(device.deviceid).online || false
+ this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory)
}
}
- }
- //*** RF BRIDGES ***\\
- else if (cns.devicesRFBridge.includes(device.extra.uiid)) {
- let accessory,
- rfChlCounter = 0,
- rfMap = [];
- if (device.hasOwnProperty("tags") && device.tags.hasOwnProperty("zyx_info")) {
+ } else if (cns.devicesRFBridge.includes(device.extra.uiid)) {
+ let rfChlCounter = 0
+ const rfMap = []
+ if (Object.prototype.hasOwnProperty.call(device, 'tags') && Object.prototype.hasOwnProperty.call(device.tags, 'zyx_info')) {
device.tags.zyx_info.forEach(remote =>
rfMap.push({
name: remote.name,
type: remote.remote_type,
- buttons: Object.assign({}, ...remote.buttonName),
+ buttons: Object.assign({}, ...remote.buttonName)
})
- );
+ )
}
- accessory = this.devicesInHB.has(device.deviceid + "SW0")
- ? this.devicesInHB.get(device.deviceid + "SW0")
- : this.addAccessory(device, device.deviceid + "SW0", "rf_pri", true, {
- rfMap,
- });
- this.log.error(JSON.stringify(accessory.context, null, 2));
+ const accessory = this.devicesInHB.has(device.deviceid + 'SW0')
+ ? this.devicesInHB.get(device.deviceid + 'SW0')
+ : this.addAccessory(device, device.deviceid + 'SW0', 'rf_pri', true, {
+ rfMap
+ })
+ this.log.error(JSON.stringify(accessory.context, null, 2))
rfMap.forEach(subDevice => {
- let swNumber = rfChlCounter + 1,
- subAccessory,
- subType,
- subExtraContext = {};
+ const swNumber = rfChlCounter + 1
+ let subAccessory
+ let subType
+ let subExtraContext = {}
switch (subDevice.type) {
- case "1":
- case "2":
- case "3":
- case "4":
- subType = "button";
- break;
- case "6":
- subType = this.cusS.has(device.deviceid + "SW" + swNumber)
- ? this.cusS.get(device.deviceid + "SW" + swNumber).type
- : "motion";
- break;
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ subType = 'button'
+ break
+ case '6':
+ subType = this.cusS.has(device.deviceid + 'SW' + swNumber)
+ ? this.cusS.get(device.deviceid + 'SW' + swNumber).type
+ : 'motion'
+ break
default:
- return;
+ return
}
subExtraContext = {
buttons: subDevice.buttons,
subType,
- swNumber,
- };
- if ((subAccessory = this.devicesInHB.get(device.deviceid + "SW" + swNumber))) {
+ swNumber
+ }
+ if ((subAccessory = this.devicesInHB.get(device.deviceid + 'SW' + swNumber))) {
if (subAccessory.context.subType !== subType || subAccessory.context.swNumber !== swNumber) {
- this.removeAccessory(subAccessory);
+ this.removeAccessory(subAccessory)
}
}
- subAccessory = this.devicesInHB.has(device.deviceid + "SW" + swNumber)
- ? this.devicesInHB.get(device.deviceid + "SW" + swNumber)
- : this.addAccessory(device, device.deviceid + "SW" + swNumber, "rf_sub", false, subExtraContext);
+ subAccessory = this.devicesInHB.has(device.deviceid + 'SW' + swNumber)
+ ? this.devicesInHB.get(device.deviceid + 'SW' + swNumber)
+ : this.addAccessory(device, device.deviceid + 'SW' + swNumber, 'rf_sub', false, subExtraContext)
subAccessory
.getService(Service.AccessoryInformation)
- .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion);
- subAccessory.context.reachableWAN = device.online;
- subAccessory.context.reachableLAN = false;
- this.devicesInHB.set(subAccessory.context.hbDeviceId, subAccessory);
- this.log.warn(JSON.stringify(subAccessory.context, null, 2));
- rfChlCounter += Object.keys(subDevice.buttons || {}).length;
- });
- accessory.context.channelCount = rfChlCounter;
- this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
- }
- //*** ZIGBEE BRIDGES ***\\
- else if (cns.devicesZBBridge.includes(device.extra.uiid)) {
+ .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion)
+ subAccessory.context.reachableWAN = device.online
+ subAccessory.context.reachableLAN = false
+ this.devicesInHB.set(subAccessory.context.hbDeviceId, subAccessory)
+ this.log.warn(JSON.stringify(subAccessory.context, null, 2))
+ rfChlCounter += Object.keys(subDevice.buttons || {}).length
+ })
+ accessory.context.channelCount = rfChlCounter
+ this.devicesInHB.set(accessory.context.hbDeviceId, accessory)
+ } else if (cns.devicesZBBridge.includes(device.extra.uiid)) {
// Nothing to do here but needed to avoid the below not supported error
- //*** @UPGRADE from v2 -> v3 23.09.2020 ***\\
- if ((accessory = this.devicesInHB.get(device.deviceid + "SWX"))) {
- this.removeAccessory(accessory);
+ //* ** @UPGRADE from v2 -> v3 23.09.2020 ***\\
+ if ((accessory = this.devicesInHB.get(device.deviceid + 'SWX'))) {
+ this.removeAccessory(accessory)
}
- //*** @ENDUPGRADE ***\\
- }
- //*** ZIGBEE DEVICES ***\\
- else if (cns.devicesZB.includes(device.extra.uiid)) {
- accessory = this.devicesInHB.has(device.deviceid + "SWX")
- ? this.devicesInHB.get(device.deviceid + "SWX")
- : this.addAccessory(device, device.deviceid + "SWX", "zb_dev");
- //*** @UPGRADE from v2 -> v3 23.09.2020 ***\\
- if (accessory.context.type === "zb_sub") {
- accessory.context.type = "zb_dev";
+ //* ** @ENDUPGRADE ***\\
+ } else if (cns.devicesZB.includes(device.extra.uiid)) {
+ accessory = this.devicesInHB.has(device.deviceid + 'SWX')
+ ? this.devicesInHB.get(device.deviceid + 'SWX')
+ : this.addAccessory(device, device.deviceid + 'SWX', 'zb_dev')
+ //* ** @UPGRADE from v2 -> v3 23.09.2020 ***\\
+ if (accessory.context.type === 'zb_sub') {
+ accessory.context.type = 'zb_dev'
}
- //*** @ENDUPGRADE ***\\
- }
- //*** SONOFF CAMERAS ***\\
- else if (cns.devicesCamera.includes(device.extra.uiid)) {
+ //* ** @ENDUPGRADE ***\\
+ } else if (cns.devicesCamera.includes(device.extra.uiid)) {
this.log.warn(
' â [%s] please see "https://github.com/bwp91/homebridge-ewelink/wiki/How-to-set-up-Sonoff-Camera".',
device.name
- );
- return;
- }
- //*** ALL OTHER = UNSUPPORTED ***\\
- else {
+ )
+ return
+ } else {
this.log.warn(
- " â [%s] cannot be added as it is not supported by this plugin. Please make a GitHub issue request.",
+ ' â [%s] cannot be added as it is not supported by this plugin. Please make a GitHub issue request.',
device.name
- );
- return;
+ )
+ return
}
- if (!accessory) return;
+ if (!accessory) return
if (!this.hiddenMasters.includes(device.deviceid)) {
accessory
.getService(Service.AccessoryInformation)
- .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion);
+ .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion)
}
- accessory.context.reachableWAN = device.online;
+ accessory.context.reachableWAN = device.online
accessory.context.reachableLAN = this.lanDevices.has(device.deviceid)
? this.lanDevices.get(device.deviceid).online
- : false;
- accessory.context.inUse = false;
+ : false
+ accessory.context.inUse = false
let str = accessory.context.reachableLAN
- ? "and found locally with IP [" + this.lanDevices.get(device.deviceid).ip + "]"
- : "but LAN mode unavailable as device ";
+ ? 'and found locally with IP [' + this.lanDevices.get(device.deviceid).ip + ']'
+ : 'but LAN mode unavailable as device '
if (!accessory.context.reachableLAN) {
if (cns.devicesNonLAN.includes(device.extra.uiid)) {
- str += "doesn't support it";
- } else if (device.hasOwnProperty("sharedBy") && device.sharedBy.hasOwnProperty("email")) {
- str += "is shared (" + device.sharedBy.email + ")";
+ str += "doesn't support it"
+ } else if (Object.prototype.hasOwnProperty.call(device, 'sharedBy') && Object.prototype.hasOwnProperty.call(device.sharedBy, 'email')) {
+ str += 'is shared (' + device.sharedBy.email + ')'
} else {
- str += "is unreachable";
+ str += 'is unreachable'
}
}
- this.log(" â [%s] initialised %s.", device.name, str);
- this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
+ this.log(' â [%s] initialised %s.', device.name, str)
+ this.devicesInHB.set(accessory.context.hbDeviceId, accessory)
if (!(this.config.disableHTTPRefresh || false)) {
if (!this.refreshAccessory(accessory, device.params)) {
this.log.warn(
- "[%s] could not be initialised. Please try removing accessory from the Homebridge cache along with any secondary devices (SW1, SW2, etc.) [debug:%s:%s].",
+ '[%s] could not be initialised. Please try removing accessory from the Homebridge cache along with any secondary devices (SW1, SW2, etc.) [debug:%s:%s].',
accessory.displayName,
accessory.context.type,
accessory.context.channelCount
- );
+ )
this.log.warn(
'If you are unsure how to do this, please see "https://github.com/bwp91/homebridge-ewelink/wiki/How-to-remove-an-accessory-from-the-cache'
- );
+ )
}
}
}
- addAccessory(device, hbDeviceId, type, hidden = false, extraContext = {}) {
- let switchNumber = hbDeviceId.substr(-1).toString(),
- newDeviceName = type === "rf_sub" ? device.tags.zyx_info[switchNumber - 1].name : device.name,
- channelCount =
- type === "rf_pri"
- ? Object.keys((device.tags && device.tags.zyx_info) || []).length
- : cns.chansFromUiid[device.extra.uiid];
- if (["1", "2", "3", "4"].includes(switchNumber) && type !== "rf_sub") {
- newDeviceName += " SW" + switchNumber;
+
+ addAccessory (device, hbDeviceId, type, hidden = false, extraContext = {}) {
+ const switchNumber = hbDeviceId.substr(-1).toString()
+ let newDeviceName = type === 'rf_sub' ? device.tags.zyx_info[switchNumber - 1].name : device.name
+ const channelCount =
+ type === 'rf_pri'
+ ? Object.keys((device.tags && device.tags.zyx_info) || []).length
+ : cns.chansFromUiid[device.extra.uiid]
+ if (['1', '2', '3', '4'].includes(switchNumber) && type !== 'rf_sub') {
+ newDeviceName += ' SW' + switchNumber
}
- if ((this.config.nameOverride || {}).hasOwnProperty(hbDeviceId)) {
- newDeviceName = this.config.nameOverride[hbDeviceId];
+ if (Object.prototype.hasOwnProperty.call(this.config.nameOverride || {}, hbDeviceId)) {
+ newDeviceName = this.config.nameOverride[hbDeviceId]
}
try {
- const accessory = new Accessory(newDeviceName, this.api.hap.uuid.generate(hbDeviceId).toString());
+ const accessory = new Accessory(newDeviceName, this.api.hap.uuid.generate(hbDeviceId).toString())
if (!hidden) {
accessory
.getService(Service.AccessoryInformation)
.setCharacteristic(Characteristic.SerialNumber, hbDeviceId)
.setCharacteristic(Characteristic.Manufacturer, device.brandName)
- .setCharacteristic(Characteristic.Model, device.productModel + " (" + device.extra.model + ")")
+ .setCharacteristic(Characteristic.Model, device.productModel + ' (' + device.extra.model + ')')
.setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion)
- .setCharacteristic(Characteristic.Identify, false);
+ .setCharacteristic(Characteristic.Identify, false)
}
accessory.context = {
...{
@@ -497,472 +458,487 @@ class eWeLink {
eweApiKey: device.apikey,
switchNumber,
channelCount,
- type,
+ type
},
- ...extraContext,
- };
+ ...extraContext
+ }
if (!hidden) {
- this.api.registerPlatformAccessories("homebridge-ewelink", "eWeLink", [accessory]);
- this.configureAccessory(accessory);
- this.log(" â [%s] has been added to Homebridge.", newDeviceName);
+ this.api.registerPlatformAccessories('homebridge-ewelink', 'eWeLink', [accessory])
+ this.configureAccessory(accessory)
+ this.log(' â [%s] has been added to Homebridge.', newDeviceName)
}
- return accessory;
+ return accessory
} catch (err) {
- this.log.warn(" â [%s] could not be added as %s.", newDeviceName, err);
- return false;
+ this.log.warn(' â [%s] could not be added as %s.', newDeviceName, err)
+ return false
}
}
- configureAccessory(accessory) {
- if (!this.log) return;
+
+ configureAccessory (accessory) {
+ if (!this.log) return
try {
- accessory.context.reachableWAN = true;
- accessory.context.reachableLAN = true;
+ accessory.context.reachableWAN = true
+ accessory.context.reachableLAN = true
switch (accessory.context.type) {
- case "curtain":
- accessory.control = new deviceCurtain(this);
- let cService;
+ case 'curtain': {
+ accessory.control = new DeviceCurtain(this)
+ let cService
if (!(cService = accessory.getService(Service.WindowCovering))) {
accessory
.addService(Service.WindowCovering)
.setCharacteristic(Characteristic.CurrentPosition, 0)
.setCharacteristic(Characteristic.TargetPosition, 0)
- .setCharacteristic(Characteristic.PositionState, 2);
- cService = accessory.getService(Service.WindowCovering);
+ .setCharacteristic(Characteristic.PositionState, 2)
+ cService = accessory.getService(Service.WindowCovering)
}
cService
.getCharacteristic(Characteristic.TargetPosition)
- .on("set", (value, callback) => accessory.control.internalCurtainUpdate(accessory, value, callback));
- break;
- case "blind":
- accessory.control = new deviceBlind(this);
- let wcService;
+ .on('set', (value, callback) => accessory.control.internalCurtainUpdate(accessory, value, callback))
+ break
+ }
+ case 'blind': {
+ accessory.control = new DeviceBlind(this)
+ let wcService
if (!(wcService = accessory.getService(Service.WindowCovering))) {
accessory
.addService(Service.WindowCovering)
.setCharacteristic(Characteristic.CurrentPosition, 0)
.setCharacteristic(Characteristic.TargetPosition, 0)
- .setCharacteristic(Characteristic.PositionState, 2);
- wcService = accessory.getService(Service.WindowCovering);
+ .setCharacteristic(Characteristic.PositionState, 2)
+ wcService = accessory.getService(Service.WindowCovering)
}
wcService
.getCharacteristic(Characteristic.TargetPosition)
- .on("set", (value, callback) => accessory.control.internalBlindUpdate(accessory, value, callback));
- break;
- case "garage":
- accessory.control = new deviceGarage(this);
- let gdService;
+ .on('set', (value, callback) => accessory.control.internalBlindUpdate(accessory, value, callback))
+ break
+ }
+ case 'garage': {
+ accessory.control = new DeviceGarage(this)
+ let gdService
if (!(gdService = accessory.getService(Service.GarageDoorOpener))) {
accessory
.addService(Service.GarageDoorOpener)
.setCharacteristic(Characteristic.CurrentDoorState, 1)
.setCharacteristic(Characteristic.TargetDoorState, 1)
- .setCharacteristic(Characteristic.ObstructionDetected, false);
- gdService = accessory.getService(Service.GarageDoorOpener);
+ .setCharacteristic(Characteristic.ObstructionDetected, false)
+ gdService = accessory.getService(Service.GarageDoorOpener)
}
gdService
.getCharacteristic(Characteristic.TargetDoorState)
- .on("set", (value, callback) => accessory.control.internalGarageUpdate(accessory, value, callback));
- break;
- case "lock":
- accessory.control = new deviceLock(this);
- let lmService = accessory.getService(Service.LockMechanism) || accessory.addService(Service.LockMechanism);
+ .on('set', (value, callback) => accessory.control.internalGarageUpdate(accessory, value, callback))
+ break
+ }
+ case 'lock': {
+ accessory.control = new DeviceLock(this)
+ const lmService = accessory.getService(Service.LockMechanism) || accessory.addService(Service.LockMechanism)
lmService
.getCharacteristic(Characteristic.LockTargetState)
- .on("set", (value, callback) => accessory.control.internalLockUpdate(accessory, value, callback));
- break;
- case "valve":
- accessory.control = new deviceValve(this);
- ["A", "B"].forEach(v => {
- let valveService;
- if (!(valveService = accessory.getService("Valve " + v))) {
+ .on('set', (value, callback) => accessory.control.internalLockUpdate(accessory, value, callback))
+ break
+ }
+ case 'valve': {
+ accessory.control = new DeviceValve(this);
+ ['A', 'B'].forEach(v => {
+ let valveService
+ if (!(valveService = accessory.getService('Valve ' + v))) {
accessory
- .addService(Service.Valve, "Valve " + v, "valve" + v.toLowerCase())
+ .addService(Service.Valve, 'Valve ' + v, 'valve' + v.toLowerCase())
.setCharacteristic(Characteristic.Active, 0)
.setCharacteristic(Characteristic.InUse, 0)
.setCharacteristic(Characteristic.ValveType, 1)
.setCharacteristic(Characteristic.SetDuration, this.config.valveTimeLength || 120)
- .addCharacteristic(Characteristic.RemainingDuration);
- valveService = accessory.getService("Valve " + v);
+ .addCharacteristic(Characteristic.RemainingDuration)
+ valveService = accessory.getService('Valve ' + v)
}
valveService
.getCharacteristic(Characteristic.Active)
- .on("set", (value, callback) =>
- accessory.control.internalValveUpdate(accessory, "Valve " + v, value, callback)
- );
- valveService.getCharacteristic(Characteristic.SetDuration).on("set", (value, callback) => {
+ .on('set', (value, callback) =>
+ accessory.control.internalValveUpdate(accessory, 'Valve ' + v, value, callback)
+ )
+ valveService.getCharacteristic(Characteristic.SetDuration).on('set', (value, callback) => {
if (valveService.getCharacteristic(Characteristic.InUse).value) {
- valveService.updateCharacteristic(Characteristic.RemainingDuration, value);
- clearTimeout(valveService.timer);
+ valveService.updateCharacteristic(Characteristic.RemainingDuration, value)
+ clearTimeout(valveService.timer)
valveService.timer = setTimeout(() => {
- valveService.setCharacteristic(Characteristic.Active, 0);
- }, value * 1000);
+ valveService.setCharacteristic(Characteristic.Active, 0)
+ }, value * 1000)
}
- callback();
- });
- });
- break;
- case "sensor":
- accessory.control = new deviceSensor(this);
- accessory.getService(Service.ContactSensor) || accessory.addService(Service.ContactSensor);
- accessory.getService(Service.BatteryService) || accessory.addService(Service.BatteryService);
- break;
- case "fan":
- accessory.control = new deviceFan(this);
- let fanService = accessory.getService(Service.Fanv2) || accessory.addService(Service.Fanv2),
- fanLightService = accessory.getService(Service.Lightbulb) || accessory.addService(Service.Lightbulb);
+ callback()
+ })
+ })
+ break
+ }
+ case 'sensor': {
+ accessory.control = new DeviceSensor(this)
+ accessory.getService(Service.ContactSensor) || accessory.addService(Service.ContactSensor)
+ accessory.getService(Service.BatteryService) || accessory.addService(Service.BatteryService)
+ break
+ }
+ case 'fan': {
+ accessory.control = new DeviceFan(this)
+ const fanService = accessory.getService(Service.Fanv2) || accessory.addService(Service.Fanv2)
+ const fanLightService = accessory.getService(Service.Lightbulb) || accessory.addService(Service.Lightbulb)
fanService
.getCharacteristic(Characteristic.Active)
- .on("set", (value, callback) => accessory.control.internalFanUpdate(accessory, "power", value, callback));
+ .on('set', (value, callback) => accessory.control.internalFanUpdate(accessory, 'power', value, callback))
fanService
.getCharacteristic(Characteristic.RotationSpeed)
- .on("set", (value, callback) => accessory.control.internalFanUpdate(accessory, "speed", value, callback))
+ .on('set', (value, callback) => accessory.control.internalFanUpdate(accessory, 'speed', value, callback))
.setProps({
- minStep: 33,
- });
+ minStep: 33
+ })
fanLightService
.getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => accessory.control.internalFanUpdate(accessory, "light", value, callback));
- break;
- case "thermostat":
- accessory.control = new deviceThermostat(this);
- let tempService =
- accessory.getService(Service.TemperatureSensor) || accessory.addService(Service.TemperatureSensor),
- humiService = false;
- if (accessory.context.sensorType !== "DS18B20") {
- humiService = accessory.getService(Service.HumiditySensor) || accessory.addService(Service.HumiditySensor);
+ .on('set', (value, callback) => accessory.control.internalFanUpdate(accessory, 'light', value, callback))
+ break
+ }
+ case 'thermostat': {
+ accessory.control = new DeviceThermostat(this)
+ const tempService =
+ accessory.getService(Service.TemperatureSensor) || accessory.addService(Service.TemperatureSensor)
+ let humiService = false
+ if (accessory.context.sensorType !== 'DS18B20') {
+ humiService = accessory.getService(Service.HumiditySensor) || accessory.addService(Service.HumiditySensor)
} else {
if (accessory.getService(Service.HumiditySensor)) {
- accessory.removeService(Service.HumiditySensor);
+ accessory.removeService(Service.HumiditySensor)
}
}
if (!this.config.hideTHSwitch) {
- let switchService = accessory.getService(Service.Switch) || accessory.addService(Service.Switch);
+ const switchService = accessory.getService(Service.Switch) || accessory.addService(Service.Switch)
switchService
.getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => accessory.control.internalThermostatUpdate(accessory, value, callback));
+ .on('set', (value, callback) => accessory.control.internalThermostatUpdate(accessory, value, callback))
}
if (!(this.config.disableEveLogging || false)) {
- accessory.log = this.log;
- accessory.eveLogger = new EveHistoryService("weather", accessory, {
- storage: "fs",
+ accessory.log = this.log
+ accessory.eveLogger = new EveHistoryService('weather', accessory, {
+ storage: 'fs',
minutes: 5,
- path: this.eveLogPath,
- });
+ path: this.eveLogPath
+ })
corrInterval.setCorrectingInterval(() => {
- let dataToAdd = {
+ const dataToAdd = {
time: Date.now(),
- temp: tempService.getCharacteristic(Characteristic.CurrentTemperature).value,
- };
+ temp: tempService.getCharacteristic(Characteristic.CurrentTemperature).value
+ }
if (humiService) {
- humiService.getCharacteristic(Characteristic.CurrentRelativeHumidity).value;
+ dataToAdd.humidity = humiService.getCharacteristic(Characteristic.CurrentRelativeHumidity).value
}
- accessory.eveLogger.addEntry(dataToAdd);
- }, 300000);
+ accessory.eveLogger.addEntry(dataToAdd)
+ }, 300000)
}
- break;
- case "outlet":
- accessory.control = new deviceOutlet(this);
- let outletService;
+ break
+ }
+ case 'outlet': {
+ accessory.control = new DeviceOutlet(this)
+ let outletService
if (!(outletService = accessory.getService(Service.Outlet))) {
- accessory.addService(Service.Outlet);
- outletService = accessory.getService(Service.Outlet);
- if (accessory.context.eweModel !== "S26" && !(this.config.disableEveLogging || false)) {
- outletService.addCharacteristic(EveService.Characteristics.Voltage);
- outletService.addCharacteristic(EveService.Characteristics.CurrentConsumption);
- outletService.addCharacteristic(EveService.Characteristics.ElectricCurrent);
- outletService.addCharacteristic(EveService.Characteristics.TotalConsumption);
- outletService.addCharacteristic(EveService.Characteristics.ResetTotal);
+ accessory.addService(Service.Outlet)
+ outletService = accessory.getService(Service.Outlet)
+ if (accessory.context.eweModel !== 'S26' && !(this.config.disableEveLogging || false)) {
+ outletService.addCharacteristic(EveService.Characteristics.Voltage)
+ outletService.addCharacteristic(EveService.Characteristics.CurrentConsumption)
+ outletService.addCharacteristic(EveService.Characteristics.ElectricCurrent)
+ outletService.addCharacteristic(EveService.Characteristics.TotalConsumption)
+ outletService.addCharacteristic(EveService.Characteristics.ResetTotal)
accessory.context = {
...accessory.context,
...{
extraPersistedData: {},
lastReset: 0,
totalEnergy: 0,
- totalEnergyTemp: 0,
- },
- };
+ totalEnergyTemp: 0
+ }
+ }
}
}
outletService
.getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => accessory.control.internalOutletUpdate(accessory, value, callback));
- if (accessory.context.eweModel !== "S26" && !(this.config.disableEveLogging || false)) {
- accessory.log = this.log;
- accessory.eveLogger = new EveHistoryService("energy", accessory, {
- storage: "fs",
+ .on('set', (value, callback) => accessory.control.internalOutletUpdate(accessory, value, callback))
+ if (accessory.context.eweModel !== 'S26' && !(this.config.disableEveLogging || false)) {
+ accessory.log = this.log
+ accessory.eveLogger = new EveHistoryService('energy', accessory, {
+ storage: 'fs',
minutes: 5,
- path: this.eveLogPath,
- });
+ path: this.eveLogPath
+ })
corrInterval.setCorrectingInterval(() => {
- let isOn = outletService.getCharacteristic(Characteristic.On).value,
- currentWatt = isOn
- ? outletService.getCharacteristic(EveService.Characteristics.CurrentConsumption).value
- : 0;
+ const isOn = outletService.getCharacteristic(Characteristic.On).value
+ const currentWatt = isOn
+ ? outletService.getCharacteristic(EveService.Characteristics.CurrentConsumption).value
+ : 0
if (accessory.eveLogger.isHistoryLoaded()) {
- accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData();
+ accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData()
if (accessory.context.extraPersistedData !== undefined) {
accessory.context.totalEnergy =
accessory.context.extraPersistedData.totalenergy +
accessory.context.totalEnergyTemp +
- (currentWatt * 10) / 3600 / 1000;
+ (currentWatt * 10) / 3600 / 1000
accessory.eveLogger.setExtraPersistedData({
totalenergy: accessory.context.totalEnergy,
- lastReset: accessory.context.extraPersistedData.lastReset,
- });
+ lastReset: accessory.context.extraPersistedData.lastReset
+ })
} else {
- accessory.context.totalEnergy = accessory.context.totalEnergyTemp + (currentWatt * 10) / 3600 / 1000;
+ accessory.context.totalEnergy = accessory.context.totalEnergyTemp + (currentWatt * 10) / 3600 / 1000
accessory.eveLogger.setExtraPersistedData({
totalenergy: accessory.context.totalEnergy,
- lastReset: 0,
- });
+ lastReset: 0
+ })
}
- accessory.context.totalEnergytemp = 0;
+ accessory.context.totalEnergytemp = 0
} else {
- accessory.context.totalEnergyTemp += (currentWatt * 10) / 3600 / 1000;
- accessory.context.totalEnergy = accessory.context.totalEnergyTemp;
+ accessory.context.totalEnergyTemp += (currentWatt * 10) / 3600 / 1000
+ accessory.context.totalEnergy = accessory.context.totalEnergyTemp
}
accessory.eveLogger.addEntry({
time: Date.now(),
- power: currentWatt,
- });
- }, 300000);
- outletService.getCharacteristic(EveService.Characteristics.TotalConsumption).on("get", callback => {
- accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData();
+ power: currentWatt
+ })
+ }, 300000)
+ outletService.getCharacteristic(EveService.Characteristics.TotalConsumption).on('get', callback => {
+ accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData()
if (accessory.context.extraPersistedData !== undefined) {
- accessory.context.totalEnergy = accessory.context.extraPersistedData.totalPower;
+ accessory.context.totalEnergy = accessory.context.extraPersistedData.totalPower
}
- callback(null, accessory.context.totalEnergy);
- });
+ callback(null, accessory.context.totalEnergy)
+ })
outletService
.getCharacteristic(EveService.Characteristics.ResetTotal)
- .on("set", (value, callback) => {
- accessory.context.totalEnergy = 0;
- accessory.context.lastReset = value;
+ .on('set', (value, callback) => {
+ accessory.context.totalEnergy = 0
+ accessory.context.lastReset = value
accessory.eveLogger.setExtraPersistedData({
totalPower: 0,
- lastReset: value,
- });
- callback();
+ lastReset: value
+ })
+ callback()
})
- .on("get", callback => {
- accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData();
+ .on('get', callback => {
+ accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData()
if (accessory.context.extraPersistedData !== undefined) {
- accessory.context.lastReset = accessory.context.extraPersistedData.lastReset;
+ accessory.context.lastReset = accessory.context.extraPersistedData.lastReset
}
- callback(null, accessory.context.lastReset);
- });
+ callback(null, accessory.context.lastReset)
+ })
}
- break;
- case "usb":
- accessory.control = new deviceUSB(this);
- let usbService = accessory.getService(Service.Outlet) || accessory.addService(Service.Outlet);
+ break
+ }
+ case 'usb': {
+ accessory.control = new DeviceUSB(this)
+ const usbService = accessory.getService(Service.Outlet) || accessory.addService(Service.Outlet)
usbService
.getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => accessory.control.internalUSBUpdate(accessory, value, callback));
- break;
- case "scm":
- accessory.control = new deviceSCM(this);
- let scmService = accessory.getService(Service.Switch) || accessory.addService(Service.Switch);
+ .on('set', (value, callback) => accessory.control.internalUSBUpdate(accessory, value, callback))
+ break
+ }
+ case 'scm': {
+ accessory.control = new DeviceSCM(this)
+ const scmService = accessory.getService(Service.Switch) || accessory.addService(Service.Switch)
scmService
.getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => accessory.control.internalSCMUpdate(accessory, value, callback));
- break;
- case "light":
- accessory.control = new deviceLight(this);
- let lightService = accessory.getService(Service.Lightbulb) || accessory.addService(Service.Lightbulb);
+ .on('set', (value, callback) => accessory.control.internalSCMUpdate(accessory, value, callback))
+ break
+ }
+ case 'light': {
+ accessory.control = new DeviceLight(this)
+ const lightService = accessory.getService(Service.Lightbulb) || accessory.addService(Service.Lightbulb)
lightService
.getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => accessory.control.internalLightbulbUpdate(accessory, value, callback));
+ .on('set', (value, callback) => accessory.control.internalLightbulbUpdate(accessory, value, callback))
if (cns.devicesBrightable.includes(accessory.context.eweUIID)) {
- lightService.getCharacteristic(Characteristic.Brightness).on("set", (value, callback) => {
+ lightService.getCharacteristic(Characteristic.Brightness).on('set', (value, callback) => {
if (value > 0) {
if (!lightService.getCharacteristic(Characteristic.On).value) {
- accessory.control.internalLightbulbUpdate(accessory, true, function () {
- return;
- });
+ accessory.control.internalLightbulbUpdate(accessory, true, function () {})
}
- accessory.control.internalBrightnessUpdate(accessory, value, callback);
+ accessory.control.internalBrightnessUpdate(accessory, value, callback)
} else {
- accessory.control.internalLightbulbUpdate(accessory, false, callback);
+ accessory.control.internalLightbulbUpdate(accessory, false, callback)
}
- });
+ })
} else if (cns.devicesColourable.includes(accessory.context.eweUIID)) {
- lightService.getCharacteristic(Characteristic.Brightness).on("set", (value, callback) => {
+ lightService.getCharacteristic(Characteristic.Brightness).on('set', (value, callback) => {
if (value > 0) {
if (!lightService.getCharacteristic(Characteristic.On).value) {
- accessory.control.internalLightbulbUpdate(accessory, true, function () {
- return;
- });
+ accessory.control.internalLightbulbUpdate(accessory, true, function () {})
}
- accessory.control.internalHSBUpdate(accessory, "bri", value, callback);
+ accessory.control.internalHSBUpdate(accessory, 'bri', value, callback)
} else {
- accessory.control.internalLightbulbUpdate(accessory, false, callback);
+ accessory.control.internalLightbulbUpdate(accessory, false, callback)
}
- });
+ })
lightService
.getCharacteristic(Characteristic.Hue)
- .on("set", (value, callback) => accessory.control.internalHSBUpdate(accessory, "hue", value, callback));
- lightService.getCharacteristic(Characteristic.Saturation).on("set", (value, callback) => callback());
+ .on('set', (value, callback) => accessory.control.internalHSBUpdate(accessory, 'hue', value, callback))
+ lightService.getCharacteristic(Characteristic.Saturation).on('set', (value, callback) => callback())
}
- break;
- case "switch":
- accessory.control = new deviceSwitch(this);
- let switchService = accessory.getService(Service.Switch) || accessory.addService(Service.Switch);
+ break
+ }
+ case 'switch': {
+ accessory.control = new DeviceSwitch(this)
+ const switchService = accessory.getService(Service.Switch) || accessory.addService(Service.Switch)
switchService
.getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => accessory.control.internalSwitchUpdate(accessory, value, callback));
- break;
- case "rf_sub":
- accessory.control = new deviceRFSub(this);
+ .on('set', (value, callback) => accessory.control.internalSwitchUpdate(accessory, value, callback))
+ break
+ }
+ case 'rf_sub': {
+ accessory.control = new DeviceRFSub(this)
switch (accessory.context.subType) {
- case "water":
- accessory.getService(Service.LeakSensor) || accessory.addService(Service.LeakSensor);
- break;
- case "fire":
- case "smoke":
- accessory.getService(Service.SmokeSensor) || accessory.addService(Service.SmokeSensor);
- break;
- case "co":
- accessory.getService(Service.CarbonMonoxideSensor) || accessory.addService(Service.CarbonMonoxideSensor);
- break;
- case "co2":
- accessory.getService(Service.CarbonDioxideSensor) || accessory.addService(Service.CarbonDioxideSensor);
- break;
- case "contact":
- accessory.getService(Service.ContactSensor) || accessory.addService(Service.ContactSensor);
- break;
- case "occupancy":
- accessory.getService(Service.OccupancySensor) || accessory.addService(Service.OccupancySensor);
- break;
+ case 'water':
+ accessory.getService(Service.LeakSensor) || accessory.addService(Service.LeakSensor)
+ break
+ case 'fire':
+ case 'smoke':
+ accessory.getService(Service.SmokeSensor) || accessory.addService(Service.SmokeSensor)
+ break
+ case 'co':
+ accessory.getService(Service.CarbonMonoxideSensor) || accessory.addService(Service.CarbonMonoxideSensor)
+ break
+ case 'co2':
+ accessory.getService(Service.CarbonDioxideSensor) || accessory.addService(Service.CarbonDioxideSensor)
+ break
+ case 'contact':
+ accessory.getService(Service.ContactSensor) || accessory.addService(Service.ContactSensor)
+ break
+ case 'occupancy':
+ accessory.getService(Service.OccupancySensor) || accessory.addService(Service.OccupancySensor)
+ break
default:
- accessory.getService(Service.MotionSensor) || accessory.addService(Service.MotionSensor);
- break;
- case "button":
+ accessory.getService(Service.MotionSensor) || accessory.addService(Service.MotionSensor)
+ break
+ case 'button':
Object.entries(accessory.context.buttons).forEach(([chan, name]) => {
- accessory.getService(name) || accessory.addService(Service.Switch, name, "switch" + chan);
- accessory.getService(name).updateCharacteristic(Characteristic.On, false);
+ accessory.getService(name) || accessory.addService(Service.Switch, name, 'switch' + chan)
+ accessory.getService(name).updateCharacteristic(Characteristic.On, false)
accessory
.getService(name)
.getCharacteristic(Characteristic.On)
- .on("set", (value, callback) => {
- value ? accessory.control.internalRFUpdate(accessory, chan, name, callback) : callback();
- });
- });
- break;
+ .on('set', (value, callback) => {
+ value ? accessory.control.internalRFUpdate(accessory, chan, name, callback) : callback()
+ })
+ })
+ break
}
- break;
- case "zb_dev": //*** credit @tasict ***\\
- accessory.control = new deviceZBDev(this);
- accessory.getService(Service.BatteryService) || accessory.addService(Service.BatteryService);
+ break
+ }
+ case 'zb_dev': { //* ** credit @tasict ***\\
+ accessory.control = new DeviceZBDev(this)
+ accessory.getService(Service.BatteryService) || accessory.addService(Service.BatteryService)
switch (accessory.context.eweUIID) {
- case 1000:
- let zbspsService =
+ case 1000: {
+ const zbspsService =
accessory.getService(Service.StatelessProgrammableSwitch) ||
- accessory.addService(Service.StatelessProgrammableSwitch);
+ accessory.addService(Service.StatelessProgrammableSwitch)
if (this.config.hideZBLDPress) {
zbspsService.getCharacteristic(Characteristic.ProgrammableSwitchEvent).setProps({
- validValues: [0],
- });
+ validValues: [0]
+ })
}
- break;
- case 1770:
- let zbTempService =
- accessory.getService(Service.TemperatureSensor) || accessory.addService(Service.TemperatureSensor);
- let zbHumiService =
- accessory.getService(Service.HumiditySensor) || accessory.addService(Service.HumiditySensor);
- accessory.log = this.log;
- accessory.eveLogger = new EveHistoryService("weather", accessory, {
- storage: "fs",
+ break
+ }
+ case 1770: {
+ const zbTempService =
+ accessory.getService(Service.TemperatureSensor) || accessory.addService(Service.TemperatureSensor)
+ const zbHumiService =
+ accessory.getService(Service.HumiditySensor) || accessory.addService(Service.HumiditySensor)
+ accessory.log = this.log
+ accessory.eveLogger = new EveHistoryService('weather', accessory, {
+ storage: 'fs',
minutes: 5,
- path: this.eveLogPath,
- });
+ path: this.eveLogPath
+ })
corrInterval.setCorrectingInterval(() => {
- let dataToAdd = {
+ const dataToAdd = {
time: Date.now(),
temp: zbTempService.getCharacteristic(Characteristic.CurrentTemperature).value,
- humidity: zbHumiService.getCharacteristic(Characteristic.CurrentRelativeHumidity).value,
- };
- accessory.eveLogger.addEntry(dataToAdd);
- }, 300000);
- break;
+ humidity: zbHumiService.getCharacteristic(Characteristic.CurrentRelativeHumidity).value
+ }
+ accessory.eveLogger.addEntry(dataToAdd)
+ }, 300000)
+ break
+ }
case 2026:
- accessory.getService(Service.MotionSensor) || accessory.addService(Service.MotionSensor);
- break;
+ accessory.getService(Service.MotionSensor) || accessory.addService(Service.MotionSensor)
+ break
case 3026:
- accessory.getService(Service.ContactSensor) || accessory.addService(Service.ContactSensor);
- break;
+ accessory.getService(Service.ContactSensor) || accessory.addService(Service.ContactSensor)
+ break
}
- break;
+ break
+ }
}
- this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
+ this.devicesInHB.set(accessory.context.hbDeviceId, accessory)
} catch (err) {
- this.log.warn("[%s] could not be refreshed as %s.", accessory.displayName, err);
+ this.log.warn('[%s] could not be refreshed as %s.', accessory.displayName, err)
}
}
- refreshAccessory(accessory, newParams) {
+
+ refreshAccessory (accessory, newParams) {
switch (accessory.context.type) {
- case "valve":
+ case 'valve':
if (Object.keys(newParams).some(v => cns.devicesValveParams.includes(v)) && Array.isArray(newParams.switches)) {
- accessory.control.externalValveUpdate(accessory, newParams);
+ accessory.control.externalValveUpdate(accessory, newParams)
}
- return true;
- case "curtain":
+ return true
+ case 'curtain':
if (Object.keys(newParams).some(v => cns.devicesCurtainParams.includes(v))) {
- accessory.control.externalCurtainUpdate(accessory, newParams);
+ accessory.control.externalCurtainUpdate(accessory, newParams)
}
- return true;
- case "blind":
- return true;
- case "garage":
+ return true
+ case 'blind':
+ return true
+ case 'garage':
if (
Object.keys(newParams).some(v => cns.devicesGarageParams.includes(v)) &&
Array.isArray(newParams.switches)
) {
- accessory.control.externalGarageUpdate(accessory, newParams);
+ accessory.control.externalGarageUpdate(accessory, newParams)
}
- return true;
- case "lock":
+ return true
+ case 'lock':
if (Object.keys(newParams).some(v => cns.devicesLockParams.includes(v))) {
- accessory.control.externalLockUpdate(accessory, newParams);
+ accessory.control.externalLockUpdate(accessory, newParams)
}
- return true;
- case "sensor":
+ return true
+ case 'sensor':
if (Object.keys(newParams).some(v => cns.devicesSensorParams.includes(v))) {
- accessory.control.externalSensorUpdate(accessory, newParams);
+ accessory.control.externalSensorUpdate(accessory, newParams)
}
- return true;
- case "fan":
+ return true
+ case 'fan':
if (Object.keys(newParams).some(v => cns.devicesFanParams.includes(v))) {
- accessory.control.externalFanUpdate(accessory, newParams);
+ accessory.control.externalFanUpdate(accessory, newParams)
}
- return true;
- case "thermostat":
+ return true
+ case 'thermostat':
if (Object.keys(newParams).some(v => cns.devicesThermostatParams.includes(v))) {
- accessory.control.externalThermostatUpdate(accessory, newParams);
+ accessory.control.externalThermostatUpdate(accessory, newParams)
}
- return true;
- case "outlet":
+ return true
+ case 'outlet':
if (Object.keys(newParams).some(v => cns.devicesOutletParams.includes(v))) {
- accessory.control.externalOutletUpdate(accessory, newParams);
+ accessory.control.externalOutletUpdate(accessory, newParams)
}
- return true;
- case "usb":
+ return true
+ case 'usb':
if (Object.keys(newParams).some(v => cns.devicesUSBParams.includes(v)) && Array.isArray(newParams.switches)) {
- accessory.control.externalUSBUpdate(accessory, newParams);
+ accessory.control.externalUSBUpdate(accessory, newParams)
}
- return true;
- case "scm":
+ return true
+ case 'scm':
if (Object.keys(newParams).some(v => cns.devicesSCMParams.includes(v)) && Array.isArray(newParams.switches)) {
- accessory.control.externalSCMUpdate(accessory, newParams);
+ accessory.control.externalSCMUpdate(accessory, newParams)
}
- return true;
- case "light":
+ return true
+ case 'light':
if (
cns.devicesSingleSwitch.includes(accessory.context.eweUIID) &&
cns.devicesSingleSwitchLight.includes(accessory.context.eweModel)
) {
if (Object.keys(newParams).some(v => cns.devicesSingleSwitchLightParams.includes(v))) {
- accessory.control.externalSingleLightUpdate(accessory, newParams);
+ accessory.control.externalSingleLightUpdate(accessory, newParams)
}
} else if (
cns.devicesMultiSwitch.includes(accessory.context.eweUIID) &&
@@ -972,168 +948,170 @@ class eWeLink {
Object.keys(newParams).some(v => cns.devicesMultiSwitchLightParams.includes(v)) &&
Array.isArray(newParams.switches)
) {
- accessory.control.externalMultiLightUpdate(accessory, newParams);
+ accessory.control.externalMultiLightUpdate(accessory, newParams)
}
}
- return true;
- case "switch":
+ return true
+ case 'switch':
if (cns.devicesSingleSwitch.includes(accessory.context.eweUIID)) {
if (Object.keys(newParams).some(v => cns.devicesSingleSwitchParams.includes(v))) {
- accessory.control.externalSingleSwitchUpdate(accessory, newParams);
+ accessory.control.externalSingleSwitchUpdate(accessory, newParams)
}
} else if (cns.devicesMultiSwitch.includes(accessory.context.eweUIID)) {
if (
Object.keys(newParams).some(v => cns.devicesMultiSwitchParams.includes(v)) &&
Array.isArray(newParams.switches)
) {
- accessory.control.externalMultiSwitchUpdate(accessory, newParams);
+ accessory.control.externalMultiSwitchUpdate(accessory, newParams)
}
}
- return true;
- case "rf_pri":
+ return true
+ case 'rf_pri':
if (Object.keys(newParams).some(v => cns.devicesRFBridgeParams.includes(v))) {
- accessory.control.externalRFUpdate(accessory, newParams);
+ accessory.control.externalRFUpdate(accessory, newParams)
}
- return true;
- case "rf_sub":
- return true;
- case "zb_dev":
+ return true
+ case 'rf_sub':
+ return true
+ case 'zb_dev':
if (Object.keys(newParams).some(v => cns.devicesZBBridgeParams.includes(v))) {
- accessory.control.externalZBUpdate(accessory, newParams);
+ accessory.control.externalZBUpdate(accessory, newParams)
}
- return true;
+ return true
default:
- return false;
+ return false
}
}
- removeAccessory(accessory) {
+
+ removeAccessory (accessory) {
try {
- this.api.unregisterPlatformAccessories("homebridge-ewelink", "eWeLink", [accessory]);
- this.devicesInHB.delete(accessory.context.hbDeviceId);
- this.log(" â [%s] was removed from Homebridge.", accessory.displayName);
+ this.api.unregisterPlatformAccessories('homebridge-ewelink', 'eWeLink', [accessory])
+ this.devicesInHB.delete(accessory.context.hbDeviceId)
+ this.log(' â [%s] was removed from Homebridge.', accessory.displayName)
} catch (err) {
- this.log.warn(" â [%s] wasn't removed as %s.", accessory.displayName, err);
+ this.log.warn(" â [%s] wasn't removed as %s.", accessory.displayName, err)
}
}
- sendDeviceUpdate(accessory, params) {
- return new Promise(async (resolve, reject) => {
- let payload = {
- apikey: accessory.context.eweApiKey,
- deviceid: accessory.context.eweDeviceId,
- params,
- };
- try {
- await utils.sleep(Math.random() * 100 + 200);
- await this.lanClient.sendUpdate(payload);
- resolve();
- } catch (err) {
- if (accessory.context.reachableWAN) {
- if (this.debug) {
- this.log.warn("[%s] Reverting to web socket as %s.", accessory.displayName, err);
- }
- try {
- await this.wsClient.sendUpdate(payload);
- resolve();
- } catch (err) {
- reject(err);
- }
- } else {
- reject("it is unreachable. I's status will be corrected once it is reachable");
+
+ async sendDeviceUpdate (accessory, params) {
+ const payload = {
+ apikey: accessory.context.eweApiKey,
+ deviceid: accessory.context.eweDeviceId,
+ params
+ }
+ try {
+ await utils.sleep(Math.random() * 100 + 200)
+ await this.lanClient.sendUpdate(payload)
+ return
+ } catch (err) {
+ if (accessory.context.reachableWAN) {
+ if (this.debug) {
+ this.log.warn('[%s] Reverting to web socket as %s.', accessory.displayName, err)
}
+ try {
+ await this.wsClient.sendUpdate(payload)
+ return
+ } catch (err) {
+ throw new Error(err)
+ }
+ } else {
+ throw new Error("it is unreachable. I's status will be corrected once it is reachable")
}
- });
+ }
}
- async receiveDeviceUpdate(device) {
- let accessory,
- deviceId = device.deviceid,
- reachableChange = false;
- if ((accessory = this.devicesInHB.get(deviceId + "SWX") || this.devicesInHB.get(deviceId + "SW0"))) {
- let isX = accessory.context.hbDeviceId.substr(-1) === "X";
- if (device.params.updateSource === "WS") {
- if (device.params.online != accessory.context.reachableWAN) {
- accessory.context.reachableWAN = device.params.online;
- this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
- if (accessory.context.reachableWAN) this.wsClient.requestUpdate(accessory).catch(() => {});
- reachableChange = true;
+
+ async receiveDeviceUpdate (device) {
+ let accessory
+ const deviceId = device.deviceid
+ let reachableChange = false
+ if ((accessory = this.devicesInHB.get(deviceId + 'SWX') || this.devicesInHB.get(deviceId + 'SW0'))) {
+ const isX = accessory.context.hbDeviceId.substr(-1) === 'X'
+ if (device.params.updateSource === 'WS') {
+ if (device.params.online !== accessory.context.reachableWAN) {
+ accessory.context.reachableWAN = device.params.online
+ this.devicesInHB.set(accessory.context.hbDeviceId, accessory)
+ if (accessory.context.reachableWAN) this.wsClient.requestUpdate(accessory).catch(() => {})
+ reachableChange = true
this.log.warn(
- "[%s] has been reported [%s] via [WS].",
+ '[%s] has been reported [%s] via [WS].',
accessory.displayName,
- accessory.context.reachableWAN ? "online" : "offline"
- );
+ accessory.context.reachableWAN ? 'online' : 'offline'
+ )
}
}
- if (device.params.updateSource === "LAN" && !accessory.context.reachableLAN) {
- accessory.context.reachableLAN = true;
- this.devicesInHB.set(accessory.context.hbDeviceId, accessory);
- this.wsClient.requestUpdate(accessory).catch(() => {});
- reachableChange = true;
- this.log.warn("[%s] has been reported [online] via [LAN].", accessory.displayName);
+ if (device.params.updateSource === 'LAN' && !accessory.context.reachableLAN) {
+ accessory.context.reachableLAN = true
+ this.devicesInHB.set(accessory.context.hbDeviceId, accessory)
+ this.wsClient.requestUpdate(accessory).catch(() => {})
+ reachableChange = true
+ this.log.warn('[%s] has been reported [online] via [LAN].', accessory.displayName)
}
if (reachableChange && !isX) {
for (let i = 1; i <= accessory.context.channelCount; i++) {
- if (this.devicesInHB.has(deviceId + "SW" + i)) {
- let oAccessory = this.devicesInHB.get(deviceId + "SW" + i);
- oAccessory.context.reachableWAN = device.params.online;
- if (device.params.updateSource === "LAN") {
- oAccessory.context.reachableLAN = true;
+ if (this.devicesInHB.has(deviceId + 'SW' + i)) {
+ const oAccessory = this.devicesInHB.get(deviceId + 'SW' + i)
+ oAccessory.context.reachableWAN = device.params.online
+ if (device.params.updateSource === 'LAN') {
+ oAccessory.context.reachableLAN = true
}
- this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory);
+ this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory)
}
}
}
if (this.debug) {
this.log(
- "[%s] externally updated from above %s message and will be refreshed.",
+ '[%s] externally updated from above %s message and will be refreshed.',
accessory.displayName,
device.params.updateSource
- );
+ )
}
if (!this.refreshAccessory(accessory, device.params)) {
this.log.warn(
- "[%s] cannot be refreshed. Please try removing accessory from the Homebridge cache along with any secondary devices (SW1, SW2, etc.). [debug:%s:%s]",
+ '[%s] cannot be refreshed. Please try removing accessory from the Homebridge cache along with any secondary devices (SW1, SW2, etc.). [debug:%s:%s]',
accessory.displayName,
accessory.context.type,
accessory.context.channelCount
- );
+ )
this.log.warn(
'If you are unsure how to do this, please see "https://github.com/bwp91/homebridge-ewelink/wiki/How-to-remove-an-accessory-from-the-cache'
- );
+ )
}
} else {
- if (!(this.config.hideDevFromHB || "").includes(deviceId)) {
+ if (!(this.config.hideDevFromHB || '').includes(deviceId)) {
this.log.warn(
- "[%s] update received via %s does not exist in Homebridge so device will be added.",
+ '[%s] update received via %s does not exist in Homebridge so device will be added.',
deviceId,
device.params.updateSource
- );
+ )
try {
- let device = await this.httpClient.getDevice(deviceId);
- this.initialiseDevice(device);
- this.lanClient.addDeviceToMap(device);
+ const device = await this.httpClient.getDevice(deviceId)
+ this.initialiseDevice(device)
+ this.lanClient.addDeviceToMap(device)
} catch (err) {
- this.log.error("[%s] error getting info [%s]", deviceId, err);
- this.log.error("[%s] Please try restarting Homebridge so this device is added.", deviceId);
+ this.log.error('[%s] error getting info [%s]', deviceId, err)
+ this.log.error('[%s] Please try restarting Homebridge so this device is added.', deviceId)
}
}
}
}
- async requestDeviceRefresh(accessory, err) {
- this.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+
+ async requestDeviceRefresh (accessory, err) {
+ this.log.warn('[%s] could not be updated as %s.', accessory.displayName, err)
if (accessory.context.reachableWAN) {
try {
- await this.wsClient.requestUpdate(accessory);
- this.log.warn("[%s] requesting previous state to revert Homebridge state.", accessory.displayName);
+ await this.wsClient.requestUpdate(accessory)
+ this.log.warn('[%s] requesting previous state to revert Homebridge state.', accessory.displayName)
} catch (err) {}
} else {
- this.log.warn("[%s] Homebridge state will be synced once the device comes back online.", accessory.displayName);
+ this.log.warn('[%s] Homebridge state will be synced once the device comes back online.', accessory.displayName)
}
}
}
module.exports = function (homebridge) {
- Accessory = homebridge.platformAccessory;
- Characteristic = homebridge.hap.Characteristic;
- EveService = new hbLib.EveHomeKitTypes(homebridge);
- EveHistoryService = fakegato(homebridge);
- Service = homebridge.hap.Service;
- return eWeLink;
-};
+ Accessory = homebridge.platformAccessory
+ Characteristic = homebridge.hap.Characteristic
+ EveService = new hbLib.EveHomeKitTypes(homebridge)
+ EveHistoryService = fakegato(homebridge)
+ Service = homebridge.hap.Service
+ return eWeLink
+}
diff --git a/lib/eWeLinkHTTP.js b/lib/eWeLinkHTTP.js
index 03e24b06..61572545 100644
--- a/lib/eWeLinkHTTP.js
+++ b/lib/eWeLinkHTTP.js
@@ -1,243 +1,267 @@
-/* jshint esversion: 9, -W014, -W030, node: true */
-"use strict";
-const axios = require("axios"),
- constants = require("./constants"),
- crypto = require("crypto"),
- utils = require("./utils");
+'use strict'
+const axios = require('axios')
+const constants = require('./constants')
+const crypto = require('crypto')
+const utils = require('./utils')
module.exports = class eWeLinkHTTP {
- constructor(config, log) {
- this.log = log;
- this.debug = config.debug || false;
- this.debugReqRes = config.debugReqRes || false;
- this.username = config.username.toString();
- this.password = config.password.toString();
- this.hideDevFromHB = (config.hideDevFromHB || "").toString();
- this.cCode = "+" + config.countryCode.toString().replace("+", "").replace(" ", "");
+ constructor (config, log) {
+ this.log = log
+ this.debug = config.debug || false
+ this.debugReqRes = config.debugReqRes || false
+ this.username = config.username.toString()
+ this.password = config.password.toString()
+ this.hideDevFromHB = (config.hideDevFromHB || '').toString()
+ this.cCode =
+ '+' + config.countryCode.toString().replace('+', '').replace(' ', '')
}
- getHost() {
- return new Promise(async (resolve, reject) => {
- let params = {
- appid: constants.appId,
- country_code: this.cCode,
- nonce: Math.random().toString(36).substr(2, 8),
- ts: Math.floor(new Date().getTime() / 1000),
- version: 8,
- },
- dataToSign = [];
- try {
- Object.keys(params).forEach(k => {
- dataToSign.push({
- key: k,
- value: params.k,
- });
- });
- dataToSign.sort((a, b) => (a.key < b.key ? -1 : 1));
- dataToSign = dataToSign.map(k => k.key + "=" + k.value).join("&");
- dataToSign = crypto.createHmac("sha256", constants.appSecret).update(dataToSign).digest("base64");
- if (this.debugReqRes) {
- this.log.warn(
- "Sending HTTP getHost request. This text is yellow for clarity.\n%s",
- JSON.stringify(params, null, 2)
- );
- } else if (this.debug) {
- this.log("Sending HTTP getHost request.");
- }
- let res = await axios.get("https://api.coolkit.cc:8080/api/user/region", {
+
+ async getHost () {
+ const params = {
+ appid: constants.appId,
+ country_code: this.cCode,
+ nonce: Math.random().toString(36).substr(2, 8),
+ ts: Math.floor(new Date().getTime() / 1000),
+ version: 8
+ }
+ let dataToSign = []
+ try {
+ Object.keys(params).forEach((k) => {
+ dataToSign.push({
+ key: k,
+ value: params.k
+ })
+ })
+ dataToSign.sort((a, b) => (a.key < b.key ? -1 : 1))
+ dataToSign = dataToSign.map((k) => k.key + '=' + k.value).join('&')
+ dataToSign = crypto
+ .createHmac('sha256', constants.appSecret)
+ .update(dataToSign)
+ .digest('base64')
+ if (this.debugReqRes) {
+ this.log.warn(
+ 'Sending HTTP getHost request. This text is yellow for clarity.\n%s',
+ JSON.stringify(params, null, 2)
+ )
+ } else if (this.debug) {
+ this.log('Sending HTTP getHost request.')
+ }
+ const res = await axios.get(
+ 'https://api.coolkit.cc:8080/api/user/region', {
headers: {
- Authorization: "Sign " + dataToSign,
- "Content-Type": "application/json",
+ Authorization: 'Sign ' + dataToSign,
+ 'Content-Type': 'application/json'
},
- params,
- });
- let body = res.data;
- if (!body.region) {
- throw "Server did not respond with a region.\n" + JSON.stringify(body, null, 2);
+ params
}
- switch (body.region) {
- case "eu":
- case "us":
- case "as":
- this.httpHost = body.region + "-apia.coolkit.cc";
- break;
- case "cn":
- this.httpHost = "cn-apia.coolkit.cn";
- break;
+ )
+ const body = res.data
+ if (!body.region) {
+ throw new Error(
+ 'Server did not respond with a region.\n' +
+ JSON.stringify(body, null, 2)
+ )
+ }
+ switch (body.region) {
+ case 'eu':
+ case 'us':
+ case 'as':
+ this.httpHost = body.region + '-apia.coolkit.cc'
+ break
+ case 'cn':
+ this.httpHost = 'cn-apia.coolkit.cn'
+ break
+ default:
+ throw new Error('No valid region received - [' + body.region + '].')
+ }
+ if (this.debug) {
+ this.log('HTTP API host received [%s].', this.httpHost)
+ }
+ return this.httpHost
+ } catch (err) {
+ if (
+ Object.prototype.hasOwnProperty.call(err, 'code') && ['ENOTFOUND', 'ETIMEDOUT', 'EAI_AGAIN'].includes(err.code)
+ ) {
+ this.log.warn('Unable to reach eWeLink. Retrying in 30 seconds.')
+ await utils.sleep(30000)
+ return this.getHost()
+ } else {
+ throw new Error(err.message || err)
+ }
+ }
+ }
+
+ async login () {
+ const data = {
+ countryCode: this.cCode,
+ password: this.password
+ }
+ try {
+ this.username.includes('@')
+ ? (data.email = this.username)
+ : (data.phoneNumber = this.username)
+ if (this.debugReqRes) {
+ const msg = JSON.stringify(data, null, 2)
+ .replace(this.password, '**hidden**')
+ .replace(this.username, '**hidden**')
+ this.log.warn(
+ 'Sending HTTP login request. This text is yellow for clarity.\n%s',
+ msg
+ )
+ } else if (this.debug) {
+ this.log('Sending HTTP login request.')
+ }
+ const dataToSign = crypto
+ .createHmac('sha256', constants.appSecret)
+ .update(JSON.stringify(data))
+ .digest('base64')
+ const res = await axios.post(
+ 'https://' + this.httpHost + '/v2/user/login',
+ data, {
+ headers: {
+ Authorization: 'Sign ' + dataToSign,
+ 'Content-Type': 'application/json',
+ Host: this.httpHost,
+ 'X-CK-Appid': constants.appId,
+ 'X-CK-Nonce': Math.random().toString(36).substr(2, 8)
+ }
+ }
+ )
+ const body = res.data
+ if (
+ Object.prototype.hasOwnProperty.call(body, 'error') &&
+ body.error === 10004 &&
+ Object.prototype.hasOwnProperty.call(body, 'data') &&
+ Object.prototype.hasOwnProperty.call(body.data, 'region')
+ ) {
+ const givenRegion = body.data.region
+ switch (givenRegion) {
+ case 'eu':
+ case 'us':
+ case 'as':
+ this.httpHost = givenRegion + '-apia.coolkit.cc'
+ break
+ case 'cn':
+ this.httpHost = 'cn-apia.coolkit.cn'
+ break
default:
- throw "No valid region received - [" + body.region + "].";
+ throw new Error('No valid region received - [' + givenRegion + '].')
}
if (this.debug) {
- this.log("HTTP API host received [%s].", this.httpHost);
+ this.log('New HTTP API host received [%s].', this.httpHost)
+ }
+ return this.login()
+ }
+ if (body.data.at) {
+ this.aToken = body.data.at
+ this.apiKey = body.data.user.apikey
+ return {
+ aToken: this.aToken,
+ apiKey: this.apiKey,
+ httpHost: this.httpHost
}
- resolve(this.httpHost);
- } catch (err) {
- if (err.hasOwnProperty("code") && ["ENOTFOUND", "ETIMEDOUT", "EAI_AGAIN"].includes(err.code)) {
- this.log.warn("Unable to reach eWeLink. Retrying in 30 seconds.");
- await utils.sleep(30000);
- resolve(this.getHost());
+ } else {
+ if (body.error === 500) {
+ this.log.warn(
+ 'An eWeLink error [500] occured. Retrying in 30 seconds.'
+ )
+ await utils.sleep(30000)
+ return this.login()
} else {
- reject(err.message || err);
+ throw new Error('No auth token received.\n' + JSON.stringify(body, null, 2))
}
}
- });
+ } catch (err) {
+ throw new Error(err.message || err)
+ }
}
- login() {
- return new Promise(async (resolve, reject) => {
- let data = {
- countryCode: this.cCode,
- password: this.password,
- };
- try {
- this.username.includes("@") ? (data.email = this.username) : (data.phoneNumber = this.username);
- if (this.debugReqRes) {
- let msg = JSON.stringify(data, null, 2)
- .replace(this.password, "**hidden**")
- .replace(this.username, "**hidden**");
- this.log.warn("Sending HTTP login request. This text is yellow for clarity.\n%s", msg);
- } else if (this.debug) {
- this.log("Sending HTTP login request.");
- }
- let dataToSign = crypto.createHmac("sha256", constants.appSecret).update(JSON.stringify(data)).digest("base64");
- let res = await axios.post("https://" + this.httpHost + "/v2/user/login", data, {
+
+ async getDevices () {
+ try {
+ const res = await axios.get(
+ 'https://' + this.httpHost + '/v2/device/thing', {
headers: {
- Authorization: "Sign " + dataToSign,
- "Content-Type": "application/json",
+ Authorization: 'Bearer ' + this.aToken,
+ 'Content-Type': 'application/json',
Host: this.httpHost,
- "X-CK-Appid": constants.appId,
- "X-CK-Nonce": Math.random().toString(36).substr(2, 8),
- },
- });
- let body = res.data;
- if (
- body.hasOwnProperty("error") &&
- body.error === 10004 &&
- body.hasOwnProperty("data") &&
- body.data.hasOwnProperty("region")
- ) {
- let givenRegion = body.data.region;
- switch (givenRegion) {
- case "eu":
- case "us":
- case "as":
- this.httpHost = givenRegion + "-apia.coolkit.cc";
- break;
- case "cn":
- this.httpHost = "cn-apia.coolkit.cn";
- break;
- default:
- throw "No valid region received - [" + givenRegion + "].";
- }
- if (this.debug) {
- this.log("New HTTP API host received [%s].", this.httpHost);
+ 'X-CK-Appid': constants.appId,
+ 'X-CK-Nonce': Math.random().toString(36).substr(2, 8)
}
- resolve(this.login());
- return;
}
- if (body.data.at) {
- this.aToken = body.data.at;
- this.apiKey = body.data.user.apikey;
- resolve({
- aToken: this.aToken,
- apiKey: this.apiKey,
- httpHost: this.httpHost,
- });
- } else {
- if (body.error === 500) {
- this.log.warn("An eWeLink error [500] occured. Retrying in 30 seconds.");
- await utils.sleep(30000);
- resolve(this.login());
- } else {
- throw "No auth token received.\n" + JSON.stringify(body, null, 2);
- }
- }
- } catch (err) {
- reject(err.message || err);
+ )
+ const body = res.data
+ if (
+ !Object.prototype.hasOwnProperty.call(body, 'data') ||
+ !Object.prototype.hasOwnProperty.call(body, 'error') ||
+ (Object.prototype.hasOwnProperty.call(body, 'error') && body.error !== 0)
+ ) {
+ throw new Error(JSON.stringify(body, null, 2))
+ }
+ const deviceList = []
+ if (body.data.thingList && body.data.thingList.length > 0) {
+ body.data.thingList.forEach((device) =>
+ deviceList.push(device.itemData)
+ )
+ }
+ deviceList
+ .filter(
+ (d) => Object.prototype.hasOwnProperty.call(d, 'extra') && Object.prototype.hasOwnProperty.call(d.extra, 'uiid')
+ )
+ .filter((d) => !this.hideDevFromHB.includes(d.deviceid))
+ return deviceList
+ } catch (err) {
+ if (
+ Object.prototype.hasOwnProperty.call(err, 'code') && ['ENOTFOUND', 'ETIMEDOUT'].includes(err.code)
+ ) {
+ this.log.warn('Unable to reach eWeLink. Retrying in 30 seconds.')
+ await utils.sleep(30000)
+ return this.getDevices()
+ } else {
+ throw new Error(err.message || err)
}
- });
+ }
}
- getDevices() {
- return new Promise(async (resolve, reject) => {
- try {
- let res = await axios.get("https://" + this.httpHost + "/v2/device/thing", {
+
+ async getDevice (deviceId) {
+ try {
+ const res = await axios.post(
+ 'https://' + this.httpHost + '/v2/device/thing', {
+ thingList: [{
+ itemType: 1,
+ id: deviceId
+ }]
+ }, {
headers: {
- Authorization: "Bearer " + this.aToken,
- "Content-Type": "application/json",
+ Authorization: 'Bearer ' + this.aToken,
+ 'Content-Type': 'application/json',
Host: this.httpHost,
- "X-CK-Appid": constants.appId,
- "X-CK-Nonce": Math.random().toString(36).substr(2, 8),
- },
- });
- let body = res.data;
- if (
- !body.hasOwnProperty("data") ||
- !body.hasOwnProperty("error") ||
- (body.hasOwnProperty("error") && body.error !== 0)
- ) {
- throw JSON.stringify(body, null, 2);
- }
- let deviceList = [];
- if (body.data.thingList && body.data.thingList.length > 0) {
- body.data.thingList.forEach(device => deviceList.push(device.itemData));
- }
- deviceList
- .filter(d => d.hasOwnProperty("extra") && d.extra.hasOwnProperty("uiid"))
- .filter(d => !this.hideDevFromHB.includes(d.deviceid));
- resolve(deviceList);
- } catch (err) {
- if (err.hasOwnProperty("code") && ["ENOTFOUND", "ETIMEDOUT"].includes(err.code)) {
- this.log.warn("Unable to reach eWeLink. Retrying in 30 seconds.");
- await utils.sleep(30000);
- resolve(this.getDevices());
- } else {
- reject(err.message || err);
- }
- }
- });
- }
- getDevice(deviceId) {
- return new Promise(async (resolve, reject) => {
- try {
- let res = await axios.post(
- "https://" + this.httpHost + "/v2/device/thing",
- {
- thingList: [
- {
- itemType: 1,
- id: deviceId,
- },
- ],
- },
- {
- headers: {
- Authorization: "Bearer " + this.aToken,
- "Content-Type": "application/json",
- Host: this.httpHost,
- "X-CK-Appid": constants.appId,
- "X-CK-Nonce": Math.random().toString(36).substr(2, 8),
- },
+ 'X-CK-Appid': constants.appId,
+ 'X-CK-Nonce': Math.random().toString(36).substr(2, 8)
}
- );
- let body = res.data;
- if (
- !body.hasOwnProperty("data") ||
- !body.hasOwnProperty("error") ||
- (body.hasOwnProperty("error") && body.error !== 0)
- ) {
- throw JSON.stringify(body, null, 2);
- }
- if (body.data.thingList && body.data.thingList.length === 1) {
- resolve(body.data.thingList[0].itemData);
- } else {
- throw "device not found in eWeLink";
- }
- } catch (err) {
- if (err.hasOwnProperty("code") && ["ENOTFOUND", "ETIMEDOUT"].includes(err.code)) {
- this.log.warn("Unable to reach eWeLink. Retrying in 30 seconds.");
- await utils.sleep(30000);
- resolve(this.getDevice(deviceId));
- } else {
- reject(err.message || err);
}
+ )
+ const body = res.data
+ if (
+ !Object.prototype.hasOwnProperty.call(body, 'data') ||
+ !Object.prototype.hasOwnProperty.call(body, 'error') ||
+ (Object.prototype.hasOwnProperty.call(body, 'error') && body.error !== 0)
+ ) {
+ throw new Error(JSON.stringify(body, null, 2))
+ }
+ if (body.data.thingList && body.data.thingList.length === 1) {
+ return body.data.thingList[0].itemData
+ } else {
+ throw new Error('device not found in eWeLink')
+ }
+ } catch (err) {
+ if (
+ Object.prototype.hasOwnProperty.call(err, 'code') && ['ENOTFOUND', 'ETIMEDOUT'].includes(err.code)
+ ) {
+ this.log.warn('Unable to reach eWeLink. Retrying in 30 seconds.')
+ await utils.sleep(30000)
+ return this.getDevice(deviceId)
+ } else {
+ throw new Error(err.message || err)
}
- });
+ }
}
-};
+}
diff --git a/lib/eWeLinkLAN.js b/lib/eWeLinkLAN.js
index 70d0c13c..a14d8cda 100644
--- a/lib/eWeLinkLAN.js
+++ b/lib/eWeLinkLAN.js
@@ -1,185 +1,186 @@
-/* jshint esversion: 9, -W014, -W030, node: true */
-"use strict";
-const axios = require("axios"),
- cns = require("./constants"),
- crypto = require("crypto"),
- dns = require("node-dns-sd"),
- eventemitter = require("events");
+'use strict'
+const axios = require('axios')
+const cns = require('./constants')
+const crypto = require('crypto')
+const dns = require('node-dns-sd')
+const EventEmitter = require('events')
module.exports = class eWeLinkLAN {
- constructor(config, log, devices) {
- this.log = log;
- this.devices = devices;
- this.ipOverrides = config.ipOverride || {};
- this.deviceMap = new Map();
+ constructor (config, log, devices) {
+ this.log = log
+ this.devices = devices
+ this.ipOverrides = config.ipOverride || {}
+ this.deviceMap = new Map()
devices.forEach(device => {
this.deviceMap.set(device.deviceid, {
apiKey: device.devicekey,
- online: this.ipOverrides.hasOwnProperty(device.deviceid) ? true : false,
- ip: this.ipOverrides.hasOwnProperty(device.deviceid) ? this.ipOverrides[device.deviceid] : null,
- });
- });
- this.debug = config.debug || false;
- this.debugReqRes = config.debugReqRes || false;
- this.emitter = new eventemitter();
+ online: !!Object.prototype.hasOwnProperty.call(this.ipOverrides, device.deviceid),
+ ip: Object.prototype.hasOwnProperty.call(this.ipOverrides, device.deviceid) ? this.ipOverrides[device.deviceid] : null
+ })
+ })
+ this.debug = config.debug || false
+ this.debugReqRes = config.debugReqRes || false
+ this.emitter = new EventEmitter()
}
- getHosts() {
- return new Promise(async (resolve, reject) => {
- try {
- let res = await dns.discover({
- name: "_ewelink._tcp.local",
- });
- res.forEach(device => {
- let d,
- deviceId = device.fqdn.replace("._ewelink._tcp.local", "").replace("eWeLink_", "");
- if ((d = this.deviceMap.get(deviceId))) {
- if (!this.ipOverrides.hasOwnProperty(deviceId)) {
- this.deviceMap.set(deviceId, {
- apiKey: d.apiKey,
- online: true,
- ip: device.address,
- });
- }
+
+ async getHosts () {
+ try {
+ const res = await dns.discover({
+ name: '_ewelink._tcp.local'
+ })
+ res.forEach(device => {
+ let d
+ const deviceId = device.fqdn.replace('._ewelink._tcp.local', '').replace('eWeLink_', '')
+ if ((d = this.deviceMap.get(deviceId))) {
+ if (!Object.prototype.hasOwnProperty.call(this.ipOverrides, deviceId)) {
+ this.deviceMap.set(deviceId, {
+ apiKey: d.apiKey,
+ online: true,
+ ip: device.address
+ })
}
- });
- resolve(this.deviceMap);
- } catch (err) {
- reject(err);
- }
- });
+ }
+ })
+ return this.deviceMap
+ } catch (err) {
+ throw new Error(err)
+ }
}
- startMonitor() {
+
+ startMonitor () {
dns.ondata = packet => {
if (packet.answers) {
packet.answers
- .filter(value => value.name.includes("_ewelink._tcp.local"))
- .filter(value => value.type === "TXT")
+ .filter(value => value.name.includes('_ewelink._tcp.local'))
+ .filter(value => value.type === 'TXT')
.filter(value => this.deviceMap.has(value.rdata.id))
.forEach(value => {
- let rdata = value.rdata,
- deviceInfo = this.deviceMap.get(rdata.id),
- data =
- rdata.data1 +
- (rdata.hasOwnProperty("data2") ? rdata.data2 : "") +
- (rdata.hasOwnProperty("data3") ? rdata.data3 : "") +
- (rdata.hasOwnProperty("data4") ? rdata.data4 : ""),
- key = crypto.createHash("md5").update(Buffer.from(deviceInfo.apiKey, "utf8")).digest(),
- dText = crypto.createDecipheriv("aes-128-cbc", key, Buffer.from(rdata.iv, "base64")),
- pText = Buffer.concat([dText.update(Buffer.from(data, "base64")), dText.final()]).toString("utf8"),
- params;
- if (packet.address !== deviceInfo.ip && !this.ipOverrides.hasOwnProperty(rdata.id)) {
+ const rdata = value.rdata
+ const deviceInfo = this.deviceMap.get(rdata.id)
+ const data =
+ rdata.data1 +
+ (Object.prototype.hasOwnProperty.call(rdata, 'data2') ? rdata.data2 : '') +
+ (Object.prototype.hasOwnProperty.call(rdata, 'data3') ? rdata.data3 : '') +
+ (Object.prototype.hasOwnProperty.call(rdata, 'data4') ? rdata.data4 : '')
+ const key = crypto.createHash('md5').update(Buffer.from(deviceInfo.apiKey, 'utf8')).digest()
+ const dText = crypto.createDecipheriv('aes-128-cbc', key, Buffer.from(rdata.iv, 'base64'))
+ const pText = Buffer.concat([dText.update(Buffer.from(data, 'base64')), dText.final()]).toString('utf8')
+ let params
+ if (packet.address !== deviceInfo.ip && !Object.prototype.hasOwnProperty.call(this.ipOverrides, rdata.id)) {
this.deviceMap.set(rdata.id, {
apiKey: deviceInfo.apiKey,
online: true,
- ip: packet.address,
- });
+ ip: packet.address
+ })
if (this.debug) {
- this.log.warn("[%s] updating IP address to [%s].", rdata.id, packet.address);
+ this.log.warn('[%s] updating IP address to [%s].', rdata.id, packet.address)
}
}
try {
- params = JSON.parse(pText);
+ params = JSON.parse(pText)
} catch (e) {
- this.log.warn("[%s] An error occured reading the LAN message [%s]", rdata.id, e);
- return;
+ this.log.warn('[%s] An error occured reading the LAN message [%s]', rdata.id, e)
+ return
}
- for (let param in params) {
- if (params.hasOwnProperty(param)) {
- if (!cns.paramsToKeep.includes(param.replace(/[0-9]/g, ""))) {
- delete params[param];
+ for (const param in params) {
+ if (Object.prototype.hasOwnProperty.call(params, param)) {
+ if (!cns.paramsToKeep.includes(param.replace(/[0-9]/g, ''))) {
+ delete params[param]
}
}
}
if (Object.keys(params).length > 0) {
- params.updateSource = "LAN";
- params.online = true;
- let returnTemplate = {
+ params.updateSource = 'LAN'
+ params.online = true
+ const returnTemplate = {
deviceid: rdata.id,
- params,
- };
+ params
+ }
if (this.debugReqRes) {
- let msg = JSON.stringify(returnTemplate, null, 2).replace(rdata.id, "**hidden**");
- this.log("LAN message received.\n%s", msg);
+ const msg = JSON.stringify(returnTemplate, null, 2).replace(rdata.id, '**hidden**')
+ this.log('LAN message received.\n%s', msg)
} else if (this.debug) {
- this.log("LAN message received.");
+ this.log('LAN message received.')
}
- this.emitter.emit("update", returnTemplate);
+ this.emitter.emit('update', returnTemplate)
}
- });
+ })
}
- };
- dns.startMonitoring();
+ }
+ dns.startMonitoring()
}
- sendUpdate(json) {
- return new Promise(async (resolve, reject) => {
- try {
- if (!this.deviceMap.get(json.deviceid).online) {
- throw "device isn't reachable via LAN mode";
+
+ async sendUpdate (json) {
+ try {
+ if (!this.deviceMap.get(json.deviceid).online) {
+ throw new Error("device isn't reachable via LAN mode")
+ }
+ let apiKey
+ let suffix
+ const params = {}
+ if (Object.prototype.hasOwnProperty.call(json.params, 'switches')) {
+ params.switches = json.params.switches
+ suffix = 'switches'
+ } else if (Object.prototype.hasOwnProperty.call(json.params, 'switch')) {
+ params.switch = json.params.switch
+ suffix = 'switch'
+ } else {
+ throw new Error("device isn't reachable via LAN mode")
+ }
+ if ((apiKey = this.deviceMap.get(json.deviceid).apiKey)) {
+ const key = crypto.createHash('md5').update(Buffer.from(apiKey, 'utf8')).digest()
+ const iv = crypto.randomBytes(16)
+ const enc = crypto.createCipheriv('aes-128-cbc', key, iv)
+ const data = {
+ data: Buffer.concat([enc.update(JSON.stringify(params)), enc.final()]).toString('base64'),
+ deviceid: json.deviceid,
+ encrypt: true,
+ iv: iv.toString('base64'),
+ selfApikey: '123',
+ sequence: Date.now().toString()
}
- let apiKey,
- suffix,
- params = {};
- if (json.params.hasOwnProperty("switches")) {
- params.switches = json.params.switches;
- suffix = "switches";
- } else if (json.params.hasOwnProperty("switch")) {
- params.switch = json.params.switch;
- suffix = "switch";
- } else {
- throw "device isn't reachable via LAN mode";
+ if (this.debugReqRes) {
+ const msg = JSON.stringify(json, null, 2)
+ .replace(json.apikey, '**hidden**')
+ .replace(json.apikey, '**hidden**')
+ .replace(json.deviceid, '**hidden**')
+ this.log.warn('LAN message sent. This text is yellow for clarity.\n%s', msg)
+ } else if (this.debug) {
+ this.log('LAN message sent.')
}
- if ((apiKey = this.deviceMap.get(json.deviceid).apiKey)) {
- let key = crypto.createHash("md5").update(Buffer.from(apiKey, "utf8")).digest(),
- iv = crypto.randomBytes(16),
- enc = crypto.createCipheriv("aes-128-cbc", key, iv),
- data = {
- data: Buffer.concat([enc.update(JSON.stringify(params)), enc.final()]).toString("base64"),
- deviceid: json.deviceid,
- encrypt: true,
- iv: iv.toString("base64"),
- selfApikey: "123",
- sequence: Date.now().toString(),
- };
- if (this.debugReqRes) {
- let msg = JSON.stringify(json, null, 2)
- .replace(json.apikey, "**hidden**")
- .replace(json.apikey, "**hidden**")
- .replace(json.deviceid, "**hidden**");
- this.log.warn("LAN message sent. This text is yellow for clarity.\n%s", msg);
- } else if (this.debug) {
- this.log("LAN message sent.");
- }
- let res = await axios({
- method: "post",
- url: "http://" + this.deviceMap.get(json.deviceid).ip + ":8081/zeroconf/" + suffix,
- headers: {
- Accept: "application/json",
- "Content-Type": "application/json",
- },
- data,
- });
- if (res.data.hasOwnProperty("error") && res.data.error === 0) {
- resolve();
- } else {
- throw res.data;
- }
+ const res = await axios({
+ method: 'post',
+ url: 'http://' + this.deviceMap.get(json.deviceid).ip + ':8081/zeroconf/' + suffix,
+ headers: {
+ Accept: 'application/json',
+ 'Content-Type': 'application/json'
+ },
+ data
+ })
+ if (Object.prototype.hasOwnProperty.call(res.data, 'error') && res.data.error === 0) {
+ return
+ } else {
+ throw new Error(res.data)
}
- } catch (err) {
- reject(err);
}
- });
+ } catch (err) {
+ throw new Error(err)
+ }
}
- receiveUpdate(f) {
- this.emitter.addListener("update", f);
+
+ receiveUpdate (f) {
+ this.emitter.addListener('update', f)
}
- addDeviceToMap(device) {
+
+ addDeviceToMap (device) {
this.deviceMap.set(device.deviceid, {
apiKey: device.devicekey,
- online: this.ipOverrides.hasOwnProperty(device.deviceid) ? true : false,
- ip: this.ipOverrides.hasOwnProperty(device.deviceid) ? this.ipOverrides[device.deviceid] : null,
- });
+ online: !!Object.prototype.hasOwnProperty.call(this.ipOverrides, device.deviceid),
+ ip: Object.prototype.hasOwnProperty.call(this.ipOverrides, device.deviceid) ? this.ipOverrides[device.deviceid] : null
+ })
}
- closeConnection() {
- dns.stopMonitoring();
- this.log("LAN monitoring gracefully stopped.");
+
+ closeConnection () {
+ dns.stopMonitoring()
+ this.log('LAN monitoring gracefully stopped.')
}
-};
+}
diff --git a/lib/eWeLinkWS.js b/lib/eWeLinkWS.js
index c3201325..647eb091 100644
--- a/lib/eWeLinkWS.js
+++ b/lib/eWeLinkWS.js
@@ -1,289 +1,317 @@
-/* jshint esversion: 9, -W014, -W030, node: true */
-"use strict";
-const axios = require("axios"),
- cns = require("./constants"),
- eventemitter = require("events"),
- utils = require("./utils"),
- ws = require("ws"),
- wsp = require("websocket-as-promised");
+'use strict'
+const axios = require('axios')
+const cns = require('./constants')
+const EventEmitter = require('events')
+const utils = require('./utils')
+const WS = require('ws')
+const WSP = require('websocket-as-promised')
module.exports = class eWeLinkWS {
- constructor(config, log, res) {
- this.config = config;
- this.log = log;
- this.debug = this.config.debug || false;
- this.debugReqRes = this.config.debugReqRes || false;
- this.httpHost = res.httpHost;
- this.aToken = res.aToken;
- this.apiKey = res.apiKey;
- this.wsIsOpen = false;
- this.emitter = new eventemitter();
- this.delaySend = 0;
+ constructor (config, log, res) {
+ this.config = config
+ this.log = log
+ this.debug = this.config.debug || false
+ this.debugReqRes = this.config.debugReqRes || false
+ this.httpHost = res.httpHost
+ this.aToken = res.aToken
+ this.apiKey = res.apiKey
+ this.wsIsOpen = false
+ this.emitter = new EventEmitter()
+ this.delaySend = 0
}
- getHost() {
- return new Promise(async (resolve, reject) => {
- try {
- let res = await axios({
- method: "post",
- url: "https://" + this.httpHost.replace("-api", "-disp") + "/dispatch/app",
- headers: {
- Authorization: "Bearer " + this.aToken,
- "Content-Type": "application/json",
- },
- data: {
- appid: cns.appId,
- nonce: Math.random().toString(36).substr(2, 8),
- ts: Math.floor(new Date().getTime() / 1000),
- version: 8,
- },
- });
- let body = res.data;
- if (!body.domain) {
- throw "Server did not respond with a web socket host.";
- }
- if (this.debug) {
- this.log("Web socket host received [%s].", body.domain);
- }
- this.wsHost = body.domain;
- resolve(body.domain);
- } catch (err) {
- if (err.hasOwnProperty("code") && ["ENOTFOUND", "ETIMEDOUT"].includes(err.code)) {
- this.log.warn("Unable to reach eWeLink. Retrying in 30 seconds.");
- await utils.sleep(30000);
- resolve(this.getDevices());
- } else {
- reject(err.message || err);
+
+ async getHost () {
+ try {
+ const res = await axios({
+ method: 'post',
+ url: 'https://' +
+ this.httpHost.replace('-api', '-disp') +
+ '/dispatch/app',
+ headers: {
+ Authorization: 'Bearer ' + this.aToken,
+ 'Content-Type': 'application/json'
+ },
+ data: {
+ appid: cns.appId,
+ nonce: Math.random().toString(36).substr(2, 8),
+ ts: Math.floor(new Date().getTime() / 1000),
+ version: 8
}
+ })
+ const body = res.data
+ if (!body.domain) {
+ throw new Error('Server did not respond with a web socket host.')
}
- });
+ if (this.debug) {
+ this.log('Web socket host received [%s].', body.domain)
+ }
+ this.wsHost = body.domain
+ return body.domain
+ } catch (err) {
+ if (
+ Object.prototype.hasOwnProperty.call(err, 'code') && ['ENOTFOUND', 'ETIMEDOUT'].includes(err.code)
+ ) {
+ this.log.warn('Unable to reach eWeLink. Retrying in 30 seconds.')
+ await utils.sleep(30000)
+ return this.getDevices()
+ } else {
+ throw new Error(err.message || err)
+ }
+ }
}
- login() {
- this.wsp = new wsp("wss://" + this.wsHost + ":8080/api/ws", {
- createWebSocket: url => new ws(url),
- extractMessageData: event => event,
+
+ login () {
+ this.wsp = new WSP('wss://' + this.wsHost + ':8080/api/ws', {
+ createWebSocket: (url) => new WS(url),
+ extractMessageData: (event) => event,
attachRequestId: (data, requestId) =>
- Object.assign(
- {
- sequence: requestId,
- },
- data
+ Object.assign({
+ sequence: requestId
+ },
+ data
),
- extractRequestId: data => data && data.sequence,
- packMessage: data => JSON.stringify(data),
- unpackMessage: data => {
- return data === "pong" ? data : JSON.parse(data);
- },
- });
- this.wsp.open();
+ extractRequestId: (data) => data && data.sequence,
+ packMessage: (data) => JSON.stringify(data),
+ unpackMessage: (data) => {
+ return data === 'pong' ? data : JSON.parse(data)
+ }
+ })
+ this.wsp.open()
this.wsp.onOpen.addListener(async () => {
- this.wsIsOpen = true;
- let sequence = Math.floor(new Date()).toString(),
- payload = {
- action: "userOnline",
- apikey: this.apiKey,
- appid: cns.appId,
- at: this.aToken,
- nonce: Math.random().toString(36).substr(2, 8),
- sequence,
- ts: Math.floor(new Date() / 1000),
- userAgent: "app",
- version: 8,
- };
+ this.wsIsOpen = true
+ const sequence = Math.floor(new Date()).toString()
+ const payload = {
+ action: 'userOnline',
+ apikey: this.apiKey,
+ appid: cns.appId,
+ at: this.aToken,
+ nonce: Math.random().toString(36).substr(2, 8),
+ sequence,
+ ts: Math.floor(new Date() / 1000),
+ userAgent: 'app',
+ version: 8
+ }
if (this.debugReqRes) {
- let msg = JSON.stringify(payload, null, 2)
- .replace(this.aToken, "**hidden**")
- .replace(this.apiKey, "**hidden**");
- this.log.warn("Sending WS login request. This text is yellow for clarity.\n%s", msg);
+ const msg = JSON.stringify(payload, null, 2)
+ .replace(this.aToken, '**hidden**')
+ .replace(this.apiKey, '**hidden**')
+ this.log.warn(
+ 'Sending WS login request. This text is yellow for clarity.\n%s',
+ msg
+ )
} else if (this.debug) {
- this.log("Sending WS login request.");
+ this.log('Sending WS login request.')
}
try {
- let res = await this.wsp.sendRequest(payload, {
- requestId: sequence,
- });
- if (res.hasOwnProperty("config") && res.config.hb && res.config.hbInterval && !this.hbInterval) {
+ const res = await this.wsp.sendRequest(payload, {
+ requestId: sequence
+ })
+ if (
+ Object.prototype.hasOwnProperty.call(res, 'config') &&
+ res.config.hb &&
+ res.config.hbInterval &&
+ !this.hbInterval
+ ) {
this.hbInterval = setInterval(() => {
- this.wsp.send("ping");
- }, (res.config.hbInterval + 7) * 1000);
+ this.wsp.send('ping')
+ }, (res.config.hbInterval + 7) * 1000)
} else {
- throw "Unknown parameters received";
+ throw new Error('Unknown parameters received')
}
} catch (err) {
- this.log.error("WS login failed [%s].", err);
+ this.log.error('WS login failed [%s].', err)
}
- });
- this.wsp.onUnpackedMessage.addListener(device => {
- if (device === "pong") return;
- let onlineStatus = true;
- if (!device.hasOwnProperty("params")) device.params = {};
- if (device.hasOwnProperty("deviceid") && device.hasOwnProperty("error")) {
- device.action = "update";
- onlineStatus = device.error === 0;
+ })
+ this.wsp.onUnpackedMessage.addListener((device) => {
+ if (device === 'pong') return
+ let onlineStatus = true
+ if (!Object.prototype.hasOwnProperty.call(device, 'params')) device.params = {}
+ if (Object.prototype.hasOwnProperty.call(device, 'deviceid') && Object.prototype.hasOwnProperty.call(device, 'error')) {
+ device.action = 'update'
+ onlineStatus = device.error === 0
}
- if (device.hasOwnProperty("action")) {
+ if (Object.prototype.hasOwnProperty.call(device, 'action')) {
switch (device.action) {
- case "update":
- case "sysmsg":
- if (device.action === "sysmsg" && device.params.hasOwnProperty("online")) {
- onlineStatus = device.params.online;
+ case 'update':
+ case 'sysmsg':
+ if (
+ device.action === 'sysmsg' &&
+ Object.prototype.hasOwnProperty.call(device.params, 'online')
+ ) {
+ onlineStatus = device.params.online
}
- for (let param in device.params) {
- if (device.params.hasOwnProperty(param)) {
- if (!cns.paramsToKeep.includes(param.replace(/[0-9]/g, ""))) {
- delete device.params[param];
+ for (const param in device.params) {
+ if (Object.prototype.hasOwnProperty.call(device.params, param)) {
+ if (!cns.paramsToKeep.includes(param.replace(/[0-9]/g, ''))) {
+ delete device.params[param]
}
}
}
- device.params.online = onlineStatus;
- device.params.updateSource = "WS";
+ device.params.online = onlineStatus
+ device.params.updateSource = 'WS'
if (Object.keys(device.params).length > 0) {
- let returnTemplate = {
+ const returnTemplate = {
deviceid: device.deviceid,
- params: device.params,
- };
+ params: device.params
+ }
if (this.debugReqRes) {
- let msg = JSON.stringify(returnTemplate, null, 2).replace(device.deviceid, "**hidden**");
- this.log("WS message received.\n%s", msg);
+ const msg = JSON.stringify(returnTemplate, null, 2).replace(
+ device.deviceid,
+ '**hidden**'
+ )
+ this.log('WS message received.\n%s', msg)
} else if (this.debug) {
- this.log("WS message received.");
+ this.log('WS message received.')
}
- this.emitter.emit("update", returnTemplate);
+ this.emitter.emit('update', returnTemplate)
}
- break;
- case "reportSubDevice":
- return;
+ break
+ case 'reportSubDevice':
+ return
default:
- this.log.warn("[%s] WS message has unknown action.\n" + JSON.stringify(device, null, 2), device.deviceid);
- return;
+ this.log.warn(
+ '[%s] WS message has unknown action.\n' +
+ JSON.stringify(device, null, 2),
+ device.deviceid
+ )
}
- } else if (device.hasOwnProperty("error") && device.error === 0) {
+ } else if (Object.prototype.hasOwnProperty.call(device, 'error') && device.error === 0) {
// *** Safe to ignore these messages *** \\
} else {
if (this.debug) {
- this.log.warn("WS unknown command received.\n" + JSON.stringify(device, null, 2));
+ this.log.warn(
+ 'WS unknown command received.\n' + JSON.stringify(device, null, 2)
+ )
}
}
- });
+ })
this.wsp.onClose.addListener((e, m) => {
- this.wsIsOpen = false;
+ this.wsIsOpen = false
if (e !== 1005) {
- this.log.warn("Web socket closed [%s].", e);
+ this.log.warn('Web socket closed [%s].', e)
if (e !== 1000) {
- this.log("Web socket will try to reconnect in five seconds.");
- setTimeout(() => this.login(), 5000);
+ this.log('Web socket will try to reconnect in five seconds.')
+ setTimeout(() => this.login(), 5000)
} else {
- this.log("Please try restarting Homebridge so that this plugin can work again.");
+ this.log(
+ 'Please try restarting Homebridge so that this plugin can work again.'
+ )
}
}
if (this.hbInterval) {
- clearInterval(this.hbInterval);
- this.hbInterval = null;
+ clearInterval(this.hbInterval)
+ this.hbInterval = null
}
- this.wsp.removeAllListeners();
- });
- this.wsp.onError.addListener(e => {
- this.log.error("Web socket error - [%s].", e);
- if (e.code === "ECONNREFUSED") {
- this.log.warn("Web socket will try to reconnect in five seconds then try the command again.");
- this.wsp.removeAllListeners();
- setTimeout(() => this.login(), 5000);
- } else {
- this.log.warn("If this was unexpected then please try restarting Homebridge.");
- }
- });
- }
- sendUpdate(json) {
- return new Promise(async (resolve, reject) => {
- let sequence = Math.floor(new Date()).toString(),
- jsonToSend = {
- ...json,
- ...{
- action: "update",
- sequence,
- userAgent: "app",
- },
- };
- if (this.wsp && this.wsIsOpen) {
- try {
- let device = await this.wsp.sendRequest(jsonToSend, {
- requestId: sequence,
- });
- if (this.debugReqRes) {
- let msg = JSON.stringify(json, null, 2)
- .replace(json.apikey, "**hidden**")
- .replace(json.apiKey, "**hidden**")
- .replace(json.deviceid, "**hidden**");
- this.log.warn("WS message sent. This text is yellow for clarity.\n%s", msg);
- } else if (this.debug) {
- this.log("WS message sent.");
- }
- device.error = device.hasOwnProperty("error") ? device.error : 504; // mimic ewelink device offline
- switch (device.error) {
- case 0:
- resolve();
- break;
- default:
- throw "Unknown response";
- }
- } catch (err) {
- reject("device update failed [" + err + "]");
- }
+ this.wsp.removeAllListeners()
+ })
+ this.wsp.onError.addListener((e) => {
+ this.log.error('Web socket error - [%s].', e)
+ if (e.code === 'ECONNREFUSED') {
+ this.log.warn(
+ 'Web socket will try to reconnect in five seconds then try the command again.'
+ )
+ this.wsp.removeAllListeners()
+ setTimeout(() => this.login(), 5000)
} else {
- if (this.debug) {
- this.log.warn("Command will be resent when WS is reconnected.");
- }
- await utils.sleep(30000);
- resolve(this.sendUpdate(json));
+ this.log.warn(
+ 'If this was unexpected then please try restarting Homebridge.'
+ )
}
- });
+ })
}
- requestUpdate(accessory) {
- return new Promise(async resolve => {
- let sequence = Math.floor(new Date()).toString(),
- json = {
- action: "query",
- apikey: accessory.context.eweApiKey,
- deviceid: accessory.context.eweDeviceId,
- params: [],
- sequence,
- ts: 0,
- userAgent: "app",
- };
- if (this.wsp && this.wsIsOpen) {
- this.wsp.send(JSON.stringify(json));
+ async sendUpdate (json) {
+ const sequence = Math.floor(new Date()).toString()
+ const jsonToSend = {
+ ...json,
+ ...{
+ action: 'update',
+ sequence,
+ userAgent: 'app'
+ }
+ }
+ if (this.wsp && this.wsIsOpen) {
+ try {
+ const device = await this.wsp.sendRequest(jsonToSend, {
+ requestId: sequence
+ })
if (this.debugReqRes) {
- let msg = JSON.stringify(json, null, 2)
- .replace(json.apikey, "**hidden**")
- .replace(json.apiKey, "**hidden**")
- .replace(json.deviceid, "**hidden**");
- this.log.warn("WS message sent. This text is yellow for clarity.\n%s", msg);
+ const msg = JSON.stringify(json, null, 2)
+ .replace(json.apikey, '**hidden**')
+ .replace(json.apiKey, '**hidden**')
+ .replace(json.deviceid, '**hidden**')
+ this.log.warn(
+ 'WS message sent. This text is yellow for clarity.\n%s',
+ msg
+ )
} else if (this.debug) {
- this.log("WS message sent.");
+ this.log('WS message sent.')
}
- } else {
- if (this.debug) {
- this.log.warn("Command will be resent when WS is reconnected.");
+ device.error = Object.prototype.hasOwnProperty.call(device, 'error') ? device.error : 504
+ switch (device.error) {
+ case 0:
+ return
+ default:
+ throw new Error('Unknown response')
}
- await utils.sleep(30000);
- resolve(this.requestUpdate(accessory));
+ } catch (err) {
+ throw new Error('device update failed [' + err + ']')
}
- });
+ } else {
+ if (this.debug) {
+ this.log.warn('Command will be resent when WS is reconnected.')
+ }
+ await utils.sleep(30000)
+ return this.sendUpdate(json)
+ }
}
- receiveUpdate(f) {
- this.emitter.addListener("update", f);
+
+ async requestUpdate (accessory) {
+ const sequence = Math.floor(new Date()).toString()
+ const json = {
+ action: 'query',
+ apikey: accessory.context.eweApiKey,
+ deviceid: accessory.context.eweDeviceId,
+ params: [],
+ sequence,
+ ts: 0,
+ userAgent: 'app'
+ }
+ if (this.wsp && this.wsIsOpen) {
+ this.wsp.send(JSON.stringify(json))
+ if (this.debugReqRes) {
+ const msg = JSON.stringify(json, null, 2)
+ .replace(json.apikey, '**hidden**')
+ .replace(json.apiKey, '**hidden**')
+ .replace(json.deviceid, '**hidden**')
+ this.log.warn(
+ 'WS message sent. This text is yellow for clarity.\n%s',
+ msg
+ )
+ } else if (this.debug) {
+ this.log('WS message sent.')
+ }
+ } else {
+ if (this.debug) {
+ this.log.warn('Command will be resent when WS is reconnected.')
+ }
+ await utils.sleep(30000)
+ return this.requestUpdate(accessory)
+ }
}
- closeConnection() {
- return new Promise(async (resolve, reject) => {
- if (this.wsp && this.wsIsOpen) {
- try {
- await this.wsp.close();
- this.log("Web socket gracefully closed.");
- resolve();
- } catch (err) {
- reject(err);
- }
+
+ receiveUpdate (f) {
+ this.emitter.addListener('update', f)
+ }
+
+ async closeConnection () {
+ if (this.wsp && this.wsIsOpen) {
+ try {
+ await this.wsp.close()
+ this.log('Web socket gracefully closed.')
+ return
+ } catch (err) {
+ throw new Error(err)
}
- resolve();
- });
+ }
}
-};
+}
diff --git a/lib/utils.js b/lib/utils.js
index 5cb638ad..bf3698e8 100644
--- a/lib/utils.js
+++ b/lib/utils.js
@@ -1,7 +1,6 @@
-/* jshint esversion: 9, -W014, -W030, node: true */
-"use strict";
+'use strict'
module.exports = {
sleep: ms => {
- return new Promise(resolve => setTimeout(resolve, ms));
- },
-};
+ return new Promise(resolve => setTimeout(resolve, ms))
+ }
+}
diff --git a/package-lock.json b/package-lock.json
index a05cbda3..d667effe 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -560,12 +560,6 @@
"object-keys": "^1.0.11"
}
},
- "prettier": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.1.2.tgz",
- "integrity": "sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg==",
- "dev": true
- },
"promise-controller": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/promise-controller/-/promise-controller-1.0.0.tgz",
diff --git a/package.json b/package.json
index 81643c16..c27caff6 100644
--- a/package.json
+++ b/package.json
@@ -67,8 +67,5 @@
"node-dns-sd": "0.4.1",
"websocket-as-promised": "1.0.1",
"ws": "7.3.1"
- },
- "devDependencies": {
- "prettier": "2.1.2"
}
}
From 007a70d42653ba9fb89854c0d1340489d4fa8b8a Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 27 Sep 2020 08:32:16 +0100
Subject: [PATCH 0235/3183] standard code style
---
lib/device/blind.js | 136 ++++++++--------
lib/device/curtain.js | 63 +++----
lib/device/fan.js | 141 ++++++++--------
lib/device/garage.js | 164 +++++++++----------
lib/device/light.js | 344 ++++++++++++++++++++-------------------
lib/device/lock.js | 83 +++++-----
lib/device/outlet.js | 73 +++++----
lib/device/rf-sub.js | 157 +++++++++---------
lib/device/scm.js | 42 ++---
lib/device/sensor.js | 58 +++----
lib/device/switch.js | 139 ++++++++--------
lib/device/thermostat.js | 71 ++++----
lib/device/usb.js | 43 ++---
lib/device/valve.js | 105 ++++++------
lib/device/zb-dev.js | 91 ++++++-----
15 files changed, 862 insertions(+), 848 deletions(-)
diff --git a/lib/device/blind.js b/lib/device/blind.js
index 377fb763..13ea726e 100644
--- a/lib/device/blind.js
+++ b/lib/device/blind.js
@@ -1,97 +1,97 @@
-/* jshint esversion: 9, -W014, -W030, node: true */
-"use strict";
-let Characteristic, Service;
-const cns = require("./../constants"),
- utils = require("./../utils");
+'use strict'
+let Characteristic, Service
+const cns = require('./../constants')
+const utils = require('./../utils')
module.exports = class deviceBlind {
- constructor(platform) {
- this.platform = platform;
- Service = platform.api.hap.Service;
- Characteristic = platform.api.hap.Characteristic;
+ constructor (platform) {
+ this.platform = platform
+ Service = platform.api.hap.Service
+ Characteristic = platform.api.hap.Characteristic
}
- async internalBlindUpdate(accessory, value, callback) {
- callback();
+
+ async internalBlindUpdate (accessory, value, callback) {
+ callback()
try {
- let blindConfig,
- params = {},
- wcService = accessory.getService(Service.WindowCovering),
- prevState = accessory.context.cachePositionState,
- prevPosition = accessory.context.cacheCurrentPosition,
- newTarget = value,
- updateKey = Math.random().toString(36).substr(2, 8);
+ let blindConfig
+ const params = {}
+ const wcService = accessory.getService(Service.WindowCovering)
+ const prevState = accessory.context.cachePositionState
+ let prevPosition = accessory.context.cacheCurrentPosition
+ const newTarget = value
+ const updateKey = Math.random().toString(36).substr(2, 8)
if (!(blindConfig = this.platform.cusG.get(accessory.context.hbDeviceId))) {
- throw "group config missing";
+ throw new Error('group config missing')
}
- if (blindConfig.type !== "blind" || blindConfig.setup !== "twoSwitch") {
- throw "improper configuration";
+ if (blindConfig.type !== 'blind' || blindConfig.setup !== 'twoSwitch') {
+ throw new Error('improper configuration')
}
- if (newTarget === prevPosition) return;
- params.switches = cns.defaultMultiSwitchOff;
- accessory.context.updateKey = updateKey;
- let percentStepPerDecisecond = blindConfig.operationTime / 100;
+ if (newTarget === prevPosition) return
+ params.switches = cns.defaultMultiSwitchOff
+ accessory.context.updateKey = updateKey
+ const percentStepPerDecisecond = blindConfig.operationTime / 100
//
//
- this.platform.log("============================");
- this.platform.log("============================");
- this.platform.log("Starting main calculation...");
+ this.platform.log('============================')
+ this.platform.log('============================')
+ this.platform.log('Starting main calculation...')
//
//
if (prevState !== 2) {
- await this.platform.sendDeviceUpdate(accessory, params);
- let positionPercentChange = Math.floor(Date.now() / 100) - accessory.context.cacheLastStartTime;
- positionPercentChange = Math.floor(percentStepPerDecisecond * positionPercentChange);
+ await this.platform.sendDeviceUpdate(accessory, params)
+ let positionPercentChange = Math.floor(Date.now() / 100) - accessory.context.cacheLastStartTime
+ positionPercentChange = Math.floor(percentStepPerDecisecond * positionPercentChange)
if (prevState === 0) {
// moving down
- prevPosition -= positionPercentChange;
+ prevPosition -= positionPercentChange
} else {
- prevPosition += positionPercentChange;
+ prevPosition += positionPercentChange
}
- wcService.updateCharacteristic(Characteristic.CurrentPosition, prevPosition);
- accessory.context.cacheCurrentPosition = prevPosition;
- this.platform.log.warn("Moving from [%s%] to [%s%]", prevPosition, newTarget);
+ wcService.updateCharacteristic(Characteristic.CurrentPosition, prevPosition)
+ accessory.context.cacheCurrentPosition = prevPosition
+ this.platform.log.warn('Moving from [%s%] to [%s%]', prevPosition, newTarget)
this.platform.log.warn(
- "Blind was already moving %s when it was changed and was probably around %s%",
- prevState === 1 ? "up" : "down",
+ 'Blind was already moving %s when it was changed and was probably around %s%',
+ prevState === 1 ? 'up' : 'down',
prevPosition
- );
+ )
this.platform.log.warn(
- "Giving a difference of %s seconds - a position change of %s%",
+ 'Giving a difference of %s seconds - a position change of %s%',
(Math.floor(Date.now() / 100) - accessory.context.cacheLastStartTime) / 10,
positionPercentChange
- );
+ )
} else {
- this.platform.log("Moving from [%s%] to [%s%].", prevPosition, newTarget);
+ this.platform.log('Moving from [%s%] to [%s%].', prevPosition, newTarget)
}
- let diffPosition = newTarget - prevPosition;
- let setToMoveUp = diffPosition > 0;
- let decisecondsToMove = Math.round(Math.abs(diffPosition) * percentStepPerDecisecond);
+ const diffPosition = newTarget - prevPosition
+ const setToMoveUp = diffPosition > 0
+ const decisecondsToMove = Math.round(Math.abs(diffPosition) * percentStepPerDecisecond)
this.platform.log(
- "So we need to move %s from the previous state of %s for about %s seconds",
- setToMoveUp ? "up" : "down",
- prevState === 0 ? "moving down" : prevState === 1 ? "moving up" : "stopped",
+ 'So we need to move %s from the previous state of %s for about %s seconds',
+ setToMoveUp ? 'up' : 'down',
+ prevState === 0 ? 'moving down' : prevState === 1 ? 'moving up' : 'stopped',
decisecondsToMove / 10
- );
- params.switches[0].switch = setToMoveUp ? "on" : "off";
- params.switches[1].switch = setToMoveUp ? "off" : "on";
- await this.platform.sendDeviceUpdate(accessory, params);
+ )
+ params.switches[0].switch = setToMoveUp ? 'on' : 'off'
+ params.switches[1].switch = setToMoveUp ? 'off' : 'on'
+ await this.platform.sendDeviceUpdate(accessory, params)
wcService
.updateCharacteristic(Characteristic.TargetPosition, newTarget)
- .updateCharacteristic(Characteristic.PositionState, setToMoveUp);
- accessory.context.cacheTargetPosition = newTarget;
- accessory.context.cachePositionState = setToMoveUp ? 1 : 0;
- accessory.context.cacheLastStartTime = Math.floor(Date.now() / 100);
- if (accessory.context.updateKey !== updateKey) return;
- await utils.sleep(decisecondsToMove * 100);
- if (accessory.context.updateKey !== updateKey) return;
- params.switches[0].switch = "off";
- params.switches[1].switch = "off";
- await this.platform.sendDeviceUpdate(accessory, params);
- wcService.updateCharacteristic(Characteristic.PositionState, 2);
- wcService.updateCharacteristic(Characteristic.CurrentPosition, newTarget);
- accessory.context.cachePositionState = 2;
- accessory.context.cacheCurrentPosition = newTarget;
+ .updateCharacteristic(Characteristic.PositionState, setToMoveUp)
+ accessory.context.cacheTargetPosition = newTarget
+ accessory.context.cachePositionState = setToMoveUp ? 1 : 0
+ accessory.context.cacheLastStartTime = Math.floor(Date.now() / 100)
+ if (accessory.context.updateKey !== updateKey) return
+ await utils.sleep(decisecondsToMove * 100)
+ if (accessory.context.updateKey !== updateKey) return
+ params.switches[0].switch = 'off'
+ params.switches[1].switch = 'off'
+ await this.platform.sendDeviceUpdate(accessory, params)
+ wcService.updateCharacteristic(Characteristic.PositionState, 2)
+ wcService.updateCharacteristic(Characteristic.CurrentPosition, newTarget)
+ accessory.context.cachePositionState = 2
+ accessory.context.cacheCurrentPosition = newTarget
} catch (err) {
- this.platform.requestDeviceRefresh(accessory, err);
+ this.platform.requestDeviceRefresh(accessory, err)
}
}
-};
+}
diff --git a/lib/device/curtain.js b/lib/device/curtain.js
index d7a8cf8a..95ab6086 100644
--- a/lib/device/curtain.js
+++ b/lib/device/curtain.js
@@ -1,52 +1,53 @@
-/* jshint esversion: 9, -W014, -W030, node: true */
-"use strict";
-let Characteristic, Service;
+'use strict'
+let Characteristic, Service
module.exports = class deviceCurtain {
- constructor(platform) {
- this.platform = platform;
- Service = platform.api.hap.Service;
- Characteristic = platform.api.hap.Characteristic;
+ constructor (platform) {
+ this.platform = platform
+ Service = platform.api.hap.Service
+ Characteristic = platform.api.hap.Characteristic
}
- async internalCurtainUpdate(accessory, value, callback) {
- callback();
+
+ async internalCurtainUpdate (accessory, value, callback) {
+ callback()
try {
- let params,
- cService = accessory.getService(Service.WindowCovering),
- prevPos = accessory.context.cacheCurrentPosition,
- newPos = value;
- if (newPos === prevPos) return;
+ let params
+ const cService = accessory.getService(Service.WindowCovering)
+ const prevPos = accessory.context.cacheCurrentPosition
+ const newPos = value
+ if (newPos === prevPos) return
if (newPos === 0 || newPos === 100) {
params = {
- switch: newPos === 100 ? "on" : "off",
- };
+ switch: newPos === 100 ? 'on' : 'off'
+ }
} else {
params = {
- setclose: Math.abs(100 - newPos),
- };
+ setclose: Math.abs(100 - newPos)
+ }
}
- await this.platform.sendDeviceUpdate(accessory, params);
+ await this.platform.sendDeviceUpdate(accessory, params)
cService
.updateCharacteristic(Characteristic.TargetPosition, newPos)
- .updateCharacteristic(Characteristic.PositionState, newPos > prevPos ? 1 : 0);
- accessory.context.cacheCurrentPosition = newPos;
+ .updateCharacteristic(Characteristic.PositionState, newPos > prevPos ? 1 : 0)
+ accessory.context.cacheCurrentPosition = newPos
} catch (err) {
- this.platform.requestDeviceRefresh(accessory, err);
+ this.platform.requestDeviceRefresh(accessory, err)
}
}
- externalCurtainUpdate(accessory, params) {
+
+ externalCurtainUpdate (accessory, params) {
try {
- let cService = accessory.getService(Service.WindowCovering);
- if (params.hasOwnProperty("switch") && params.hasOwnProperty("setclose")) {
- let newPos = Math.abs(100 - parseInt(params.setclose));
+ const cService = accessory.getService(Service.WindowCovering)
+ if (Object.prototype.hasOwnProperty.call(params, 'switch') && Object.prototype.hasOwnProperty.call(params, 'setclose')) {
+ const newPos = Math.abs(100 - parseInt(params.setclose))
cService
.updateCharacteristic(Characteristic.TargetPosition, newPos)
.updateCharacteristic(Characteristic.CurrentPosition, newPos)
- .updateCharacteristic(Characteristic.PositionState, 2);
- accessory.context.cacheCurrentPosition = newPos;
- return;
+ .updateCharacteristic(Characteristic.PositionState, 2)
+ accessory.context.cacheCurrentPosition = newPos
+ return
}
} catch (err) {
- this.platform.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.platform.log.warn('[%s] could not be updated as %s.', accessory.displayName, err)
}
}
-};
+}
diff --git a/lib/device/fan.js b/lib/device/fan.js
index 2c12a5e7..09323633 100644
--- a/lib/device/fan.js
+++ b/lib/device/fan.js
@@ -1,92 +1,93 @@
-/* jshint esversion: 9, -W014, -W030, node: true */
-"use strict";
-let Characteristic, Service;
+'use strict'
+let Characteristic, Service
module.exports = class deviceFan {
- constructor(platform) {
- this.platform = platform;
- Service = platform.api.hap.Service;
- Characteristic = platform.api.hap.Characteristic;
+ constructor (platform) {
+ this.platform = platform
+ Service = platform.api.hap.Service
+ Characteristic = platform.api.hap.Characteristic
}
- async internalFanUpdate(accessory, type, value, callback) {
- callback();
+
+ async internalFanUpdate (accessory, type, value, callback) {
+ callback()
try {
- let newPower,
- newSpeed,
- newLight,
- lightService = accessory.getService(Service.Lightbulb),
- fanService = accessory.getService(Service.Fanv2);
+ let newPower
+ let newSpeed
+ let newLight
+ const lightService = accessory.getService(Service.Lightbulb)
+ const fanService = accessory.getService(Service.Fanv2)
switch (type) {
- case "power":
- newPower = value;
- newSpeed = value ? 33 : 0;
- newLight = lightService.getCharacteristic(Characteristic.On).value;
- break;
- case "speed":
- newPower = value >= 33 ? 1 : 0;
- newSpeed = value;
- newLight = lightService.getCharacteristic(Characteristic.On).value;
- break;
- case "light":
- newPower = fanService.getCharacteristic(Characteristic.Active).value;
- newSpeed = fanService.getCharacteristic(Characteristic.RotationSpeed).value;
- newLight = value;
- break;
+ case 'power':
+ newPower = value
+ newSpeed = value ? 33 : 0
+ newLight = lightService.getCharacteristic(Characteristic.On).value
+ break
+ case 'speed':
+ newPower = value >= 33 ? 1 : 0
+ newSpeed = value
+ newLight = lightService.getCharacteristic(Characteristic.On).value
+ break
+ case 'light':
+ newPower = fanService.getCharacteristic(Characteristic.Active).value
+ newSpeed = fanService.getCharacteristic(Characteristic.RotationSpeed).value
+ newLight = value
+ break
}
- let params = {
- switches: this.platform.devicesInEW.get(accessory.context.eweDeviceId).params.switches,
- };
- params.switches[0].switch = newLight ? "on" : "off";
- params.switches[1].switch = newPower === 1 && newSpeed >= 33 ? "on" : "off";
- params.switches[2].switch = newPower === 1 && newSpeed >= 66 && newSpeed < 99 ? "on" : "off";
- params.switches[3].switch = newPower === 1 && newSpeed >= 99 ? "on" : "off";
- await this.platform.sendDeviceUpdate(accessory, params);
- lightService.updateCharacteristic(Characteristic.On, newLight);
+ const params = {
+ switches: this.platform.devicesInEW.get(accessory.context.eweDeviceId).params.switches
+ }
+ params.switches[0].switch = newLight ? 'on' : 'off'
+ params.switches[1].switch = newPower === 1 && newSpeed >= 33 ? 'on' : 'off'
+ params.switches[2].switch = newPower === 1 && newSpeed >= 66 && newSpeed < 99 ? 'on' : 'off'
+ params.switches[3].switch = newPower === 1 && newSpeed >= 99 ? 'on' : 'off'
+ await this.platform.sendDeviceUpdate(accessory, params)
+ lightService.updateCharacteristic(Characteristic.On, newLight)
fanService
.updateCharacteristic(Characteristic.Active, newPower)
- .updateCharacteristic(Characteristic.RotationSpeed, newSpeed);
+ .updateCharacteristic(Characteristic.RotationSpeed, newSpeed)
} catch (err) {
- this.platform.requestDeviceRefresh(accessory, err);
+ this.platform.requestDeviceRefresh(accessory, err)
}
}
- externalFanUpdate(accessory, params) {
+
+ externalFanUpdate (accessory, params) {
try {
- let light,
- status,
- speed,
- lightService = accessory.getService(Service.Lightbulb),
- fanService = accessory.getService(Service.Fanv2);
+ let light
+ let status
+ let speed
+ const lightService = accessory.getService(Service.Lightbulb)
+ const fanService = accessory.getService(Service.Fanv2)
if (Array.isArray(params.switches)) {
- light = params.switches[0].switch === "on";
+ light = params.switches[0].switch === 'on'
switch (params.switches[1].switch + params.switches[2].switch + params.switches[3].switch) {
default:
- status = 0;
- speed = 0;
- break;
- case "onoffoff":
- status = 1;
- speed = 33;
- break;
- case "ononoff":
- status = 1;
- speed = 66;
- break;
- case "onoffon":
- status = 1;
- speed = 99;
+ status = 0
+ speed = 0
+ break
+ case 'onoffoff':
+ status = 1
+ speed = 33
+ break
+ case 'ononoff':
+ status = 1
+ speed = 66
+ break
+ case 'onoffon':
+ status = 1
+ speed = 99
}
- } else if (params.hasOwnProperty("light") && params.hasOwnProperty("fan") && params.hasOwnProperty("speed")) {
- light = params.light === "on";
- status = params.fan === "on" ? 1 : 0;
- speed = params.speed * 33 * status;
+ } else if (Object.prototype.hasOwnProperty.call(params, 'light') && Object.prototype.hasOwnProperty.call(params, 'fan') && Object.prototype.hasOwnProperty.call(params, 'speed')) {
+ light = params.light === 'on'
+ status = params.fan === 'on' ? 1 : 0
+ speed = params.speed * 33 * status
} else {
- throw "unknown parameters received";
+ throw new Error('unknown parameters received')
}
- lightService.updateCharacteristic(Characteristic.On, light);
+ lightService.updateCharacteristic(Characteristic.On, light)
fanService
.updateCharacteristic(Characteristic.Active, status)
- .updateCharacteristic(Characteristic.RotationSpeed, speed);
+ .updateCharacteristic(Characteristic.RotationSpeed, speed)
} catch (err) {
- this.platform.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.platform.log.warn('[%s] could not be updated as %s.', accessory.displayName, err)
}
}
-};
+}
diff --git a/lib/device/garage.js b/lib/device/garage.js
index e888c551..30ec61ec 100644
--- a/lib/device/garage.js
+++ b/lib/device/garage.js
@@ -1,125 +1,125 @@
-/* jshint esversion: 9, -W014, -W030, node: true */
-"use strict";
-let Characteristic, Service;
-const utils = require("./../utils");
+'use strict'
+let Characteristic, Service
+const utils = require('./../utils')
module.exports = class deviceGarage {
- constructor(platform) {
- this.platform = platform;
- Service = platform.api.hap.Service;
- Characteristic = platform.api.hap.Characteristic;
+ constructor (platform) {
+ this.platform = platform
+ Service = platform.api.hap.Service
+ Characteristic = platform.api.hap.Characteristic
}
- async internalGarageUpdate(accessory, value, callback) {
- callback();
+
+ async internalGarageUpdate (accessory, value, callback) {
+ callback()
try {
- let garageConfig;
+ let garageConfig
if (!(garageConfig = this.platform.cusG.get(accessory.context.hbDeviceId))) {
- throw "group config missing";
+ throw new Error('group config missing')
}
- if (garageConfig.type !== "garage" || !["oneSwitch", "twoSwitch"].includes(garageConfig.setup)) {
- throw "improper configuration";
+ if (garageConfig.type !== 'garage' || !['oneSwitch', 'twoSwitch'].includes(garageConfig.setup)) {
+ throw new Error('improper configuration')
}
- let sensorDefinition = garageConfig.sensorId || false,
- sAccessory = false,
- prevState,
- newPos = value,
- params = {},
- delay = 0,
- gdService = accessory.getService(Service.GarageDoorOpener);
- if (sensorDefinition && !(sAccessory = this.platform.devicesInHB.get(garageConfig.sensorId + "SWX"))) {
- throw "defined DW2 sensor doesn't exist";
+ const sensorDefinition = garageConfig.sensorId || false
+ let sAccessory = false
+ const newPos = value
+ const params = {}
+ let delay = 0
+ const gdService = accessory.getService(Service.GarageDoorOpener)
+ if (sensorDefinition && !(sAccessory = this.platform.devicesInHB.get(garageConfig.sensorId + 'SWX'))) {
+ throw new Error("defined DW2 sensor doesn't exist")
}
- if (sensorDefinition && sAccessory.context.type !== "sensor") {
- throw "defined DW2 sensor isn't a sensor";
+ if (sensorDefinition && sAccessory.context.type !== 'sensor') {
+ throw new Error("defined DW2 sensor isn't a sensor")
}
- prevState = sAccessory
+ const prevState = sAccessory
? sAccessory.getService(Service.ContactSensor).getCharacteristic(Characteristic.ContactSensorState).value === 0
? 1
: 0
- : accessory.context.cacheCurrentDoorState;
- if (newPos === prevState % 2) return;
- accessory.context.inUse = true;
- accessory.context.state = value;
- if (garageConfig.setup === "oneSwitch" && [2, 3].includes(prevState)) {
- gdService.updateCharacteristic(Characteristic.CurrentDoorState, ((prevState * 2) % 3) + 2);
- accessory.context.cacheCurrentDoorState = ((prevState * 2) % 3) + 2;
- delay = 1500;
+ : accessory.context.cacheCurrentDoorState
+ if (newPos === prevState % 2) return
+ accessory.context.inUse = true
+ accessory.context.state = value
+ if (garageConfig.setup === 'oneSwitch' && [2, 3].includes(prevState)) {
+ gdService.updateCharacteristic(Characteristic.CurrentDoorState, ((prevState * 2) % 3) + 2)
+ accessory.context.cacheCurrentDoorState = ((prevState * 2) % 3) + 2
+ delay = 1500
}
- if (accessory.context.state !== newPos) return;
- await utils.sleep(delay);
+ if (accessory.context.state !== newPos) return
+ await utils.sleep(delay)
gdService
.updateCharacteristic(Characteristic.TargetDoorState, newPos)
- .updateCharacteristic(Characteristic.CurrentDoorState, newPos + 2);
- accessory.context.cacheTargetDoorState = newPos;
- accessory.context.cacheCurrentDoorState = newPos + 2;
+ .updateCharacteristic(Characteristic.CurrentDoorState, newPos + 2)
+ accessory.context.cacheTargetDoorState = newPos
+ accessory.context.cacheCurrentDoorState = newPos + 2
switch (garageConfig.setup) {
- case "oneSwitch":
- params.switch = "on";
- break;
- case "twoSwitch":
- params.switches = this.platform.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
- params.switches[0].switch = newPos === 0 ? "on" : "off";
- params.switches[1].switch = newPos === 1 ? "on" : "off";
- break;
+ case 'oneSwitch':
+ params.switch = 'on'
+ break
+ case 'twoSwitch':
+ params.switches = this.platform.devicesInEW.get(accessory.context.eweDeviceId).params.switches
+ params.switches[0].switch = newPos === 0 ? 'on' : 'off'
+ params.switches[1].switch = newPos === 1 ? 'on' : 'off'
+ break
}
- await this.platform.sendDeviceUpdate(accessory, params);
- await utils.sleep(garageConfig.operationTime * 100);
+ await this.platform.sendDeviceUpdate(accessory, params)
+ await utils.sleep(garageConfig.operationTime * 100)
if (!sAccessory) {
- gdService.updateCharacteristic(Characteristic.CurrentDoorState, newPos);
- accessory.context.cacheCurrentDoorState = newPos;
+ gdService.updateCharacteristic(Characteristic.CurrentDoorState, newPos)
+ accessory.context.cacheCurrentDoorState = newPos
}
- accessory.context.inUse = false;
+ accessory.context.inUse = false
} catch (err) {
- this.platform.requestDeviceRefresh(accessory, err);
+ this.platform.requestDeviceRefresh(accessory, err)
}
}
- externalGarageUpdate(accessory, params) {
+
+ externalGarageUpdate (accessory, params) {
try {
- let garageConfig,
- gcService = accessory.getService(Service.GarageDoorOpener),
- prevState = accessory.context.cacheCurrentDoorState,
- newPos = [0, 2].includes(prevState) ? 3 : 2;
+ let garageConfig
+ const gcService = accessory.getService(Service.GarageDoorOpener)
+ const prevState = accessory.context.cacheCurrentDoorState
+ const newPos = [0, 2].includes(prevState) ? 3 : 2
if (!(garageConfig = this.platform.cusG.get(accessory.context.hbDeviceId))) {
- throw "group config missing";
+ throw new Error('group config missing')
}
- if (garageConfig.type !== "garage" || !["oneSwitch", "twoSwitch"].includes(garageConfig.setup)) {
- throw "improper configuration";
+ if (garageConfig.type !== 'garage' || !['oneSwitch', 'twoSwitch'].includes(garageConfig.setup)) {
+ throw new Error('improper configuration')
}
if (accessory.context.inUse || garageConfig.sensorId) {
- return;
+ return
}
switch (garageConfig.setup) {
- case "oneSwitch":
- if (params.switch === "off") {
- return;
+ case 'oneSwitch':
+ if (params.switch === 'off') {
+ return
}
- break;
- case "twoSwitch":
+ break
+ case 'twoSwitch':
if (
params.switches[0].switch === params.switches[1].switch ||
- params.switches[prevState % 2].switch === "on"
+ params.switches[prevState % 2].switch === 'on'
) {
- return;
+ return
}
- break;
+ break
}
- accessory.context.inUse = true;
+ accessory.context.inUse = true
if (!garageConfig.sensorId) {
gcService
.updateCharacteristic(Characteristic.CurrentDoorState, newPos)
- .updateCharacteristic(Characteristic.TargetDoorState, newPos - 2);
- accessory.context.cacheCurrentDoorState = newPos;
- accessory.context.cacheTargetDoorState = newPos - 2;
+ .updateCharacteristic(Characteristic.TargetDoorState, newPos - 2)
+ accessory.context.cacheCurrentDoorState = newPos
+ accessory.context.cacheTargetDoorState = newPos - 2
setTimeout(() => {
- gcService.updateCharacteristic(Characteristic.CurrentDoorState, newPos - 2);
- accessory.context.cacheCurrentDoorState = newPos - 2;
- }, parseInt(garageConfig.operationTime) * 100);
+ gcService.updateCharacteristic(Characteristic.CurrentDoorState, newPos - 2)
+ accessory.context.cacheCurrentDoorState = newPos - 2
+ }, parseInt(garageConfig.operationTime) * 100)
}
setTimeout(() => {
- accessory.context.inUse = false;
- }, parseInt(garageConfig.operationTime) * 100);
+ accessory.context.inUse = false
+ }, parseInt(garageConfig.operationTime) * 100)
} catch (err) {
- accessory.context.inUse = false;
- this.platform.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ accessory.context.inUse = false
+ this.platform.log.warn('[%s] could not be updated as %s.', accessory.displayName, err)
}
}
-};
+}
diff --git a/lib/device/light.js b/lib/device/light.js
index ac838310..42006e45 100644
--- a/lib/device/light.js
+++ b/lib/device/light.js
@@ -1,287 +1,289 @@
-/* jshint esversion: 9, -W014, -W030, node: true */
-"use strict";
-let Characteristic, Service;
-const convert = require("color-convert"),
- utils = require("./../utils");
+'use strict'
+let Characteristic, Service
+const convert = require('color-convert')
+const utils = require('./../utils')
module.exports = class deviceLight {
- constructor(platform) {
- this.platform = platform;
- Service = platform.api.hap.Service;
- Characteristic = platform.api.hap.Characteristic;
+ constructor (platform) {
+ this.platform = platform
+ Service = platform.api.hap.Service
+ Characteristic = platform.api.hap.Characteristic
}
- async internalLightbulbUpdate(accessory, value, callback) {
- callback();
+
+ async internalLightbulbUpdate (accessory, value, callback) {
+ callback()
try {
- let oAccessory,
- params = {},
- lightService = accessory.getService(Service.Lightbulb);
+ let oAccessory
+ const params = {}
+ const lightService = accessory.getService(Service.Lightbulb)
switch (accessory.context.switchNumber) {
- case "X":
+ case 'X':
if (accessory.context.eweUIID === 22) {
- //*** B1 ***\\
- params.state = value ? "on" : "off";
+ //* ** B1 ***\\
+ params.state = value ? 'on' : 'off'
} else {
- params.switch = value ? "on" : "off";
+ params.switch = value ? 'on' : 'off'
}
- break;
- case "0":
- params.switches = this.platform.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
- params.switches[0].switch = value ? "on" : "off";
- params.switches[1].switch = value ? "on" : "off";
- params.switches[2].switch = value ? "on" : "off";
- params.switches[3].switch = value ? "on" : "off";
- break;
- case "1":
- case "2":
- case "3":
- case "4":
- params.switches = this.platform.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
+ break
+ case '0':
+ params.switches = this.platform.devicesInEW.get(accessory.context.eweDeviceId).params.switches
+ params.switches[0].switch = value ? 'on' : 'off'
+ params.switches[1].switch = value ? 'on' : 'off'
+ params.switches[2].switch = value ? 'on' : 'off'
+ params.switches[3].switch = value ? 'on' : 'off'
+ break
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ params.switches = this.platform.devicesInEW.get(accessory.context.eweDeviceId).params.switches
for (let i = 1; i <= 4; i++) {
- if ((oAccessory = this.platform.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
+ if ((oAccessory = this.platform.devicesInHB.get(accessory.context.eweDeviceId + 'SW' + i))) {
i === parseInt(accessory.context.switchNumber)
- ? (params.switches[i - 1].switch = value ? "on" : "off")
+ ? (params.switches[i - 1].switch = value ? 'on' : 'off')
: (params.switches[i - 1].switch = oAccessory
- .getService(Service.Lightbulb)
- .getCharacteristic(Characteristic.On).value
- ? "on"
- : "off");
+ .getService(Service.Lightbulb)
+ .getCharacteristic(Characteristic.On).value
+ ? 'on'
+ : 'off')
} else {
- params.switches[i - 1].switch = "off";
+ params.switches[i - 1].switch = 'off'
}
}
- break;
+ break
}
- await this.platform.sendDeviceUpdate(accessory, params);
+ await this.platform.sendDeviceUpdate(accessory, params)
switch (accessory.context.switchNumber) {
- case "X":
- lightService.updateCharacteristic(Characteristic.On, value);
- break;
- case "0":
+ case 'X':
+ lightService.updateCharacteristic(Characteristic.On, value)
+ break
+ case '0':
for (let i = 0; i <= 4; i++) {
- if ((oAccessory = this.platform.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
- oAccessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value);
+ if ((oAccessory = this.platform.devicesInHB.get(accessory.context.eweDeviceId + 'SW' + i))) {
+ oAccessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value)
}
}
- break;
- case "1":
- case "2":
- case "3":
- case "4":
- lightService.updateCharacteristic(Characteristic.On, value);
- let masterState = "off";
+ break
+ case '1':
+ case '2':
+ case '3':
+ case '4': {
+ lightService.updateCharacteristic(Characteristic.On, value)
+ let masterState = 'off'
for (let i = 1; i <= 4; i++) {
- if ((oAccessory = this.platform.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
+ if ((oAccessory = this.platform.devicesInHB.get(accessory.context.eweDeviceId + 'SW' + i))) {
if (oAccessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value) {
- masterState = "on";
+ masterState = 'on'
}
}
}
if (!this.platform.hiddenMasters.includes(accessory.context.eweDeviceId)) {
- oAccessory = this.platform.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
- oAccessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, masterState === "on");
+ oAccessory = this.platform.devicesInHB.get(accessory.context.eweDeviceId + 'SW0')
+ oAccessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, masterState === 'on')
}
- break;
+ break
+ }
}
} catch (err) {
- this.platform.requestDeviceRefresh(accessory, err);
+ this.platform.requestDeviceRefresh(accessory, err)
}
}
- async internalBrightnessUpdate(accessory, value, callback) {
- callback();
+
+ async internalBrightnessUpdate (accessory, value, callback) {
+ callback()
try {
- let params = {},
- lightService = accessory.getService(Service.Lightbulb);
+ const params = {}
+ const lightService = accessory.getService(Service.Lightbulb)
if (value === 0) {
- params.switch = "off";
+ params.switch = 'off'
} else {
if (!lightService.getCharacteristic(Characteristic.On).value) {
- params.switch = "on";
+ params.switch = 'on'
}
switch (accessory.context.eweUIID) {
- case 36: //*** KING-M4 ***\\
- params.bright = Math.round((value * 9) / 10 + 10);
- break;
- case 44: //*** D1 ***\\
- params.brightness = value;
- params.mode = 0;
- break;
+ case 36: //* ** KING-M4 ***\\
+ params.bright = Math.round((value * 9) / 10 + 10)
+ break
+ case 44: //* ** D1 ***\\
+ params.brightness = value
+ params.mode = 0
+ break
}
}
- await utils.sleep(250);
- await this.platform.sendDeviceUpdate(accessory, params);
+ await utils.sleep(250)
+ await this.platform.sendDeviceUpdate(accessory, params)
if (value === 0) {
- lightService.updateCharacteristic(Characteristic.On, false);
+ lightService.updateCharacteristic(Characteristic.On, false)
} else {
- lightService.updateCharacteristic(Characteristic.Brightness, value);
+ lightService.updateCharacteristic(Characteristic.Brightness, value)
}
} catch (err) {
- this.platform.requestDeviceRefresh(accessory, err);
+ this.platform.requestDeviceRefresh(accessory, err)
}
}
- async internalHSBUpdate(accessory, type, value, callback) {
- callback();
+
+ async internalHSBUpdate (accessory, type, value, callback) {
+ callback()
try {
- if (!accessory.context.reachableWAN && !accessory.context.reachableLAN) {
- throw "it is currently offline";
- }
- let newRGB,
- params = {},
- lightService = accessory.getService(Service.Lightbulb),
- curHue = lightService.getCharacteristic(Characteristic.Hue).value,
- curSat = lightService.getCharacteristic(Characteristic.Saturation).value;
+ let newRGB
+ let params = {}
+ const lightService = accessory.getService(Service.Lightbulb)
+ const curHue = lightService.getCharacteristic(Characteristic.Hue).value
+ const curSat = lightService.getCharacteristic(Characteristic.Saturation).value
switch (type) {
- case "hue":
- newRGB = convert.hsv.rgb(value, curSat, 100);
+ case 'hue':
+ newRGB = convert.hsv.rgb(value, curSat, 100)
switch (accessory.context.eweUIID) {
- case 22: //*** B1 ***\\
+ case 22: //* ** B1 ***\\
params = {
zyx_mode: 2,
- type: "middle",
- channel0: "0",
- channel1: "0",
+ type: 'middle',
+ channel0: '0',
+ channel1: '0',
channel2: newRGB[0].toString(),
channel3: newRGB[1].toString(),
- channel4: newRGB[2].toString(),
- };
- break;
- case 59: //*** L1 ***\\
+ channel4: newRGB[2].toString()
+ }
+ break
+ case 59: //* ** L1 ***\\
params = {
mode: 1,
colorR: newRGB[0],
colorG: newRGB[1],
- colorB: newRGB[2],
- };
- break;
+ colorB: newRGB[2]
+ }
+ break
}
- break;
- case "bri":
+ break
+ case 'bri':
switch (accessory.context.eweUIID) {
- case 22: //*** B1 ***\\
- newRGB = convert.hsv.rgb(curHue, curSat, value);
+ case 22: //* ** B1 ***\\
+ newRGB = convert.hsv.rgb(curHue, curSat, value)
params = {
zyx_mode: 2,
- type: "middle",
- channel0: "0",
- channel1: "0",
+ type: 'middle',
+ channel0: '0',
+ channel1: '0',
channel2: newRGB[0].toString(),
channel3: newRGB[1].toString(),
- channel4: newRGB[2].toString(),
- };
- break;
- case 59: //*** L1 ***\\
+ channel4: newRGB[2].toString()
+ }
+ break
+ case 59: //* ** L1 ***\\
params = {
mode: 1,
- bright: value,
- };
- break;
+ bright: value
+ }
+ break
}
- break;
+ break
}
- await utils.sleep(250);
- await this.platform.sendDeviceUpdate(accessory, params);
+ await utils.sleep(250)
+ await this.platform.sendDeviceUpdate(accessory, params)
switch (type) {
- case "hue":
- lightService.updateCharacteristic(Characteristic.Hue, value);
- break;
- case "bri":
- lightService.updateCharacteristic(Characteristic.Brightness, value);
- break;
+ case 'hue':
+ lightService.updateCharacteristic(Characteristic.Hue, value)
+ break
+ case 'bri':
+ lightService.updateCharacteristic(Characteristic.Brightness, value)
+ break
}
} catch (err) {
- this.platform.requestDeviceRefresh(accessory, err);
+ this.platform.requestDeviceRefresh(accessory, err)
}
}
- externalSingleLightUpdate(accessory, params) {
+
+ externalSingleLightUpdate (accessory, params) {
try {
- let newColour,
- mode,
- isOn = false,
- lightService = accessory.getService(Service.Lightbulb);
- if (accessory.context.eweUIID === 22 && params.hasOwnProperty("state")) {
- isOn = params.state === "on";
- } else if (accessory.context.eweUIID !== 22 && params.hasOwnProperty("switch")) {
- isOn = params.switch === "on";
+ let newColour
+ let mode
+ let isOn = false
+ const lightService = accessory.getService(Service.Lightbulb)
+ if (accessory.context.eweUIID === 22 && Object.prototype.hasOwnProperty.call(params, 'state')) {
+ isOn = params.state === 'on'
+ } else if (accessory.context.eweUIID !== 22 && Object.prototype.hasOwnProperty.call(params, 'switch')) {
+ isOn = params.switch === 'on'
} else {
- isOn = lightService.getCharacteristic(Characteristic.On).value;
+ isOn = lightService.getCharacteristic(Characteristic.On).value
}
if (isOn) {
- lightService.updateCharacteristic(Characteristic.On, true);
+ lightService.updateCharacteristic(Characteristic.On, true)
switch (accessory.context.eweUIID) {
case 36: // KING-M4
- if (params.hasOwnProperty("bright")) {
- let nb = Math.round(((params.bright - 10) * 10) / 9); // eWeLink scale is 10-100 and HomeKit scale is 0-100.
- lightService.updateCharacteristic(Characteristic.Brightness, nb);
+ if (Object.prototype.hasOwnProperty.call(params, 'bright')) {
+ const nb = Math.round(((params.bright - 10) * 10) / 9) // eWeLink scale is 10-100 and HomeKit scale is 0-100.
+ lightService.updateCharacteristic(Characteristic.Brightness, nb)
}
- break;
+ break
case 44: // D1
- if (params.hasOwnProperty("brightness")) {
- lightService.updateCharacteristic(Characteristic.Brightness, params.brightness);
+ if (Object.prototype.hasOwnProperty.call(params, 'brightness')) {
+ lightService.updateCharacteristic(Characteristic.Brightness, params.brightness)
}
- break;
+ break
case 22: // B1
- if (params.hasOwnProperty("zyx_mode")) {
- mode = parseInt(params.zyx_mode);
- } else if (params.hasOwnProperty("channel0") && parseInt(params.channel0) + parseInt(params.channel1) > 0) {
- mode = 1;
+ if (Object.prototype.hasOwnProperty.call(params, 'zyx_mode')) {
+ mode = parseInt(params.zyx_mode)
+ } else if (Object.prototype.hasOwnProperty.call(params, 'channel0') && parseInt(params.channel0) + parseInt(params.channel1) > 0) {
+ mode = 1
} else {
- mode = 2;
+ mode = 2
}
if (mode === 2) {
- lightService.updateCharacteristic(Characteristic.On, true);
+ lightService.updateCharacteristic(Characteristic.On, true)
newColour = convert.rgb.hsv(
parseInt(params.channel2),
parseInt(params.channel3),
parseInt(params.channel4)
- );
+ )
lightService
.updateCharacteristic(Characteristic.Hue, newColour[0])
.updateCharacteristic(Characteristic.Saturation, 100)
- .updateCharacteristic(Characteristic.Brightness, 100);
+ .updateCharacteristic(Characteristic.Brightness, 100)
} else if (mode === 1) {
- throw "has been set to white mode which is not supported";
+ throw new Error('has been set to white mode which is not supported')
}
- break;
+ break
case 59: // L1
- if (params.hasOwnProperty("bright")) {
- lightService.updateCharacteristic(Characteristic.Brightness, params.bright);
+ if (Object.prototype.hasOwnProperty.call(params, 'bright')) {
+ lightService.updateCharacteristic(Characteristic.Brightness, params.bright)
}
- if (params.hasOwnProperty("colorR")) {
- newColour = convert.rgb.hsv(params.colorR, params.colorG, params.colorB);
+ if (Object.prototype.hasOwnProperty.call(params, 'colorR')) {
+ newColour = convert.rgb.hsv(params.colorR, params.colorG, params.colorB)
lightService
.updateCharacteristic(Characteristic.Hue, newColour[0])
- .updateCharacteristic(Characteristic.Saturation, newColour[1]);
+ .updateCharacteristic(Characteristic.Saturation, newColour[1])
}
- break;
+ break
default:
- return;
+ return
}
} else {
- lightService.updateCharacteristic(Characteristic.On, false);
+ lightService.updateCharacteristic(Characteristic.On, false)
}
} catch (err) {
- this.platform.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.platform.log.warn('[%s] could not be updated as %s.', accessory.displayName, err)
}
}
- externalMultiLightUpdate(accessory, params) {
+
+ externalMultiLightUpdate (accessory, params) {
try {
- let idToCheck = accessory.context.hbDeviceId.slice(0, -1),
- primaryState = false;
+ const idToCheck = accessory.context.hbDeviceId.slice(0, -1)
+ let primaryState = false
for (let i = 1; i <= accessory.context.channelCount; i++) {
if (this.platform.devicesInHB.has(idToCheck + i)) {
- let oAccessory = this.platform.devicesInHB.get(idToCheck + i);
+ const oAccessory = this.platform.devicesInHB.get(idToCheck + i)
oAccessory
.getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.On, params.switches[i - 1].switch === "on");
- if (params.switches[i - 1].switch === "on") {
- primaryState = true;
+ .updateCharacteristic(Characteristic.On, params.switches[i - 1].switch === 'on')
+ if (params.switches[i - 1].switch === 'on') {
+ primaryState = true
}
}
}
if (!this.platform.hiddenMasters.includes(accessory.context.eweDeviceId)) {
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, primaryState);
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, primaryState)
}
} catch (err) {
- this.platform.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.platform.log.warn('[%s] could not be updated as %s.', accessory.displayName, err)
}
}
-};
+}
diff --git a/lib/device/lock.js b/lib/device/lock.js
index ac74af5e..93278892 100644
--- a/lib/device/lock.js
+++ b/lib/device/lock.js
@@ -1,67 +1,68 @@
-/* jshint esversion: 9, -W014, -W030, node: true */
-"use strict";
-let Characteristic, Service;
-const utils = require("./../utils");
+'use strict'
+let Characteristic, Service
+const utils = require('./../utils')
module.exports = class deviceLock {
- constructor(platform) {
- this.platform = platform;
- Service = platform.api.hap.Service;
- Characteristic = platform.api.hap.Characteristic;
+ constructor (platform) {
+ this.platform = platform
+ Service = platform.api.hap.Service
+ Characteristic = platform.api.hap.Characteristic
}
- async internalLockUpdate(accessory, value, callback) {
- callback();
+
+ async internalLockUpdate (accessory, value, callback) {
+ callback()
try {
- let lockConfig,
- params = {
- switch: "on",
- },
- lmService = accessory.getService(Service.LockMechanism);
+ let lockConfig
+ const params = {
+ switch: 'on'
+ }
+ const lmService = accessory.getService(Service.LockMechanism)
if (!(lockConfig = this.platform.cusG.get(accessory.context.hbDeviceId))) {
- throw "group config missing";
+ throw new Error('group config missing')
}
- if (lockConfig.type !== "lock") {
- throw "improper configuration";
+ if (lockConfig.type !== 'lock') {
+ throw new Error('improper configuration')
}
- accessory.context.inUse = true;
- await this.platform.sendDeviceUpdate(accessory, params);
+ accessory.context.inUse = true
+ await this.platform.sendDeviceUpdate(accessory, params)
lmService
.updateCharacteristic(Characteristic.LockTargetState, 0)
- .updateCharacteristic(Characteristic.LockCurrentState, 0);
- await utils.sleep(lockConfig.operationTime * 100);
+ .updateCharacteristic(Characteristic.LockCurrentState, 0)
+ await utils.sleep(lockConfig.operationTime * 100)
lmService
.updateCharacteristic(Characteristic.LockTargetState, 1)
- .updateCharacteristic(Characteristic.LockCurrentState, 1);
- accessory.context.inUse = false;
+ .updateCharacteristic(Characteristic.LockCurrentState, 1)
+ accessory.context.inUse = false
} catch (err) {
- this.platform.requestDeviceRefresh(accessory, err);
+ this.platform.requestDeviceRefresh(accessory, err)
}
}
- externalLockUpdate(accessory, params) {
+
+ externalLockUpdate (accessory, params) {
try {
- let lockConfig,
- lmService = accessory.getService(Service.LockMechanism);
+ let lockConfig
+ const lmService = accessory.getService(Service.LockMechanism)
if (!(lockConfig = this.platform.cusG.get(accessory.context.hbDeviceId))) {
- throw "group config missing";
+ throw new Error('group config missing')
}
- if (lockConfig.type !== "lock") {
- throw "improper configuration";
+ if (lockConfig.type !== 'lock') {
+ throw new Error('improper configuration')
}
- if (params.switch === "off" || accessory.context.inUse) {
- return;
+ if (params.switch === 'off' || accessory.context.inUse) {
+ return
}
- accessory.context.inUse = true;
+ accessory.context.inUse = true
lmService
.updateCharacteristic(Characteristic.LockCurrentState, 0)
- .updateCharacteristic(Characteristic.LockTargetState, 0);
+ .updateCharacteristic(Characteristic.LockTargetState, 0)
setTimeout(() => {
lmService
.updateCharacteristic(Characteristic.LockCurrentState, 1)
- .updateCharacteristic(Characteristic.LockTargetState, 1);
- accessory.context.inUse = false;
- }, parseInt(lockConfig.operationTime) * 100);
+ .updateCharacteristic(Characteristic.LockTargetState, 1)
+ accessory.context.inUse = false
+ }, parseInt(lockConfig.operationTime) * 100)
} catch (err) {
- accessory.context.inUse = false;
- this.platform.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ accessory.context.inUse = false
+ this.platform.log.warn('[%s] could not be updated as %s.', accessory.displayName, err)
}
}
-};
+}
diff --git a/lib/device/outlet.js b/lib/device/outlet.js
index a1d7145b..8696dc36 100644
--- a/lib/device/outlet.js
+++ b/lib/device/outlet.js
@@ -1,56 +1,57 @@
-/* jshint esversion: 9, -W014, -W030, node: true */
-"use strict";
-let Characteristic, EveService, Service;
-const hbLib = require("homebridge-lib");
+'use strict'
+let Characteristic, EveService, Service
+const hbLib = require('homebridge-lib')
module.exports = class deviceOutlet {
- constructor(platform, homebridge) {
- this.platform = platform;
- Service = platform.api.hap.Service;
- Characteristic = platform.api.hap.Characteristic;
- EveService = new hbLib.EveHomeKitTypes(platform.api);
+ constructor (platform, homebridge) {
+ this.platform = platform
+ Service = platform.api.hap.Service
+ Characteristic = platform.api.hap.Characteristic
+ EveService = new hbLib.EveHomeKitTypes(platform.api)
}
- async internalOutletUpdate(accessory, value, callback) {
- callback();
+
+ async internalOutletUpdate (accessory, value, callback) {
+ callback()
try {
- let params = {
- switch: value ? "on" : "off",
- },
- outletService = accessory.getService(Service.Outlet);
- await this.platform.sendDeviceUpdate(accessory, params);
- outletService.updateCharacteristic(Characteristic.On, value);
+ const params = {
+ switch: value ? 'on' : 'off'
+ }
+ const outletService = accessory.getService(Service.Outlet)
+ await this.platform.sendDeviceUpdate(accessory, params)
+ outletService.updateCharacteristic(Characteristic.On, value)
} catch (err) {
- this.platform.requestDeviceRefresh(accessory, err);
+ this.platform.requestDeviceRefresh(accessory, err)
}
}
- externalOutletUpdate(accessory, params) {
+
+ externalOutletUpdate (accessory, params) {
try {
- let outletService = accessory.getService(Service.Outlet);
- if (params.hasOwnProperty("switch")) {
- outletService.updateCharacteristic(Characteristic.On, params.switch === "on");
- if (accessory.context.eweModel === "S26" || this.platform.config.disableEveLogging || false) {
- outletService.updateCharacteristic(Characteristic.OutletInUse, params.switch === "on");
+ const outletService = accessory.getService(Service.Outlet)
+ if (Object.prototype.hasOwnProperty.call(params, 'switch')) {
+ outletService.updateCharacteristic(Characteristic.On, params.switch === 'on')
+ if (accessory.context.eweModel === 'S26' || this.platform.config.disableEveLogging || false) {
+ outletService.updateCharacteristic(Characteristic.OutletInUse, params.switch === 'on')
}
}
- if (params.hasOwnProperty("power")) {
- outletService.updateCharacteristic(EveService.Characteristics.CurrentConsumption, parseFloat(params.power));
+ if (Object.prototype.hasOwnProperty.call(params, 'power')) {
+ outletService.updateCharacteristic(EveService.Characteristics.CurrentConsumption, parseFloat(params.power))
outletService.updateCharacteristic(
Characteristic.OutletInUse,
parseFloat(params.power) > (this.platform.config.inUsePowerThreshold || 0)
- );
- let isOn = accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On).value;
+ )
+ const isOn = accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On).value
accessory.eveLogger.addEntry({
time: Date.now(),
- power: isOn ? parseFloat(params.power) : 0,
- });
+ power: isOn ? parseFloat(params.power) : 0
+ })
}
- if (params.hasOwnProperty("voltage")) {
- outletService.updateCharacteristic(EveService.Characteristics.Voltage, parseFloat(params.voltage));
+ if (Object.prototype.hasOwnProperty.call(params, 'voltage')) {
+ outletService.updateCharacteristic(EveService.Characteristics.Voltage, parseFloat(params.voltage))
}
- if (params.hasOwnProperty("current")) {
- outletService.updateCharacteristic(EveService.Characteristics.ElectricCurrent, parseFloat(params.current));
+ if (Object.prototype.hasOwnProperty.call(params, 'current')) {
+ outletService.updateCharacteristic(EveService.Characteristics.ElectricCurrent, parseFloat(params.current))
}
} catch (err) {
- this.platform.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.platform.log.warn('[%s] could not be updated as %s.', accessory.displayName, err)
}
}
-};
+}
diff --git a/lib/device/rf-sub.js b/lib/device/rf-sub.js
index 59dcfb06..3bf3320c 100644
--- a/lib/device/rf-sub.js
+++ b/lib/device/rf-sub.js
@@ -1,122 +1,123 @@
-/* jshint esversion: 9, -W014, -W030, node: true */
-"use strict";
-let Characteristic, Service;
-const utils = require("./../utils");
+'use strict'
+let Characteristic, Service
+const utils = require('./../utils')
module.exports = class deviceRFSub {
- constructor(platform) {
- this.platform = platform;
- Service = platform.api.hap.Service;
- Characteristic = platform.api.hap.Characteristic;
+ constructor (platform) {
+ this.platform = platform
+ Service = platform.api.hap.Service
+ Characteristic = platform.api.hap.Characteristic
}
- async internalRFUpdate(accessory, rfChl, service, callback) {
- callback();
+
+ async internalRFUpdate (accessory, rfChl, service, callback) {
+ callback()
try {
- let params = {
- cmd: "transmit",
- rfChl: parseInt(rfChl),
- },
- rfService = accessory.getService(service);
- await this.platform.sendDeviceUpdate(accessory, params);
- rfService.updateCharacteristic(Characteristic.On, true);
- await utils.sleep(3000);
- rfService.updateCharacteristic(Characteristic.On, false);
+ const params = {
+ cmd: 'transmit',
+ rfChl: parseInt(rfChl)
+ }
+ const rfService = accessory.getService(service)
+ await this.platform.sendDeviceUpdate(accessory, params)
+ rfService.updateCharacteristic(Characteristic.On, true)
+ await utils.sleep(3000)
+ rfService.updateCharacteristic(Characteristic.On, false)
} catch (err) {
- this.platform.requestDeviceRefresh(accessory, err);
+ this.platform.requestDeviceRefresh(accessory, err)
}
}
- externalRFUpdate(accessory, params) {
+
+ externalRFUpdate (accessory, params) {
try {
- if (!params.hasOwnProperty("updateSource")) return;
- let timeNow = new Date(),
- oAccessory = false;
- if (params.hasOwnProperty("cmd") && params.cmd === "transmit" && params.hasOwnProperty("rfChl")) {
- //*** RF Button ***\\
+ if (!Object.prototype.hasOwnProperty.call(params, 'updateSource')) return
+ const timeNow = new Date()
+ let oAccessory = false
+ if (Object.prototype.hasOwnProperty.call(params, 'cmd') && params.cmd === 'transmit' && Object.prototype.hasOwnProperty.call(params, 'rfChl')) {
+ //* ** RF Button ***\\
// the device needed is SW% corresponding to params.rfChl
this.platform.devicesInHB.forEach(acc => {
if (
acc.context.eweDeviceId === accessory.context.eweDeviceId &&
- acc.context.buttons.hasOwnProperty(params.rfChl.toString())
+ Object.prototype.hasOwnProperty.call(acc.context.buttons, params.rfChl.toString())
) {
- oAccessory = acc;
+ oAccessory = acc
}
- });
+ })
if (oAccessory) {
- oAccessory.getService(oAccessory.context.buttons[params.rfChl]).updateCharacteristic(Characteristic.On, 1);
+ oAccessory.getService(oAccessory.context.buttons[params.rfChl]).updateCharacteristic(Characteristic.On, 1)
setTimeout(
() =>
oAccessory
.getService(oAccessory.context.buttons[params.rfChl])
.updateCharacteristic(Characteristic.On, 0),
3000
- );
+ )
} else {
- throw "rf button not found in Homebridge";
+ throw new Error('rf button not found in Homebridge')
}
- } else if (params.hasOwnProperty("cmd") && params.cmd === "trigger") {
- //*** RF Sensor ***\\
+ } else if (Object.prototype.hasOwnProperty.call(params, 'cmd') && params.cmd === 'trigger') {
+ //* ** RF Sensor ***\\
Object.keys(params)
.filter(name => /rfTrig/.test(name))
.forEach(chan => {
this.platform.devicesInHB.forEach(acc => {
if (
acc.context.eweDeviceId === accessory.context.eweDeviceId &&
- acc.context.buttons.hasOwnProperty(chan.substr(-1).toString())
+ Object.prototype.hasOwnProperty.call(acc.context.buttons, chan.substr(-1).toString())
) {
- oAccessory = acc;
+ oAccessory = acc
}
- });
+ })
if (oAccessory) {
- let timeOfMotion = new Date(params[chan]),
- diff = (timeNow.getTime() - timeOfMotion.getTime()) / 1000,
- serv,
- char;
+ const timeOfMotion = new Date(params[chan])
+ const diff = (timeNow.getTime() - timeOfMotion.getTime()) / 1000
+ let serv
+ let char
if (diff < (this.platform.config.sensorTimeDifference || 120)) {
switch (oAccessory.context.sensorType) {
- case "button":
- break;
- case "water":
- serv = Service.LeakSensor;
- char = Characteristic.LeakDetected;
- break;
- case "fire":
- case "smoke":
- serv = Service.SmokeSensor;
- char = Characteristic.LeakDetected;
- break;
- case "co":
- serv = Service.CarbonMonoxideSensor;
- char = Characteristic.CarbonMonoxideDetected;
- break;
- case "co2":
- serv = Service.CarbonDioxideSensor;
- char = Characteristic.CarbonDioxideDetected;
- break;
- case "contact":
- serv = Service.ContactSensor;
- char = Characteristic.ContactSensorState;
- break;
- case "occupancy":
- serv = Service.OccupancySensor;
- char = Characteristic.OccupancyDetected;
- break;
+ case 'button':
+ break
+ case 'water':
+ serv = Service.LeakSensor
+ char = Characteristic.LeakDetected
+ break
+ case 'fire':
+ case 'smoke':
+ serv = Service.SmokeSensor
+ char = Characteristic.LeakDetected
+ break
+ case 'co':
+ serv = Service.CarbonMonoxideSensor
+ char = Characteristic.CarbonMonoxideDetected
+ break
+ case 'co2':
+ serv = Service.CarbonDioxideSensor
+ char = Characteristic.CarbonDioxideDetected
+ break
+ case 'contact':
+ serv = Service.ContactSensor
+ char = Characteristic.ContactSensorState
+ break
+ case 'occupancy':
+ serv = Service.OccupancySensor
+ char = Characteristic.OccupancyDetected
+ break
default:
- serv = Service.MotionSensor;
- char = Characteristic.MotionDetected;
- break;
+ serv = Service.MotionSensor
+ char = Characteristic.MotionDetected
+ break
}
- oAccessory.getService(serv).updateCharacteristic(char, 1);
+ oAccessory.getService(serv).updateCharacteristic(char, 1)
setTimeout(() => {
- oAccessory.getService(serv).updateCharacteristic(char, 0);
- }, (this.platform.config.sensorTimeLength || 2) * 1000);
+ oAccessory.getService(serv).updateCharacteristic(char, 0)
+ }, (this.platform.config.sensorTimeLength || 2) * 1000)
if (this.platform.debug) {
- this.platform.log("[%s] has detected [%s].", oAccessory.displayName, oAccessory.context.sensorType);
+ this.platform.log('[%s] has detected [%s].', oAccessory.displayName, oAccessory.context.sensorType)
}
}
}
- });
+ })
}
} catch (err) {
- this.platform.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.platform.log.warn('[%s] could not be updated as %s.', accessory.displayName, err)
}
}
-};
+}
diff --git a/lib/device/scm.js b/lib/device/scm.js
index e424e8eb..276c385f 100644
--- a/lib/device/scm.js
+++ b/lib/device/scm.js
@@ -1,32 +1,32 @@
-/* jshint esversion: 9, -W014, -W030, node: true */
-"use strict";
-let Characteristic, Service;
+'use strict'
+let Characteristic, Service
module.exports = class deviceSCM {
- constructor(platform) {
- this.platform = platform;
- Service = platform.api.hap.Service;
- Characteristic = platform.api.hap.Characteristic;
+ constructor (platform) {
+ this.platform = platform
+ Service = platform.api.hap.Service
+ Characteristic = platform.api.hap.Characteristic
}
- async internalSCMUpdate(accessory, value, callback) {
- callback();
+ async internalSCMUpdate (accessory, value, callback) {
+ callback()
try {
- let params = {
- switches: this.platform.devicesInEW.get(accessory.context.eweDeviceId).params.switches,
- },
- switchService = accessory.getService(Service.Switch);
- params.switches[0].switch = value ? "on" : "off";
- await this.platform.sendDeviceUpdate(accessory, params);
- switchService.updateCharacteristic(Characteristic.On, value);
+ const params = {
+ switches: this.platform.devicesInEW.get(accessory.context.eweDeviceId).params.switches
+ }
+ const switchService = accessory.getService(Service.Switch)
+ params.switches[0].switch = value ? 'on' : 'off'
+ await this.platform.sendDeviceUpdate(accessory, params)
+ switchService.updateCharacteristic(Characteristic.On, value)
} catch (err) {
- this.platform.requestDeviceRefresh(accessory, err);
+ this.platform.requestDeviceRefresh(accessory, err)
}
}
- externalSCMUpdate(accessory, params) {
+
+ externalSCMUpdate (accessory, params) {
try {
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, params.switches[0].switch === "on");
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, params.switches[0].switch === 'on')
} catch (err) {
- this.platform.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.platform.log.warn('[%s] could not be updated as %s.', accessory.displayName, err)
}
}
-};
+}
diff --git a/lib/device/sensor.js b/lib/device/sensor.js
index 391d7f08..b16f3a5c 100644
--- a/lib/device/sensor.js
+++ b/lib/device/sensor.js
@@ -1,54 +1,54 @@
-/* jshint esversion: 9, -W014, -W030, node: true */
-"use strict";
-let Characteristic, Service;
+'use strict'
+let Characteristic, Service
module.exports = class deviceSensor {
- constructor(platform) {
- this.platform = platform;
- Service = platform.api.hap.Service;
- Characteristic = platform.api.hap.Characteristic;
+ constructor (platform) {
+ this.platform = platform
+ Service = platform.api.hap.Service
+ Characteristic = platform.api.hap.Characteristic
}
- externalSensorUpdate(accessory, params) {
+
+ externalSensorUpdate (accessory, params) {
try {
- if (params.hasOwnProperty("battery")) {
- let batteryService =
- accessory.getService(Service.BatteryService) || accessory.addService(Service.BatteryService),
- scaledBattery = Math.round(params.battery * 33.3);
- batteryService.updateCharacteristic(Characteristic.BatteryLevel, scaledBattery);
+ if (Object.prototype.hasOwnProperty.call(params, 'battery')) {
+ const batteryService =
+ accessory.getService(Service.BatteryService) || accessory.addService(Service.BatteryService)
+ const scaledBattery = Math.round(params.battery * 33.3)
+ batteryService.updateCharacteristic(Characteristic.BatteryLevel, scaledBattery)
batteryService.updateCharacteristic(
Characteristic.StatusLowBattery,
scaledBattery < (this.platform.config.lowBattThreshold || 25)
- );
+ )
}
- let newState = params.switch === "on" ? 1 : 0,
- oAccessory = false,
- contactService = accessory.getService(Service.ContactSensor);
- contactService.updateCharacteristic(Characteristic.ContactSensorState, newState);
+ const newState = params.switch === 'on' ? 1 : 0
+ let oAccessory = false
+ const contactService = accessory.getService(Service.ContactSensor)
+ contactService.updateCharacteristic(Characteristic.ContactSensorState, newState)
this.platform.cusG.forEach(group => {
- if (group.sensorId === accessory.context.eweDeviceId && group.type === "garage") {
- if ((oAccessory = this.platform.devicesInHB.get(group.deviceId + "SWX"))) {
+ if (group.sensorId === accessory.context.eweDeviceId && group.type === 'garage') {
+ if ((oAccessory = this.platform.devicesInHB.get(group.deviceId + 'SWX'))) {
switch (newState) {
case 0:
oAccessory
.getService(Service.GarageDoorOpener)
.updateCharacteristic(Characteristic.TargetDoorState, 1)
- .updateCharacteristic(Characteristic.CurrentDoorState, 1);
- break;
+ .updateCharacteristic(Characteristic.CurrentDoorState, 1)
+ break
case 1:
setTimeout(() => {
oAccessory
.getService(Service.GarageDoorOpener)
.updateCharacteristic(Characteristic.TargetDoorState, 0)
- .updateCharacteristic(Characteristic.CurrentDoorState, 0);
- }, group.operationTime * 100);
- break;
+ .updateCharacteristic(Characteristic.CurrentDoorState, 0)
+ }, group.operationTime * 100)
+ break
default:
- throw "unknown sensor status received [" + newState + "]";
+ throw new Error('unknown sensor status received [' + newState + ']')
}
}
}
- });
+ })
} catch (err) {
- this.platform.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.platform.log.warn('[%s] could not be updated as %s.', accessory.displayName, err)
}
}
-};
+}
diff --git a/lib/device/switch.js b/lib/device/switch.js
index e446492a..0f49f802 100644
--- a/lib/device/switch.js
+++ b/lib/device/switch.js
@@ -1,111 +1,114 @@
-/* jshint esversion: 9, -W014, -W030, node: true */
-"use strict";
-let Characteristic, Service;
+'use strict'
+let Characteristic, Service
module.exports = class deviceSwitch {
- constructor(platform) {
- this.platform = platform;
- Service = platform.api.hap.Service;
- Characteristic = platform.api.hap.Characteristic;
+ constructor (platform) {
+ this.platform = platform
+ Service = platform.api.hap.Service
+ Characteristic = platform.api.hap.Characteristic
}
- async internalSwitchUpdate(accessory, value, callback) {
- callback();
+
+ async internalSwitchUpdate (accessory, value, callback) {
+ callback()
try {
- let oAccessory,
- params = {},
- switchService = accessory.getService(Service.Switch);
+ let oAccessory
+ const params = {}
+ const switchService = accessory.getService(Service.Switch)
switch (accessory.context.switchNumber) {
- case "X":
- params.switch = value ? "on" : "off";
- break;
- case "0":
- params.switches = this.platform.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
- params.switches[0].switch = value ? "on" : "off";
- params.switches[1].switch = value ? "on" : "off";
- params.switches[2].switch = value ? "on" : "off";
- params.switches[3].switch = value ? "on" : "off";
- break;
- case "1":
- case "2":
- case "3":
- case "4":
- params.switches = this.platform.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
+ case 'X':
+ params.switch = value ? 'on' : 'off'
+ break
+ case '0':
+ params.switches = this.platform.devicesInEW.get(accessory.context.eweDeviceId).params.switches
+ params.switches[0].switch = value ? 'on' : 'off'
+ params.switches[1].switch = value ? 'on' : 'off'
+ params.switches[2].switch = value ? 'on' : 'off'
+ params.switches[3].switch = value ? 'on' : 'off'
+ break
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ params.switches = this.platform.devicesInEW.get(accessory.context.eweDeviceId).params.switches
for (let i = 1; i <= 4; i++) {
- if ((oAccessory = this.platform.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
+ if ((oAccessory = this.platform.devicesInHB.get(accessory.context.eweDeviceId + 'SW' + i))) {
i === parseInt(accessory.context.switchNumber)
- ? (params.switches[i - 1].switch = value ? "on" : "off")
+ ? (params.switches[i - 1].switch = value ? 'on' : 'off')
: (params.switches[i - 1].switch = oAccessory
- .getService(Service.Switch)
- .getCharacteristic(Characteristic.On).value
- ? "on"
- : "off");
+ .getService(Service.Switch)
+ .getCharacteristic(Characteristic.On).value
+ ? 'on'
+ : 'off')
} else {
- params.switches[i - 1].switch = "off";
+ params.switches[i - 1].switch = 'off'
}
}
- break;
+ break
}
- await this.platform.sendDeviceUpdate(accessory, params);
+ await this.platform.sendDeviceUpdate(accessory, params)
switch (accessory.context.switchNumber) {
- case "X":
- switchService.updateCharacteristic(Characteristic.On, value);
- break;
- case "0":
+ case 'X':
+ switchService.updateCharacteristic(Characteristic.On, value)
+ break
+ case '0':
for (let i = 0; i <= 4; i++) {
- if ((oAccessory = this.platform.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
- oAccessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value);
+ if ((oAccessory = this.platform.devicesInHB.get(accessory.context.eweDeviceId + 'SW' + i))) {
+ oAccessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, value)
}
}
- break;
- case "1":
- case "2":
- case "3":
- case "4":
- switchService.updateCharacteristic(Characteristic.On, value);
- let masterState = "off";
+ break
+ case '1':
+ case '2':
+ case '3':
+ case '4': {
+ switchService.updateCharacteristic(Characteristic.On, value)
+ let masterState = 'off'
for (let i = 1; i <= 4; i++) {
- if ((oAccessory = this.platform.devicesInHB.get(accessory.context.eweDeviceId + "SW" + i))) {
+ if ((oAccessory = this.platform.devicesInHB.get(accessory.context.eweDeviceId + 'SW' + i))) {
if (oAccessory.getService(Service.Switch).getCharacteristic(Characteristic.On).value) {
- masterState = "on";
+ masterState = 'on'
}
}
}
if (!this.platform.hiddenMasters.includes(accessory.context.eweDeviceId)) {
- oAccessory = this.platform.devicesInHB.get(accessory.context.eweDeviceId + "SW0");
- oAccessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, masterState === "on");
+ oAccessory = this.platform.devicesInHB.get(accessory.context.eweDeviceId + 'SW0')
+ oAccessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, masterState === 'on')
}
- break;
+ break
+ }
}
} catch (err) {
- this.platform.requestDeviceRefresh(accessory, err);
+ this.platform.requestDeviceRefresh(accessory, err)
}
}
- externalSingleSwitchUpdate(accessory, params) {
+
+ externalSingleSwitchUpdate (accessory, params) {
try {
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, params.switch === "on");
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, params.switch === 'on')
} catch (err) {
- this.platform.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.platform.log.warn('[%s] could not be updated as %s.', accessory.displayName, err)
}
}
- externalMultiSwitchUpdate(accessory, params) {
+
+ externalMultiSwitchUpdate (accessory, params) {
try {
- let idToCheck = accessory.context.hbDeviceId.slice(0, -1),
- primaryState = false;
+ const idToCheck = accessory.context.hbDeviceId.slice(0, -1)
+ let primaryState = false
for (let i = 1; i <= accessory.context.channelCount; i++) {
if (this.platform.devicesInHB.has(idToCheck + i)) {
- let oAccessory = this.platform.devicesInHB.get(idToCheck + i);
+ const oAccessory = this.platform.devicesInHB.get(idToCheck + i)
oAccessory
.getService(Service.Switch)
- .updateCharacteristic(Characteristic.On, params.switches[i - 1].switch === "on");
- if (params.switches[i - 1].switch === "on") {
- primaryState = true;
+ .updateCharacteristic(Characteristic.On, params.switches[i - 1].switch === 'on')
+ if (params.switches[i - 1].switch === 'on') {
+ primaryState = true
}
}
}
if (!this.platform.hiddenMasters.includes(accessory.context.eweDeviceId)) {
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, primaryState);
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, primaryState)
}
} catch (err) {
- this.platform.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.platform.log.warn('[%s] could not be updated as %s.', accessory.displayName, err)
}
}
-};
+}
diff --git a/lib/device/thermostat.js b/lib/device/thermostat.js
index dfc0baec..fe076368 100644
--- a/lib/device/thermostat.js
+++ b/lib/device/thermostat.js
@@ -1,58 +1,59 @@
-/* jshint esversion: 9, -W014, -W030, node: true */
-"use strict";
-let Characteristic, Service;
+'use strict'
+let Characteristic, Service
module.exports = class deviceThermostat {
- constructor(platform, homebridge) {
- this.platform = platform;
+ constructor (platform, homebridge) {
+ this.platform = platform
}
- async internalThermostatUpdate(accessory, value, callback) {
- callback();
+
+ async internalThermostatUpdate (accessory, value, callback) {
+ callback()
try {
- let params = {
- switch: value ? "on" : "off",
- mainSwitch: value ? "on" : "off",
- },
- switchService = accessory.getService(Service.Switch);
- await this.platform.sendDeviceUpdate(accessory, params);
- switchService.updateCharacteristic(Characteristic.On, value);
+ const params = {
+ switch: value ? 'on' : 'off',
+ mainSwitch: value ? 'on' : 'off'
+ }
+ const switchService = accessory.getService(Service.Switch)
+ await this.platform.sendDeviceUpdate(accessory, params)
+ switchService.updateCharacteristic(Characteristic.On, value)
} catch (err) {
- this.platform.requestDeviceRefresh(accessory, err);
+ this.platform.requestDeviceRefresh(accessory, err)
}
}
- externalThermostatUpdate(accessory, params) {
+
+ externalThermostatUpdate (accessory, params) {
try {
if (
!this.platform.config.hideTHSwitch &&
- (params.hasOwnProperty("switch") || params.hasOwnProperty("mainSwitch"))
+ (Object.prototype.hasOwnProperty.call(params, 'switch') || Object.prototype.hasOwnProperty.call(params, 'mainSwitch'))
) {
- let newState = params.hasOwnProperty("switch") ? params.switch === "on" : params.mainSwitch === "on",
- switchService = accessory.getService(Service.Switch);
- switchService.updateCharacteristic(Characteristic.On, newState);
+ const newState = Object.prototype.hasOwnProperty.call(params, 'switch') ? params.switch === 'on' : params.mainSwitch === 'on'
+ const switchService = accessory.getService(Service.Switch)
+ switchService.updateCharacteristic(Characteristic.On, newState)
}
if (!(this.platform.config.disableEveLogging || false)) {
- let eveLog = {
- time: Date.now(),
- };
- if (params.hasOwnProperty("currentTemperature") && accessory.getService(Service.TemperatureSensor)) {
- let currentTemp = params.currentTemperature !== "unavailable" ? params.currentTemperature : 0;
+ const eveLog = {
+ time: Date.now()
+ }
+ if (Object.prototype.hasOwnProperty.call(params, 'currentTemperature') && accessory.getService(Service.TemperatureSensor)) {
+ const currentTemp = params.currentTemperature !== 'unavailable' ? params.currentTemperature : 0
accessory
.getService(Service.TemperatureSensor)
- .updateCharacteristic(Characteristic.CurrentTemperature, currentTemp);
- eveLog.temp = parseFloat(currentTemp);
+ .updateCharacteristic(Characteristic.CurrentTemperature, currentTemp)
+ eveLog.temp = parseFloat(currentTemp)
}
- if (params.hasOwnProperty("currentHumidity") && accessory.getService(Service.HumiditySensor)) {
- let currentHumi = params.currentHumidity !== "unavailable" ? params.currentHumidity : 0;
+ if (Object.prototype.hasOwnProperty.call(params, 'currentHumidity') && accessory.getService(Service.HumiditySensor)) {
+ const currentHumi = params.currentHumidity !== 'unavailable' ? params.currentHumidity : 0
accessory
.getService(Service.HumiditySensor)
- .updateCharacteristic(Characteristic.CurrentRelativeHumidity, currentHumi);
- eveLog.humidity = parseFloat(currentHumi);
+ .updateCharacteristic(Characteristic.CurrentRelativeHumidity, currentHumi)
+ eveLog.humidity = parseFloat(currentHumi)
}
- if (eveLog.hasOwnProperty("temp") || eveLog.hasOwnProperty("humidity")) {
- accessory.eveLogger.addEntry(eveLog);
+ if (Object.prototype.hasOwnProperty.call(eveLog, 'temp') || Object.prototype.hasOwnProperty.call(eveLog, 'humidity')) {
+ accessory.eveLogger.addEntry(eveLog)
}
}
} catch (err) {
- this.platform.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.platform.log.warn('[%s] could not be updated as %s.', accessory.displayName, err)
}
}
-};
+}
diff --git a/lib/device/usb.js b/lib/device/usb.js
index 7d6e244f..d78cf020 100644
--- a/lib/device/usb.js
+++ b/lib/device/usb.js
@@ -1,31 +1,32 @@
-/* jshint esversion: 9, -W014, -W030, node: true */
-"use strict";
-let Characteristic, Service;
+'use strict'
+let Characteristic, Service
module.exports = class deviceUSB {
- constructor(platform) {
- this.platform = platform;
- Service = platform.api.hap.Service;
- Characteristic = platform.api.hap.Characteristic;
+ constructor (platform) {
+ this.platform = platform
+ Service = platform.api.hap.Service
+ Characteristic = platform.api.hap.Characteristic
}
- async internalUSBUpdate(accessory, value, callback) {
- callback();
+
+ async internalUSBUpdate (accessory, value, callback) {
+ callback()
try {
- let params = {
- switches: this.platform.devicesInEW.get(accessory.context.eweDeviceId).params.switches,
- },
- outletService = accessory.getService(Service.Outlet);
- params.switches[0].switch = value ? "on" : "off";
- await this.platform.sendDeviceUpdate(accessory, params);
- outletService.updateCharacteristic(Characteristic.On, value);
+ const params = {
+ switches: this.platform.devicesInEW.get(accessory.context.eweDeviceId).params.switches
+ }
+ const outletService = accessory.getService(Service.Outlet)
+ params.switches[0].switch = value ? 'on' : 'off'
+ await this.platform.sendDeviceUpdate(accessory, params)
+ outletService.updateCharacteristic(Characteristic.On, value)
} catch (err) {
- this.platform.requestDeviceRefresh(accessory, err);
+ this.platform.requestDeviceRefresh(accessory, err)
}
}
- externalUSBUpdate(accessory, params) {
+
+ externalUSBUpdate (accessory, params) {
try {
- accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, params.switches[0].switch === "on");
+ accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, params.switches[0].switch === 'on')
} catch (err) {
- this.platform.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.platform.log.warn('[%s] could not be updated as %s.', accessory.displayName, err)
}
}
-};
+}
diff --git a/lib/device/valve.js b/lib/device/valve.js
index 6336871d..121f139e 100644
--- a/lib/device/valve.js
+++ b/lib/device/valve.js
@@ -1,71 +1,72 @@
-/* jshint esversion: 9, -W014, -W030, node: true */
-"use strict";
-let Characteristic, Service;
+'use strict'
+let Characteristic
module.exports = class deviceValve {
- constructor(platform) {
- this.platform = platform;
- Service = platform.api.hap.Service;
- Characteristic = platform.api.hap.Characteristic;
+ constructor (platform) {
+ this.platform = platform
+ Characteristic = platform.api.hap.Characteristic
}
- async internalValveUpdate(accessory, valve, value, callback) {
- callback();
+
+ async internalValveUpdate (accessory, valve, value, callback) {
+ callback()
try {
- let params = {},
- serviceValve = accessory.getService(valve);
- params.switches = this.platform.devicesInEW.get(accessory.context.eweDeviceId).params.switches;
+ const params = {}
+ const serviceValve = accessory.getService(valve)
+ params.switches = this.platform.devicesInEW.get(accessory.context.eweDeviceId).params.switches
switch (valve) {
- case "Valve A":
- params.switches[0].switch = value ? "on" : "off";
- params.switches[1].switch = accessory.getService("Valve B").getCharacteristic(Characteristic.Active).value
- ? "on"
- : "off";
- break;
- case "Valve B":
- params.switches[0].switch = accessory.getService("Valve A").getCharacteristic(Characteristic.Active).value
- ? "on"
- : "off";
- params.switches[1].switch = value ? "on" : "off";
- break;
+ case 'Valve A':
+ params.switches[0].switch = value ? 'on' : 'off'
+ params.switches[1].switch = accessory.getService('Valve B').getCharacteristic(Characteristic.Active).value
+ ? 'on'
+ : 'off'
+ break
+ case 'Valve B':
+ params.switches[0].switch = accessory.getService('Valve A').getCharacteristic(Characteristic.Active).value
+ ? 'on'
+ : 'off'
+ params.switches[1].switch = value ? 'on' : 'off'
+ break
}
- params.switches[2].switch = "off";
- params.switches[3].switch = "off";
- await this.platform.sendDeviceUpdate(accessory, params);
- serviceValve.updateCharacteristic(Characteristic.Active, value).updateCharacteristic(Characteristic.InUse, value);
+ params.switches[2].switch = 'off'
+ params.switches[3].switch = 'off'
+ await this.platform.sendDeviceUpdate(accessory, params)
+ serviceValve.updateCharacteristic(Characteristic.Active, value).updateCharacteristic(Characteristic.InUse, value)
switch (value) {
case 0:
- serviceValve.updateCharacteristic(Characteristic.RemainingDuration, 0);
- clearTimeout(accessory.getService(valve).timer);
- break;
- case 1:
- let timer = serviceValve.getCharacteristic(Characteristic.SetDuration).value;
- serviceValve.updateCharacteristic(Characteristic.RemainingDuration, timer);
- serviceValve.timer = setTimeout(() => serviceValve.setCharacteristic(Characteristic.Active, 0), timer * 1000);
- break;
+ serviceValve.updateCharacteristic(Characteristic.RemainingDuration, 0)
+ clearTimeout(accessory.getService(valve).timer)
+ break
+ case 1: {
+ const timer = serviceValve.getCharacteristic(Characteristic.SetDuration).value
+ serviceValve.updateCharacteristic(Characteristic.RemainingDuration, timer)
+ serviceValve.timer = setTimeout(() => serviceValve.setCharacteristic(Characteristic.Active, 0), timer * 1000)
+ break
+ }
}
} catch (err) {
- this.platform.requestDeviceRefresh(accessory, err);
+ this.platform.requestDeviceRefresh(accessory, err)
}
}
- externalValveUpdate(accessory, params) {
+
+ externalValveUpdate (accessory, params) {
try {
- ["A", "B"].forEach((v, k) => {
- let valveService = accessory.getService("Valve " + v);
+ ['A', 'B'].forEach((v, k) => {
+ const valveService = accessory.getService('Valve ' + v)
valveService
- .updateCharacteristic(Characteristic.Active, params.switches[k].switch === "on")
- .updateCharacteristic(Characteristic.InUse, params.switches[k].switch === "on");
- if (params.switches[k].switch === "on") {
- let timer = valveService.getCharacteristic(Characteristic.SetDuration).value;
- valveService.updateCharacteristic(Characteristic.RemainingDuration, timer);
+ .updateCharacteristic(Characteristic.Active, params.switches[k].switch === 'on')
+ .updateCharacteristic(Characteristic.InUse, params.switches[k].switch === 'on')
+ if (params.switches[k].switch === 'on') {
+ const timer = valveService.getCharacteristic(Characteristic.SetDuration).value
+ valveService.updateCharacteristic(Characteristic.RemainingDuration, timer)
valveService.timer = setTimeout(() => {
- valveService.setCharacteristic(Characteristic.Active, 0);
- }, timer * 1000);
+ valveService.setCharacteristic(Characteristic.Active, 0)
+ }, timer * 1000)
} else {
- valveService.updateCharacteristic(Characteristic.RemainingDuration, 0);
- clearTimeout(valveService.timer);
+ valveService.updateCharacteristic(Characteristic.RemainingDuration, 0)
+ clearTimeout(valveService.timer)
}
- });
+ })
} catch (err) {
- this.platform.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.platform.log.warn('[%s] could not be updated as %s.', accessory.displayName, err)
}
}
-};
+}
diff --git a/lib/device/zb-dev.js b/lib/device/zb-dev.js
index 07e64a8f..d4b2f58e 100644
--- a/lib/device/zb-dev.js
+++ b/lib/device/zb-dev.js
@@ -1,82 +1,83 @@
-/* jshint esversion: 9, -W014, -W030, node: true */
-"use strict";
-let Characteristic, Service;
+'use strict'
+let Characteristic, Service
module.exports = class deviceZBDev {
- constructor(platform) {
- this.platform = platform;
- Service = platform.api.hap.Service;
- Characteristic = platform.api.hap.Characteristic;
+ constructor (platform) {
+ this.platform = platform
+ Service = platform.api.hap.Service
+ Characteristic = platform.api.hap.Characteristic
}
- externalZBUpdate(accessory, params) {
+
+ externalZBUpdate (accessory, params) {
try {
- //*** credit @tasict ***\\
- if (params.hasOwnProperty("battery")) {
+ //* ** credit @tasict ***\\
+ if (Object.prototype.hasOwnProperty.call(params, 'battery')) {
if (accessory.context.eweUIID === 3026 && (this.platform.config.ZBDWBatt || false)) {
- params.battery *= 10;
+ params.battery *= 10
}
- let batteryService =
- accessory.getService(Service.BatteryService) || accessory.addService(Service.BatteryService);
- batteryService.updateCharacteristic(Characteristic.BatteryLevel, params.battery);
+ const batteryService =
+ accessory.getService(Service.BatteryService) || accessory.addService(Service.BatteryService)
+ batteryService.updateCharacteristic(Characteristic.BatteryLevel, params.battery)
batteryService.updateCharacteristic(
Characteristic.StatusLowBattery,
params.battery < (this.platform.config.lowBattThreshold || 25)
- );
+ )
}
switch (accessory.context.eweUIID) {
case 1000:
- if (params.hasOwnProperty("key") && [0, 1, 2].includes(params.key)) {
+ if (Object.prototype.hasOwnProperty.call(params, 'key') && [0, 1, 2].includes(params.key)) {
accessory
.getService(Service.StatelessProgrammableSwitch)
- .updateCharacteristic(Characteristic.ProgrammableSwitchEvent, params.key);
+ .updateCharacteristic(Characteristic.ProgrammableSwitchEvent, params.key)
}
- break;
- case 1770:
- let eveLog = {
- time: Date.now(),
- };
- if (params.hasOwnProperty("temperature")) {
- let currentTemp = parseInt(params.temperature) / 100;
+ break
+ case 1770: {
+ const eveLog = {
+ time: Date.now()
+ }
+ if (Object.prototype.hasOwnProperty.call(params, 'temperature')) {
+ const currentTemp = parseInt(params.temperature) / 100
accessory
.getService(Service.TemperatureSensor)
- .updateCharacteristic(Characteristic.CurrentTemperature, currentTemp);
- eveLog.temp = parseFloat(currentTemp);
+ .updateCharacteristic(Characteristic.CurrentTemperature, currentTemp)
+ eveLog.temp = parseFloat(currentTemp)
}
- if (params.hasOwnProperty("humidity")) {
- let currentHumi = parseInt(params.humidity) / 100;
+ if (Object.prototype.hasOwnProperty.call(params, 'humidity')) {
+ const currentHumi = parseInt(params.humidity) / 100
accessory
.getService(Service.HumiditySensor)
- .updateCharacteristic(Characteristic.CurrentRelativeHumidity, currentHumi);
- eveLog.humidity = parseFloat(currentHumi);
+ .updateCharacteristic(Characteristic.CurrentRelativeHumidity, currentHumi)
+ eveLog.humidity = parseFloat(currentHumi)
}
- if (eveLog.hasOwnProperty("temp") || eveLog.hasOwnProperty("humidity")) {
- accessory.eveLogger.addEntry(eveLog);
+ if (Object.prototype.hasOwnProperty.call(eveLog, 'temp') || Object.prototype.hasOwnProperty.call(eveLog, 'humidity')) {
+ accessory.eveLogger.addEntry(eveLog)
}
- break;
+ break
+ }
case 2026:
- if (params.hasOwnProperty("motion") && params.hasOwnProperty("trigTime")) {
- let timeNow = new Date(),
- diff = (timeNow.getTime() - params.trigTime) / 1000;
+ if (Object.prototype.hasOwnProperty.call(params, 'motion') && Object.prototype.hasOwnProperty.call(params, 'trigTime')) {
+ const timeNow = new Date()
+ const diff = (timeNow.getTime() - params.trigTime) / 1000
accessory
.getService(Service.MotionSensor)
.updateCharacteristic(
Characteristic.MotionDetected,
- params.hasOwnProperty("updateSource") &&
+ Object.prototype.hasOwnProperty.call(params, 'updateSource') &&
params.motion === 1 &&
diff < (this.platform.config.sensorTimeDifference || 120)
- );
- break;
+ )
+ break
}
- break;
+ break
case 3026:
- if (params.hasOwnProperty("lock") && [0, 1].includes(params.lock)) {
+ if (Object.prototype.hasOwnProperty.call(params, 'lock') && [0, 1].includes(params.lock)) {
accessory
.getService(Service.ContactSensor)
- .updateCharacteristic(Characteristic.ContactSensorState, params.lock);
+ .updateCharacteristic(Characteristic.ContactSensorState, params.lock)
}
- break;
+ break
}
} catch (err) {
- this.platform.log.warn("[%s] could not be updated as %s.", accessory.displayName, err);
+ this.platform.log.warn('[%s] could not be updated as %s.', accessory.displayName, err)
}
}
-};
+}
From ab86a1f6df73a4d87593e48db8fd80b32e22be55 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 27 Sep 2020 09:38:46 +0100
Subject: [PATCH 0236/3183] irrigation to custom group
---
config.schema.json | 20 +++++++++-----------
lib/constants.js | 2 +-
lib/device/valve.js | 14 ++++++++++++++
lib/eWeLink.js | 7 ++++---
4 files changed, 28 insertions(+), 15 deletions(-)
diff --git a/config.schema.json b/config.schema.json
index 037b6c42..5e99588c 100644
--- a/config.schema.json
+++ b/config.schema.json
@@ -88,14 +88,6 @@
"minimum": 10,
"maximum": 300
},
- "valveTimeLength": {
- "type": "integer",
- "title": "Valve Duration",
- "description": "The default number of seconds that irrigation valves will run for.",
- "default": 20,
- "minimum": 10,
- "maximum": 1800
- },
"inUsePowerThreshold": {
"type": "integer",
"title": "Outlet 'In Use' Threshold",
@@ -151,6 +143,12 @@
"enum": [
"lock"
]
+ },
+ {
+ "title": "Irrigation",
+ "enum": [
+ "valve"
+ ]
}
]
},
@@ -158,7 +156,7 @@
"type": "string",
"title": "Device Setup",
"default": "null",
- "description": "The device setup. Blinds must be set up with two switches. Please ignore this setting for locks.",
+ "description": "The device setup. Blinds must be set up with two switches. Please ignore this setting for locks and irrigation.",
"oneOf": [
{
"title": "One Switch - for up and down",
@@ -176,8 +174,8 @@
},
"operationTime": {
"type": "integer",
- "title": "Operation Time",
- "description": "For blinds and garage doors this is the total time in deciseconds to fully open/close the device. For locks this is the time to show the Home app tile as unlocked. Count the time in seconds and multiply by 10, for example 100 for 10 seconds or 75 for 7.5 seconds.",
+ "title": "Operation Time (Deciseconds)",
+ "description": "Blinds/garage doors: the time to fully open/close the device. Locks: the time to show as unlocked. Irrigation: the time the valves will open for. This setting is in deciseconds - count the time in seconds and multiply by 10, for example 100 for 10 seconds or 75 for 7.5 seconds.",
"default": 100,
"minimum": 10,
"maximum": 600
diff --git a/lib/constants.js b/lib/constants.js
index 1ec671bc..72090079 100644
--- a/lib/constants.js
+++ b/lib/constants.js
@@ -2,6 +2,7 @@
module.exports = {
appId: 'oeVkj2lYFGnJu5XUtWisfW4utiN4u9Mq',
appSecret: '6Nz4n0xA8s8qdxQf2GqurZj2Fs55FUvM',
+ allowedGroups: ['blind', 'garage', 'lock', 'valve'],
devicesHideable: ['switch', 'light'],
devicesNonLAN: [22, 28, 59, 102],
devicesSingleSwitch: [1, 5, 6, 14, 15, 22, 24, 27, 32, 36, 44, 59],
@@ -38,7 +39,6 @@ module.exports = {
devicesValveParams: ['switches'],
devicesGarageParams: ['switch', 'switches'],
devicesLockParams: ['switch'],
- allowedGroups: ['blind', 'garage', 'lock'],
paramsToKeep: ['battery', 'bright', 'brightness', 'channel', 'cmd', 'colorB', 'colorG', 'colorR', 'current', 'currentHumidity', 'currentTemperature', 'fan', 'humidity', 'key', 'light', 'lock', 'mainSwitch', 'mode', 'motion', 'online', 'power', 'rfChl', 'rfList', 'rfTrig', 'sensorType', 'setclose', 'speed', 'state', 'switch', 'switches', 'temperature', 'trigTime', 'type', 'voltage', 'zyx_mode'],
defaultMultiSwitchOff: [{
switch: 'off',
diff --git a/lib/device/valve.js b/lib/device/valve.js
index 121f139e..84129895 100644
--- a/lib/device/valve.js
+++ b/lib/device/valve.js
@@ -9,7 +9,14 @@ module.exports = class deviceValve {
async internalValveUpdate (accessory, valve, value, callback) {
callback()
try {
+ let valveConfig
const params = {}
+ if (!(valveConfig = this.platform.cusG.get(accessory.context.hbDeviceId))) {
+ throw new Error('group config missing')
+ }
+ if (valveConfig.type !== 'valve') {
+ throw new Error('improper configuration')
+ }
const serviceValve = accessory.getService(valve)
params.switches = this.platform.devicesInEW.get(accessory.context.eweDeviceId).params.switches
switch (valve) {
@@ -49,6 +56,13 @@ module.exports = class deviceValve {
externalValveUpdate (accessory, params) {
try {
+ let valveConfig
+ if (!(valveConfig = this.platform.cusG.get(accessory.context.hbDeviceId))) {
+ throw new Error('group config missing')
+ }
+ if (valveConfig.type !== 'valve') {
+ throw new Error('improper configuration')
+ }
['A', 'B'].forEach((v, k) => {
const valveService = accessory.getService('Valve ' + v)
valveService
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 7ea7569b..30a78aed 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -28,7 +28,7 @@ class eWeLink {
constructor (log, config, api) {
if (!log || !api || !config) return
if (!config.username || !config.password || !config.countryCode) {
- log.error('*********** Cannot load homebridge-ewelink ***********')
+ log.error('*********** Cannot load homebridge-ewelink ************')
log.error('eWeLink credentials missing from the Homebridge config.')
log.error('*******************************************************')
return
@@ -183,7 +183,7 @@ class eWeLink {
accessory = this.devicesInHB.has(device.deviceid + 'SWX')
? this.devicesInHB.get(device.deviceid + 'SWX')
: this.addAccessory(device, device.deviceid + 'SWX', 'sensor')
- } else if (device.extra.uiid === 2 && device.brandName === 'coolkit' && device.productModel === '0285') {
+ } else if (this.cusG.has(device.deviceid + 'SWX') && this.cusG.get(device.deviceid + 'SWX').type === 'valve') {
accessory = this.devicesInHB.has(device.deviceid + 'SWX')
? this.devicesInHB.get(device.deviceid + 'SWX')
: this.addAccessory(device, device.deviceid + 'SWX', 'valve')
@@ -538,6 +538,7 @@ class eWeLink {
}
case 'valve': {
accessory.control = new DeviceValve(this);
+ let valveConfig = this.platform.cusG.get(accessory.context.hbDeviceId)
['A', 'B'].forEach(v => {
let valveService
if (!(valveService = accessory.getService('Valve ' + v))) {
@@ -546,7 +547,7 @@ class eWeLink {
.setCharacteristic(Characteristic.Active, 0)
.setCharacteristic(Characteristic.InUse, 0)
.setCharacteristic(Characteristic.ValveType, 1)
- .setCharacteristic(Characteristic.SetDuration, this.config.valveTimeLength || 120)
+ .setCharacteristic(Characteristic.SetDuration, Math.round(valveConfig.operationTime / 10) || 120)
.addCharacteristic(Characteristic.RemainingDuration)
valveService = accessory.getService('Valve ' + v)
}
From af7271c7785e6cb278d8c0c9ceb5a99bbf18072c Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 27 Sep 2020 10:18:02 +0100
Subject: [PATCH 0237/3183] irrigation valve bug
---
lib/device/valve.js | 3 ++-
lib/eWeLink.js | 17 +++++++++--------
2 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/lib/device/valve.js b/lib/device/valve.js
index 84129895..9feff0c4 100644
--- a/lib/device/valve.js
+++ b/lib/device/valve.js
@@ -63,7 +63,8 @@ module.exports = class deviceValve {
if (valveConfig.type !== 'valve') {
throw new Error('improper configuration')
}
- ['A', 'B'].forEach((v, k) => {
+ const arr = ['A', 'B']
+ arr.forEach((v, k) => {
const valveService = accessory.getService('Valve ' + v)
valveService
.updateCharacteristic(Characteristic.Active, params.switches[k].switch === 'on')
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 30a78aed..8281a2d7 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -179,14 +179,14 @@ class eWeLink {
accessory = this.devicesInHB.has(device.deviceid + 'SWX')
? this.devicesInHB.get(device.deviceid + 'SWX')
: this.addAccessory(device, device.deviceid + 'SWX', 'lock')
- } else if (cns.devicesSensor.includes(device.extra.uiid)) {
- accessory = this.devicesInHB.has(device.deviceid + 'SWX')
- ? this.devicesInHB.get(device.deviceid + 'SWX')
- : this.addAccessory(device, device.deviceid + 'SWX', 'sensor')
} else if (this.cusG.has(device.deviceid + 'SWX') && this.cusG.get(device.deviceid + 'SWX').type === 'valve') {
accessory = this.devicesInHB.has(device.deviceid + 'SWX')
? this.devicesInHB.get(device.deviceid + 'SWX')
: this.addAccessory(device, device.deviceid + 'SWX', 'valve')
+ } else if (cns.devicesSensor.includes(device.extra.uiid)) {
+ accessory = this.devicesInHB.has(device.deviceid + 'SWX')
+ ? this.devicesInHB.get(device.deviceid + 'SWX')
+ : this.addAccessory(device, device.deviceid + 'SWX', 'sensor')
} else if (cns.devicesFan.includes(device.extra.uiid)) {
accessory = this.devicesInHB.has(device.deviceid + 'SWX')
? this.devicesInHB.get(device.deviceid + 'SWX')
@@ -537,9 +537,10 @@ class eWeLink {
break
}
case 'valve': {
- accessory.control = new DeviceValve(this);
- let valveConfig = this.platform.cusG.get(accessory.context.hbDeviceId)
- ['A', 'B'].forEach(v => {
+ accessory.control = new DeviceValve(this)
+ const valveConfig = this.cusG.get(accessory.context.hbDeviceId)
+ const arr = ['A', 'B']
+ arr.forEach(v => {
let valveService
if (!(valveService = accessory.getService('Valve ' + v))) {
accessory
@@ -872,7 +873,7 @@ class eWeLink {
}
this.devicesInHB.set(accessory.context.hbDeviceId, accessory)
} catch (err) {
- this.log.warn('[%s] could not be refreshed as %s.', accessory.displayName, err)
+ this.log.warn('[%s] could not be configured as %s.', accessory.displayName, err)
}
}
From dfcfb64257ebb21c973b0f65b2e4c8ac4337f2d8 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 27 Sep 2020 10:41:27 +0100
Subject: [PATCH 0238/3183] 3.1.0
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index d667effe..2dcb3e8d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.0.3-4",
+ "version": "3.1.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index c27caff6..1554d21e 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.0.3-4",
+ "version": "3.1.0",
"author": "bwp91",
"contributors": [
"gbro115",
From 12066e1ca040b36cfee424be2c787076cf3578e9 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 27 Sep 2020 12:18:13 +0100
Subject: [PATCH 0239/3183] Update eWeLink.js
---
lib/eWeLink.js | 97 +++++++++++++++++++++++++++++++++-----------------
1 file changed, 65 insertions(+), 32 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 8281a2d7..4e1fbdbf 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -90,7 +90,7 @@ class eWeLink {
this.removeAccessory(a)
}
})
- //* ** Synchronise devices between eWeLink and Homebridge and set up ws/lan listeners ***\\
+ //* ** Synchronise devices between eWeLink and Homebridge and set up WS/LAN listeners ***\\
this.devicesInEW.forEach(d => this.initialiseDevice(d))
this.wsClient.receiveUpdate(d => this.receiveDeviceUpdate(d))
this.lanClient.receiveUpdate(d => this.receiveDeviceUpdate(d))
@@ -596,8 +596,7 @@ class eWeLink {
}
case 'thermostat': {
accessory.control = new DeviceThermostat(this)
- const tempService =
- accessory.getService(Service.TemperatureSensor) || accessory.addService(Service.TemperatureSensor)
+ const tempService = accessory.getService(Service.TemperatureSensor) || accessory.addService(Service.TemperatureSensor)
let humiService = false
if (accessory.context.sensorType !== 'DS18B20') {
humiService = accessory.getService(Service.HumiditySensor) || accessory.addService(Service.HumiditySensor)
@@ -698,13 +697,15 @@ class eWeLink {
power: currentWatt
})
}, 300000)
- outletService.getCharacteristic(EveService.Characteristics.TotalConsumption).on('get', callback => {
- accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData()
- if (accessory.context.extraPersistedData !== undefined) {
- accessory.context.totalEnergy = accessory.context.extraPersistedData.totalPower
- }
- callback(null, accessory.context.totalEnergy)
- })
+ outletService
+ .getCharacteristic(EveService.Characteristics.TotalConsumption)
+ .on('get', callback => {
+ accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData()
+ if (accessory.context.extraPersistedData !== undefined) {
+ accessory.context.totalEnergy = accessory.context.extraPersistedData.totalPower
+ }
+ callback(null, accessory.context.totalEnergy)
+ })
outletService
.getCharacteristic(EveService.Characteristics.ResetTotal)
.on('set', (value, callback) => {
@@ -880,12 +881,16 @@ class eWeLink {
refreshAccessory (accessory, newParams) {
switch (accessory.context.type) {
case 'valve':
- if (Object.keys(newParams).some(v => cns.devicesValveParams.includes(v)) && Array.isArray(newParams.switches)) {
+ if (Object.keys(newParams).some(v => {
+ cns.devicesValveParams.includes(v)
+ }) && Array.isArray(newParams.switches)) {
accessory.control.externalValveUpdate(accessory, newParams)
}
return true
case 'curtain':
- if (Object.keys(newParams).some(v => cns.devicesCurtainParams.includes(v))) {
+ if (Object.keys(newParams).some(v => {
+ cns.devicesCurtainParams.includes(v)
+ })) {
accessory.control.externalCurtainUpdate(accessory, newParams)
}
return true
@@ -893,62 +898,82 @@ class eWeLink {
return true
case 'garage':
if (
- Object.keys(newParams).some(v => cns.devicesGarageParams.includes(v)) &&
- Array.isArray(newParams.switches)
+ Object.keys(newParams).some(v => {
+ cns.devicesGarageParams.includes(v)
+ }) &&
+ Array.isArray(newParams.switches)
) {
accessory.control.externalGarageUpdate(accessory, newParams)
}
return true
case 'lock':
- if (Object.keys(newParams).some(v => cns.devicesLockParams.includes(v))) {
+ if (Object.keys(newParams).some(v => {
+ cns.devicesLockParams.includes(v)
+ })) {
accessory.control.externalLockUpdate(accessory, newParams)
}
return true
case 'sensor':
- if (Object.keys(newParams).some(v => cns.devicesSensorParams.includes(v))) {
+ if (Object.keys(newParams).some(v => {
+ cns.devicesSensorParams.includes(v)
+ })) {
accessory.control.externalSensorUpdate(accessory, newParams)
}
return true
case 'fan':
- if (Object.keys(newParams).some(v => cns.devicesFanParams.includes(v))) {
+ if (Object.keys(newParams).some(v => {
+ cns.devicesFanParams.includes(v)
+ })) {
accessory.control.externalFanUpdate(accessory, newParams)
}
return true
case 'thermostat':
- if (Object.keys(newParams).some(v => cns.devicesThermostatParams.includes(v))) {
+ if (Object.keys(newParams).some(v => {
+ cns.devicesThermostatParams.includes(v)
+ })) {
accessory.control.externalThermostatUpdate(accessory, newParams)
}
return true
case 'outlet':
- if (Object.keys(newParams).some(v => cns.devicesOutletParams.includes(v))) {
+ if (Object.keys(newParams).some(v => {
+ cns.devicesOutletParams.includes(v)
+ })) {
accessory.control.externalOutletUpdate(accessory, newParams)
}
return true
case 'usb':
- if (Object.keys(newParams).some(v => cns.devicesUSBParams.includes(v)) && Array.isArray(newParams.switches)) {
+ if (Object.keys(newParams).some(v => {
+ cns.devicesUSBParams.includes(v)
+ }) && Array.isArray(newParams.switches)) {
accessory.control.externalUSBUpdate(accessory, newParams)
}
return true
case 'scm':
- if (Object.keys(newParams).some(v => cns.devicesSCMParams.includes(v)) && Array.isArray(newParams.switches)) {
+ if (Object.keys(newParams).some(v => {
+ cns.devicesSCMParams.includes(v)
+ }) && Array.isArray(newParams.switches)) {
accessory.control.externalSCMUpdate(accessory, newParams)
}
return true
case 'light':
if (
cns.devicesSingleSwitch.includes(accessory.context.eweUIID) &&
- cns.devicesSingleSwitchLight.includes(accessory.context.eweModel)
+ cns.devicesSingleSwitchLight.includes(accessory.context.eweModel)
) {
- if (Object.keys(newParams).some(v => cns.devicesSingleSwitchLightParams.includes(v))) {
+ if (Object.keys(newParams).some(v => {
+ cns.devicesSingleSwitchLightParams.includes(v)
+ })) {
accessory.control.externalSingleLightUpdate(accessory, newParams)
}
} else if (
cns.devicesMultiSwitch.includes(accessory.context.eweUIID) &&
- cns.devicesMultiSwitchLight.includes(accessory.context.eweModel)
+ cns.devicesMultiSwitchLight.includes(accessory.context.eweModel)
) {
if (
- Object.keys(newParams).some(v => cns.devicesMultiSwitchLightParams.includes(v)) &&
- Array.isArray(newParams.switches)
+ Object.keys(newParams).some(v => {
+ cns.devicesMultiSwitchLightParams.includes(v)
+ }) &&
+ Array.isArray(newParams.switches)
) {
accessory.control.externalMultiLightUpdate(accessory, newParams)
}
@@ -956,27 +981,35 @@ class eWeLink {
return true
case 'switch':
if (cns.devicesSingleSwitch.includes(accessory.context.eweUIID)) {
- if (Object.keys(newParams).some(v => cns.devicesSingleSwitchParams.includes(v))) {
+ if (Object.keys(newParams).some(v => {
+ cns.devicesSingleSwitchParams.includes(v)
+ })) {
accessory.control.externalSingleSwitchUpdate(accessory, newParams)
}
} else if (cns.devicesMultiSwitch.includes(accessory.context.eweUIID)) {
if (
- Object.keys(newParams).some(v => cns.devicesMultiSwitchParams.includes(v)) &&
- Array.isArray(newParams.switches)
+ Object.keys(newParams).some(v => {
+ cns.devicesMultiSwitchParams.includes(v)
+ }) &&
+ Array.isArray(newParams.switches)
) {
accessory.control.externalMultiSwitchUpdate(accessory, newParams)
}
}
return true
case 'rf_pri':
- if (Object.keys(newParams).some(v => cns.devicesRFBridgeParams.includes(v))) {
+ if (Object.keys(newParams).some(v => {
+ cns.devicesRFBridgeParams.includes(v)
+ })) {
accessory.control.externalRFUpdate(accessory, newParams)
}
return true
case 'rf_sub':
return true
case 'zb_dev':
- if (Object.keys(newParams).some(v => cns.devicesZBBridgeParams.includes(v))) {
+ if (Object.keys(newParams).some(v => {
+ cns.devicesZBBridgeParams.includes(v)
+ })) {
accessory.control.externalZBUpdate(accessory, newParams)
}
return true
@@ -1017,7 +1050,7 @@ class eWeLink {
throw new Error(err)
}
} else {
- throw new Error("it is unreachable. I's status will be corrected once it is reachable")
+ throw new Error("it is unreachable. It's status will be corrected once it is reachable")
}
}
}
From febc689ac8b34b6a390db38a98b258bf16fd87e3 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 27 Sep 2020 12:22:10 +0100
Subject: [PATCH 0240/3183] Update eWeLink.js
---
lib/eWeLink.js | 13 +++++--------
1 file changed, 5 insertions(+), 8 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 4e1fbdbf..b4f5e8a8 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -900,8 +900,7 @@ class eWeLink {
if (
Object.keys(newParams).some(v => {
cns.devicesGarageParams.includes(v)
- }) &&
- Array.isArray(newParams.switches)
+ }) && Array.isArray(newParams.switches)
) {
accessory.control.externalGarageUpdate(accessory, newParams)
}
@@ -958,7 +957,7 @@ class eWeLink {
case 'light':
if (
cns.devicesSingleSwitch.includes(accessory.context.eweUIID) &&
- cns.devicesSingleSwitchLight.includes(accessory.context.eweModel)
+ cns.devicesSingleSwitchLight.includes(accessory.context.eweModel)
) {
if (Object.keys(newParams).some(v => {
cns.devicesSingleSwitchLightParams.includes(v)
@@ -967,13 +966,12 @@ class eWeLink {
}
} else if (
cns.devicesMultiSwitch.includes(accessory.context.eweUIID) &&
- cns.devicesMultiSwitchLight.includes(accessory.context.eweModel)
+ cns.devicesMultiSwitchLight.includes(accessory.context.eweModel)
) {
if (
Object.keys(newParams).some(v => {
cns.devicesMultiSwitchLightParams.includes(v)
- }) &&
- Array.isArray(newParams.switches)
+ }) && Array.isArray(newParams.switches)
) {
accessory.control.externalMultiLightUpdate(accessory, newParams)
}
@@ -990,8 +988,7 @@ class eWeLink {
if (
Object.keys(newParams).some(v => {
cns.devicesMultiSwitchParams.includes(v)
- }) &&
- Array.isArray(newParams.switches)
+ }) && Array.isArray(newParams.switches)
) {
accessory.control.externalMultiSwitchUpdate(accessory, newParams)
}
From 575fcd7c36cc25ca746aa78bf8b0bbdfe8885c9e Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 27 Sep 2020 12:23:33 +0100
Subject: [PATCH 0241/3183] 3.1.1-0
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 2dcb3e8d..1152196f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.1.0",
+ "version": "3.1.1-0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 1554d21e..7e30e8f7 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.1.0",
+ "version": "3.1.1-0",
"author": "bwp91",
"contributors": [
"gbro115",
From 6034b461a24d43950a086cb7854c7c796a320fea Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 27 Sep 2020 15:43:09 +0100
Subject: [PATCH 0242/3183] catch lan stop error
---
lib/eWeLinkLAN.js | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/lib/eWeLinkLAN.js b/lib/eWeLinkLAN.js
index a14d8cda..d0982e59 100644
--- a/lib/eWeLinkLAN.js
+++ b/lib/eWeLinkLAN.js
@@ -180,7 +180,9 @@ module.exports = class eWeLinkLAN {
}
closeConnection () {
- dns.stopMonitoring()
+ dns.stopMonitoring().catch(err) => {
+ if (this.debug) this.log.warn(err);
+ })
this.log('LAN monitoring gracefully stopped.')
}
}
From 33bbc5dc34b6b8878f96c1cff90a6bc874c76d05 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 27 Sep 2020 15:44:55 +0100
Subject: [PATCH 0243/3183] 3.1.1
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 1152196f..e5221ca0 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.1.1-0",
+ "version": "3.1.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 7e30e8f7..3b696966 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.1.1-0",
+ "version": "3.1.1",
"author": "bwp91",
"contributors": [
"gbro115",
From f4f2330e8a338ad47cdaa43a614701db7f35938b Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 27 Sep 2020 15:53:03 +0100
Subject: [PATCH 0244/3183] Update eWeLinkLAN.js
---
lib/eWeLinkLAN.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/eWeLinkLAN.js b/lib/eWeLinkLAN.js
index d0982e59..f2f49e1f 100644
--- a/lib/eWeLinkLAN.js
+++ b/lib/eWeLinkLAN.js
@@ -180,7 +180,7 @@ module.exports = class eWeLinkLAN {
}
closeConnection () {
- dns.stopMonitoring().catch(err) => {
+ dns.stopMonitoring().catch(err => {
if (this.debug) this.log.warn(err);
})
this.log('LAN monitoring gracefully stopped.')
From c9e1f5aa77f8642c79c4ad3e779887bae801dc70 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 27 Sep 2020 15:53:38 +0100
Subject: [PATCH 0245/3183] 3.1.2
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index e5221ca0..0b9fccd4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.1.1",
+ "version": "3.1.2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 3b696966..f7d967f0 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.1.1",
+ "version": "3.1.2",
"author": "bwp91",
"contributors": [
"gbro115",
From 2962a8f8f4731f10e6c8d7c445171358213066f7 Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Sun, 27 Sep 2020 16:42:44 +0100
Subject: [PATCH 0246/3183] Update README.md
---
README.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/README.md b/README.md
index d8a98c3f..1c683be2 100644
--- a/README.md
+++ b/README.md
@@ -35,3 +35,5 @@
* [Support Request](https://github.com/bwp91/homebridge-ewelink/issues/new/choose)
* [Roadmap](https://github.com/bwp91/homebridge-ewelink/wiki/Roadmap)
* [Credits](https://github.com/bwp91/homebridge-ewelink/wiki/Credits)
+### Disclaimer
+I am in no way affiliated with eWeLink nor any of the device brands (like Sonoff) and this plugin is a personal project that I maintain in my free time.
From 3c4e603b0785f9f5fb5d77ace0a396d919422f66 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 27 Sep 2020 21:46:02 +0100
Subject: [PATCH 0247/3183] random fixes
---
lib/device/thermostat.js | 40 +++++++-------
lib/eWeLink.js | 111 +++++++--------------------------------
lib/eWeLinkHTTP.js | 8 +--
lib/eWeLinkLAN.js | 16 +++---
lib/eWeLinkWS.js | 4 +-
5 files changed, 56 insertions(+), 123 deletions(-)
diff --git a/lib/device/thermostat.js b/lib/device/thermostat.js
index fe076368..a5d5f2b0 100644
--- a/lib/device/thermostat.js
+++ b/lib/device/thermostat.js
@@ -1,8 +1,10 @@
'use strict'
let Characteristic, Service
module.exports = class deviceThermostat {
- constructor (platform, homebridge) {
+ constructor (platform) {
this.platform = platform
+ Service = platform.api.hap.Service
+ Characteristic = platform.api.hap.Characteristic
}
async internalThermostatUpdate (accessory, value, callback) {
@@ -30,24 +32,24 @@ module.exports = class deviceThermostat {
const switchService = accessory.getService(Service.Switch)
switchService.updateCharacteristic(Characteristic.On, newState)
}
- if (!(this.platform.config.disableEveLogging || false)) {
- const eveLog = {
- time: Date.now()
- }
- if (Object.prototype.hasOwnProperty.call(params, 'currentTemperature') && accessory.getService(Service.TemperatureSensor)) {
- const currentTemp = params.currentTemperature !== 'unavailable' ? params.currentTemperature : 0
- accessory
- .getService(Service.TemperatureSensor)
- .updateCharacteristic(Characteristic.CurrentTemperature, currentTemp)
- eveLog.temp = parseFloat(currentTemp)
- }
- if (Object.prototype.hasOwnProperty.call(params, 'currentHumidity') && accessory.getService(Service.HumiditySensor)) {
- const currentHumi = params.currentHumidity !== 'unavailable' ? params.currentHumidity : 0
- accessory
- .getService(Service.HumiditySensor)
- .updateCharacteristic(Characteristic.CurrentRelativeHumidity, currentHumi)
- eveLog.humidity = parseFloat(currentHumi)
- }
+ const eveLog = {
+ time: Date.now()
+ }
+ if (Object.prototype.hasOwnProperty.call(params, 'currentTemperature') && accessory.getService(Service.TemperatureSensor)) {
+ const currentTemp = parseFloat(params.currentTemperature !== 'unavailable' ? params.currentTemperature : 0)
+ accessory
+ .getService(Service.TemperatureSensor)
+ .updateCharacteristic(Characteristic.CurrentTemperature, currentTemp)
+ eveLog.temp = currentTemp
+ }
+ if (Object.prototype.hasOwnProperty.call(params, 'currentHumidity') && accessory.getService(Service.HumiditySensor)) {
+ const currentHumi = parseFloat(params.currentHumidity !== 'unavailable' ? params.currentHumidity : 0)
+ accessory
+ .getService(Service.HumiditySensor)
+ .updateCharacteristic(Characteristic.CurrentRelativeHumidity, currentHumi)
+ eveLog.humidity = currentHumi
+ }
+ if (!this.platform.config.disableEveLogging) {
if (Object.prototype.hasOwnProperty.call(eveLog, 'temp') || Object.prototype.hasOwnProperty.call(eveLog, 'humidity')) {
accessory.eveLogger.addEntry(eveLog)
}
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index b4f5e8a8..fa08826e 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -311,7 +311,7 @@ class eWeLink {
: this.addAccessory(device, device.deviceid + 'SW0', 'rf_pri', true, {
rfMap
})
- this.log.error(JSON.stringify(accessory.context, null, 2))
+ // this.log.error(JSON.stringify(accessory.context, null, 2))
rfMap.forEach(subDevice => {
const swNumber = rfChlCounter + 1
let subAccessory
@@ -351,7 +351,7 @@ class eWeLink {
subAccessory.context.reachableWAN = device.online
subAccessory.context.reachableLAN = false
this.devicesInHB.set(subAccessory.context.hbDeviceId, subAccessory)
- this.log.warn(JSON.stringify(subAccessory.context, null, 2))
+ // this.log.warn(JSON.stringify(subAccessory.context, null, 2))
rfChlCounter += Object.keys(subDevice.buttons || {}).length
})
accessory.context.channelCount = rfChlCounter
@@ -410,7 +410,7 @@ class eWeLink {
}
this.log(' â [%s] initialised %s.', device.name, str)
this.devicesInHB.set(accessory.context.hbDeviceId, accessory)
- if (!(this.config.disableHTTPRefresh || false)) {
+ if (!this.config.disableHTTPRefresh && !(accessory.context.switchNumber === '0' && this.hiddenMasters.includes(device.deviceid))) {
if (!this.refreshAccessory(accessory, device.params)) {
this.log.warn(
'[%s] could not be initialised. Please try removing accessory from the Homebridge cache along with any secondary devices (SW1, SW2, etc.) [debug:%s:%s].',
@@ -881,134 +881,64 @@ class eWeLink {
refreshAccessory (accessory, newParams) {
switch (accessory.context.type) {
case 'valve':
- if (Object.keys(newParams).some(v => {
- cns.devicesValveParams.includes(v)
- }) && Array.isArray(newParams.switches)) {
- accessory.control.externalValveUpdate(accessory, newParams)
- }
+ accessory.control.externalValveUpdate(accessory, newParams)
return true
case 'curtain':
- if (Object.keys(newParams).some(v => {
- cns.devicesCurtainParams.includes(v)
- })) {
- accessory.control.externalCurtainUpdate(accessory, newParams)
- }
+ accessory.control.externalCurtainUpdate(accessory, newParams)
return true
case 'blind':
return true
case 'garage':
- if (
- Object.keys(newParams).some(v => {
- cns.devicesGarageParams.includes(v)
- }) && Array.isArray(newParams.switches)
- ) {
- accessory.control.externalGarageUpdate(accessory, newParams)
- }
+ accessory.control.externalGarageUpdate(accessory, newParams)
return true
case 'lock':
- if (Object.keys(newParams).some(v => {
- cns.devicesLockParams.includes(v)
- })) {
- accessory.control.externalLockUpdate(accessory, newParams)
- }
+ accessory.control.externalLockUpdate(accessory, newParams)
return true
case 'sensor':
- if (Object.keys(newParams).some(v => {
- cns.devicesSensorParams.includes(v)
- })) {
- accessory.control.externalSensorUpdate(accessory, newParams)
- }
+ accessory.control.externalSensorUpdate(accessory, newParams)
return true
case 'fan':
- if (Object.keys(newParams).some(v => {
- cns.devicesFanParams.includes(v)
- })) {
- accessory.control.externalFanUpdate(accessory, newParams)
- }
+ accessory.control.externalFanUpdate(accessory, newParams)
return true
case 'thermostat':
- if (Object.keys(newParams).some(v => {
- cns.devicesThermostatParams.includes(v)
- })) {
- accessory.control.externalThermostatUpdate(accessory, newParams)
- }
+ accessory.control.externalThermostatUpdate(accessory, newParams)
return true
case 'outlet':
- if (Object.keys(newParams).some(v => {
- cns.devicesOutletParams.includes(v)
- })) {
- accessory.control.externalOutletUpdate(accessory, newParams)
- }
+ accessory.control.externalOutletUpdate(accessory, newParams)
return true
case 'usb':
- if (Object.keys(newParams).some(v => {
- cns.devicesUSBParams.includes(v)
- }) && Array.isArray(newParams.switches)) {
- accessory.control.externalUSBUpdate(accessory, newParams)
- }
+ accessory.control.externalUSBUpdate(accessory, newParams)
return true
case 'scm':
- if (Object.keys(newParams).some(v => {
- cns.devicesSCMParams.includes(v)
- }) && Array.isArray(newParams.switches)) {
- accessory.control.externalSCMUpdate(accessory, newParams)
- }
+ accessory.control.externalSCMUpdate(accessory, newParams)
return true
case 'light':
if (
cns.devicesSingleSwitch.includes(accessory.context.eweUIID) &&
cns.devicesSingleSwitchLight.includes(accessory.context.eweModel)
) {
- if (Object.keys(newParams).some(v => {
- cns.devicesSingleSwitchLightParams.includes(v)
- })) {
- accessory.control.externalSingleLightUpdate(accessory, newParams)
- }
+ accessory.control.externalSingleLightUpdate(accessory, newParams)
} else if (
cns.devicesMultiSwitch.includes(accessory.context.eweUIID) &&
cns.devicesMultiSwitchLight.includes(accessory.context.eweModel)
) {
- if (
- Object.keys(newParams).some(v => {
- cns.devicesMultiSwitchLightParams.includes(v)
- }) && Array.isArray(newParams.switches)
- ) {
- accessory.control.externalMultiLightUpdate(accessory, newParams)
- }
+ accessory.control.externalMultiLightUpdate(accessory, newParams)
}
return true
case 'switch':
if (cns.devicesSingleSwitch.includes(accessory.context.eweUIID)) {
- if (Object.keys(newParams).some(v => {
- cns.devicesSingleSwitchParams.includes(v)
- })) {
- accessory.control.externalSingleSwitchUpdate(accessory, newParams)
- }
+ accessory.control.externalSingleSwitchUpdate(accessory, newParams)
} else if (cns.devicesMultiSwitch.includes(accessory.context.eweUIID)) {
- if (
- Object.keys(newParams).some(v => {
- cns.devicesMultiSwitchParams.includes(v)
- }) && Array.isArray(newParams.switches)
- ) {
- accessory.control.externalMultiSwitchUpdate(accessory, newParams)
- }
+ accessory.control.externalMultiSwitchUpdate(accessory, newParams)
}
return true
case 'rf_pri':
- if (Object.keys(newParams).some(v => {
- cns.devicesRFBridgeParams.includes(v)
- })) {
- accessory.control.externalRFUpdate(accessory, newParams)
- }
+ accessory.control.externalRFUpdate(accessory, newParams)
return true
case 'rf_sub':
return true
case 'zb_dev':
- if (Object.keys(newParams).some(v => {
- cns.devicesZBBridgeParams.includes(v)
- })) {
- accessory.control.externalZBUpdate(accessory, newParams)
- }
+ accessory.control.externalZBUpdate(accessory, newParams)
return true
default:
return false
@@ -1034,11 +964,10 @@ class eWeLink {
try {
await utils.sleep(Math.random() * 100 + 200)
await this.lanClient.sendUpdate(payload)
- return
} catch (err) {
if (accessory.context.reachableWAN) {
if (this.debug) {
- this.log.warn('[%s] Reverting to web socket as %s.', accessory.displayName, err)
+ this.log.warn('[%s] Reverting to web socket as %s.', accessory.displayName, err.message)
}
try {
await this.wsClient.sendUpdate(payload)
diff --git a/lib/eWeLinkHTTP.js b/lib/eWeLinkHTTP.js
index 61572545..292de844 100644
--- a/lib/eWeLinkHTTP.js
+++ b/lib/eWeLinkHTTP.js
@@ -85,7 +85,7 @@ module.exports = class eWeLinkHTTP {
await utils.sleep(30000)
return this.getHost()
} else {
- throw new Error(err.message || err)
+ throw err
}
}
}
@@ -171,7 +171,7 @@ module.exports = class eWeLinkHTTP {
}
}
} catch (err) {
- throw new Error(err.message || err)
+ throw err
}
}
@@ -216,7 +216,7 @@ module.exports = class eWeLinkHTTP {
await utils.sleep(30000)
return this.getDevices()
} else {
- throw new Error(err.message || err)
+ throw err
}
}
}
@@ -260,7 +260,7 @@ module.exports = class eWeLinkHTTP {
await utils.sleep(30000)
return this.getDevice(deviceId)
} else {
- throw new Error(err.message || err)
+ throw err
}
}
}
diff --git a/lib/eWeLinkLAN.js b/lib/eWeLinkLAN.js
index f2f49e1f..5a121315 100644
--- a/lib/eWeLinkLAN.js
+++ b/lib/eWeLinkLAN.js
@@ -42,7 +42,7 @@ module.exports = class eWeLinkLAN {
})
return this.deviceMap
} catch (err) {
- throw new Error(err)
+ throw err
}
}
@@ -163,7 +163,7 @@ module.exports = class eWeLinkLAN {
}
}
} catch (err) {
- throw new Error(err)
+ throw err
}
}
@@ -179,10 +179,12 @@ module.exports = class eWeLinkLAN {
})
}
- closeConnection () {
- dns.stopMonitoring().catch(err => {
- if (this.debug) this.log.warn(err);
- })
- this.log('LAN monitoring gracefully stopped.')
+ async closeConnection () {
+ try {
+ await dns.stopMonitoring()
+ this.log('LAN monitoring gracefully stopped.')
+ } catch (err) {
+ throw err
+ }
}
}
diff --git a/lib/eWeLinkWS.js b/lib/eWeLinkWS.js
index 647eb091..9478517b 100644
--- a/lib/eWeLinkWS.js
+++ b/lib/eWeLinkWS.js
@@ -54,7 +54,7 @@ module.exports = class eWeLinkWS {
await utils.sleep(30000)
return this.getDevices()
} else {
- throw new Error(err.message || err)
+ throw err
}
}
}
@@ -310,7 +310,7 @@ module.exports = class eWeLinkWS {
this.log('Web socket gracefully closed.')
return
} catch (err) {
- throw new Error(err)
+ throw err
}
}
}
From 66909899291bc842a6b66e1b112f78ad3e63b225 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 27 Sep 2020 21:46:42 +0100
Subject: [PATCH 0248/3183] 3.1.3-0
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 0b9fccd4..95960a98 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.1.2",
+ "version": "3.1.3-0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index f7d967f0..0b048b64 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.1.2",
+ "version": "3.1.3-0",
"author": "bwp91",
"contributors": [
"gbro115",
From c0173c8edf0575114268c9cda9b8c2ad0aa7b2a0 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 27 Sep 2020 22:09:22 +0100
Subject: [PATCH 0249/3183] Update eWeLink.js
---
lib/eWeLink.js | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index fa08826e..1e818b4e 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -201,6 +201,11 @@ class eWeLink {
if (!Object.prototype.hasOwnProperty.call(accessory.context, 'sensorType')) {
accessory.context.sensorType = device.params.sensorType
}
+ if (accessory.context.sensorType === 'DS18B20') {
+ if (accessory.getService(Service.HumiditySensor)) {
+ accessory.removeService(Service.HumiditySensor)
+ }
+ }
//* ** @ENDUPGRADE ***\\
if (accessory.context.sensorType !== device.params.sensorType) {
accessory.context.sensorType = device.params.sensorType
@@ -600,10 +605,6 @@ class eWeLink {
let humiService = false
if (accessory.context.sensorType !== 'DS18B20') {
humiService = accessory.getService(Service.HumiditySensor) || accessory.addService(Service.HumiditySensor)
- } else {
- if (accessory.getService(Service.HumiditySensor)) {
- accessory.removeService(Service.HumiditySensor)
- }
}
if (!this.config.hideTHSwitch) {
const switchService = accessory.getService(Service.Switch) || accessory.addService(Service.Switch)
@@ -611,7 +612,7 @@ class eWeLink {
.getCharacteristic(Characteristic.On)
.on('set', (value, callback) => accessory.control.internalThermostatUpdate(accessory, value, callback))
}
- if (!(this.config.disableEveLogging || false)) {
+ if (!this.config.disableEveLogging) {
accessory.log = this.log
accessory.eveLogger = new EveHistoryService('weather', accessory, {
storage: 'fs',
From ab59289c483ab6a0c14042aba2bb9e9ce2195121 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 27 Sep 2020 22:10:07 +0100
Subject: [PATCH 0250/3183] 3.1.3-1
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 95960a98..b79c5a20 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.1.3-0",
+ "version": "3.1.3-1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 0b048b64..1700b110 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.1.3-0",
+ "version": "3.1.3-1",
"author": "bwp91",
"contributors": [
"gbro115",
From 48d97100d0d90c2d2ed3d108e320380c1dd4c7cf Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 27 Sep 2020 22:22:13 +0100
Subject: [PATCH 0251/3183] no-useless-catch
---
lib/eWeLinkHTTP.js | 140 ++++++++++++++++++++++-----------------------
lib/eWeLinkLAN.js | 140 ++++++++++++++++++++-------------------------
lib/eWeLinkWS.js | 9 +--
3 files changed, 133 insertions(+), 156 deletions(-)
diff --git a/lib/eWeLinkHTTP.js b/lib/eWeLinkHTTP.js
index 292de844..10df3508 100644
--- a/lib/eWeLinkHTTP.js
+++ b/lib/eWeLinkHTTP.js
@@ -95,83 +95,79 @@ module.exports = class eWeLinkHTTP {
countryCode: this.cCode,
password: this.password
}
- try {
- this.username.includes('@')
- ? (data.email = this.username)
- : (data.phoneNumber = this.username)
- if (this.debugReqRes) {
- const msg = JSON.stringify(data, null, 2)
- .replace(this.password, '**hidden**')
- .replace(this.username, '**hidden**')
- this.log.warn(
- 'Sending HTTP login request. This text is yellow for clarity.\n%s',
- msg
- )
- } else if (this.debug) {
- this.log('Sending HTTP login request.')
- }
- const dataToSign = crypto
- .createHmac('sha256', constants.appSecret)
- .update(JSON.stringify(data))
- .digest('base64')
- const res = await axios.post(
- 'https://' + this.httpHost + '/v2/user/login',
- data, {
- headers: {
- Authorization: 'Sign ' + dataToSign,
- 'Content-Type': 'application/json',
- Host: this.httpHost,
- 'X-CK-Appid': constants.appId,
- 'X-CK-Nonce': Math.random().toString(36).substr(2, 8)
- }
- }
+ this.username.includes('@')
+ ? (data.email = this.username)
+ : (data.phoneNumber = this.username)
+ if (this.debugReqRes) {
+ const msg = JSON.stringify(data, null, 2)
+ .replace(this.password, '**hidden**')
+ .replace(this.username, '**hidden**')
+ this.log.warn(
+ 'Sending HTTP login request. This text is yellow for clarity.\n%s',
+ msg
)
- const body = res.data
- if (
- Object.prototype.hasOwnProperty.call(body, 'error') &&
- body.error === 10004 &&
- Object.prototype.hasOwnProperty.call(body, 'data') &&
- Object.prototype.hasOwnProperty.call(body.data, 'region')
- ) {
- const givenRegion = body.data.region
- switch (givenRegion) {
- case 'eu':
- case 'us':
- case 'as':
- this.httpHost = givenRegion + '-apia.coolkit.cc'
- break
- case 'cn':
- this.httpHost = 'cn-apia.coolkit.cn'
- break
- default:
- throw new Error('No valid region received - [' + givenRegion + '].')
- }
- if (this.debug) {
- this.log('New HTTP API host received [%s].', this.httpHost)
+ } else if (this.debug) {
+ this.log('Sending HTTP login request.')
+ }
+ const dataToSign = crypto
+ .createHmac('sha256', constants.appSecret)
+ .update(JSON.stringify(data))
+ .digest('base64')
+ const res = await axios.post(
+ 'https://' + this.httpHost + '/v2/user/login',
+ data, {
+ headers: {
+ Authorization: 'Sign ' + dataToSign,
+ 'Content-Type': 'application/json',
+ Host: this.httpHost,
+ 'X-CK-Appid': constants.appId,
+ 'X-CK-Nonce': Math.random().toString(36).substr(2, 8)
}
- return this.login()
}
- if (body.data.at) {
- this.aToken = body.data.at
- this.apiKey = body.data.user.apikey
- return {
- aToken: this.aToken,
- apiKey: this.apiKey,
- httpHost: this.httpHost
- }
+ )
+ const body = res.data
+ if (
+ Object.prototype.hasOwnProperty.call(body, 'error') &&
+ body.error === 10004 &&
+ Object.prototype.hasOwnProperty.call(body, 'data') &&
+ Object.prototype.hasOwnProperty.call(body.data, 'region')
+ ) {
+ const givenRegion = body.data.region
+ switch (givenRegion) {
+ case 'eu':
+ case 'us':
+ case 'as':
+ this.httpHost = givenRegion + '-apia.coolkit.cc'
+ break
+ case 'cn':
+ this.httpHost = 'cn-apia.coolkit.cn'
+ break
+ default:
+ throw new Error('No valid region received - [' + givenRegion + '].')
+ }
+ if (this.debug) {
+ this.log('New HTTP API host received [%s].', this.httpHost)
+ }
+ return this.login()
+ }
+ if (body.data.at) {
+ this.aToken = body.data.at
+ this.apiKey = body.data.user.apikey
+ return {
+ aToken: this.aToken,
+ apiKey: this.apiKey,
+ httpHost: this.httpHost
+ }
+ } else {
+ if (body.error === 500) {
+ this.log.warn(
+ 'An eWeLink error [500] occured. Retrying in 30 seconds.'
+ )
+ await utils.sleep(30000)
+ return this.login()
} else {
- if (body.error === 500) {
- this.log.warn(
- 'An eWeLink error [500] occured. Retrying in 30 seconds.'
- )
- await utils.sleep(30000)
- return this.login()
- } else {
- throw new Error('No auth token received.\n' + JSON.stringify(body, null, 2))
- }
+ throw new Error('No auth token received.\n' + JSON.stringify(body, null, 2))
}
- } catch (err) {
- throw err
}
}
diff --git a/lib/eWeLinkLAN.js b/lib/eWeLinkLAN.js
index 5a121315..7d4a7226 100644
--- a/lib/eWeLinkLAN.js
+++ b/lib/eWeLinkLAN.js
@@ -23,27 +23,23 @@ module.exports = class eWeLinkLAN {
}
async getHosts () {
- try {
- const res = await dns.discover({
- name: '_ewelink._tcp.local'
- })
- res.forEach(device => {
- let d
- const deviceId = device.fqdn.replace('._ewelink._tcp.local', '').replace('eWeLink_', '')
- if ((d = this.deviceMap.get(deviceId))) {
- if (!Object.prototype.hasOwnProperty.call(this.ipOverrides, deviceId)) {
- this.deviceMap.set(deviceId, {
- apiKey: d.apiKey,
- online: true,
- ip: device.address
- })
- }
+ const res = await dns.discover({
+ name: '_ewelink._tcp.local'
+ })
+ res.forEach(device => {
+ let d
+ const deviceId = device.fqdn.replace('._ewelink._tcp.local', '').replace('eWeLink_', '')
+ if ((d = this.deviceMap.get(deviceId))) {
+ if (!Object.prototype.hasOwnProperty.call(this.ipOverrides, deviceId)) {
+ this.deviceMap.set(deviceId, {
+ apiKey: d.apiKey,
+ online: true,
+ ip: device.address
+ })
}
- })
- return this.deviceMap
- } catch (err) {
- throw err
- }
+ }
+ })
+ return this.deviceMap
}
startMonitor () {
@@ -110,60 +106,54 @@ module.exports = class eWeLinkLAN {
}
async sendUpdate (json) {
- try {
- if (!this.deviceMap.get(json.deviceid).online) {
- throw new Error("device isn't reachable via LAN mode")
+ if (!this.deviceMap.get(json.deviceid).online) {
+ throw new Error("device isn't reachable via LAN mode")
+ }
+ let apiKey
+ let suffix
+ const params = {}
+ if (Object.prototype.hasOwnProperty.call(json.params, 'switches')) {
+ params.switches = json.params.switches
+ suffix = 'switches'
+ } else if (Object.prototype.hasOwnProperty.call(json.params, 'switch')) {
+ params.switch = json.params.switch
+ suffix = 'switch'
+ } else {
+ throw new Error("device isn't reachable via LAN mode")
+ }
+ if ((apiKey = this.deviceMap.get(json.deviceid).apiKey)) {
+ const key = crypto.createHash('md5').update(Buffer.from(apiKey, 'utf8')).digest()
+ const iv = crypto.randomBytes(16)
+ const enc = crypto.createCipheriv('aes-128-cbc', key, iv)
+ const data = {
+ data: Buffer.concat([enc.update(JSON.stringify(params)), enc.final()]).toString('base64'),
+ deviceid: json.deviceid,
+ encrypt: true,
+ iv: iv.toString('base64'),
+ selfApikey: '123',
+ sequence: Date.now().toString()
}
- let apiKey
- let suffix
- const params = {}
- if (Object.prototype.hasOwnProperty.call(json.params, 'switches')) {
- params.switches = json.params.switches
- suffix = 'switches'
- } else if (Object.prototype.hasOwnProperty.call(json.params, 'switch')) {
- params.switch = json.params.switch
- suffix = 'switch'
- } else {
- throw new Error("device isn't reachable via LAN mode")
+ if (this.debugReqRes) {
+ const msg = JSON.stringify(json, null, 2)
+ .replace(json.apikey, '**hidden**')
+ .replace(json.apikey, '**hidden**')
+ .replace(json.deviceid, '**hidden**')
+ this.log.warn('LAN message sent. This text is yellow for clarity.\n%s', msg)
+ } else if (this.debug) {
+ this.log('LAN message sent.')
}
- if ((apiKey = this.deviceMap.get(json.deviceid).apiKey)) {
- const key = crypto.createHash('md5').update(Buffer.from(apiKey, 'utf8')).digest()
- const iv = crypto.randomBytes(16)
- const enc = crypto.createCipheriv('aes-128-cbc', key, iv)
- const data = {
- data: Buffer.concat([enc.update(JSON.stringify(params)), enc.final()]).toString('base64'),
- deviceid: json.deviceid,
- encrypt: true,
- iv: iv.toString('base64'),
- selfApikey: '123',
- sequence: Date.now().toString()
- }
- if (this.debugReqRes) {
- const msg = JSON.stringify(json, null, 2)
- .replace(json.apikey, '**hidden**')
- .replace(json.apikey, '**hidden**')
- .replace(json.deviceid, '**hidden**')
- this.log.warn('LAN message sent. This text is yellow for clarity.\n%s', msg)
- } else if (this.debug) {
- this.log('LAN message sent.')
- }
- const res = await axios({
- method: 'post',
- url: 'http://' + this.deviceMap.get(json.deviceid).ip + ':8081/zeroconf/' + suffix,
- headers: {
- Accept: 'application/json',
- 'Content-Type': 'application/json'
- },
- data
- })
- if (Object.prototype.hasOwnProperty.call(res.data, 'error') && res.data.error === 0) {
- return
- } else {
- throw new Error(res.data)
- }
+ const res = await axios({
+ method: 'post',
+ url: 'http://' + this.deviceMap.get(json.deviceid).ip + ':8081/zeroconf/' + suffix,
+ headers: {
+ Accept: 'application/json',
+ 'Content-Type': 'application/json'
+ },
+ data
+ })
+ if (!Object.prototype.hasOwnProperty.call(res.data, 'error') || res.data.error !== 0) {
+ throw new Error(res.data)
}
- } catch (err) {
- throw err
}
}
@@ -180,11 +170,7 @@ module.exports = class eWeLinkLAN {
}
async closeConnection () {
- try {
- await dns.stopMonitoring()
- this.log('LAN monitoring gracefully stopped.')
- } catch (err) {
- throw err
- }
+ await dns.stopMonitoring()
+ this.log('LAN monitoring gracefully stopped.')
}
}
diff --git a/lib/eWeLinkWS.js b/lib/eWeLinkWS.js
index 9478517b..137035d2 100644
--- a/lib/eWeLinkWS.js
+++ b/lib/eWeLinkWS.js
@@ -305,13 +305,8 @@ module.exports = class eWeLinkWS {
async closeConnection () {
if (this.wsp && this.wsIsOpen) {
- try {
- await this.wsp.close()
- this.log('Web socket gracefully closed.')
- return
- } catch (err) {
- throw err
- }
+ await this.wsp.close()
+ this.log('Web socket gracefully closed.')
}
}
}
From 013f1941ad9b73497cc3fa814eedd855415a54ca Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 27 Sep 2020 22:32:31 +0100
Subject: [PATCH 0252/3183] error handling
---
lib/eWeLink.js | 7 +------
lib/eWeLinkWS.js | 2 +-
2 files changed, 2 insertions(+), 7 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 1e818b4e..7393124f 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -970,12 +970,7 @@ class eWeLink {
if (this.debug) {
this.log.warn('[%s] Reverting to web socket as %s.', accessory.displayName, err.message)
}
- try {
- await this.wsClient.sendUpdate(payload)
- return
- } catch (err) {
- throw new Error(err)
- }
+ await this.wsClient.sendUpdate(payload)
} else {
throw new Error("it is unreachable. It's status will be corrected once it is reachable")
}
diff --git a/lib/eWeLinkWS.js b/lib/eWeLinkWS.js
index 137035d2..a6adfc5b 100644
--- a/lib/eWeLinkWS.js
+++ b/lib/eWeLinkWS.js
@@ -254,7 +254,7 @@ module.exports = class eWeLinkWS {
throw new Error('Unknown response')
}
} catch (err) {
- throw new Error('device update failed [' + err + ']')
+ throw new Error('device update failed [' + err.message + ']')
}
} else {
if (this.debug) {
From c186dea4aa99be2f897fe623214c5e69014ad691 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 27 Sep 2020 22:41:49 +0100
Subject: [PATCH 0253/3183] 3.1.3
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index b79c5a20..429c84d8 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.1.3-1",
+ "version": "3.1.3",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 1700b110..12f96bd0 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.1.3-1",
+ "version": "3.1.3",
"author": "bwp91",
"contributors": [
"gbro115",
From a6218f03169b68135f3f831083fd81417c125fea Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Mon, 28 Sep 2020 10:20:53 +0100
Subject: [PATCH 0254/3183] cleaning up + improved error
---
lib/constants.js | 1 +
lib/device/blind.js | 29 +------
lib/device/curtain.js | 19 +++--
lib/device/fan.js | 4 +-
lib/device/garage.js | 7 +-
lib/device/light.js | 16 ++--
lib/device/lock.js | 5 +-
lib/device/outlet.js | 26 +++---
lib/device/rf-sub.js | 9 +-
lib/device/scm.js | 8 +-
lib/device/sensor.js | 5 +-
lib/device/switch.js | 13 +--
lib/device/thermostat.js | 4 +-
lib/device/usb.js | 8 +-
lib/device/valve.js | 5 +-
lib/device/zb-dev.js | 6 +-
lib/eWeLink.js | 42 ++++++----
lib/eWeLinkHTTP.js | 172 ++++++++++++++-------------------------
lib/eWeLinkLAN.js | 19 +++--
lib/eWeLinkWS.js | 112 ++++++++-----------------
20 files changed, 209 insertions(+), 301 deletions(-)
diff --git a/lib/constants.js b/lib/constants.js
index 72090079..ba6d44fa 100644
--- a/lib/constants.js
+++ b/lib/constants.js
@@ -2,6 +2,7 @@
module.exports = {
appId: 'oeVkj2lYFGnJu5XUtWisfW4utiN4u9Mq',
appSecret: '6Nz4n0xA8s8qdxQf2GqurZj2Fs55FUvM',
+ httpRetryCodes: ['ENOTFOUND', 'ETIMEDOUT', 'EAI_AGAIN'],
allowedGroups: ['blind', 'garage', 'lock', 'valve'],
devicesHideable: ['switch', 'light'],
devicesNonLAN: [22, 28, 59, 102],
diff --git a/lib/device/blind.js b/lib/device/blind.js
index 13ea726e..9223338a 100644
--- a/lib/device/blind.js
+++ b/lib/device/blind.js
@@ -29,48 +29,21 @@ module.exports = class deviceBlind {
params.switches = cns.defaultMultiSwitchOff
accessory.context.updateKey = updateKey
const percentStepPerDecisecond = blindConfig.operationTime / 100
- //
- //
- this.platform.log('============================')
- this.platform.log('============================')
- this.platform.log('Starting main calculation...')
- //
- //
if (prevState !== 2) {
await this.platform.sendDeviceUpdate(accessory, params)
let positionPercentChange = Math.floor(Date.now() / 100) - accessory.context.cacheLastStartTime
positionPercentChange = Math.floor(percentStepPerDecisecond * positionPercentChange)
if (prevState === 0) {
- // moving down
prevPosition -= positionPercentChange
} else {
prevPosition += positionPercentChange
}
wcService.updateCharacteristic(Characteristic.CurrentPosition, prevPosition)
accessory.context.cacheCurrentPosition = prevPosition
- this.platform.log.warn('Moving from [%s%] to [%s%]', prevPosition, newTarget)
- this.platform.log.warn(
- 'Blind was already moving %s when it was changed and was probably around %s%',
- prevState === 1 ? 'up' : 'down',
- prevPosition
- )
- this.platform.log.warn(
- 'Giving a difference of %s seconds - a position change of %s%',
- (Math.floor(Date.now() / 100) - accessory.context.cacheLastStartTime) / 10,
- positionPercentChange
- )
- } else {
- this.platform.log('Moving from [%s%] to [%s%].', prevPosition, newTarget)
}
const diffPosition = newTarget - prevPosition
const setToMoveUp = diffPosition > 0
const decisecondsToMove = Math.round(Math.abs(diffPosition) * percentStepPerDecisecond)
- this.platform.log(
- 'So we need to move %s from the previous state of %s for about %s seconds',
- setToMoveUp ? 'up' : 'down',
- prevState === 0 ? 'moving down' : prevState === 1 ? 'moving up' : 'stopped',
- decisecondsToMove / 10
- )
params.switches[0].switch = setToMoveUp ? 'on' : 'off'
params.switches[1].switch = setToMoveUp ? 'off' : 'on'
await this.platform.sendDeviceUpdate(accessory, params)
@@ -91,7 +64,7 @@ module.exports = class deviceBlind {
accessory.context.cachePositionState = 2
accessory.context.cacheCurrentPosition = newTarget
} catch (err) {
- this.platform.requestDeviceRefresh(accessory, err)
+ this.platform.deviceUpdateError(accessory, err, true)
}
}
}
diff --git a/lib/device/curtain.js b/lib/device/curtain.js
index 95ab6086..73e5fc3f 100644
--- a/lib/device/curtain.js
+++ b/lib/device/curtain.js
@@ -30,24 +30,25 @@ module.exports = class deviceCurtain {
.updateCharacteristic(Characteristic.PositionState, newPos > prevPos ? 1 : 0)
accessory.context.cacheCurrentPosition = newPos
} catch (err) {
- this.platform.requestDeviceRefresh(accessory, err)
+ this.platform.deviceUpdateError(accessory, err, true)
}
}
externalCurtainUpdate (accessory, params) {
try {
const cService = accessory.getService(Service.WindowCovering)
- if (Object.prototype.hasOwnProperty.call(params, 'switch') && Object.prototype.hasOwnProperty.call(params, 'setclose')) {
- const newPos = Math.abs(100 - parseInt(params.setclose))
- cService
- .updateCharacteristic(Characteristic.TargetPosition, newPos)
- .updateCharacteristic(Characteristic.CurrentPosition, newPos)
- .updateCharacteristic(Characteristic.PositionState, 2)
- accessory.context.cacheCurrentPosition = newPos
+ if (!Object.prototype.hasOwnProperty.call(params, 'switch') && !Object.prototype.hasOwnProperty.call(params, 'setclose')) {
return
}
+ const newPos = Math.abs(100 - parseInt(params.setclose))
+ cService
+ .updateCharacteristic(Characteristic.TargetPosition, newPos)
+ .updateCharacteristic(Characteristic.CurrentPosition, newPos)
+ .updateCharacteristic(Characteristic.PositionState, 2)
+ accessory.context.cacheCurrentPosition = newPos
+ return
} catch (err) {
- this.platform.log.warn('[%s] could not be updated as %s.', accessory.displayName, err)
+ this.platform.deviceUpdateError(accessory, err, false)
}
}
}
diff --git a/lib/device/fan.js b/lib/device/fan.js
index 09323633..9e829390 100644
--- a/lib/device/fan.js
+++ b/lib/device/fan.js
@@ -45,7 +45,7 @@ module.exports = class deviceFan {
.updateCharacteristic(Characteristic.Active, newPower)
.updateCharacteristic(Characteristic.RotationSpeed, newSpeed)
} catch (err) {
- this.platform.requestDeviceRefresh(accessory, err)
+ this.platform.deviceUpdateError(accessory, err, true)
}
}
@@ -87,7 +87,7 @@ module.exports = class deviceFan {
.updateCharacteristic(Characteristic.Active, status)
.updateCharacteristic(Characteristic.RotationSpeed, speed)
} catch (err) {
- this.platform.log.warn('[%s] could not be updated as %s.', accessory.displayName, err)
+ this.platform.deviceUpdateError(accessory, err, false)
}
}
}
diff --git a/lib/device/garage.js b/lib/device/garage.js
index 30ec61ec..5f4cd1dc 100644
--- a/lib/device/garage.js
+++ b/lib/device/garage.js
@@ -68,12 +68,15 @@ module.exports = class deviceGarage {
}
accessory.context.inUse = false
} catch (err) {
- this.platform.requestDeviceRefresh(accessory, err)
+ this.platform.deviceUpdateError(accessory, err, true)
}
}
externalGarageUpdate (accessory, params) {
try {
+ if (!Object.prototype.hasOwnProperty.call(params, 'switch') && !Object.prototype.hasOwnProperty.call(params, 'switches')) {
+ return
+ }
let garageConfig
const gcService = accessory.getService(Service.GarageDoorOpener)
const prevState = accessory.context.cacheCurrentDoorState
@@ -119,7 +122,7 @@ module.exports = class deviceGarage {
}, parseInt(garageConfig.operationTime) * 100)
} catch (err) {
accessory.context.inUse = false
- this.platform.log.warn('[%s] could not be updated as %s.', accessory.displayName, err)
+ this.platform.deviceUpdateError(accessory, err, false)
}
}
}
diff --git a/lib/device/light.js b/lib/device/light.js
index 42006e45..cd8fe085 100644
--- a/lib/device/light.js
+++ b/lib/device/light.js
@@ -1,5 +1,6 @@
'use strict'
let Characteristic, Service
+const cns = require('./../constants')
const convert = require('color-convert')
const utils = require('./../utils')
module.exports = class deviceLight {
@@ -25,7 +26,7 @@ module.exports = class deviceLight {
}
break
case '0':
- params.switches = this.platform.devicesInEW.get(accessory.context.eweDeviceId).params.switches
+ params.switches = cns.defaultMultiSwitchOff
params.switches[0].switch = value ? 'on' : 'off'
params.switches[1].switch = value ? 'on' : 'off'
params.switches[2].switch = value ? 'on' : 'off'
@@ -35,7 +36,7 @@ module.exports = class deviceLight {
case '2':
case '3':
case '4':
- params.switches = this.platform.devicesInEW.get(accessory.context.eweDeviceId).params.switches
+ params.switches = cns.defaultMultiSwitchOff
for (let i = 1; i <= 4; i++) {
if ((oAccessory = this.platform.devicesInHB.get(accessory.context.eweDeviceId + 'SW' + i))) {
i === parseInt(accessory.context.switchNumber)
@@ -84,7 +85,7 @@ module.exports = class deviceLight {
}
}
} catch (err) {
- this.platform.requestDeviceRefresh(accessory, err)
+ this.platform.deviceUpdateError(accessory, err, true)
}
}
@@ -117,7 +118,7 @@ module.exports = class deviceLight {
lightService.updateCharacteristic(Characteristic.Brightness, value)
}
} catch (err) {
- this.platform.requestDeviceRefresh(accessory, err)
+ this.platform.deviceUpdateError(accessory, err, true)
}
}
@@ -188,7 +189,7 @@ module.exports = class deviceLight {
break
}
} catch (err) {
- this.platform.requestDeviceRefresh(accessory, err)
+ this.platform.deviceUpdateError(accessory, err, true)
}
}
@@ -260,12 +261,13 @@ module.exports = class deviceLight {
lightService.updateCharacteristic(Characteristic.On, false)
}
} catch (err) {
- this.platform.log.warn('[%s] could not be updated as %s.', accessory.displayName, err)
+ this.platform.deviceUpdateError(accessory, err, false)
}
}
externalMultiLightUpdate (accessory, params) {
try {
+ if (!Object.prototype.hasOwnProperty.call(params, 'switches')) return
const idToCheck = accessory.context.hbDeviceId.slice(0, -1)
let primaryState = false
for (let i = 1; i <= accessory.context.channelCount; i++) {
@@ -283,7 +285,7 @@ module.exports = class deviceLight {
accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, primaryState)
}
} catch (err) {
- this.platform.log.warn('[%s] could not be updated as %s.', accessory.displayName, err)
+ this.platform.deviceUpdateError(accessory, err, false)
}
}
}
diff --git a/lib/device/lock.js b/lib/device/lock.js
index 93278892..e82e3882 100644
--- a/lib/device/lock.js
+++ b/lib/device/lock.js
@@ -33,12 +33,13 @@ module.exports = class deviceLock {
.updateCharacteristic(Characteristic.LockCurrentState, 1)
accessory.context.inUse = false
} catch (err) {
- this.platform.requestDeviceRefresh(accessory, err)
+ this.platform.deviceUpdateError(accessory, err, true)
}
}
externalLockUpdate (accessory, params) {
try {
+ if (!Object.prototype.hasOwnProperty.call(params, 'switch')) return
let lockConfig
const lmService = accessory.getService(Service.LockMechanism)
if (!(lockConfig = this.platform.cusG.get(accessory.context.hbDeviceId))) {
@@ -62,7 +63,7 @@ module.exports = class deviceLock {
}, parseInt(lockConfig.operationTime) * 100)
} catch (err) {
accessory.context.inUse = false
- this.platform.log.warn('[%s] could not be updated as %s.', accessory.displayName, err)
+ this.platform.deviceUpdateError(accessory, err, false)
}
}
}
diff --git a/lib/device/outlet.js b/lib/device/outlet.js
index 8696dc36..c244e42f 100644
--- a/lib/device/outlet.js
+++ b/lib/device/outlet.js
@@ -19,7 +19,7 @@ module.exports = class deviceOutlet {
await this.platform.sendDeviceUpdate(accessory, params)
outletService.updateCharacteristic(Characteristic.On, value)
} catch (err) {
- this.platform.requestDeviceRefresh(accessory, err)
+ this.platform.deviceUpdateError(accessory, err, true)
}
}
@@ -28,21 +28,23 @@ module.exports = class deviceOutlet {
const outletService = accessory.getService(Service.Outlet)
if (Object.prototype.hasOwnProperty.call(params, 'switch')) {
outletService.updateCharacteristic(Characteristic.On, params.switch === 'on')
- if (accessory.context.eweModel === 'S26' || this.platform.config.disableEveLogging || false) {
+ if (accessory.context.eweModel === 'S26' || this.platform.config.disableEveLogging) {
outletService.updateCharacteristic(Characteristic.OutletInUse, params.switch === 'on')
}
}
if (Object.prototype.hasOwnProperty.call(params, 'power')) {
outletService.updateCharacteristic(EveService.Characteristics.CurrentConsumption, parseFloat(params.power))
- outletService.updateCharacteristic(
- Characteristic.OutletInUse,
- parseFloat(params.power) > (this.platform.config.inUsePowerThreshold || 0)
- )
- const isOn = accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On).value
- accessory.eveLogger.addEntry({
- time: Date.now(),
- power: isOn ? parseFloat(params.power) : 0
- })
+ if (accessory.context.eweModel !== 'S26' && !this.platform.config.disableEveLogging) {
+ outletService.updateCharacteristic(
+ Characteristic.OutletInUse,
+ parseFloat(params.power) > (this.platform.config.inUsePowerThreshold || 0)
+ )
+ const isOn = accessory.getService(Service.Outlet).getCharacteristic(Characteristic.On).value
+ accessory.eveLogger.addEntry({
+ time: Date.now(),
+ power: isOn ? parseFloat(params.power) : 0
+ })
+ }
}
if (Object.prototype.hasOwnProperty.call(params, 'voltage')) {
outletService.updateCharacteristic(EveService.Characteristics.Voltage, parseFloat(params.voltage))
@@ -51,7 +53,7 @@ module.exports = class deviceOutlet {
outletService.updateCharacteristic(EveService.Characteristics.ElectricCurrent, parseFloat(params.current))
}
} catch (err) {
- this.platform.log.warn('[%s] could not be updated as %s.', accessory.displayName, err)
+ this.platform.deviceUpdateError(accessory, err, false)
}
}
}
diff --git a/lib/device/rf-sub.js b/lib/device/rf-sub.js
index 3bf3320c..e1800637 100644
--- a/lib/device/rf-sub.js
+++ b/lib/device/rf-sub.js
@@ -21,7 +21,7 @@ module.exports = class deviceRFSub {
await utils.sleep(3000)
rfService.updateCharacteristic(Characteristic.On, false)
} catch (err) {
- this.platform.requestDeviceRefresh(accessory, err)
+ this.platform.deviceUpdateError(accessory, err, true)
}
}
@@ -31,8 +31,6 @@ module.exports = class deviceRFSub {
const timeNow = new Date()
let oAccessory = false
if (Object.prototype.hasOwnProperty.call(params, 'cmd') && params.cmd === 'transmit' && Object.prototype.hasOwnProperty.call(params, 'rfChl')) {
- //* ** RF Button ***\\
- // the device needed is SW% corresponding to params.rfChl
this.platform.devicesInHB.forEach(acc => {
if (
acc.context.eweDeviceId === accessory.context.eweDeviceId &&
@@ -109,15 +107,12 @@ module.exports = class deviceRFSub {
setTimeout(() => {
oAccessory.getService(serv).updateCharacteristic(char, 0)
}, (this.platform.config.sensorTimeLength || 2) * 1000)
- if (this.platform.debug) {
- this.platform.log('[%s] has detected [%s].', oAccessory.displayName, oAccessory.context.sensorType)
- }
}
}
})
}
} catch (err) {
- this.platform.log.warn('[%s] could not be updated as %s.', accessory.displayName, err)
+ this.platform.deviceUpdateError(accessory, err, false)
}
}
}
diff --git a/lib/device/scm.js b/lib/device/scm.js
index 276c385f..501bdb29 100644
--- a/lib/device/scm.js
+++ b/lib/device/scm.js
@@ -1,5 +1,6 @@
'use strict'
let Characteristic, Service
+const cns = require('./../constants')
module.exports = class deviceSCM {
constructor (platform) {
this.platform = platform
@@ -11,22 +12,23 @@ module.exports = class deviceSCM {
callback()
try {
const params = {
- switches: this.platform.devicesInEW.get(accessory.context.eweDeviceId).params.switches
+ switches: cns.defaultMultiSwitchOff
}
const switchService = accessory.getService(Service.Switch)
params.switches[0].switch = value ? 'on' : 'off'
await this.platform.sendDeviceUpdate(accessory, params)
switchService.updateCharacteristic(Characteristic.On, value)
} catch (err) {
- this.platform.requestDeviceRefresh(accessory, err)
+ this.platform.deviceUpdateError(accessory, err, true)
}
}
externalSCMUpdate (accessory, params) {
try {
+ if (!Object.prototype.hasOwnProperty.call(params, 'switches')) return
accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, params.switches[0].switch === 'on')
} catch (err) {
- this.platform.log.warn('[%s] could not be updated as %s.', accessory.displayName, err)
+ this.platform.deviceUpdateError(accessory, err, false)
}
}
}
diff --git a/lib/device/sensor.js b/lib/device/sensor.js
index b16f3a5c..844bca01 100644
--- a/lib/device/sensor.js
+++ b/lib/device/sensor.js
@@ -19,6 +19,7 @@ module.exports = class deviceSensor {
scaledBattery < (this.platform.config.lowBattThreshold || 25)
)
}
+ if (!Object.prototype.hasOwnProperty.call(params, 'switch')) return
const newState = params.switch === 'on' ? 1 : 0
let oAccessory = false
const contactService = accessory.getService(Service.ContactSensor)
@@ -41,14 +42,12 @@ module.exports = class deviceSensor {
.updateCharacteristic(Characteristic.CurrentDoorState, 0)
}, group.operationTime * 100)
break
- default:
- throw new Error('unknown sensor status received [' + newState + ']')
}
}
}
})
} catch (err) {
- this.platform.log.warn('[%s] could not be updated as %s.', accessory.displayName, err)
+ this.platform.deviceUpdateError(accessory, err, false)
}
}
}
diff --git a/lib/device/switch.js b/lib/device/switch.js
index 0f49f802..9a70c3c1 100644
--- a/lib/device/switch.js
+++ b/lib/device/switch.js
@@ -1,5 +1,6 @@
'use strict'
let Characteristic, Service
+const cns = require('./../constants')
module.exports = class deviceSwitch {
constructor (platform) {
this.platform = platform
@@ -18,7 +19,7 @@ module.exports = class deviceSwitch {
params.switch = value ? 'on' : 'off'
break
case '0':
- params.switches = this.platform.devicesInEW.get(accessory.context.eweDeviceId).params.switches
+ params.switches = cns.defaultMultiSwitchOff
params.switches[0].switch = value ? 'on' : 'off'
params.switches[1].switch = value ? 'on' : 'off'
params.switches[2].switch = value ? 'on' : 'off'
@@ -28,7 +29,7 @@ module.exports = class deviceSwitch {
case '2':
case '3':
case '4':
- params.switches = this.platform.devicesInEW.get(accessory.context.eweDeviceId).params.switches
+ params.switches = cns.defaultMultiSwitchOff
for (let i = 1; i <= 4; i++) {
if ((oAccessory = this.platform.devicesInHB.get(accessory.context.eweDeviceId + 'SW' + i))) {
i === parseInt(accessory.context.switchNumber)
@@ -77,20 +78,22 @@ module.exports = class deviceSwitch {
}
}
} catch (err) {
- this.platform.requestDeviceRefresh(accessory, err)
+ this.platform.deviceUpdateError(accessory, err, true)
}
}
externalSingleSwitchUpdate (accessory, params) {
try {
+ if (!Object.prototype.hasOwnProperty.call(params, 'switch')) return
accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, params.switch === 'on')
} catch (err) {
- this.platform.log.warn('[%s] could not be updated as %s.', accessory.displayName, err)
+ this.platform.deviceUpdateError(accessory, err, false)
}
}
externalMultiSwitchUpdate (accessory, params) {
try {
+ if (!Object.prototype.hasOwnProperty.call(params, 'switches')) return
const idToCheck = accessory.context.hbDeviceId.slice(0, -1)
let primaryState = false
for (let i = 1; i <= accessory.context.channelCount; i++) {
@@ -108,7 +111,7 @@ module.exports = class deviceSwitch {
accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, primaryState)
}
} catch (err) {
- this.platform.log.warn('[%s] could not be updated as %s.', accessory.displayName, err)
+ this.platform.deviceUpdateError(accessory, err, false)
}
}
}
diff --git a/lib/device/thermostat.js b/lib/device/thermostat.js
index a5d5f2b0..ba86d219 100644
--- a/lib/device/thermostat.js
+++ b/lib/device/thermostat.js
@@ -18,7 +18,7 @@ module.exports = class deviceThermostat {
await this.platform.sendDeviceUpdate(accessory, params)
switchService.updateCharacteristic(Characteristic.On, value)
} catch (err) {
- this.platform.requestDeviceRefresh(accessory, err)
+ this.platform.deviceUpdateError(accessory, err, true)
}
}
@@ -55,7 +55,7 @@ module.exports = class deviceThermostat {
}
}
} catch (err) {
- this.platform.log.warn('[%s] could not be updated as %s.', accessory.displayName, err)
+ this.platform.deviceUpdateError(accessory, err, false)
}
}
}
diff --git a/lib/device/usb.js b/lib/device/usb.js
index d78cf020..67a58833 100644
--- a/lib/device/usb.js
+++ b/lib/device/usb.js
@@ -1,5 +1,6 @@
'use strict'
let Characteristic, Service
+const cns = require('./../constants')
module.exports = class deviceUSB {
constructor (platform) {
this.platform = platform
@@ -11,22 +12,23 @@ module.exports = class deviceUSB {
callback()
try {
const params = {
- switches: this.platform.devicesInEW.get(accessory.context.eweDeviceId).params.switches
+ switches: cns.defaultMultiSwitchOff
}
const outletService = accessory.getService(Service.Outlet)
params.switches[0].switch = value ? 'on' : 'off'
await this.platform.sendDeviceUpdate(accessory, params)
outletService.updateCharacteristic(Characteristic.On, value)
} catch (err) {
- this.platform.requestDeviceRefresh(accessory, err)
+ this.platform.deviceUpdateError(accessory, err, true)
}
}
externalUSBUpdate (accessory, params) {
try {
+ if (!Object.prototype.hasOwnProperty.call(params, 'switches')) return
accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, params.switches[0].switch === 'on')
} catch (err) {
- this.platform.log.warn('[%s] could not be updated as %s.', accessory.displayName, err)
+ this.platform.deviceUpdateError(accessory, err, false)
}
}
}
diff --git a/lib/device/valve.js b/lib/device/valve.js
index 9feff0c4..c7d1dab8 100644
--- a/lib/device/valve.js
+++ b/lib/device/valve.js
@@ -50,12 +50,13 @@ module.exports = class deviceValve {
}
}
} catch (err) {
- this.platform.requestDeviceRefresh(accessory, err)
+ this.platform.deviceUpdateError(accessory, err, true)
}
}
externalValveUpdate (accessory, params) {
try {
+ if (!Object.prototype.hasOwnProperty.call(params, 'switches')) return
let valveConfig
if (!(valveConfig = this.platform.cusG.get(accessory.context.hbDeviceId))) {
throw new Error('group config missing')
@@ -81,7 +82,7 @@ module.exports = class deviceValve {
}
})
} catch (err) {
- this.platform.log.warn('[%s] could not be updated as %s.', accessory.displayName, err)
+ this.platform.deviceUpdateError(accessory, err, false)
}
}
}
diff --git a/lib/device/zb-dev.js b/lib/device/zb-dev.js
index d4b2f58e..365cedb8 100644
--- a/lib/device/zb-dev.js
+++ b/lib/device/zb-dev.js
@@ -11,7 +11,7 @@ module.exports = class deviceZBDev {
try {
//* ** credit @tasict ***\\
if (Object.prototype.hasOwnProperty.call(params, 'battery')) {
- if (accessory.context.eweUIID === 3026 && (this.platform.config.ZBDWBatt || false)) {
+ if (accessory.context.eweUIID === 3026 && this.platform.config.ZBDWBatt) {
params.battery *= 10
}
const batteryService =
@@ -75,9 +75,11 @@ module.exports = class deviceZBDev {
.updateCharacteristic(Characteristic.ContactSensorState, params.lock)
}
break
+ default:
+ throw new Error('Zigbee device type not supported [uiid ' + accessory.context.eweUIID + ']')
}
} catch (err) {
- this.platform.log.warn('[%s] could not be updated as %s.', accessory.displayName, err)
+ this.platform.deviceUpdateError(accessory, err, false)
}
}
}
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 7393124f..3fd6d668 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -120,7 +120,7 @@ class eWeLink {
})()
} catch (err) {
this.log.error('************** Cannot load homebridge-ewelink **************')
- this.log.error(err)
+ this.log.error(this.debug ? err : err.message)
this.log.error('************************************************************')
if (this.lanClient) this.lanClient.closeConnection()
if (this.wsClient) this.wsClient.closeConnection()
@@ -638,7 +638,7 @@ class eWeLink {
if (!(outletService = accessory.getService(Service.Outlet))) {
accessory.addService(Service.Outlet)
outletService = accessory.getService(Service.Outlet)
- if (accessory.context.eweModel !== 'S26' && !(this.config.disableEveLogging || false)) {
+ if (accessory.context.eweModel !== 'S26' && !this.config.disableEveLogging) {
outletService.addCharacteristic(EveService.Characteristics.Voltage)
outletService.addCharacteristic(EveService.Characteristics.CurrentConsumption)
outletService.addCharacteristic(EveService.Characteristics.ElectricCurrent)
@@ -658,7 +658,7 @@ class eWeLink {
outletService
.getCharacteristic(Characteristic.On)
.on('set', (value, callback) => accessory.control.internalOutletUpdate(accessory, value, callback))
- if (accessory.context.eweModel !== 'S26' && !(this.config.disableEveLogging || false)) {
+ if (accessory.context.eweModel !== 'S26' && !this.config.disableEveLogging) {
accessory.log = this.log
accessory.eveLogger = new EveHistoryService('energy', accessory, {
storage: 'fs',
@@ -968,7 +968,7 @@ class eWeLink {
} catch (err) {
if (accessory.context.reachableWAN) {
if (this.debug) {
- this.log.warn('[%s] Reverting to web socket as %s.', accessory.displayName, err.message)
+ this.log.warn('[%s] Reverting to web socket as LAN mode warning - %s.', accessory.displayName, this.debug ? err : err.message)
}
await this.wsClient.sendUpdate(payload)
} else {
@@ -987,21 +987,31 @@ class eWeLink {
if (device.params.online !== accessory.context.reachableWAN) {
accessory.context.reachableWAN = device.params.online
this.devicesInHB.set(accessory.context.hbDeviceId, accessory)
- if (accessory.context.reachableWAN) this.wsClient.requestUpdate(accessory).catch(() => {})
reachableChange = true
this.log.warn(
'[%s] has been reported [%s] via [WS].',
accessory.displayName,
accessory.context.reachableWAN ? 'online' : 'offline'
)
+ if (accessory.context.reachableWAN) {
+ try {
+ this.wsClient.requestUpdate(accessory)
+ } catch (err) {
+ this.log.warn('[%s] update could not be requested as %s', accessory.displayName, this.debug ? err.message : err)
+ }
+ }
}
}
if (device.params.updateSource === 'LAN' && !accessory.context.reachableLAN) {
accessory.context.reachableLAN = true
this.devicesInHB.set(accessory.context.hbDeviceId, accessory)
- this.wsClient.requestUpdate(accessory).catch(() => {})
reachableChange = true
this.log.warn('[%s] has been reported [online] via [LAN].', accessory.displayName)
+ try {
+ this.wsClient.requestUpdate(accessory)
+ } catch (err) {
+ this.log.warn('[%s] update could not be requested as %s', accessory.displayName, this.debug ? err.message : err)
+ }
}
if (reachableChange && !isX) {
for (let i = 1; i <= accessory.context.channelCount; i++) {
@@ -1052,15 +1062,17 @@ class eWeLink {
}
}
- async requestDeviceRefresh (accessory, err) {
- this.log.warn('[%s] could not be updated as %s.', accessory.displayName, err)
- if (accessory.context.reachableWAN) {
- try {
- await this.wsClient.requestUpdate(accessory)
- this.log.warn('[%s] requesting previous state to revert Homebridge state.', accessory.displayName)
- } catch (err) {}
- } else {
- this.log.warn('[%s] Homebridge state will be synced once the device comes back online.', accessory.displayName)
+ async deviceUpdateError (accessory, err, requestRefresh) {
+ this.log.warn('[%s] could not be updated as %s.', accessory.displayName, this.debug ? err : err.message)
+ if (requestRefresh) {
+ if (accessory.context.reachableWAN) {
+ try {
+ await this.wsClient.requestUpdate(accessory)
+ this.log.warn('[%s] requesting previous state to revert Homebridge state.', accessory.displayName)
+ } catch (err) {}
+ } else {
+ this.log.warn('[%s] Homebridge state will be synced once the device comes back online.', accessory.displayName)
+ }
}
}
}
diff --git a/lib/eWeLinkHTTP.js b/lib/eWeLinkHTTP.js
index 10df3508..c3497f4b 100644
--- a/lib/eWeLinkHTTP.js
+++ b/lib/eWeLinkHTTP.js
@@ -1,6 +1,6 @@
'use strict'
const axios = require('axios')
-const constants = require('./constants')
+const cns = require('./constants')
const crypto = require('crypto')
const utils = require('./utils')
module.exports = class eWeLinkHTTP {
@@ -11,13 +11,12 @@ module.exports = class eWeLinkHTTP {
this.username = config.username.toString()
this.password = config.password.toString()
this.hideDevFromHB = (config.hideDevFromHB || '').toString()
- this.cCode =
- '+' + config.countryCode.toString().replace('+', '').replace(' ', '')
+ this.cCode = '+' + config.countryCode.toString().replace('+', '').replace(' ', '')
}
async getHost () {
const params = {
- appid: constants.appId,
+ appid: cns.appId,
country_code: this.cCode,
nonce: Math.random().toString(36).substr(2, 8),
ts: Math.floor(new Date().getTime() / 1000),
@@ -33,33 +32,22 @@ module.exports = class eWeLinkHTTP {
})
dataToSign.sort((a, b) => (a.key < b.key ? -1 : 1))
dataToSign = dataToSign.map((k) => k.key + '=' + k.value).join('&')
- dataToSign = crypto
- .createHmac('sha256', constants.appSecret)
- .update(dataToSign)
- .digest('base64')
+ dataToSign = crypto.createHmac('sha256', cns.appSecret).update(dataToSign).digest('base64')
if (this.debugReqRes) {
- this.log.warn(
- 'Sending HTTP getHost request. This text is yellow for clarity.\n%s',
- JSON.stringify(params, null, 2)
- )
+ this.log.warn('Sending HTTP getHost request. This text is yellow for clarity.\n%s', JSON.stringify(params, null, 2))
} else if (this.debug) {
this.log('Sending HTTP getHost request.')
}
- const res = await axios.get(
- 'https://api.coolkit.cc:8080/api/user/region', {
- headers: {
- Authorization: 'Sign ' + dataToSign,
- 'Content-Type': 'application/json'
- },
- params
- }
- )
+ const res = await axios.get('https://api.coolkit.cc:8080/api/user/region', {
+ headers: {
+ Authorization: 'Sign ' + dataToSign,
+ 'Content-Type': 'application/json'
+ },
+ params
+ })
const body = res.data
if (!body.region) {
- throw new Error(
- 'Server did not respond with a region.\n' +
- JSON.stringify(body, null, 2)
- )
+ throw new Error('Server did not respond with a region.\n' + JSON.stringify(body, null, 2))
}
switch (body.region) {
case 'eu':
@@ -78,14 +66,12 @@ module.exports = class eWeLinkHTTP {
}
return this.httpHost
} catch (err) {
- if (
- Object.prototype.hasOwnProperty.call(err, 'code') && ['ENOTFOUND', 'ETIMEDOUT', 'EAI_AGAIN'].includes(err.code)
- ) {
+ if (Object.prototype.hasOwnProperty.call(err, 'code') && cns.httpRetryCodes.includes(err.code)) {
this.log.warn('Unable to reach eWeLink. Retrying in 30 seconds.')
await utils.sleep(30000)
return this.getHost()
} else {
- throw err
+ return err
}
}
}
@@ -95,43 +81,25 @@ module.exports = class eWeLinkHTTP {
countryCode: this.cCode,
password: this.password
}
- this.username.includes('@')
- ? (data.email = this.username)
- : (data.phoneNumber = this.username)
+ this.username.includes('@') ? (data.email = this.username) : (data.phoneNumber = this.username)
if (this.debugReqRes) {
- const msg = JSON.stringify(data, null, 2)
- .replace(this.password, '**hidden**')
- .replace(this.username, '**hidden**')
- this.log.warn(
- 'Sending HTTP login request. This text is yellow for clarity.\n%s',
- msg
- )
+ const msg = JSON.stringify(data, null, 2).replace(this.password, '**hidden**').replace(this.username, '**hidden**')
+ this.log.warn('Sending HTTP login request. This text is yellow for clarity.\n%s', msg)
} else if (this.debug) {
this.log('Sending HTTP login request.')
}
- const dataToSign = crypto
- .createHmac('sha256', constants.appSecret)
- .update(JSON.stringify(data))
- .digest('base64')
- const res = await axios.post(
- 'https://' + this.httpHost + '/v2/user/login',
- data, {
- headers: {
- Authorization: 'Sign ' + dataToSign,
- 'Content-Type': 'application/json',
- Host: this.httpHost,
- 'X-CK-Appid': constants.appId,
- 'X-CK-Nonce': Math.random().toString(36).substr(2, 8)
- }
- }
- )
+ const dataToSign = crypto.createHmac('sha256', cns.appSecret).update(JSON.stringify(data)).digest('base64')
+ const res = await axios.post('https://' + this.httpHost + '/v2/user/login', data, {
+ headers: {
+ Authorization: 'Sign ' + dataToSign,
+ 'Content-Type': 'application/json',
+ Host: this.httpHost,
+ 'X-CK-Appid': cns.appId,
+ 'X-CK-Nonce': Math.random().toString(36).substr(2, 8)
+ }
+ })
const body = res.data
- if (
- Object.prototype.hasOwnProperty.call(body, 'error') &&
- body.error === 10004 &&
- Object.prototype.hasOwnProperty.call(body, 'data') &&
- Object.prototype.hasOwnProperty.call(body.data, 'region')
- ) {
+ if (Object.prototype.hasOwnProperty.call(body, 'error') && body.error === 10004 && Object.prototype.hasOwnProperty.call(body, 'data') && Object.prototype.hasOwnProperty.call(body.data, 'region')) {
const givenRegion = body.data.region
switch (givenRegion) {
case 'eu':
@@ -160,9 +128,7 @@ module.exports = class eWeLinkHTTP {
}
} else {
if (body.error === 500) {
- this.log.warn(
- 'An eWeLink error [500] occured. Retrying in 30 seconds.'
- )
+ this.log.warn('An eWeLink error [500] occured. Retrying in 30 seconds.')
await utils.sleep(30000)
return this.login()
} else {
@@ -173,74 +139,56 @@ module.exports = class eWeLinkHTTP {
async getDevices () {
try {
- const res = await axios.get(
- 'https://' + this.httpHost + '/v2/device/thing', {
- headers: {
- Authorization: 'Bearer ' + this.aToken,
- 'Content-Type': 'application/json',
- Host: this.httpHost,
- 'X-CK-Appid': constants.appId,
- 'X-CK-Nonce': Math.random().toString(36).substr(2, 8)
- }
+ const res = await axios.get('https://' + this.httpHost + '/v2/device/thing', {
+ headers: {
+ Authorization: 'Bearer ' + this.aToken,
+ 'Content-Type': 'application/json',
+ Host: this.httpHost,
+ 'X-CK-Appid': cns.appId,
+ 'X-CK-Nonce': Math.random().toString(36).substr(2, 8)
}
- )
+ })
const body = res.data
- if (
- !Object.prototype.hasOwnProperty.call(body, 'data') ||
- !Object.prototype.hasOwnProperty.call(body, 'error') ||
- (Object.prototype.hasOwnProperty.call(body, 'error') && body.error !== 0)
- ) {
+ if (!Object.prototype.hasOwnProperty.call(body, 'data') || !Object.prototype.hasOwnProperty.call(body, 'error') || (Object.prototype.hasOwnProperty.call(body, 'error') && body.error !== 0)) {
throw new Error(JSON.stringify(body, null, 2))
}
const deviceList = []
if (body.data.thingList && body.data.thingList.length > 0) {
- body.data.thingList.forEach((device) =>
- deviceList.push(device.itemData)
- )
+ body.data.thingList.forEach((device) => deviceList.push(device.itemData))
}
deviceList
- .filter(
- (d) => Object.prototype.hasOwnProperty.call(d, 'extra') && Object.prototype.hasOwnProperty.call(d.extra, 'uiid')
- )
+ .filter((d) => Object.prototype.hasOwnProperty.call(d, 'extra') && Object.prototype.hasOwnProperty.call(d.extra, 'uiid'))
.filter((d) => !this.hideDevFromHB.includes(d.deviceid))
return deviceList
} catch (err) {
- if (
- Object.prototype.hasOwnProperty.call(err, 'code') && ['ENOTFOUND', 'ETIMEDOUT'].includes(err.code)
- ) {
+ if (Object.prototype.hasOwnProperty.call(err, 'code') && cns.httpRetryCodes.includes(err.code)) {
this.log.warn('Unable to reach eWeLink. Retrying in 30 seconds.')
await utils.sleep(30000)
return this.getDevices()
} else {
- throw err
+ return err
}
}
}
async getDevice (deviceId) {
try {
- const res = await axios.post(
- 'https://' + this.httpHost + '/v2/device/thing', {
- thingList: [{
- itemType: 1,
- id: deviceId
- }]
- }, {
- headers: {
- Authorization: 'Bearer ' + this.aToken,
- 'Content-Type': 'application/json',
- Host: this.httpHost,
- 'X-CK-Appid': constants.appId,
- 'X-CK-Nonce': Math.random().toString(36).substr(2, 8)
- }
+ const res = await axios.post('https://' + this.httpHost + '/v2/device/thing', {
+ thingList: [{
+ itemType: 1,
+ id: deviceId
+ }]
+ }, {
+ headers: {
+ Authorization: 'Bearer ' + this.aToken,
+ 'Content-Type': 'application/json',
+ Host: this.httpHost,
+ 'X-CK-Appid': cns.appId,
+ 'X-CK-Nonce': Math.random().toString(36).substr(2, 8)
}
- )
+ })
const body = res.data
- if (
- !Object.prototype.hasOwnProperty.call(body, 'data') ||
- !Object.prototype.hasOwnProperty.call(body, 'error') ||
- (Object.prototype.hasOwnProperty.call(body, 'error') && body.error !== 0)
- ) {
+ if (!Object.prototype.hasOwnProperty.call(body, 'data') || !Object.prototype.hasOwnProperty.call(body, 'error') || (Object.prototype.hasOwnProperty.call(body, 'error') && body.error !== 0)) {
throw new Error(JSON.stringify(body, null, 2))
}
if (body.data.thingList && body.data.thingList.length === 1) {
@@ -249,14 +197,12 @@ module.exports = class eWeLinkHTTP {
throw new Error('device not found in eWeLink')
}
} catch (err) {
- if (
- Object.prototype.hasOwnProperty.call(err, 'code') && ['ENOTFOUND', 'ETIMEDOUT'].includes(err.code)
- ) {
+ if (Object.prototype.hasOwnProperty.call(err, 'code') && cns.httpRetryCodes.includes(err.code)) {
this.log.warn('Unable to reach eWeLink. Retrying in 30 seconds.')
await utils.sleep(30000)
return this.getDevice(deviceId)
} else {
- throw err
+ return err
}
}
}
diff --git a/lib/eWeLinkLAN.js b/lib/eWeLinkLAN.js
index 7d4a7226..73e97cea 100644
--- a/lib/eWeLinkLAN.js
+++ b/lib/eWeLinkLAN.js
@@ -7,8 +7,12 @@ const EventEmitter = require('events')
module.exports = class eWeLinkLAN {
constructor (config, log, devices) {
this.log = log
+ this.config = config
+ this.debug = this.config.debug || false
+ this.debugReqRes = this.config.debugReqRes || false
+ this.ipOverrides = this.config.ipOverride || {}
+ this.emitter = new EventEmitter()
this.devices = devices
- this.ipOverrides = config.ipOverride || {}
this.deviceMap = new Map()
devices.forEach(device => {
this.deviceMap.set(device.deviceid, {
@@ -17,9 +21,6 @@ module.exports = class eWeLinkLAN {
ip: Object.prototype.hasOwnProperty.call(this.ipOverrides, device.deviceid) ? this.ipOverrides[device.deviceid] : null
})
})
- this.debug = config.debug || false
- this.debugReqRes = config.debugReqRes || false
- this.emitter = new EventEmitter()
}
async getHosts () {
@@ -42,7 +43,7 @@ module.exports = class eWeLinkLAN {
return this.deviceMap
}
- startMonitor () {
+ async startMonitor () {
dns.ondata = packet => {
if (packet.answers) {
packet.answers
@@ -170,7 +171,11 @@ module.exports = class eWeLinkLAN {
}
async closeConnection () {
- await dns.stopMonitoring()
- this.log('LAN monitoring gracefully stopped.')
+ try {
+ await dns.stopMonitoring()
+ this.log('LAN monitoring gracefully stopped.')
+ } catch (err) {
+ this.log.warn('LAN monitoring could not be stopped as %s', this.debug ? err : err.message)
+ }
}
}
diff --git a/lib/eWeLinkWS.js b/lib/eWeLinkWS.js
index a6adfc5b..92f46dab 100644
--- a/lib/eWeLinkWS.js
+++ b/lib/eWeLinkWS.js
@@ -23,9 +23,7 @@ module.exports = class eWeLinkWS {
try {
const res = await axios({
method: 'post',
- url: 'https://' +
- this.httpHost.replace('-api', '-disp') +
- '/dispatch/app',
+ url: 'https://' + this.httpHost.replace('-api', '-disp') + '/dispatch/app',
headers: {
Authorization: 'Bearer ' + this.aToken,
'Content-Type': 'application/json'
@@ -47,14 +45,12 @@ module.exports = class eWeLinkWS {
this.wsHost = body.domain
return body.domain
} catch (err) {
- if (
- Object.prototype.hasOwnProperty.call(err, 'code') && ['ENOTFOUND', 'ETIMEDOUT'].includes(err.code)
- ) {
+ if (Object.prototype.hasOwnProperty.call(err, 'code') && cns.httpRetryCodes.includes(err.code)) {
this.log.warn('Unable to reach eWeLink. Retrying in 30 seconds.')
await utils.sleep(30000)
return this.getDevices()
} else {
- throw err
+ return err
}
}
}
@@ -63,12 +59,9 @@ module.exports = class eWeLinkWS {
this.wsp = new WSP('wss://' + this.wsHost + ':8080/api/ws', {
createWebSocket: (url) => new WS(url),
extractMessageData: (event) => event,
- attachRequestId: (data, requestId) =>
- Object.assign({
- sequence: requestId
- },
- data
- ),
+ attachRequestId: (data, requestId) => Object.assign({
+ sequence: requestId
+ }, data),
extractRequestId: (data) => data && data.sequence,
packMessage: (data) => JSON.stringify(data),
unpackMessage: (data) => {
@@ -91,13 +84,8 @@ module.exports = class eWeLinkWS {
version: 8
}
if (this.debugReqRes) {
- const msg = JSON.stringify(payload, null, 2)
- .replace(this.aToken, '**hidden**')
- .replace(this.apiKey, '**hidden**')
- this.log.warn(
- 'Sending WS login request. This text is yellow for clarity.\n%s',
- msg
- )
+ const msg = JSON.stringify(payload, null, 2).replace(this.aToken, '**hidden**').replace(this.apiKey, '**hidden**')
+ this.log.warn('Sending WS login request. This text is yellow for clarity.\n%s', msg)
} else if (this.debug) {
this.log('Sending WS login request.')
}
@@ -105,12 +93,7 @@ module.exports = class eWeLinkWS {
const res = await this.wsp.sendRequest(payload, {
requestId: sequence
})
- if (
- Object.prototype.hasOwnProperty.call(res, 'config') &&
- res.config.hb &&
- res.config.hbInterval &&
- !this.hbInterval
- ) {
+ if (Object.prototype.hasOwnProperty.call(res, 'config') && res.config.hb && res.config.hbInterval && !this.hbInterval) {
this.hbInterval = setInterval(() => {
this.wsp.send('ping')
}, (res.config.hbInterval + 7) * 1000)
@@ -118,7 +101,7 @@ module.exports = class eWeLinkWS {
throw new Error('Unknown parameters received')
}
} catch (err) {
- this.log.error('WS login failed [%s].', err)
+ this.log.error('WS login failed [%s].', this.debug ? err : err.message)
}
})
this.wsp.onUnpackedMessage.addListener((device) => {
@@ -133,10 +116,7 @@ module.exports = class eWeLinkWS {
switch (device.action) {
case 'update':
case 'sysmsg':
- if (
- device.action === 'sysmsg' &&
- Object.prototype.hasOwnProperty.call(device.params, 'online')
- ) {
+ if (device.action === 'sysmsg' && Object.prototype.hasOwnProperty.call(device.params, 'online')) {
onlineStatus = device.params.online
}
for (const param in device.params) {
@@ -154,10 +134,7 @@ module.exports = class eWeLinkWS {
params: device.params
}
if (this.debugReqRes) {
- const msg = JSON.stringify(returnTemplate, null, 2).replace(
- device.deviceid,
- '**hidden**'
- )
+ const msg = JSON.stringify(returnTemplate, null, 2).replace(device.deviceid, '**hidden**')
this.log('WS message received.\n%s', msg)
} else if (this.debug) {
this.log('WS message received.')
@@ -168,33 +145,25 @@ module.exports = class eWeLinkWS {
case 'reportSubDevice':
return
default:
- this.log.warn(
- '[%s] WS message has unknown action.\n' +
- JSON.stringify(device, null, 2),
- device.deviceid
- )
+ this.log.warn('[%s] WS message has unknown action.\n' + JSON.stringify(device, null, 2), device.deviceid)
}
} else if (Object.prototype.hasOwnProperty.call(device, 'error') && device.error === 0) {
// *** Safe to ignore these messages *** \\
} else {
if (this.debug) {
- this.log.warn(
- 'WS unknown command received.\n' + JSON.stringify(device, null, 2)
- )
+ this.log.warn('WS unknown command received.\n' + JSON.stringify(device, null, 2))
}
}
})
- this.wsp.onClose.addListener((e, m) => {
+ this.wsp.onClose.addListener(e => {
this.wsIsOpen = false
- if (e !== 1005) {
- this.log.warn('Web socket closed [%s].', e)
- if (e !== 1000) {
+ if (e.code !== 1005) {
+ this.log.warn('Web socket closed [%s - %s].', e.code, e.reason)
+ if (e.code !== 1000) {
this.log('Web socket will try to reconnect in five seconds.')
setTimeout(() => this.login(), 5000)
} else {
- this.log(
- 'Please try restarting Homebridge so that this plugin can work again.'
- )
+ this.log('Please try restarting Homebridge so that this plugin can work again.')
}
}
if (this.hbInterval) {
@@ -203,18 +172,14 @@ module.exports = class eWeLinkWS {
}
this.wsp.removeAllListeners()
})
- this.wsp.onError.addListener((e) => {
- this.log.error('Web socket error - [%s].', e)
+ this.wsp.onError.addListener(e => {
+ this.log.warn('Web socket error - [%s].', e)
if (e.code === 'ECONNREFUSED') {
- this.log.warn(
- 'Web socket will try to reconnect in five seconds then try the command again.'
- )
+ this.log.warn('Web socket will try to reconnect in five seconds then try the command again.')
this.wsp.removeAllListeners()
setTimeout(() => this.login(), 5000)
} else {
- this.log.warn(
- 'If this was unexpected then please try restarting Homebridge.'
- )
+ this.log.warn('If this was unexpected then please try restarting Homebridge.')
}
})
}
@@ -235,14 +200,8 @@ module.exports = class eWeLinkWS {
requestId: sequence
})
if (this.debugReqRes) {
- const msg = JSON.stringify(json, null, 2)
- .replace(json.apikey, '**hidden**')
- .replace(json.apiKey, '**hidden**')
- .replace(json.deviceid, '**hidden**')
- this.log.warn(
- 'WS message sent. This text is yellow for clarity.\n%s',
- msg
- )
+ const msg = JSON.stringify(json, null, 2).replace(json.apikey, '**hidden**').replace(json.apiKey, '**hidden**').replace(json.deviceid, '**hidden**')
+ this.log.warn('WS message sent. This text is yellow for clarity.\n%s', msg)
} else if (this.debug) {
this.log('WS message sent.')
}
@@ -254,7 +213,8 @@ module.exports = class eWeLinkWS {
throw new Error('Unknown response')
}
} catch (err) {
- throw new Error('device update failed [' + err.message + ']')
+ const msg = this.debug ? err : err.message
+ return new Error('device update failed as ' + msg)
}
} else {
if (this.debug) {
@@ -279,14 +239,8 @@ module.exports = class eWeLinkWS {
if (this.wsp && this.wsIsOpen) {
this.wsp.send(JSON.stringify(json))
if (this.debugReqRes) {
- const msg = JSON.stringify(json, null, 2)
- .replace(json.apikey, '**hidden**')
- .replace(json.apiKey, '**hidden**')
- .replace(json.deviceid, '**hidden**')
- this.log.warn(
- 'WS message sent. This text is yellow for clarity.\n%s',
- msg
- )
+ const msg = JSON.stringify(json, null, 2).replace(json.apikey, '**hidden**').replace(json.apiKey, '**hidden**').replace(json.deviceid, '**hidden**')
+ this.log.warn('WS message sent. This text is yellow for clarity.\n%s', msg)
} else if (this.debug) {
this.log('WS message sent.')
}
@@ -305,8 +259,12 @@ module.exports = class eWeLinkWS {
async closeConnection () {
if (this.wsp && this.wsIsOpen) {
- await this.wsp.close()
- this.log('Web socket gracefully closed.')
+ try {
+ await this.wsp.close()
+ this.log('Web socket gracefully closed.')
+ } catch (err) {
+ this.log.warn('Web socket could not be closed as %s', this.debug ? err : err.message)
+ }
}
}
}
From 4940049ae5caddfd6c385bf9f9f868a72e5dd1ce Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Mon, 28 Sep 2020 10:22:43 +0100
Subject: [PATCH 0255/3183] 3.1.4
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 429c84d8..da735c95 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.1.3",
+ "version": "3.1.4",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 12f96bd0..e2d5e794 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.1.3",
+ "version": "3.1.4",
"author": "bwp91",
"contributors": [
"gbro115",
From 4b444002f28802d5a69f4e2f66b9efa9e009d2a7 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Mon, 28 Sep 2020 11:17:25 +0100
Subject: [PATCH 0256/3183] setup + shutdown
---
lib/eWeLink.js | 30 ++++++++++++++++++++----------
lib/eWeLinkLAN.js | 8 ++------
lib/eWeLinkWS.js | 8 ++------
3 files changed, 24 insertions(+), 22 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 3fd6d668..5e06b1af 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -45,15 +45,11 @@ class eWeLink {
this.eveLogPath = this.api.user.storagePath() + '/homebridge-ewelink/'
this.wsRefreshFlag = true
this.api
- .on('didFinishLaunching', () => this.eWeLinkSync())
- .on('shutdown', () => {
- if (this.lanClient) this.lanClient.closeConnection()
- if (this.wsClient) this.wsClient.closeConnection()
- this.wsRefreshFlag = false
- })
+ .on('didFinishLaunching', () => this.eWeLinkSetup())
+ .on('shutdown', () => this.eWeLinkShutdown())
}
- async eWeLinkSync () {
+ async eWeLinkSetup () {
try {
this.log('Plugin has finished initialising. Synching with eWeLink.')
this.httpClient = new EWeLinkHTTP(this.config, this.log)
@@ -105,7 +101,7 @@ class eWeLink {
await this.wsClient.login()
}
} catch (err) {
- this.log.warn(err)
+ this.log.warn(this.debug ? err : err.message)
}
}
},
@@ -122,12 +118,26 @@ class eWeLink {
this.log.error('************** Cannot load homebridge-ewelink **************')
this.log.error(this.debug ? err : err.message)
this.log.error('************************************************************')
- if (this.lanClient) this.lanClient.closeConnection()
- if (this.wsClient) this.wsClient.closeConnection()
+ try {
+ if (this.lanClient) await this.lanClient.closeConnection()
+ if (this.wsClient) await this.wsClient.closeConnection()
+ } catch (err) {
+ this.log.warn(this.debug ? err : err.message)
+ }
this.wsRefreshFlag = false
}
}
+ async eWeLinkShutdown () {
+ try {
+ if (this.lanClient) await this.lanClient.closeConnection()
+ if (this.wsClient) await this.wsClient.closeConnection()
+ } catch (err) {
+ this.log.warn(this.debug ? err : err.message)
+ }
+ this.wsRefreshFlag = false
+ }
+
initialiseDevice (device) {
let accessory
//* ** CURTAINS ***\\
diff --git a/lib/eWeLinkLAN.js b/lib/eWeLinkLAN.js
index 73e97cea..855819fd 100644
--- a/lib/eWeLinkLAN.js
+++ b/lib/eWeLinkLAN.js
@@ -171,11 +171,7 @@ module.exports = class eWeLinkLAN {
}
async closeConnection () {
- try {
- await dns.stopMonitoring()
- this.log('LAN monitoring gracefully stopped.')
- } catch (err) {
- this.log.warn('LAN monitoring could not be stopped as %s', this.debug ? err : err.message)
- }
+ await dns.stopMonitoring()
+ this.log('LAN monitoring gracefully stopped.')
}
}
diff --git a/lib/eWeLinkWS.js b/lib/eWeLinkWS.js
index 92f46dab..086856d3 100644
--- a/lib/eWeLinkWS.js
+++ b/lib/eWeLinkWS.js
@@ -259,12 +259,8 @@ module.exports = class eWeLinkWS {
async closeConnection () {
if (this.wsp && this.wsIsOpen) {
- try {
- await this.wsp.close()
- this.log('Web socket gracefully closed.')
- } catch (err) {
- this.log.warn('Web socket could not be closed as %s', this.debug ? err : err.message)
- }
+ await this.wsp.close()
+ this.log('Web socket gracefully closed.')
}
}
}
From f3d340d4060217ae68b10f868d733fe236ac495f Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Mon, 28 Sep 2020 11:55:39 +0100
Subject: [PATCH 0257/3183] log changes
---
lib/eWeLinkLAN.js | 2 +-
lib/eWeLinkWS.js | 10 +++++-----
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/lib/eWeLinkLAN.js b/lib/eWeLinkLAN.js
index 855819fd..67bfbae3 100644
--- a/lib/eWeLinkLAN.js
+++ b/lib/eWeLinkLAN.js
@@ -172,6 +172,6 @@ module.exports = class eWeLinkLAN {
async closeConnection () {
await dns.stopMonitoring()
- this.log('LAN monitoring gracefully stopped.')
+ if (this.debug) this.log('LAN monitoring gracefully stopped.')
}
}
diff --git a/lib/eWeLinkWS.js b/lib/eWeLinkWS.js
index 086856d3..3c305920 100644
--- a/lib/eWeLinkWS.js
+++ b/lib/eWeLinkWS.js
@@ -98,7 +98,7 @@ module.exports = class eWeLinkWS {
this.wsp.send('ping')
}, (res.config.hbInterval + 7) * 1000)
} else {
- throw new Error('Unknown parameters received')
+ throw new Error('Unknown parameters received\n' + res)
}
} catch (err) {
this.log.error('WS login failed [%s].', this.debug ? err : err.message)
@@ -157,9 +157,9 @@ module.exports = class eWeLinkWS {
})
this.wsp.onClose.addListener(e => {
this.wsIsOpen = false
- if (e.code !== 1005) {
- this.log.warn('Web socket closed [%s - %s].', e.code, e.reason)
- if (e.code !== 1000) {
+ if (e !== 1005) {
+ this.log.warn('Web socket closed [%s].', e)
+ if (e !== 1000) {
this.log('Web socket will try to reconnect in five seconds.')
setTimeout(() => this.login(), 5000)
} else {
@@ -260,7 +260,7 @@ module.exports = class eWeLinkWS {
async closeConnection () {
if (this.wsp && this.wsIsOpen) {
await this.wsp.close()
- this.log('Web socket gracefully closed.')
+ if (this.debug) this.log('Web socket gracefully closed.')
}
}
}
From 283121e81ade308625dfa926937ddba1365a858c Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Mon, 28 Sep 2020 20:58:05 +0100
Subject: [PATCH 0258/3183] Update FUNDING.yml
---
.github/FUNDING.yml | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
index 9444c69e..9ccddac1 100644
--- a/.github/FUNDING.yml
+++ b/.github/FUNDING.yml
@@ -1,3 +1,4 @@
+github: bwp91
patreon: bwp91
ko_fi: bwp91
-custom: ["https://www.paypal.me/BenPotter"]
+custom: https://www.paypal.me/BenPotter
From 7d9cd2ed191bcfa26417c1568745a62eb5baf2a6 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Mon, 28 Sep 2020 22:27:05 +0100
Subject: [PATCH 0259/3183] Update eWeLink.js
---
lib/eWeLink.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 5e06b1af..b07aea8f 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -97,7 +97,7 @@ class eWeLink {
if (this.wsClient) {
await this.wsClient.getHost()
await this.wsClient.closeConnection()
- await utils.sleep(250)
+ await utils.sleep(500)
await this.wsClient.login()
}
} catch (err) {
@@ -105,7 +105,7 @@ class eWeLink {
}
}
},
- 1800000, {
+ 3600000, {
stopOnError: false
}
)
From f9477090c1ece42f8974bc2b0818a44ba9fae557 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 29 Sep 2020 08:54:55 +0100
Subject: [PATCH 0260/3183] hideMasters bug
---
lib/eWeLink.js | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index b07aea8f..e34924a6 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -97,7 +97,7 @@ class eWeLink {
if (this.wsClient) {
await this.wsClient.getHost()
await this.wsClient.closeConnection()
- await utils.sleep(500)
+ await utils.sleep(250)
await this.wsClient.login()
}
} catch (err) {
@@ -105,7 +105,7 @@ class eWeLink {
}
}
},
- 3600000, {
+ 1800000, {
stopOnError: false
}
)
@@ -477,7 +477,10 @@ class eWeLink {
},
...extraContext
}
- if (!hidden) {
+ if (hidden) {
+ if (type === 'light') accessory.control = new DeviceLight(this)
+ if (type === 'switch') accessory.control = new DeviceSwitch(this)
+ } else {
this.api.registerPlatformAccessories('homebridge-ewelink', 'eWeLink', [accessory])
this.configureAccessory(accessory)
this.log(' â [%s] has been added to Homebridge.', newDeviceName)
From d24da5c354f79d1950da251783fd6c360efc1f89 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 29 Sep 2020 08:56:55 +0100
Subject: [PATCH 0261/3183] 3.1.5
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index da735c95..745f3ceb 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.1.4",
+ "version": "3.1.5",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index e2d5e794..3f36e1b5 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.1.4",
+ "version": "3.1.5",
"author": "bwp91",
"contributors": [
"gbro115",
From 88a84f3d2ce4d99c0f61092d47e0d02ba58e30b1 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 29 Sep 2020 15:57:36 +0100
Subject: [PATCH 0262/3183] rf sensor fix
---
lib/device/{rf-sub.js => rf-bridge.js} | 3 ++-
lib/eWeLink.js | 12 ++++++------
2 files changed, 8 insertions(+), 7 deletions(-)
rename lib/device/{rf-sub.js => rf-bridge.js} (97%)
diff --git a/lib/device/rf-sub.js b/lib/device/rf-bridge.js
similarity index 97%
rename from lib/device/rf-sub.js
rename to lib/device/rf-bridge.js
index e1800637..18704edd 100644
--- a/lib/device/rf-sub.js
+++ b/lib/device/rf-bridge.js
@@ -1,7 +1,7 @@
'use strict'
let Characteristic, Service
const utils = require('./../utils')
-module.exports = class deviceRFSub {
+module.exports = class deviceRFBridge {
constructor (platform) {
this.platform = platform
Service = platform.api.hap.Service
@@ -59,6 +59,7 @@ module.exports = class deviceRFSub {
this.platform.devicesInHB.forEach(acc => {
if (
acc.context.eweDeviceId === accessory.context.eweDeviceId &&
+ Object.prototype.hasOwnProperty.call(acc.context, 'buttons') &&
Object.prototype.hasOwnProperty.call(acc.context.buttons, chan.substr(-1).toString())
) {
oAccessory = acc
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index e34924a6..c7012c01 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -15,7 +15,7 @@ const DeviceUSB = require('./device/usb')
const DeviceSCM = require('./device/scm')
const DeviceLight = require('./device/light')
const DeviceSwitch = require('./device/switch')
-const DeviceRFSub = require('./device/rf-sub')
+const DeviceRFBridge = require('./device/rf-bridge')
const DeviceZBDev = require('./device/zb-dev')
const EWeLinkHTTP = require('./eWeLinkHTTP')
const EWeLinkWS = require('./eWeLinkWS')
@@ -254,6 +254,7 @@ class eWeLink {
}
this.hiddenMasters.push(device.deviceid)
accessory = this.addAccessory(device, device.deviceid + 'SW0', 'light', true)
+ accessory.control = new DeviceLight(this)
} else {
accessory = this.devicesInHB.has(device.deviceid + 'SW0')
? this.devicesInHB.get(device.deviceid + 'SW0')
@@ -287,6 +288,7 @@ class eWeLink {
}
this.hiddenMasters.push(device.deviceid)
accessory = this.addAccessory(device, device.deviceid + 'SW0', 'switch', true)
+ accessory.control = new DeviceSwitch(this)
} else {
accessory = this.devicesInHB.has(device.deviceid + 'SW0')
? this.devicesInHB.get(device.deviceid + 'SW0')
@@ -326,6 +328,7 @@ class eWeLink {
: this.addAccessory(device, device.deviceid + 'SW0', 'rf_pri', true, {
rfMap
})
+ accessory.control = new DeviceRFBridge(this)
// this.log.error(JSON.stringify(accessory.context, null, 2))
rfMap.forEach(subDevice => {
const swNumber = rfChlCounter + 1
@@ -477,10 +480,7 @@ class eWeLink {
},
...extraContext
}
- if (hidden) {
- if (type === 'light') accessory.control = new DeviceLight(this)
- if (type === 'switch') accessory.control = new DeviceSwitch(this)
- } else {
+ if (!hidden) {
this.api.registerPlatformAccessories('homebridge-ewelink', 'eWeLink', [accessory])
this.configureAccessory(accessory)
this.log(' â [%s] has been added to Homebridge.', newDeviceName)
@@ -801,7 +801,7 @@ class eWeLink {
break
}
case 'rf_sub': {
- accessory.control = new DeviceRFSub(this)
+ accessory.control = new DeviceRFBridge(this)
switch (accessory.context.subType) {
case 'water':
accessory.getService(Service.LeakSensor) || accessory.addService(Service.LeakSensor)
From 21ce252e20749ebee659792d6239fc0cab338fb7 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 29 Sep 2020 16:10:34 +0100
Subject: [PATCH 0263/3183] subType fix
---
lib/device/rf-bridge.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/device/rf-bridge.js b/lib/device/rf-bridge.js
index 18704edd..cb49dd63 100644
--- a/lib/device/rf-bridge.js
+++ b/lib/device/rf-bridge.js
@@ -71,7 +71,7 @@ module.exports = class deviceRFBridge {
let serv
let char
if (diff < (this.platform.config.sensorTimeDifference || 120)) {
- switch (oAccessory.context.sensorType) {
+ switch (oAccessory.context.subType) {
case 'button':
break
case 'water':
From 30ae0be2b8566864f362501ac0ab5344c1f456c4 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 29 Sep 2020 16:11:09 +0100
Subject: [PATCH 0264/3183] 3.1.6
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 745f3ceb..b2a0e397 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.1.5",
+ "version": "3.1.6",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 3f36e1b5..94fe430b 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.1.5",
+ "version": "3.1.6",
"author": "bwp91",
"contributors": [
"gbro115",
From 1607087dcf431dd21e4e08f2584e17b4c3afd05a Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Tue, 29 Sep 2020 18:38:49 +0100
Subject: [PATCH 0265/3183] Update package.json
---
package.json | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/package.json b/package.json
index 94fe430b..34f1b04d 100644
--- a/package.json
+++ b/package.json
@@ -54,6 +54,10 @@
{
"type": "paypal",
"url": "https://www.paypal.me/BenPotter"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/bwp91"
}
],
"dependencies": {
From d4e1b057e2d3ea8b0a3fe8d3193a938e73415713 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Wed, 30 Sep 2020 01:41:39 +0100
Subject: [PATCH 0266/3183] node-dns-sd dep
---
package-lock.json | 5 ++---
package.json | 2 +-
2 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index b2a0e397..630834c2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -516,9 +516,8 @@
"integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE="
},
"node-dns-sd": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/node-dns-sd/-/node-dns-sd-0.4.1.tgz",
- "integrity": "sha512-x+WSuMgvDBQv24OCq75YHcZj1SOzvP5fU4Tz+PBUiVvVBsfc+9XAHAuIftaCpf2nPLl+ys71uZoGr/v9fVDa6A=="
+ "version": "github:bwp91/node-dns-sd#0babcfdd9a9512283df41f184e5f569e63f786fd",
+ "from": "github:bwp91/node-dns-sd"
},
"node-fetch": {
"version": "2.6.1",
diff --git a/package.json b/package.json
index 34f1b04d..e94394e4 100644
--- a/package.json
+++ b/package.json
@@ -68,7 +68,7 @@
"fakegato-history": "0.5.6",
"homebridge-lib": "4.7.15",
"interval-promise": "1.4.0",
- "node-dns-sd": "0.4.1",
+ "node-dns-sd": "bwp91/node-dns-sd",
"websocket-as-promised": "1.0.1",
"ws": "7.3.1"
}
From 80bb88b2a9dd0dcfa65e12ea65b08c149a5efc06 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Wed, 30 Sep 2020 01:48:06 +0100
Subject: [PATCH 0267/3183] return correct devicelist
---
lib/eWeLinkHTTP.js | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/lib/eWeLinkHTTP.js b/lib/eWeLinkHTTP.js
index c3497f4b..45e2b6f4 100644
--- a/lib/eWeLinkHTTP.js
+++ b/lib/eWeLinkHTTP.js
@@ -153,13 +153,14 @@ module.exports = class eWeLinkHTTP {
throw new Error(JSON.stringify(body, null, 2))
}
const deviceList = []
+ const returnList = []
if (body.data.thingList && body.data.thingList.length > 0) {
body.data.thingList.forEach((device) => deviceList.push(device.itemData))
}
- deviceList
+ returnList = deviceList
.filter((d) => Object.prototype.hasOwnProperty.call(d, 'extra') && Object.prototype.hasOwnProperty.call(d.extra, 'uiid'))
.filter((d) => !this.hideDevFromHB.includes(d.deviceid))
- return deviceList
+ return returnList
} catch (err) {
if (Object.prototype.hasOwnProperty.call(err, 'code') && cns.httpRetryCodes.includes(err.code)) {
this.log.warn('Unable to reach eWeLink. Retrying in 30 seconds.')
From 3676f41da938f42b0872c6bfba999aa1be39428c Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Wed, 30 Sep 2020 01:52:35 +0100
Subject: [PATCH 0268/3183] Update eWeLinkHTTP.js
---
lib/eWeLinkHTTP.js | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/lib/eWeLinkHTTP.js b/lib/eWeLinkHTTP.js
index 45e2b6f4..c5d3bbcf 100644
--- a/lib/eWeLinkHTTP.js
+++ b/lib/eWeLinkHTTP.js
@@ -153,14 +153,18 @@ module.exports = class eWeLinkHTTP {
throw new Error(JSON.stringify(body, null, 2))
}
const deviceList = []
- const returnList = []
if (body.data.thingList && body.data.thingList.length > 0) {
- body.data.thingList.forEach((device) => deviceList.push(device.itemData))
+ body.data.thingList.forEach(d => {
+ if (
+ Object.prototype.hasOwnProperty.call(d, 'extra') &&
+ Object.prototype.hasOwnProperty.call(d.extra, 'uiid') &&
+ !this.hideDevFromHB.includes(d.deviceid)
+ ) {
+ deviceList.push(d.itemData)
+ }
+ })
}
- returnList = deviceList
- .filter((d) => Object.prototype.hasOwnProperty.call(d, 'extra') && Object.prototype.hasOwnProperty.call(d.extra, 'uiid'))
- .filter((d) => !this.hideDevFromHB.includes(d.deviceid))
- return returnList
+ return deviceList
} catch (err) {
if (Object.prototype.hasOwnProperty.call(err, 'code') && cns.httpRetryCodes.includes(err.code)) {
this.log.warn('Unable to reach eWeLink. Retrying in 30 seconds.')
From f18345dbb8200dce2bc49b86651bc366b1394283 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Wed, 30 Sep 2020 02:01:56 +0100
Subject: [PATCH 0269/3183] fix deviceList
---
lib/eWeLinkHTTP.js | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/lib/eWeLinkHTTP.js b/lib/eWeLinkHTTP.js
index c5d3bbcf..a40122a9 100644
--- a/lib/eWeLinkHTTP.js
+++ b/lib/eWeLinkHTTP.js
@@ -156,9 +156,10 @@ module.exports = class eWeLinkHTTP {
if (body.data.thingList && body.data.thingList.length > 0) {
body.data.thingList.forEach(d => {
if (
- Object.prototype.hasOwnProperty.call(d, 'extra') &&
- Object.prototype.hasOwnProperty.call(d.extra, 'uiid') &&
- !this.hideDevFromHB.includes(d.deviceid)
+ Object.prototype.hasOwnProperty.call(d, 'itemData') &&
+ Object.prototype.hasOwnProperty.call(d.itemData, 'extra') &&
+ Object.prototype.hasOwnProperty.call(d.itemData.extra, 'uiid') &&
+ !this.hideDevFromHB.includes(d.itemData.deviceid)
) {
deviceList.push(d.itemData)
}
From b6fe1aafd05dd23bf48737c9595fc34a47000f78 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Wed, 30 Sep 2020 06:50:21 +0100
Subject: [PATCH 0270/3183] node-dns-sd dep
---
package-lock.json | 5 +++--
package.json | 2 +-
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 630834c2..e81a9949 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -516,8 +516,9 @@
"integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE="
},
"node-dns-sd": {
- "version": "github:bwp91/node-dns-sd#0babcfdd9a9512283df41f184e5f569e63f786fd",
- "from": "github:bwp91/node-dns-sd"
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/node-dns-sd/-/node-dns-sd-0.4.2.tgz",
+ "integrity": "sha512-fZvDqy19zyaiSXajmRjwue1VWLrJcy8bTV/LJVtAx8DeEFVlXRBMyZknW+q6CEfiW8Y4MQDDKh9x5wF32BHAHQ=="
},
"node-fetch": {
"version": "2.6.1",
diff --git a/package.json b/package.json
index e94394e4..96a831d3 100644
--- a/package.json
+++ b/package.json
@@ -68,7 +68,7 @@
"fakegato-history": "0.5.6",
"homebridge-lib": "4.7.15",
"interval-promise": "1.4.0",
- "node-dns-sd": "bwp91/node-dns-sd",
+ "node-dns-sd": "0.4.2",
"websocket-as-promised": "1.0.1",
"ws": "7.3.1"
}
From 78ee826163b356158633c1e84cf09cc67de66188 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Wed, 30 Sep 2020 06:51:51 +0100
Subject: [PATCH 0271/3183] 3.1.7
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index e81a9949..f42e1988 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.1.6",
+ "version": "3.1.7",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 96a831d3..256697ec 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.1.6",
+ "version": "3.1.7",
"author": "bwp91",
"contributors": [
"gbro115",
From 71308867b5f37811269e66f71c7f997839c39460 Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Wed, 30 Sep 2020 08:55:41 +0100
Subject: [PATCH 0272/3183] Update README.md
---
README.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index 1c683be2..02449b11 100644
--- a/README.md
+++ b/README.md
@@ -7,12 +7,12 @@
Homebridge plugin to control eWeLink devices with original firmware.
- [![verified-by-homebridge](https://badgen.net/badge/homebridge/verified/purple)](https://github.com/homebridge/homebridge/wiki/Verified-Plugins)
- [![Discord](https://img.shields.io/discord/432663330281226270?color=728ED5&logo=discord&label=discord)](https://discord.com/channels/432663330281226270/742733745743855627)
- [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)
+ [![verified-by-homebridge](https://badgen.net/badge/homebridge/verified/purple)](https://github.com/homebridge/homebridge/wiki/Verified-Plugins)
[![npm](https://img.shields.io/npm/v/homebridge-ewelink/latest?label=release)](https://www.npmjs.com/package/homebridge-ewelink)
[![npm](https://img.shields.io/npm/v/homebridge-ewelink/beta?label=beta)](https://www.npmjs.com/package/homebridge-ewelink)
[![npm](https://img.shields.io/npm/dt/homebridge-ewelink)](https://www.npmjs.com/package/homebridge-ewelink)
+ [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)
+ [![Discord](https://img.shields.io/discord/432663330281226270?color=728ED5&logo=discord&label=discord)](https://discord.com/channels/432663330281226270/742733745743855627)
[![Contribute](https://img.shields.io/badge/contribute-a%20drink-yellow)](https://ko-fi.com/bwp91)
From 3f7af86ae8e576db796a7fddb1dc95c223ce6af9 Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Wed, 30 Sep 2020 08:55:53 +0100
Subject: [PATCH 0273/3183] Update README.md
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 02449b11..33b6d570 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,7 @@
[![npm](https://img.shields.io/npm/v/homebridge-ewelink/latest?label=release)](https://www.npmjs.com/package/homebridge-ewelink)
[![npm](https://img.shields.io/npm/v/homebridge-ewelink/beta?label=beta)](https://www.npmjs.com/package/homebridge-ewelink)
[![npm](https://img.shields.io/npm/dt/homebridge-ewelink)](https://www.npmjs.com/package/homebridge-ewelink)
- [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)
+ [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)
[![Discord](https://img.shields.io/discord/432663330281226270?color=728ED5&logo=discord&label=discord)](https://discord.com/channels/432663330281226270/742733745743855627)
[![Contribute](https://img.shields.io/badge/contribute-a%20drink-yellow)](https://ko-fi.com/bwp91)
From 1c5e5c6a1edc89e8a2b55d4d34dc96446e530989 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Wed, 30 Sep 2020 11:18:16 +0100
Subject: [PATCH 0274/3183] eachen garage door
---
config.schema.json | 6 +++++
lib/constants.js | 2 +-
lib/device/garage-eachen.js | 52 +++++++++++++++++++++++++++++++++++++
lib/eWeLink.js | 24 +++++++++++++++++
4 files changed, 83 insertions(+), 1 deletion(-)
create mode 100644 lib/device/garage-eachen.js
diff --git a/config.schema.json b/config.schema.json
index 5e99588c..e3c794e0 100644
--- a/config.schema.json
+++ b/config.schema.json
@@ -138,6 +138,12 @@
"garage"
]
},
+ {
+ "title": "Garage Door (Eachen)",
+ "enum": [
+ "garage_eachen"
+ ]
+ },
{
"title": "Lock",
"enum": [
diff --git a/lib/constants.js b/lib/constants.js
index ba6d44fa..0f618fb6 100644
--- a/lib/constants.js
+++ b/lib/constants.js
@@ -3,7 +3,7 @@ module.exports = {
appId: 'oeVkj2lYFGnJu5XUtWisfW4utiN4u9Mq',
appSecret: '6Nz4n0xA8s8qdxQf2GqurZj2Fs55FUvM',
httpRetryCodes: ['ENOTFOUND', 'ETIMEDOUT', 'EAI_AGAIN'],
- allowedGroups: ['blind', 'garage', 'lock', 'valve'],
+ allowedGroups: ['blind', 'garage', 'garage_eachen', 'lock', 'valve'],
devicesHideable: ['switch', 'light'],
devicesNonLAN: [22, 28, 59, 102],
devicesSingleSwitch: [1, 5, 6, 14, 15, 22, 24, 27, 32, 36, 44, 59],
diff --git a/lib/device/garage-eachen.js b/lib/device/garage-eachen.js
new file mode 100644
index 00000000..22c6c3eb
--- /dev/null
+++ b/lib/device/garage-eachen.js
@@ -0,0 +1,52 @@
+'use strict'
+let Characteristic, Service
+const utils = require('./../utils')
+module.exports = class deviceGarageEachen {
+ constructor (platform) {
+ this.platform = platform
+ Service = platform.api.hap.Service
+ Characteristic = platform.api.hap.Characteristic
+ }
+
+ async internalGarageEachenUpdate (accessory, value, callback) {
+ callback()
+ try {
+ let garageConfig
+ if (!(garageConfig = this.platform.cusG.get(accessory.context.hbDeviceId))) {
+ throw new Error('group config missing')
+ }
+ const params = {}
+ const newPos = value
+ const gdService = accessory.getService(Service.GarageDoorOpener)
+ const prevState = gdService.getCharacteristic(Characteristic.CurrentDoorState).value
+ if (newPos === prevState % 2) return
+ accessory.context.inUse = true
+ gdService
+ .updateCharacteristic(Characteristic.TargetDoorState, newPos)
+ .updateCharacteristic(Characteristic.CurrentDoorState, newPos + 2)
+ // newPos can be 0 TO open and 1 TO CLOSE
+ // params.switch === 'on' TO open and 'off' TO close
+ // HK 0 for open 1 for closed
+ params.switch = value === 0 ? 'on' : 'off'
+ await this.platform.sendDeviceUpdate(accessory, params)
+ await utils.sleep(garageConfig.operationTime * 100)
+ gdService.updateCharacteristic(Characteristic.CurrentDoorState, newPos)
+ accessory.context.inUse = false
+ } catch (err) {
+ this.platform.deviceUpdateError(accessory, err, true)
+ }
+ }
+
+ externalGarageEachenUpdate (accessory, params) {
+ try {
+ if (!Object.prototype.hasOwnProperty.call(params, 'switch') || accessory.context.inUse) {
+ return
+ }
+ const gdService = accessory.getService(Service.GarageDoorOpener)
+ gdService.updateCharacteristic(Characteristic.CurrentDoorState, params.switch === 'on' ? 0 : 1)
+ gdService.updateCharacteristic(Characteristic.TargetDoorState, params.switch === 'on' ? 0 : 1)
+ } catch (err) {
+ this.platform.deviceUpdateError(accessory, err, false)
+ }
+ }
+}
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index c7012c01..216a93af 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -5,6 +5,7 @@ const corrInterval = require('correcting-interval')
const DeviceCurtain = require('./device/curtain')
const DeviceBlind = require('./device/blind')
const DeviceGarage = require('./device/garage')
+const DeviceGarageEachen = require('./device/garage-eachen')
const DeviceLock = require('./device/lock')
const DeviceValve = require('./device/valve')
const DeviceSensor = require('./device/sensor')
@@ -185,6 +186,10 @@ class eWeLink {
accessory.context.cacheTargetDoorState = 1
}
//* ** @ENDUPGRADE ***\\
+ } else if (this.cusG.has(device.deviceid + 'SWX') && this.cusG.get(device.deviceid + 'SWX').type === 'garage_eachen') {
+ accessory = this.devicesInHB.has(device.deviceid + 'SWX')
+ ? this.devicesInHB.get(device.deviceid + 'SWX')
+ : this.addAccessory(device, device.deviceid + 'SWX', 'garage_eachen')
} else if (this.cusG.has(device.deviceid + 'SWX') && this.cusG.get(device.deviceid + 'SWX').type === 'lock') {
accessory = this.devicesInHB.has(device.deviceid + 'SWX')
? this.devicesInHB.get(device.deviceid + 'SWX')
@@ -546,6 +551,22 @@ class eWeLink {
.on('set', (value, callback) => accessory.control.internalGarageUpdate(accessory, value, callback))
break
}
+ case 'garage_eachen': {
+ accessory.control = new DeviceGarageEachen(this)
+ let gdeService
+ if (!(gdeService = accessory.getService(Service.GarageDoorOpener))) {
+ accessory
+ .addService(Service.GarageDoorOpener)
+ .setCharacteristic(Characteristic.CurrentDoorState, 1)
+ .setCharacteristic(Characteristic.TargetDoorState, 1)
+ .setCharacteristic(Characteristic.ObstructionDetected, false)
+ gdeService = accessory.getService(Service.GarageDoorOpener)
+ }
+ gdeService
+ .getCharacteristic(Characteristic.TargetDoorState)
+ .on('set', (value, callback) => accessory.control.internalGarageEachenUpdate(accessory, value, callback))
+ break
+ }
case 'lock': {
accessory.control = new DeviceLock(this)
const lmService = accessory.getService(Service.LockMechanism) || accessory.addService(Service.LockMechanism)
@@ -905,6 +926,9 @@ class eWeLink {
case 'garage':
accessory.control.externalGarageUpdate(accessory, newParams)
return true
+ case 'garage_eachen':
+ accessory.control.externalGarageEachenUpdate(accessory, newParams)
+ return true
case 'lock':
accessory.control.externalLockUpdate(accessory, newParams)
return true
From 76f8549888651267bba5d64e38d21a7f06717e7f Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Wed, 30 Sep 2020 11:19:24 +0100
Subject: [PATCH 0275/3183] 3.2.0-0
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index f42e1988..9c316094 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.1.7",
+ "version": "3.2.0-0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 256697ec..5fe27906 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.1.7",
+ "version": "3.2.0-0",
"author": "bwp91",
"contributors": [
"gbro115",
From 418bd33ecfa61369ad1d9de0e4d16aca2ca5d470 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Wed, 30 Sep 2020 12:41:15 +0100
Subject: [PATCH 0276/3183] clean up
---
lib/device/garage-eachen.js | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/lib/device/garage-eachen.js b/lib/device/garage-eachen.js
index 22c6c3eb..e3b683a2 100644
--- a/lib/device/garage-eachen.js
+++ b/lib/device/garage-eachen.js
@@ -24,15 +24,13 @@ module.exports = class deviceGarageEachen {
gdService
.updateCharacteristic(Characteristic.TargetDoorState, newPos)
.updateCharacteristic(Characteristic.CurrentDoorState, newPos + 2)
- // newPos can be 0 TO open and 1 TO CLOSE
- // params.switch === 'on' TO open and 'off' TO close
- // HK 0 for open 1 for closed
params.switch = value === 0 ? 'on' : 'off'
await this.platform.sendDeviceUpdate(accessory, params)
await utils.sleep(garageConfig.operationTime * 100)
gdService.updateCharacteristic(Characteristic.CurrentDoorState, newPos)
accessory.context.inUse = false
} catch (err) {
+ accessory.context.inUse = false
this.platform.deviceUpdateError(accessory, err, true)
}
}
From 1e81de777fe02300fa720e30bcb95fd4568b4379 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Wed, 30 Sep 2020 18:12:27 +0100
Subject: [PATCH 0277/3183] improved ui for custom setups
---
config.schema.json | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/config.schema.json b/config.schema.json
index e3c794e0..24211140 100644
--- a/config.schema.json
+++ b/config.schema.json
@@ -127,31 +127,31 @@
"description": "The new type for this device.",
"oneOf": [
{
- "title": "Blind",
+ "title": "Blind (Generic Setup)",
"enum": [
"blind"
]
},
{
- "title": "Garage Door",
+ "title": "Garage Door (Generic Setup)",
"enum": [
"garage"
]
},
{
- "title": "Garage Door (Eachen)",
+ "title": "Garage Door (Eachen GD-DC5)",
"enum": [
"garage_eachen"
]
},
{
- "title": "Lock",
+ "title": "Lock (Generic Setup)",
"enum": [
"lock"
]
},
{
- "title": "Irrigation",
+ "title": "Irrigation (Generic Setup)",
"enum": [
"valve"
]
@@ -162,7 +162,10 @@
"type": "string",
"title": "Device Setup",
"default": "null",
- "description": "The device setup. Blinds must be set up with two switches. Please ignore this setting for locks and irrigation.",
+ "description": "The setup for your garage doors.",
+ "condition": {
+ "functionBody": "return (model.groups[arrayIndices] && model.groups[arrayIndices].type==='garage')"
+ },
"oneOf": [
{
"title": "One Switch - for up and down",
@@ -189,7 +192,10 @@
"sensorId": {
"type": "string",
"title": "Sensor",
- "description": "A Sonoff DW2 sensor can optionally be used for garage doors. This is to determine the current open/closed state of the garage door. Please enter the 10 digit device ID (normally in the format 1000ab23cd). Otherwise leave this blank."
+ "description": "A Sonoff DW2 sensor can optionally be used for garage doors. This is to determine the current open/closed state of the garage door. Please enter the 10 digit device ID (normally in the format 1000ab23cd). Otherwise leave this blank.",
+ "condition": {
+ "functionBody": "return (model.groups[arrayIndices] && model.groups[arrayIndices].type==='garage')"
+ }
}
}
}
From 20cbbe6be8220a7cf1defb9f8ceedc4e4df0b8fe Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Thu, 1 Oct 2020 09:05:09 +0100
Subject: [PATCH 0278/3183] consistent function names
---
lib/device/blind.js | 8 +-
lib/device/curtain.js | 4 +-
lib/device/fan.js | 4 +-
lib/device/garage-eachen.js | 14 +-
lib/device/garage.js | 4 +-
lib/device/light.js | 406 +++++++++++++++++-------------------
lib/device/lock.js | 4 +-
lib/device/outlet.js | 4 +-
lib/device/rf-bridge.js | 4 +-
lib/device/scm.js | 4 +-
lib/device/sensor.js | 2 +-
lib/device/switch.js | 46 ++--
lib/device/thermostat.js | 4 +-
lib/device/usb.js | 4 +-
lib/device/valve.js | 4 +-
lib/device/zb-dev.js | 2 +-
16 files changed, 256 insertions(+), 262 deletions(-)
diff --git a/lib/device/blind.js b/lib/device/blind.js
index 9223338a..6584d7b3 100644
--- a/lib/device/blind.js
+++ b/lib/device/blind.js
@@ -9,7 +9,7 @@ module.exports = class deviceBlind {
Characteristic = platform.api.hap.Characteristic
}
- async internalBlindUpdate (accessory, value, callback) {
+ async internalUpdate (accessory, value, callback) {
callback()
try {
let blindConfig
@@ -22,7 +22,7 @@ module.exports = class deviceBlind {
if (!(blindConfig = this.platform.cusG.get(accessory.context.hbDeviceId))) {
throw new Error('group config missing')
}
- if (blindConfig.type !== 'blind' || blindConfig.setup !== 'twoSwitch') {
+ if (blindConfig.type !== 'blind') {
throw new Error('improper configuration')
}
if (newTarget === prevPosition) return
@@ -67,4 +67,8 @@ module.exports = class deviceBlind {
this.platform.deviceUpdateError(accessory, err, true)
}
}
+
+ externalUpdate (accessory, params) {
+ return true
+ }
}
diff --git a/lib/device/curtain.js b/lib/device/curtain.js
index 73e5fc3f..1b5d07cb 100644
--- a/lib/device/curtain.js
+++ b/lib/device/curtain.js
@@ -7,7 +7,7 @@ module.exports = class deviceCurtain {
Characteristic = platform.api.hap.Characteristic
}
- async internalCurtainUpdate (accessory, value, callback) {
+ async internalUpdate (accessory, value, callback) {
callback()
try {
let params
@@ -34,7 +34,7 @@ module.exports = class deviceCurtain {
}
}
- externalCurtainUpdate (accessory, params) {
+ externalUpdate (accessory, params) {
try {
const cService = accessory.getService(Service.WindowCovering)
if (!Object.prototype.hasOwnProperty.call(params, 'switch') && !Object.prototype.hasOwnProperty.call(params, 'setclose')) {
diff --git a/lib/device/fan.js b/lib/device/fan.js
index 9e829390..16221475 100644
--- a/lib/device/fan.js
+++ b/lib/device/fan.js
@@ -7,7 +7,7 @@ module.exports = class deviceFan {
Characteristic = platform.api.hap.Characteristic
}
- async internalFanUpdate (accessory, type, value, callback) {
+ async internalUpdate (accessory, type, value, callback) {
callback()
try {
let newPower
@@ -49,7 +49,7 @@ module.exports = class deviceFan {
}
}
- externalFanUpdate (accessory, params) {
+ externalUpdate (accessory, params) {
try {
let light
let status
diff --git a/lib/device/garage-eachen.js b/lib/device/garage-eachen.js
index e3b683a2..dc27d4e6 100644
--- a/lib/device/garage-eachen.js
+++ b/lib/device/garage-eachen.js
@@ -8,13 +8,16 @@ module.exports = class deviceGarageEachen {
Characteristic = platform.api.hap.Characteristic
}
- async internalGarageEachenUpdate (accessory, value, callback) {
+ async internalUpdate (accessory, value, callback) {
callback()
try {
let garageConfig
if (!(garageConfig = this.platform.cusG.get(accessory.context.hbDeviceId))) {
throw new Error('group config missing')
}
+ if (garageConfig.type !== 'garage_eachen') {
+ throw new Error('improper configuration')
+ }
const params = {}
const newPos = value
const gdService = accessory.getService(Service.GarageDoorOpener)
@@ -35,11 +38,18 @@ module.exports = class deviceGarageEachen {
}
}
- externalGarageEachenUpdate (accessory, params) {
+ externalUpdate (accessory, params) {
try {
if (!Object.prototype.hasOwnProperty.call(params, 'switch') || accessory.context.inUse) {
return
}
+ let garageConfig
+ if (!(garageConfig = this.platform.cusG.get(accessory.context.hbDeviceId))) {
+ throw new Error('group config missing')
+ }
+ if (garageConfig.type !== 'garage_eachen') {
+ throw new Error('improper configuration')
+ }
const gdService = accessory.getService(Service.GarageDoorOpener)
gdService.updateCharacteristic(Characteristic.CurrentDoorState, params.switch === 'on' ? 0 : 1)
gdService.updateCharacteristic(Characteristic.TargetDoorState, params.switch === 'on' ? 0 : 1)
diff --git a/lib/device/garage.js b/lib/device/garage.js
index 5f4cd1dc..4c1270dc 100644
--- a/lib/device/garage.js
+++ b/lib/device/garage.js
@@ -8,7 +8,7 @@ module.exports = class deviceGarage {
Characteristic = platform.api.hap.Characteristic
}
- async internalGarageUpdate (accessory, value, callback) {
+ async internalUpdate (accessory, value, callback) {
callback()
try {
let garageConfig
@@ -72,7 +72,7 @@ module.exports = class deviceGarage {
}
}
- externalGarageUpdate (accessory, params) {
+ externalUpdate (accessory, params) {
try {
if (!Object.prototype.hasOwnProperty.call(params, 'switch') && !Object.prototype.hasOwnProperty.call(params, 'switches')) {
return
diff --git a/lib/device/light.js b/lib/device/light.js
index cd8fe085..3b210f76 100644
--- a/lib/device/light.js
+++ b/lib/device/light.js
@@ -10,131 +10,117 @@ module.exports = class deviceLight {
Characteristic = platform.api.hap.Characteristic
}
- async internalLightbulbUpdate (accessory, value, callback) {
+ async internalUpdate (accessory, type, value, callback) {
callback()
try {
let oAccessory
- const params = {}
+ let newRGB
+ let params = {}
const lightService = accessory.getService(Service.Lightbulb)
- switch (accessory.context.switchNumber) {
- case 'X':
- if (accessory.context.eweUIID === 22) {
- //* ** B1 ***\\
- params.state = value ? 'on' : 'off'
- } else {
- params.switch = value ? 'on' : 'off'
+ switch (type) {
+ case 'onoff':
+ switch (accessory.context.switchNumber) {
+ case 'X':
+ if (accessory.context.eweUIID === 22) {
+ //* ** B1 ***\\
+ params.state = value ? 'on' : 'off'
+ } else {
+ params.switch = value ? 'on' : 'off'
+ }
+ break
+ case '0':
+ params.switches = cns.defaultMultiSwitchOff
+ params.switches[0].switch = value ? 'on' : 'off'
+ params.switches[1].switch = value ? 'on' : 'off'
+ params.switches[2].switch = value ? 'on' : 'off'
+ params.switches[3].switch = value ? 'on' : 'off'
+ break
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ params.switches = cns.defaultMultiSwitchOff
+ for (let i = 1; i <= 4; i++) {
+ if ((oAccessory = this.platform.devicesInHB.get(accessory.context.eweDeviceId + 'SW' + i))) {
+ i === parseInt(accessory.context.switchNumber)
+ ? (params.switches[i - 1].switch = value ? 'on' : 'off')
+ : (params.switches[i - 1].switch = oAccessory
+ .getService(Service.Lightbulb)
+ .getCharacteristic(Characteristic.On).value
+ ? 'on'
+ : 'off')
+ } else {
+ params.switches[i - 1].switch = 'off'
+ }
+ }
+ break
}
- break
- case '0':
- params.switches = cns.defaultMultiSwitchOff
- params.switches[0].switch = value ? 'on' : 'off'
- params.switches[1].switch = value ? 'on' : 'off'
- params.switches[2].switch = value ? 'on' : 'off'
- params.switches[3].switch = value ? 'on' : 'off'
- break
- case '1':
- case '2':
- case '3':
- case '4':
- params.switches = cns.defaultMultiSwitchOff
- for (let i = 1; i <= 4; i++) {
- if ((oAccessory = this.platform.devicesInHB.get(accessory.context.eweDeviceId + 'SW' + i))) {
- i === parseInt(accessory.context.switchNumber)
- ? (params.switches[i - 1].switch = value ? 'on' : 'off')
- : (params.switches[i - 1].switch = oAccessory
- .getService(Service.Lightbulb)
- .getCharacteristic(Characteristic.On).value
- ? 'on'
- : 'off')
- } else {
- params.switches[i - 1].switch = 'off'
+ await this.platform.sendDeviceUpdate(accessory, params)
+ switch (accessory.context.switchNumber) {
+ case 'X':
+ lightService.updateCharacteristic(Characteristic.On, value)
+ break
+ case '0':
+ for (let i = 0; i <= 4; i++) {
+ if ((oAccessory = this.platform.devicesInHB.get(accessory.context.eweDeviceId + 'SW' + i))) {
+ oAccessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value)
+ }
+ }
+ break
+ case '1':
+ case '2':
+ case '3':
+ case '4': {
+ lightService.updateCharacteristic(Characteristic.On, value)
+ let masterState = 'off'
+ for (let i = 1; i <= 4; i++) {
+ if ((oAccessory = this.platform.devicesInHB.get(accessory.context.eweDeviceId + 'SW' + i))) {
+ if (oAccessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value) {
+ masterState = 'on'
+ }
+ }
+ }
+ if (!this.platform.hiddenMasters.includes(accessory.context.eweDeviceId)) {
+ oAccessory = this.platform.devicesInHB.get(accessory.context.eweDeviceId + 'SW0')
+ oAccessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, masterState === 'on')
+ }
+ break
}
}
break
- }
- await this.platform.sendDeviceUpdate(accessory, params)
- switch (accessory.context.switchNumber) {
- case 'X':
- lightService.updateCharacteristic(Characteristic.On, value)
- break
- case '0':
- for (let i = 0; i <= 4; i++) {
- if ((oAccessory = this.platform.devicesInHB.get(accessory.context.eweDeviceId + 'SW' + i))) {
- oAccessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, value)
+ case 'brightness':
+ if (value === 0) {
+ params.switch = 'off'
+ } else {
+ if (!lightService.getCharacteristic(Characteristic.On).value) {
+ params.switch = 'on'
}
- }
- break
- case '1':
- case '2':
- case '3':
- case '4': {
- lightService.updateCharacteristic(Characteristic.On, value)
- let masterState = 'off'
- for (let i = 1; i <= 4; i++) {
- if ((oAccessory = this.platform.devicesInHB.get(accessory.context.eweDeviceId + 'SW' + i))) {
- if (oAccessory.getService(Service.Lightbulb).getCharacteristic(Characteristic.On).value) {
- masterState = 'on'
- }
+ switch (accessory.context.eweUIID) {
+ case 36: //* ** KING-M4 ***\\
+ params.bright = Math.round((value * 9) / 10 + 10)
+ break
+ case 44: //* ** D1 ***\\
+ params.brightness = value
+ params.mode = 0
+ break
}
}
- if (!this.platform.hiddenMasters.includes(accessory.context.eweDeviceId)) {
- oAccessory = this.platform.devicesInHB.get(accessory.context.eweDeviceId + 'SW0')
- oAccessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, masterState === 'on')
+ await utils.sleep(250)
+ await this.platform.sendDeviceUpdate(accessory, params)
+ if (value === 0) {
+ lightService.updateCharacteristic(Characteristic.On, false)
+ } else {
+ lightService.updateCharacteristic(Characteristic.Brightness, value)
}
break
- }
- }
- } catch (err) {
- this.platform.deviceUpdateError(accessory, err, true)
- }
- }
-
- async internalBrightnessUpdate (accessory, value, callback) {
- callback()
- try {
- const params = {}
- const lightService = accessory.getService(Service.Lightbulb)
- if (value === 0) {
- params.switch = 'off'
- } else {
- if (!lightService.getCharacteristic(Characteristic.On).value) {
- params.switch = 'on'
- }
- switch (accessory.context.eweUIID) {
- case 36: //* ** KING-M4 ***\\
- params.bright = Math.round((value * 9) / 10 + 10)
- break
- case 44: //* ** D1 ***\\
- params.brightness = value
- params.mode = 0
- break
- }
- }
- await utils.sleep(250)
- await this.platform.sendDeviceUpdate(accessory, params)
- if (value === 0) {
- lightService.updateCharacteristic(Characteristic.On, false)
- } else {
- lightService.updateCharacteristic(Characteristic.Brightness, value)
- }
- } catch (err) {
- this.platform.deviceUpdateError(accessory, err, true)
- }
- }
-
- async internalHSBUpdate (accessory, type, value, callback) {
- callback()
- try {
- let newRGB
- let params = {}
- const lightService = accessory.getService(Service.Lightbulb)
- const curHue = lightService.getCharacteristic(Characteristic.Hue).value
- const curSat = lightService.getCharacteristic(Characteristic.Saturation).value
- switch (type) {
- case 'hue':
- newRGB = convert.hsv.rgb(value, curSat, 100)
+ case 'c_brightness':
switch (accessory.context.eweUIID) {
case 22: //* ** B1 ***\\
+ newRGB = convert.hsv.rgb(
+ lightService.getCharacteristic(Characteristic.Hue).value,
+ lightService.getCharacteristic(Characteristic.Saturation).value,
+ value
+ )
params = {
zyx_mode: 2,
type: 'middle',
@@ -148,17 +134,18 @@ module.exports = class deviceLight {
case 59: //* ** L1 ***\\
params = {
mode: 1,
- colorR: newRGB[0],
- colorG: newRGB[1],
- colorB: newRGB[2]
+ bright: value
}
break
}
+ await utils.sleep(250)
+ await this.platform.sendDeviceUpdate(accessory, params)
+ lightService.updateCharacteristic(Characteristic.Brightness, value)
break
- case 'bri':
+ case 'c_hue':
+ newRGB = convert.hsv.rgb(value, lightService.getCharacteristic(Characteristic.Saturation).value, 100)
switch (accessory.context.eweUIID) {
case 22: //* ** B1 ***\\
- newRGB = convert.hsv.rgb(curHue, curSat, value)
params = {
zyx_mode: 2,
type: 'middle',
@@ -172,117 +159,114 @@ module.exports = class deviceLight {
case 59: //* ** L1 ***\\
params = {
mode: 1,
- bright: value
+ colorR: newRGB[0],
+ colorG: newRGB[1],
+ colorB: newRGB[2]
}
break
}
- break
- }
- await utils.sleep(250)
- await this.platform.sendDeviceUpdate(accessory, params)
- switch (type) {
- case 'hue':
+ await utils.sleep(250)
+ await this.platform.sendDeviceUpdate(accessory, params)
lightService.updateCharacteristic(Characteristic.Hue, value)
break
- case 'bri':
- lightService.updateCharacteristic(Characteristic.Brightness, value)
- break
}
} catch (err) {
this.platform.deviceUpdateError(accessory, err, true)
}
}
- externalSingleLightUpdate (accessory, params) {
+ externalUpdate (accessory, params) {
try {
- let newColour
- let mode
- let isOn = false
- const lightService = accessory.getService(Service.Lightbulb)
- if (accessory.context.eweUIID === 22 && Object.prototype.hasOwnProperty.call(params, 'state')) {
- isOn = params.state === 'on'
- } else if (accessory.context.eweUIID !== 22 && Object.prototype.hasOwnProperty.call(params, 'switch')) {
- isOn = params.switch === 'on'
- } else {
- isOn = lightService.getCharacteristic(Characteristic.On).value
- }
- if (isOn) {
- lightService.updateCharacteristic(Characteristic.On, true)
- switch (accessory.context.eweUIID) {
- case 36: // KING-M4
- if (Object.prototype.hasOwnProperty.call(params, 'bright')) {
- const nb = Math.round(((params.bright - 10) * 10) / 9) // eWeLink scale is 10-100 and HomeKit scale is 0-100.
- lightService.updateCharacteristic(Characteristic.Brightness, nb)
- }
- break
- case 44: // D1
- if (Object.prototype.hasOwnProperty.call(params, 'brightness')) {
- lightService.updateCharacteristic(Characteristic.Brightness, params.brightness)
- }
- break
- case 22: // B1
- if (Object.prototype.hasOwnProperty.call(params, 'zyx_mode')) {
- mode = parseInt(params.zyx_mode)
- } else if (Object.prototype.hasOwnProperty.call(params, 'channel0') && parseInt(params.channel0) + parseInt(params.channel1) > 0) {
- mode = 1
- } else {
- mode = 2
- }
- if (mode === 2) {
- lightService.updateCharacteristic(Characteristic.On, true)
- newColour = convert.rgb.hsv(
- parseInt(params.channel2),
- parseInt(params.channel3),
- parseInt(params.channel4)
- )
- lightService
- .updateCharacteristic(Characteristic.Hue, newColour[0])
- .updateCharacteristic(Characteristic.Saturation, 100)
- .updateCharacteristic(Characteristic.Brightness, 100)
- } else if (mode === 1) {
- throw new Error('has been set to white mode which is not supported')
- }
- break
- case 59: // L1
- if (Object.prototype.hasOwnProperty.call(params, 'bright')) {
- lightService.updateCharacteristic(Characteristic.Brightness, params.bright)
- }
- if (Object.prototype.hasOwnProperty.call(params, 'colorR')) {
- newColour = convert.rgb.hsv(params.colorR, params.colorG, params.colorB)
- lightService
- .updateCharacteristic(Characteristic.Hue, newColour[0])
- .updateCharacteristic(Characteristic.Saturation, newColour[1])
- }
- break
- default:
- return
+ if (
+ cns.devicesSingleSwitch.includes(accessory.context.eweUIID) &&
+ cns.devicesSingleSwitchLight.includes(accessory.context.eweModel)
+ ) {
+ let newColour
+ let mode
+ let isOn = false
+ const lightService = accessory.getService(Service.Lightbulb)
+ if (accessory.context.eweUIID === 22 && Object.prototype.hasOwnProperty.call(params, 'state')) {
+ isOn = params.state === 'on'
+ } else if (accessory.context.eweUIID !== 22 && Object.prototype.hasOwnProperty.call(params, 'switch')) {
+ isOn = params.switch === 'on'
+ } else {
+ isOn = lightService.getCharacteristic(Characteristic.On).value
}
- } else {
- lightService.updateCharacteristic(Characteristic.On, false)
- }
- } catch (err) {
- this.platform.deviceUpdateError(accessory, err, false)
- }
- }
-
- externalMultiLightUpdate (accessory, params) {
- try {
- if (!Object.prototype.hasOwnProperty.call(params, 'switches')) return
- const idToCheck = accessory.context.hbDeviceId.slice(0, -1)
- let primaryState = false
- for (let i = 1; i <= accessory.context.channelCount; i++) {
- if (this.platform.devicesInHB.has(idToCheck + i)) {
- const oAccessory = this.platform.devicesInHB.get(idToCheck + i)
- oAccessory
- .getService(Service.Lightbulb)
- .updateCharacteristic(Characteristic.On, params.switches[i - 1].switch === 'on')
- if (params.switches[i - 1].switch === 'on') {
- primaryState = true
+ if (isOn) {
+ lightService.updateCharacteristic(Characteristic.On, true)
+ switch (accessory.context.eweUIID) {
+ case 36: // KING-M4
+ if (Object.prototype.hasOwnProperty.call(params, 'bright')) {
+ const nb = Math.round(((params.bright - 10) * 10) / 9) // eWeLink scale is 10-100 and HomeKit scale is 0-100.
+ lightService.updateCharacteristic(Characteristic.Brightness, nb)
+ }
+ break
+ case 44: // D1
+ if (Object.prototype.hasOwnProperty.call(params, 'brightness')) {
+ lightService.updateCharacteristic(Characteristic.Brightness, params.brightness)
+ }
+ break
+ case 22: // B1
+ if (Object.prototype.hasOwnProperty.call(params, 'zyx_mode')) {
+ mode = parseInt(params.zyx_mode)
+ } else if (Object.prototype.hasOwnProperty.call(params, 'channel0') && parseInt(params.channel0) + parseInt(params.channel1) > 0) {
+ mode = 1
+ } else {
+ mode = 2
+ }
+ if (mode === 2) {
+ lightService.updateCharacteristic(Characteristic.On, true)
+ newColour = convert.rgb.hsv(
+ parseInt(params.channel2),
+ parseInt(params.channel3),
+ parseInt(params.channel4)
+ )
+ lightService
+ .updateCharacteristic(Characteristic.Hue, newColour[0])
+ .updateCharacteristic(Characteristic.Saturation, 100)
+ .updateCharacteristic(Characteristic.Brightness, 100)
+ } else if (mode === 1) {
+ throw new Error('has been set to white mode which is not supported')
+ }
+ break
+ case 59: // L1
+ if (Object.prototype.hasOwnProperty.call(params, 'bright')) {
+ lightService.updateCharacteristic(Characteristic.Brightness, params.bright)
+ }
+ if (Object.prototype.hasOwnProperty.call(params, 'colorR')) {
+ newColour = convert.rgb.hsv(params.colorR, params.colorG, params.colorB)
+ lightService
+ .updateCharacteristic(Characteristic.Hue, newColour[0])
+ .updateCharacteristic(Characteristic.Saturation, newColour[1])
+ }
+ break
+ default:
+ return
}
+ } else {
+ lightService.updateCharacteristic(Characteristic.On, false)
+ }
+ } else if (
+ cns.devicesMultiSwitch.includes(accessory.context.eweUIID) &&
+ cns.devicesMultiSwitchLight.includes(accessory.context.eweModel)
+ ) {
+ if (!Object.prototype.hasOwnProperty.call(params, 'switches')) return
+ const idToCheck = accessory.context.hbDeviceId.slice(0, -1)
+ let primaryState = false
+ for (let i = 1; i <= accessory.context.channelCount; i++) {
+ if (this.platform.devicesInHB.has(idToCheck + i)) {
+ const oAccessory = this.platform.devicesInHB.get(idToCheck + i)
+ oAccessory
+ .getService(Service.Lightbulb)
+ .updateCharacteristic(Characteristic.On, params.switches[i - 1].switch === 'on')
+ if (params.switches[i - 1].switch === 'on') {
+ primaryState = true
+ }
+ }
+ }
+ if (!this.platform.hiddenMasters.includes(accessory.context.eweDeviceId)) {
+ accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, primaryState)
}
- }
- if (!this.platform.hiddenMasters.includes(accessory.context.eweDeviceId)) {
- accessory.getService(Service.Lightbulb).updateCharacteristic(Characteristic.On, primaryState)
}
} catch (err) {
this.platform.deviceUpdateError(accessory, err, false)
diff --git a/lib/device/lock.js b/lib/device/lock.js
index e82e3882..8a4972be 100644
--- a/lib/device/lock.js
+++ b/lib/device/lock.js
@@ -8,7 +8,7 @@ module.exports = class deviceLock {
Characteristic = platform.api.hap.Characteristic
}
- async internalLockUpdate (accessory, value, callback) {
+ async internalUpdate (accessory, value, callback) {
callback()
try {
let lockConfig
@@ -37,7 +37,7 @@ module.exports = class deviceLock {
}
}
- externalLockUpdate (accessory, params) {
+ externalUpdate (accessory, params) {
try {
if (!Object.prototype.hasOwnProperty.call(params, 'switch')) return
let lockConfig
diff --git a/lib/device/outlet.js b/lib/device/outlet.js
index c244e42f..56e31434 100644
--- a/lib/device/outlet.js
+++ b/lib/device/outlet.js
@@ -9,7 +9,7 @@ module.exports = class deviceOutlet {
EveService = new hbLib.EveHomeKitTypes(platform.api)
}
- async internalOutletUpdate (accessory, value, callback) {
+ async internalUpdate (accessory, value, callback) {
callback()
try {
const params = {
@@ -23,7 +23,7 @@ module.exports = class deviceOutlet {
}
}
- externalOutletUpdate (accessory, params) {
+ externalUpdate (accessory, params) {
try {
const outletService = accessory.getService(Service.Outlet)
if (Object.prototype.hasOwnProperty.call(params, 'switch')) {
diff --git a/lib/device/rf-bridge.js b/lib/device/rf-bridge.js
index cb49dd63..2e988d4c 100644
--- a/lib/device/rf-bridge.js
+++ b/lib/device/rf-bridge.js
@@ -8,7 +8,7 @@ module.exports = class deviceRFBridge {
Characteristic = platform.api.hap.Characteristic
}
- async internalRFUpdate (accessory, rfChl, service, callback) {
+ async internalUpdate (accessory, rfChl, service, callback) {
callback()
try {
const params = {
@@ -25,7 +25,7 @@ module.exports = class deviceRFBridge {
}
}
- externalRFUpdate (accessory, params) {
+ externalUpdate (accessory, params) {
try {
if (!Object.prototype.hasOwnProperty.call(params, 'updateSource')) return
const timeNow = new Date()
diff --git a/lib/device/scm.js b/lib/device/scm.js
index 501bdb29..98dc1357 100644
--- a/lib/device/scm.js
+++ b/lib/device/scm.js
@@ -8,7 +8,7 @@ module.exports = class deviceSCM {
Characteristic = platform.api.hap.Characteristic
}
- async internalSCMUpdate (accessory, value, callback) {
+ async internalUpdate (accessory, value, callback) {
callback()
try {
const params = {
@@ -23,7 +23,7 @@ module.exports = class deviceSCM {
}
}
- externalSCMUpdate (accessory, params) {
+ externalUpdate (accessory, params) {
try {
if (!Object.prototype.hasOwnProperty.call(params, 'switches')) return
accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, params.switches[0].switch === 'on')
diff --git a/lib/device/sensor.js b/lib/device/sensor.js
index 844bca01..47a4bd2b 100644
--- a/lib/device/sensor.js
+++ b/lib/device/sensor.js
@@ -7,7 +7,7 @@ module.exports = class deviceSensor {
Characteristic = platform.api.hap.Characteristic
}
- externalSensorUpdate (accessory, params) {
+ externalUpdate (accessory, params) {
try {
if (Object.prototype.hasOwnProperty.call(params, 'battery')) {
const batteryService =
diff --git a/lib/device/switch.js b/lib/device/switch.js
index 9a70c3c1..a7422968 100644
--- a/lib/device/switch.js
+++ b/lib/device/switch.js
@@ -8,7 +8,7 @@ module.exports = class deviceSwitch {
Characteristic = platform.api.hap.Characteristic
}
- async internalSwitchUpdate (accessory, value, callback) {
+ async internalUpdate (accessory, value, callback) {
callback()
try {
let oAccessory
@@ -82,33 +82,29 @@ module.exports = class deviceSwitch {
}
}
- externalSingleSwitchUpdate (accessory, params) {
+ externalUpdate (accessory, params) {
try {
- if (!Object.prototype.hasOwnProperty.call(params, 'switch')) return
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, params.switch === 'on')
- } catch (err) {
- this.platform.deviceUpdateError(accessory, err, false)
- }
- }
-
- externalMultiSwitchUpdate (accessory, params) {
- try {
- if (!Object.prototype.hasOwnProperty.call(params, 'switches')) return
- const idToCheck = accessory.context.hbDeviceId.slice(0, -1)
- let primaryState = false
- for (let i = 1; i <= accessory.context.channelCount; i++) {
- if (this.platform.devicesInHB.has(idToCheck + i)) {
- const oAccessory = this.platform.devicesInHB.get(idToCheck + i)
- oAccessory
- .getService(Service.Switch)
- .updateCharacteristic(Characteristic.On, params.switches[i - 1].switch === 'on')
- if (params.switches[i - 1].switch === 'on') {
- primaryState = true
+ if (cns.devicesSingleSwitch.includes(accessory.context.eweUIID)) {
+ if (!Object.prototype.hasOwnProperty.call(params, 'switch')) return
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, params.switch === 'on')
+ } else if (cns.devicesMultiSwitch.includes(accessory.context.eweUIID)) {
+ if (!Object.prototype.hasOwnProperty.call(params, 'switches')) return
+ const idToCheck = accessory.context.hbDeviceId.slice(0, -1)
+ let primaryState = false
+ for (let i = 1; i <= accessory.context.channelCount; i++) {
+ if (this.platform.devicesInHB.has(idToCheck + i)) {
+ const oAccessory = this.platform.devicesInHB.get(idToCheck + i)
+ oAccessory
+ .getService(Service.Switch)
+ .updateCharacteristic(Characteristic.On, params.switches[i - 1].switch === 'on')
+ if (params.switches[i - 1].switch === 'on') {
+ primaryState = true
+ }
}
}
- }
- if (!this.platform.hiddenMasters.includes(accessory.context.eweDeviceId)) {
- accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, primaryState)
+ if (!this.platform.hiddenMasters.includes(accessory.context.eweDeviceId)) {
+ accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, primaryState)
+ }
}
} catch (err) {
this.platform.deviceUpdateError(accessory, err, false)
diff --git a/lib/device/thermostat.js b/lib/device/thermostat.js
index ba86d219..b987d601 100644
--- a/lib/device/thermostat.js
+++ b/lib/device/thermostat.js
@@ -7,7 +7,7 @@ module.exports = class deviceThermostat {
Characteristic = platform.api.hap.Characteristic
}
- async internalThermostatUpdate (accessory, value, callback) {
+ async internalUpdate (accessory, value, callback) {
callback()
try {
const params = {
@@ -22,7 +22,7 @@ module.exports = class deviceThermostat {
}
}
- externalThermostatUpdate (accessory, params) {
+ externalUpdate (accessory, params) {
try {
if (
!this.platform.config.hideTHSwitch &&
diff --git a/lib/device/usb.js b/lib/device/usb.js
index 67a58833..a2305136 100644
--- a/lib/device/usb.js
+++ b/lib/device/usb.js
@@ -8,7 +8,7 @@ module.exports = class deviceUSB {
Characteristic = platform.api.hap.Characteristic
}
- async internalUSBUpdate (accessory, value, callback) {
+ async internalUpdate (accessory, value, callback) {
callback()
try {
const params = {
@@ -23,7 +23,7 @@ module.exports = class deviceUSB {
}
}
- externalUSBUpdate (accessory, params) {
+ externalUpdate (accessory, params) {
try {
if (!Object.prototype.hasOwnProperty.call(params, 'switches')) return
accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, params.switches[0].switch === 'on')
diff --git a/lib/device/valve.js b/lib/device/valve.js
index c7d1dab8..8522fd19 100644
--- a/lib/device/valve.js
+++ b/lib/device/valve.js
@@ -6,7 +6,7 @@ module.exports = class deviceValve {
Characteristic = platform.api.hap.Characteristic
}
- async internalValveUpdate (accessory, valve, value, callback) {
+ async internalUpdate (accessory, valve, value, callback) {
callback()
try {
let valveConfig
@@ -54,7 +54,7 @@ module.exports = class deviceValve {
}
}
- externalValveUpdate (accessory, params) {
+ externalUpdate (accessory, params) {
try {
if (!Object.prototype.hasOwnProperty.call(params, 'switches')) return
let valveConfig
diff --git a/lib/device/zb-dev.js b/lib/device/zb-dev.js
index 365cedb8..d4e9cec5 100644
--- a/lib/device/zb-dev.js
+++ b/lib/device/zb-dev.js
@@ -7,7 +7,7 @@ module.exports = class deviceZBDev {
Characteristic = platform.api.hap.Characteristic
}
- externalZBUpdate (accessory, params) {
+ externalUpdate (accessory, params) {
try {
//* ** credit @tasict ***\\
if (Object.prototype.hasOwnProperty.call(params, 'battery')) {
From 8c9ab90b1d2042435faa05785a9f627307c8d0d9 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Thu, 1 Oct 2020 09:05:28 +0100
Subject: [PATCH 0279/3183] code cleanups
---
lib/eWeLink.js | 276 +++++++++++--------------------------------------
1 file changed, 58 insertions(+), 218 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 216a93af..92ff7214 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -29,9 +29,8 @@ class eWeLink {
constructor (log, config, api) {
if (!log || !api || !config) return
if (!config.username || !config.password || !config.countryCode) {
- log.error('*********** Cannot load homebridge-ewelink ************')
- log.error('eWeLink credentials missing from the Homebridge config.')
- log.error('*******************************************************')
+ log.error('************* Cannot load homebridge-ewelink *************')
+ log.error('*** eWeLink credentials missing from Homebridge config ***')
return
}
this.log = log
@@ -65,29 +64,22 @@ class eWeLink {
this.lanDevices = await this.lanClient.getHosts()
await this.lanClient.startMonitor();
(() => {
- //* ** Make a map of custom groups from Homebridge config ***\\
if (Object.keys(this.config.groups || []).length > 0) {
this.config.groups
.filter(g => Object.prototype.hasOwnProperty.call(g, 'type') && cns.allowedGroups.includes(g.type))
.filter(g => Object.prototype.hasOwnProperty.call(g, 'deviceId') && this.devicesInEW.has(g.deviceId))
.forEach(g => this.cusG.set(g.deviceId + 'SWX', g))
}
- //* ** Make a map of RF Bridge custom sensors from Homebridge config ***\\
if (Object.keys(this.config.bridgeSensors || []).length > 0) {
this.config.bridgeSensors
.filter(s => Object.prototype.hasOwnProperty.call(s, 'deviceId') && this.devicesInEW.has(s.deviceId))
.forEach(s => this.cusS.set(s.fullDeviceId, s))
}
- //* ** Logging always helps to see if everything is okay so far ***\\
this.log('[%s] eWeLink devices loaded from the Homebridge cache.', this.devicesInHB.size)
this.log('[%s] primary devices loaded from your eWeLink account.', this.devicesInEW.size)
- //* ** Remove Homebridge accessories that don't appear in eWeLink ***\\
this.devicesInHB.forEach(a => {
- if (!this.devicesInEW.has(a.context.eweDeviceId)) {
- this.removeAccessory(a)
- }
+ if (!this.devicesInEW.has(a.context.eweDeviceId)) this.removeAccessory(a)
})
- //* ** Synchronise devices between eWeLink and Homebridge and set up WS/LAN listeners ***\\
this.devicesInEW.forEach(d => this.initialiseDevice(d))
this.wsClient.receiveUpdate(d => this.receiveDeviceUpdate(d))
this.lanClient.receiveUpdate(d => this.receiveDeviceUpdate(d))
@@ -111,17 +103,16 @@ class eWeLink {
}
)
this.log("eWeLink sync complete. Don't forget to âī¸ this plugin on GitHub!")
- if (this.config.debugReqRes || false) {
+ if (this.config.debugReqRes) {
this.log.warn("Note: 'Request & Response Logging' is not advised for long-term use.")
}
})()
} catch (err) {
- this.log.error('************** Cannot load homebridge-ewelink **************')
+ this.log.error('************* Cannot load homebridge-ewelink *************')
this.log.error(this.debug ? err : err.message)
- this.log.error('************************************************************')
try {
- if (this.lanClient) await this.lanClient.closeConnection()
- if (this.wsClient) await this.wsClient.closeConnection()
+ if (this.lanClient) this.lanClient.closeConnection()
+ if (this.wsClient) this.wsClient.closeConnection()
} catch (err) {
this.log.warn(this.debug ? err : err.message)
}
@@ -129,10 +120,10 @@ class eWeLink {
}
}
- async eWeLinkShutdown () {
+ eWeLinkShutdown () {
try {
- if (this.lanClient) await this.lanClient.closeConnection()
- if (this.wsClient) await this.wsClient.closeConnection()
+ if (this.lanClient) this.lanClient.closeConnection()
+ if (this.wsClient) this.wsClient.closeConnection()
} catch (err) {
this.log.warn(this.debug ? err : err.message)
}
@@ -141,23 +132,12 @@ class eWeLink {
initialiseDevice (device) {
let accessory
- //* ** CURTAINS ***\\
if (cns.devicesCurtain.includes(device.extra.uiid)) {
accessory = this.devicesInHB.has(device.deviceid + 'SWX')
? this.devicesInHB.get(device.deviceid + 'SWX')
: this.addAccessory(device, device.deviceid + 'SWX', 'curtain', false, {
cacheCurrentPosition: 0
})
- //* ** @UPGRADE from v2 -> v3 23.09.2020 ***\\
- if (Object.prototype.hasOwnProperty.call(accessory.context, 'prevPos')) {
- accessory.context.cacheCurrentPosition = accessory.context.prevPos
- delete accessory.context.prevPos
- //* ** @ENDUPGRADE ***\\
- }
- if (!Object.prototype.hasOwnProperty.call(accessory.context, 'cacheCurrentPosition')) {
- accessory.context.cacheCurrentPosition = 0
- //* ** @ENDUPGRADE ***\\
- }
} else if (this.cusG.has(device.deviceid + 'SWX') && this.cusG.get(device.deviceid + 'SWX').type === 'blind') {
accessory = this.devicesInHB.has(device.deviceid + 'SWX')
? this.devicesInHB.get(device.deviceid + 'SWX')
@@ -166,13 +146,6 @@ class eWeLink {
cachePositionState: 2,
cacheTargetPosition: 0
})
- //* ** @UPGRADE from v2 -> v3 23.09.2020 ***\\
- if (!Object.prototype.hasOwnProperty.call(accessory.context, 'cacheCurrentPosition')) {
- accessory.context.cacheCurrentPosition = 0
- accessory.context.cachePositionState = 2
- accessory.context.cacheTargetPosition = 0
- }
- //* ** @ENDUPGRADE ***\\
} else if (this.cusG.has(device.deviceid + 'SWX') && this.cusG.get(device.deviceid + 'SWX').type === 'garage') {
accessory = this.devicesInHB.has(device.deviceid + 'SWX')
? this.devicesInHB.get(device.deviceid + 'SWX')
@@ -180,12 +153,6 @@ class eWeLink {
cacheCurrentDoorState: 1,
cacheTargetDoorState: 1
})
- //* ** @UPGRADE from v2 -> v3 23.09.2020 ***\\
- if (!Object.prototype.hasOwnProperty.call(accessory.context, 'cacheCurrentDoorState')) {
- accessory.context.cacheCurrentDoorState = 1
- accessory.context.cacheTargetDoorState = 1
- }
- //* ** @ENDUPGRADE ***\\
} else if (this.cusG.has(device.deviceid + 'SWX') && this.cusG.get(device.deviceid + 'SWX').type === 'garage_eachen') {
accessory = this.devicesInHB.has(device.deviceid + 'SWX')
? this.devicesInHB.get(device.deviceid + 'SWX')
@@ -212,16 +179,6 @@ class eWeLink {
: this.addAccessory(device, device.deviceid + 'SWX', 'thermostat', false, {
sensorType: device.params.sensorType
})
- //* ** @UPGRADE from v2 -> v3 23.09.2020 ***\\
- if (!Object.prototype.hasOwnProperty.call(accessory.context, 'sensorType')) {
- accessory.context.sensorType = device.params.sensorType
- }
- if (accessory.context.sensorType === 'DS18B20') {
- if (accessory.getService(Service.HumiditySensor)) {
- accessory.removeService(Service.HumiditySensor)
- }
- }
- //* ** @ENDUPGRADE ***\\
if (accessory.context.sensorType !== device.params.sensorType) {
accessory.context.sensorType = device.params.sensorType
this.devicesInHB.set(accessory.context.hbDeviceId, accessory)
@@ -334,7 +291,7 @@ class eWeLink {
rfMap
})
accessory.control = new DeviceRFBridge(this)
- // this.log.error(JSON.stringify(accessory.context, null, 2))
+ this.hiddenMasters.push(device.deviceid)
rfMap.forEach(subDevice => {
const swNumber = rfChlCounter + 1
let subAccessory
@@ -374,42 +331,23 @@ class eWeLink {
subAccessory.context.reachableWAN = device.online
subAccessory.context.reachableLAN = false
this.devicesInHB.set(subAccessory.context.hbDeviceId, subAccessory)
- // this.log.warn(JSON.stringify(subAccessory.context, null, 2))
rfChlCounter += Object.keys(subDevice.buttons || {}).length
})
accessory.context.channelCount = rfChlCounter
this.devicesInHB.set(accessory.context.hbDeviceId, accessory)
- } else if (cns.devicesZBBridge.includes(device.extra.uiid)) {
- // Nothing to do here but needed to avoid the below not supported error
- //* ** @UPGRADE from v2 -> v3 23.09.2020 ***\\
- if ((accessory = this.devicesInHB.get(device.deviceid + 'SWX'))) {
- this.removeAccessory(accessory)
- }
- //* ** @ENDUPGRADE ***\\
} else if (cns.devicesZB.includes(device.extra.uiid)) {
accessory = this.devicesInHB.has(device.deviceid + 'SWX')
? this.devicesInHB.get(device.deviceid + 'SWX')
: this.addAccessory(device, device.deviceid + 'SWX', 'zb_dev')
- //* ** @UPGRADE from v2 -> v3 23.09.2020 ***\\
- if (accessory.context.type === 'zb_sub') {
- accessory.context.type = 'zb_dev'
- }
- //* ** @ENDUPGRADE ***\\
} else if (cns.devicesCamera.includes(device.extra.uiid)) {
- this.log.warn(
- ' â [%s] please see "https://github.com/bwp91/homebridge-ewelink/wiki/How-to-set-up-Sonoff-Camera".',
- device.name
- )
+ this.log.warn(' â [%s] please see the homebridge-ewelink wiki for details to enable the camera', device.name)
return
- } else {
- this.log.warn(
- ' â [%s] cannot be added as it is not supported by this plugin. Please make a GitHub issue request.',
- device.name
- )
+ } else if (!cns.devicesZBBridge.includes(device.extra.uiid)) {
+ this.log.warn(' â [%s] has not been added as it is not supported. Please make a GitHub issue request.', device.name)
return
}
if (!accessory) return
- if (!this.hiddenMasters.includes(device.deviceid)) {
+ if (this.hiddenMasters.includes(device.deviceid)) {
accessory
.getService(Service.AccessoryInformation)
.setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion)
@@ -433,18 +371,11 @@ class eWeLink {
}
this.log(' â [%s] initialised %s.', device.name, str)
this.devicesInHB.set(accessory.context.hbDeviceId, accessory)
- if (!this.config.disableHTTPRefresh && !(accessory.context.switchNumber === '0' && this.hiddenMasters.includes(device.deviceid))) {
- if (!this.refreshAccessory(accessory, device.params)) {
- this.log.warn(
- '[%s] could not be initialised. Please try removing accessory from the Homebridge cache along with any secondary devices (SW1, SW2, etc.) [debug:%s:%s].',
- accessory.displayName,
- accessory.context.type,
- accessory.context.channelCount
- )
- this.log.warn(
- 'If you are unsure how to do this, please see "https://github.com/bwp91/homebridge-ewelink/wiki/How-to-remove-an-accessory-from-the-cache'
- )
- }
+ if (this.config.disableHTTPRefresh) return
+ try {
+ accessory.control.externalUpdate(accessory, device.params)
+ } catch (err) {
+ this.log.warn('[%s] could not be initialised as %s.', accessory.displayName, this.debug ? err : err.message)
}
}
@@ -516,7 +447,7 @@ class eWeLink {
}
cService
.getCharacteristic(Characteristic.TargetPosition)
- .on('set', (value, callback) => accessory.control.internalCurtainUpdate(accessory, value, callback))
+ .on('set', (value, callback) => accessory.control.internalUpdate(accessory, value, callback))
break
}
case 'blind': {
@@ -532,7 +463,7 @@ class eWeLink {
}
wcService
.getCharacteristic(Characteristic.TargetPosition)
- .on('set', (value, callback) => accessory.control.internalBlindUpdate(accessory, value, callback))
+ .on('set', (value, callback) => accessory.control.internalUpdate(accessory, value, callback))
break
}
case 'garage': {
@@ -548,7 +479,7 @@ class eWeLink {
}
gdService
.getCharacteristic(Characteristic.TargetDoorState)
- .on('set', (value, callback) => accessory.control.internalGarageUpdate(accessory, value, callback))
+ .on('set', (value, callback) => accessory.control.internalUpdate(accessory, value, callback))
break
}
case 'garage_eachen': {
@@ -564,7 +495,7 @@ class eWeLink {
}
gdeService
.getCharacteristic(Characteristic.TargetDoorState)
- .on('set', (value, callback) => accessory.control.internalGarageEachenUpdate(accessory, value, callback))
+ .on('set', (value, callback) => accessory.control.internalUpdate(accessory, value, callback))
break
}
case 'lock': {
@@ -572,7 +503,7 @@ class eWeLink {
const lmService = accessory.getService(Service.LockMechanism) || accessory.addService(Service.LockMechanism)
lmService
.getCharacteristic(Characteristic.LockTargetState)
- .on('set', (value, callback) => accessory.control.internalLockUpdate(accessory, value, callback))
+ .on('set', (value, callback) => accessory.control.internalUpdate(accessory, value, callback))
break
}
case 'valve': {
@@ -594,7 +525,7 @@ class eWeLink {
valveService
.getCharacteristic(Characteristic.Active)
.on('set', (value, callback) =>
- accessory.control.internalValveUpdate(accessory, 'Valve ' + v, value, callback)
+ accessory.control.internalUpdate(accessory, 'Valve ' + v, value, callback)
)
valveService.getCharacteristic(Characteristic.SetDuration).on('set', (value, callback) => {
if (valveService.getCharacteristic(Characteristic.InUse).value) {
@@ -621,16 +552,16 @@ class eWeLink {
const fanLightService = accessory.getService(Service.Lightbulb) || accessory.addService(Service.Lightbulb)
fanService
.getCharacteristic(Characteristic.Active)
- .on('set', (value, callback) => accessory.control.internalFanUpdate(accessory, 'power', value, callback))
+ .on('set', (value, callback) => accessory.control.internalUpdate(accessory, 'power', value, callback))
fanService
.getCharacteristic(Characteristic.RotationSpeed)
- .on('set', (value, callback) => accessory.control.internalFanUpdate(accessory, 'speed', value, callback))
+ .on('set', (value, callback) => accessory.control.internalUpdate(accessory, 'speed', value, callback))
.setProps({
minStep: 33
})
fanLightService
.getCharacteristic(Characteristic.On)
- .on('set', (value, callback) => accessory.control.internalFanUpdate(accessory, 'light', value, callback))
+ .on('set', (value, callback) => accessory.control.internalUpdate(accessory, 'light', value, callback))
break
}
case 'thermostat': {
@@ -644,7 +575,7 @@ class eWeLink {
const switchService = accessory.getService(Service.Switch) || accessory.addService(Service.Switch)
switchService
.getCharacteristic(Characteristic.On)
- .on('set', (value, callback) => accessory.control.internalThermostatUpdate(accessory, value, callback))
+ .on('set', (value, callback) => accessory.control.internalUpdate(accessory, value, callback))
}
if (!this.config.disableEveLogging) {
accessory.log = this.log
@@ -691,7 +622,7 @@ class eWeLink {
}
outletService
.getCharacteristic(Characteristic.On)
- .on('set', (value, callback) => accessory.control.internalOutletUpdate(accessory, value, callback))
+ .on('set', (value, callback) => accessory.control.internalUpdate(accessory, value, callback))
if (accessory.context.eweModel !== 'S26' && !this.config.disableEveLogging) {
accessory.log = this.log
accessory.eveLogger = new EveHistoryService('energy', accessory, {
@@ -767,7 +698,7 @@ class eWeLink {
const usbService = accessory.getService(Service.Outlet) || accessory.addService(Service.Outlet)
usbService
.getCharacteristic(Characteristic.On)
- .on('set', (value, callback) => accessory.control.internalUSBUpdate(accessory, value, callback))
+ .on('set', (value, callback) => accessory.control.internalUpdate(accessory, value, callback))
break
}
case 'scm': {
@@ -775,7 +706,7 @@ class eWeLink {
const scmService = accessory.getService(Service.Switch) || accessory.addService(Service.Switch)
scmService
.getCharacteristic(Characteristic.On)
- .on('set', (value, callback) => accessory.control.internalSCMUpdate(accessory, value, callback))
+ .on('set', (value, callback) => accessory.control.internalUpdate(accessory, value, callback))
break
}
case 'light': {
@@ -783,32 +714,32 @@ class eWeLink {
const lightService = accessory.getService(Service.Lightbulb) || accessory.addService(Service.Lightbulb)
lightService
.getCharacteristic(Characteristic.On)
- .on('set', (value, callback) => accessory.control.internalLightbulbUpdate(accessory, value, callback))
+ .on('set', (value, callback) => accessory.control.internalUpdate(accessory, 'onoff', value, callback))
if (cns.devicesBrightable.includes(accessory.context.eweUIID)) {
lightService.getCharacteristic(Characteristic.Brightness).on('set', (value, callback) => {
if (value > 0) {
if (!lightService.getCharacteristic(Characteristic.On).value) {
- accessory.control.internalLightbulbUpdate(accessory, true, function () {})
+ accessory.control.internalUpdate(accessory, 'onoff', true, function () {})
}
- accessory.control.internalBrightnessUpdate(accessory, value, callback)
+ accessory.control.internalUpdate(accessory, 'brightness', value, callback)
} else {
- accessory.control.internalLightbulbUpdate(accessory, false, callback)
+ accessory.control.internalUpdate(accessory, 'onoff', false, callback)
}
})
} else if (cns.devicesColourable.includes(accessory.context.eweUIID)) {
lightService.getCharacteristic(Characteristic.Brightness).on('set', (value, callback) => {
if (value > 0) {
if (!lightService.getCharacteristic(Characteristic.On).value) {
- accessory.control.internalLightbulbUpdate(accessory, true, function () {})
+ accessory.control.internalUpdate(accessory, 'onoff', true, function () {})
}
- accessory.control.internalHSBUpdate(accessory, 'bri', value, callback)
+ accessory.control.internalUpdate(accessory, 'c_brightness', value, callback)
} else {
- accessory.control.internalLightbulbUpdate(accessory, false, callback)
+ accessory.control.internalUpdate(accessory, 'onoff', false, callback)
}
})
lightService
.getCharacteristic(Characteristic.Hue)
- .on('set', (value, callback) => accessory.control.internalHSBUpdate(accessory, 'hue', value, callback))
+ .on('set', (value, callback) => accessory.control.internalUpdate(accessory, 'c_hue', value, callback))
lightService.getCharacteristic(Characteristic.Saturation).on('set', (value, callback) => callback())
}
break
@@ -818,7 +749,7 @@ class eWeLink {
const switchService = accessory.getService(Service.Switch) || accessory.addService(Service.Switch)
switchService
.getCharacteristic(Characteristic.On)
- .on('set', (value, callback) => accessory.control.internalSwitchUpdate(accessory, value, callback))
+ .on('set', (value, callback) => accessory.control.internalUpdate(accessory, value, callback))
break
}
case 'rf_sub': {
@@ -850,11 +781,9 @@ class eWeLink {
Object.entries(accessory.context.buttons).forEach(([chan, name]) => {
accessory.getService(name) || accessory.addService(Service.Switch, name, 'switch' + chan)
accessory.getService(name).updateCharacteristic(Characteristic.On, false)
- accessory
- .getService(name)
- .getCharacteristic(Characteristic.On)
+ accessory.getService(name).getCharacteristic(Characteristic.On)
.on('set', (value, callback) => {
- value ? accessory.control.internalRFUpdate(accessory, chan, name, callback) : callback()
+ value ? accessory.control.internalUpdate(accessory, chan, name, callback) : callback()
})
})
break
@@ -913,76 +842,6 @@ class eWeLink {
}
}
- refreshAccessory (accessory, newParams) {
- switch (accessory.context.type) {
- case 'valve':
- accessory.control.externalValveUpdate(accessory, newParams)
- return true
- case 'curtain':
- accessory.control.externalCurtainUpdate(accessory, newParams)
- return true
- case 'blind':
- return true
- case 'garage':
- accessory.control.externalGarageUpdate(accessory, newParams)
- return true
- case 'garage_eachen':
- accessory.control.externalGarageEachenUpdate(accessory, newParams)
- return true
- case 'lock':
- accessory.control.externalLockUpdate(accessory, newParams)
- return true
- case 'sensor':
- accessory.control.externalSensorUpdate(accessory, newParams)
- return true
- case 'fan':
- accessory.control.externalFanUpdate(accessory, newParams)
- return true
- case 'thermostat':
- accessory.control.externalThermostatUpdate(accessory, newParams)
- return true
- case 'outlet':
- accessory.control.externalOutletUpdate(accessory, newParams)
- return true
- case 'usb':
- accessory.control.externalUSBUpdate(accessory, newParams)
- return true
- case 'scm':
- accessory.control.externalSCMUpdate(accessory, newParams)
- return true
- case 'light':
- if (
- cns.devicesSingleSwitch.includes(accessory.context.eweUIID) &&
- cns.devicesSingleSwitchLight.includes(accessory.context.eweModel)
- ) {
- accessory.control.externalSingleLightUpdate(accessory, newParams)
- } else if (
- cns.devicesMultiSwitch.includes(accessory.context.eweUIID) &&
- cns.devicesMultiSwitchLight.includes(accessory.context.eweModel)
- ) {
- accessory.control.externalMultiLightUpdate(accessory, newParams)
- }
- return true
- case 'switch':
- if (cns.devicesSingleSwitch.includes(accessory.context.eweUIID)) {
- accessory.control.externalSingleSwitchUpdate(accessory, newParams)
- } else if (cns.devicesMultiSwitch.includes(accessory.context.eweUIID)) {
- accessory.control.externalMultiSwitchUpdate(accessory, newParams)
- }
- return true
- case 'rf_pri':
- accessory.control.externalRFUpdate(accessory, newParams)
- return true
- case 'rf_sub':
- return true
- case 'zb_dev':
- accessory.control.externalZBUpdate(accessory, newParams)
- return true
- default:
- return false
- }
- }
-
removeAccessory (accessory) {
try {
this.api.unregisterPlatformAccessories('homebridge-ewelink', 'eWeLink', [accessory])
@@ -1025,11 +884,7 @@ class eWeLink {
accessory.context.reachableWAN = device.params.online
this.devicesInHB.set(accessory.context.hbDeviceId, accessory)
reachableChange = true
- this.log.warn(
- '[%s] has been reported [%s] via [WS].',
- accessory.displayName,
- accessory.context.reachableWAN ? 'online' : 'offline'
- )
+ this.log.warn('[%s] reported [%sline] via [WS].', accessory.displayName, accessory.context.reachableWAN ? 'on' : 'off')
if (accessory.context.reachableWAN) {
try {
this.wsClient.requestUpdate(accessory)
@@ -1063,38 +918,23 @@ class eWeLink {
}
}
if (this.debug) {
- this.log(
- '[%s] externally updated from above %s message and will be refreshed.',
- accessory.displayName,
- device.params.updateSource
- )
+ this.log('[%s] %s update received and will be refreshed.', accessory.displayName, device.params.updateSource)
}
- if (!this.refreshAccessory(accessory, device.params)) {
- this.log.warn(
- '[%s] cannot be refreshed. Please try removing accessory from the Homebridge cache along with any secondary devices (SW1, SW2, etc.). [debug:%s:%s]',
- accessory.displayName,
- accessory.context.type,
- accessory.context.channelCount
- )
- this.log.warn(
- 'If you are unsure how to do this, please see "https://github.com/bwp91/homebridge-ewelink/wiki/How-to-remove-an-accessory-from-the-cache'
- )
+ try {
+ accessory.control.externalUpdate(accessory, device.params)
+ } catch (err) {
+ this.log.warn('[%s] could not be refreshed as %s.', accessory.displayName, this.debug ? err : err.message)
}
} else {
- if (!(this.config.hideDevFromHB || '').includes(deviceId)) {
- this.log.warn(
- '[%s] update received via %s does not exist in Homebridge so device will be added.',
- deviceId,
- device.params.updateSource
- )
- try {
- const device = await this.httpClient.getDevice(deviceId)
- this.initialiseDevice(device)
- this.lanClient.addDeviceToMap(device)
- } catch (err) {
- this.log.error('[%s] error getting info [%s]', deviceId, err)
- this.log.error('[%s] Please try restarting Homebridge so this device is added.', deviceId)
+ try {
+ if (!(this.config.hideDevFromHB || '').includes(deviceId)) {
+ this.log.warn('[%s] %s update received for new device which will be added.', deviceId, device.params.updateSource)
+ const newDevice = await this.httpClient.getDevice(deviceId)
+ this.initialiseDevice(newDevice)
+ this.lanClient.addDeviceToMap(newDevice)
}
+ } catch (err) {
+ this.log.warn('[%s] error getting info [%s]. Restart Homebeidge to add device.', deviceId, err.message)
}
}
}
From eb78373fd907dd61f686205ef667bd4fe2b7628b Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Thu, 1 Oct 2020 09:07:43 +0100
Subject: [PATCH 0280/3183] 3.2.0-1
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 9c316094..463b984a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.2.0-0",
+ "version": "3.2.0-1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 5fe27906..af23f2ff 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.2.0-0",
+ "version": "3.2.0-1",
"author": "bwp91",
"contributors": [
"gbro115",
From 450fe6ee139e5ad4cc6fd50eb2a7d4eb6c80ad75 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Thu, 1 Oct 2020 10:39:27 +0100
Subject: [PATCH 0281/3183] code format
---
lib/eWeLink.js | 20 +++++---------------
1 file changed, 5 insertions(+), 15 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 92ff7214..8a6cf223 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -51,7 +51,7 @@ class eWeLink {
async eWeLinkSetup () {
try {
- this.log('Plugin has finished initialising. Synching with eWeLink.')
+ this.log('Plugin has finished initialising. Syncing with eWeLink.')
this.httpClient = new EWeLinkHTTP(this.config, this.log)
await this.httpClient.getHost()
this.authData = await this.httpClient.login()
@@ -102,7 +102,7 @@ class eWeLink {
stopOnError: false
}
)
- this.log("eWeLink sync complete. Don't forget to âī¸ this plugin on GitHub!")
+ this.log("eWeLink sync complete. Don't forget to âī¸ this plugin on GitHub if you're finding it useful!")
if (this.config.debugReqRes) {
this.log.warn("Note: 'Request & Response Logging' is not advised for long-term use.")
}
@@ -183,11 +183,7 @@ class eWeLink {
accessory.context.sensorType = device.params.sensorType
this.devicesInHB.set(accessory.context.hbDeviceId, accessory)
}
- } else if (
- cns.devicesOutlet.includes(device.extra.uiid) ||
- (cns.devicesSingleSwitch.includes(device.extra.uiid) &&
- cns.devicesSingleSwitchOutlet.includes(device.productModel))
- ) {
+ } else if (cns.devicesOutlet.includes(device.extra.uiid) || (cns.devicesSingleSwitch.includes(device.extra.uiid) && cns.devicesSingleSwitchOutlet.includes(device.productModel))) {
accessory = this.devicesInHB.has(device.deviceid + 'SWX')
? this.devicesInHB.get(device.deviceid + 'SWX')
: this.addAccessory(device, device.deviceid + 'SWX', 'outlet')
@@ -199,17 +195,11 @@ class eWeLink {
accessory = this.devicesInHB.has(device.deviceid + 'SWX')
? this.devicesInHB.get(device.deviceid + 'SWX')
: this.addAccessory(device, device.deviceid + 'SWX', 'scm')
- } else if (
- cns.devicesSingleSwitch.includes(device.extra.uiid) &&
- cns.devicesSingleSwitchLight.includes(device.productModel)
- ) {
+ } else if (cns.devicesSingleSwitch.includes(device.extra.uiid) && cns.devicesSingleSwitchLight.includes(device.productModel)) {
accessory = this.devicesInHB.has(device.deviceid + 'SWX')
? this.devicesInHB.get(device.deviceid + 'SWX')
: this.addAccessory(device, device.deviceid + 'SWX', 'light')
- } else if (
- cns.devicesMultiSwitch.includes(device.extra.uiid) &&
- cns.devicesMultiSwitchLight.includes(device.productModel)
- ) {
+ } else if (cns.devicesMultiSwitch.includes(device.extra.uiid) && cns.devicesMultiSwitchLight.includes(device.productModel)) {
if (this.config.hideMasters) {
if (this.devicesInHB.has(device.deviceid + 'SW0')) {
this.removeAccessory(this.devicesInHB.get(device.deviceid + 'SW0'))
From c70c327c74c8d3b6c38cf438b6a222b9c2ef1dd3 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Thu, 1 Oct 2020 10:43:36 +0100
Subject: [PATCH 0282/3183] logic error
---
lib/eWeLink.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 8a6cf223..fa86bde0 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -337,7 +337,7 @@ class eWeLink {
return
}
if (!accessory) return
- if (this.hiddenMasters.includes(device.deviceid)) {
+ if (!this.hiddenMasters.includes(device.deviceid)) {
accessory
.getService(Service.AccessoryInformation)
.setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion)
From dc7dc7895ad86067da8589c9bd79079af8ba0509 Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Thu, 1 Oct 2020 10:49:16 +0100
Subject: [PATCH 0283/3183] Update FUNDING.yml
---
.github/FUNDING.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
index 9ccddac1..72a6f9c3 100644
--- a/.github/FUNDING.yml
+++ b/.github/FUNDING.yml
@@ -1,4 +1,4 @@
github: bwp91
patreon: bwp91
ko_fi: bwp91
-custom: https://www.paypal.me/BenPotter
+custom: ["https://www.paypal.me/BenPotter", "https://www.gofundme.com/f/aspergers-has-rules-my-life"]
From 770808a09eccc7549d3a3f9c6780013b09584ff2 Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Thu, 1 Oct 2020 10:50:17 +0100
Subject: [PATCH 0284/3183] Update FUNDING.yml
---
.github/FUNDING.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
index 72a6f9c3..0729bbfe 100644
--- a/.github/FUNDING.yml
+++ b/.github/FUNDING.yml
@@ -1,4 +1,4 @@
github: bwp91
patreon: bwp91
ko_fi: bwp91
-custom: ["https://www.paypal.me/BenPotter", "https://www.gofundme.com/f/aspergers-has-rules-my-life"]
+custom: ["https://www.paypal.me/BenPotter", "https://www.gofundme.com/f/bwp91"]
From 7173da66ce4e34f2b65d436f71d948c4705d6dde Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Thu, 1 Oct 2020 10:54:45 +0100
Subject: [PATCH 0285/3183] Update package.json
---
package.json | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/package.json b/package.json
index af23f2ff..fd2e214f 100644
--- a/package.json
+++ b/package.json
@@ -58,6 +58,10 @@
{
"type": "github",
"url": "https://github.com/sponsors/bwp91"
+ },
+ {
+ "type": "gofundme",
+ "url": "https://www.gofundme.com/f/bwp91"
}
],
"dependencies": {
From 64d6f0d3e5fc704494ae9141c046a767df9ab43d Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Thu, 1 Oct 2020 12:01:56 +0100
Subject: [PATCH 0286/3183] clarify custom device types
---
config.schema.json | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/config.schema.json b/config.schema.json
index 24211140..5732a4f1 100644
--- a/config.schema.json
+++ b/config.schema.json
@@ -111,7 +111,7 @@
"groups": {
"type": "array",
"title": "Custom Device Types",
- "description": "You can use this setting to set up custom device types within Homebridge. Currently only blinds, garage doors and locks are supported.",
+ "description": "You can use this setting to set up custom simulated HomeKit accessories from a generic single/multi-switch device.",
"items": {
"type": "object",
"properties": {
@@ -127,31 +127,31 @@
"description": "The new type for this device.",
"oneOf": [
{
- "title": "Blind (Generic Setup)",
+ "title": "Blind (using channel 0 for 'UP' and channel 1 for 'DOWN' of a multi-channel device)",
"enum": [
"blind"
]
},
{
- "title": "Garage Door (Generic Setup)",
+ "title": "Garage Door (using a single/multi-channel device)",
"enum": [
"garage"
]
},
{
- "title": "Garage Door (Eachen GD-DC5)",
+ "title": "Garage Door (using the Eachen GD-DC5)",
"enum": [
"garage_eachen"
]
},
{
- "title": "Lock (Generic Setup)",
+ "title": "Lock (using a single channel device)",
"enum": [
"lock"
]
},
{
- "title": "Irrigation (Generic Setup)",
+ "title": "Irrigation (using channels 0 and 1 of a multi-channel device)",
"enum": [
"valve"
]
@@ -320,7 +320,7 @@
{
"key": "groups",
"expandable": true,
- "title": "Custom Device Types",
+ "title": "Custom Device Simulations",
"add": "Add Another Type",
"type": "array",
"items": [
From 351455c6685f32ea03dfe644d3cfcc54ec2987ac Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Thu, 1 Oct 2020 14:30:45 +0100
Subject: [PATCH 0287/3183] code reformat
---
lib/device/blind.js | 14 +-
lib/device/curtain.js | 14 +-
lib/device/fan.js | 16 +-
lib/device/garage-eachen.js | 14 +-
lib/device/garage.js | 14 +-
lib/device/light.js | 33 ++-
lib/device/lock.js | 6 +-
lib/device/outlet.js | 99 +++++++-
lib/device/rf-bridge.js | 36 ++-
lib/device/scm.js | 6 +-
lib/device/sensor.js | 4 +-
lib/device/switch.js | 6 +-
lib/device/thermostat.js | 36 ++-
lib/device/usb.js | 6 +-
lib/device/valve.js | 34 ++-
lib/device/zb-dev.js | 48 +++-
lib/eWeLink.js | 438 ++++--------------------------------
17 files changed, 407 insertions(+), 417 deletions(-)
diff --git a/lib/device/blind.js b/lib/device/blind.js
index 6584d7b3..242eeaaf 100644
--- a/lib/device/blind.js
+++ b/lib/device/blind.js
@@ -3,10 +3,22 @@ let Characteristic, Service
const cns = require('./../constants')
const utils = require('./../utils')
module.exports = class deviceBlind {
- constructor (platform) {
+ constructor (platform, accessory) {
this.platform = platform
Service = platform.api.hap.Service
Characteristic = platform.api.hap.Characteristic
+ let wcService
+ if (!(wcService = accessory.getService(Service.WindowCovering))) {
+ accessory
+ .addService(Service.WindowCovering)
+ .setCharacteristic(Characteristic.CurrentPosition, 0)
+ .setCharacteristic(Characteristic.TargetPosition, 0)
+ .setCharacteristic(Characteristic.PositionState, 2)
+ wcService = accessory.getService(Service.WindowCovering)
+ }
+ wcService
+ .getCharacteristic(Characteristic.TargetPosition)
+ .on('set', (value, callback) => this.internalUpdate(accessory, value, callback))
}
async internalUpdate (accessory, value, callback) {
diff --git a/lib/device/curtain.js b/lib/device/curtain.js
index 1b5d07cb..d96de66a 100644
--- a/lib/device/curtain.js
+++ b/lib/device/curtain.js
@@ -1,10 +1,22 @@
'use strict'
let Characteristic, Service
module.exports = class deviceCurtain {
- constructor (platform) {
+ constructor (platform, accessory) {
this.platform = platform
Service = platform.api.hap.Service
Characteristic = platform.api.hap.Characteristic
+ let cService
+ if (!(cService = accessory.getService(Service.WindowCovering))) {
+ accessory
+ .addService(Service.WindowCovering)
+ .setCharacteristic(Characteristic.CurrentPosition, 0)
+ .setCharacteristic(Characteristic.TargetPosition, 0)
+ .setCharacteristic(Characteristic.PositionState, 2)
+ cService = accessory.getService(Service.WindowCovering)
+ }
+ cService
+ .getCharacteristic(Characteristic.TargetPosition)
+ .on('set', (value, callback) => this.internalUpdate(accessory, value, callback))
}
async internalUpdate (accessory, value, callback) {
diff --git a/lib/device/fan.js b/lib/device/fan.js
index 16221475..2eac5d9b 100644
--- a/lib/device/fan.js
+++ b/lib/device/fan.js
@@ -1,10 +1,24 @@
'use strict'
let Characteristic, Service
module.exports = class deviceFan {
- constructor (platform) {
+ constructor (platform, accessory) {
this.platform = platform
Service = platform.api.hap.Service
Characteristic = platform.api.hap.Characteristic
+ const fanService = accessory.getService(Service.Fanv2) || accessory.addService(Service.Fanv2)
+ const fanLightService = accessory.getService(Service.Lightbulb) || accessory.addService(Service.Lightbulb)
+ fanService
+ .getCharacteristic(Characteristic.Active)
+ .on('set', (value, callback) => this.internalUpdate(accessory, 'power', value, callback))
+ fanService
+ .getCharacteristic(Characteristic.RotationSpeed)
+ .on('set', (value, callback) => this.internalUpdate(accessory, 'speed', value, callback))
+ .setProps({
+ minStep: 33
+ })
+ fanLightService
+ .getCharacteristic(Characteristic.On)
+ .on('set', (value, callback) => this.internalUpdate(accessory, 'light', value, callback))
}
async internalUpdate (accessory, type, value, callback) {
diff --git a/lib/device/garage-eachen.js b/lib/device/garage-eachen.js
index dc27d4e6..91bd7e81 100644
--- a/lib/device/garage-eachen.js
+++ b/lib/device/garage-eachen.js
@@ -2,10 +2,22 @@
let Characteristic, Service
const utils = require('./../utils')
module.exports = class deviceGarageEachen {
- constructor (platform) {
+ constructor (platform, accessory) {
this.platform = platform
Service = platform.api.hap.Service
Characteristic = platform.api.hap.Characteristic
+ let gdeService
+ if (!(gdeService = accessory.getService(Service.GarageDoorOpener))) {
+ accessory
+ .addService(Service.GarageDoorOpener)
+ .setCharacteristic(Characteristic.CurrentDoorState, 1)
+ .setCharacteristic(Characteristic.TargetDoorState, 1)
+ .setCharacteristic(Characteristic.ObstructionDetected, false)
+ gdeService = accessory.getService(Service.GarageDoorOpener)
+ }
+ gdeService
+ .getCharacteristic(Characteristic.TargetDoorState)
+ .on('set', (value, callback) => this.internalUpdate(accessory, value, callback))
}
async internalUpdate (accessory, value, callback) {
diff --git a/lib/device/garage.js b/lib/device/garage.js
index 4c1270dc..599316e7 100644
--- a/lib/device/garage.js
+++ b/lib/device/garage.js
@@ -2,10 +2,22 @@
let Characteristic, Service
const utils = require('./../utils')
module.exports = class deviceGarage {
- constructor (platform) {
+ constructor (platform, accessory) {
this.platform = platform
Service = platform.api.hap.Service
Characteristic = platform.api.hap.Characteristic
+ let gdService
+ if (!(gdService = accessory.getService(Service.GarageDoorOpener))) {
+ accessory
+ .addService(Service.GarageDoorOpener)
+ .setCharacteristic(Characteristic.CurrentDoorState, 1)
+ .setCharacteristic(Characteristic.TargetDoorState, 1)
+ .setCharacteristic(Characteristic.ObstructionDetected, false)
+ gdService = accessory.getService(Service.GarageDoorOpener)
+ }
+ gdService
+ .getCharacteristic(Characteristic.TargetDoorState)
+ .on('set', (value, callback) => this.internalUpdate(accessory, value, callback))
}
async internalUpdate (accessory, value, callback) {
diff --git a/lib/device/light.js b/lib/device/light.js
index 3b210f76..7d67c7d0 100644
--- a/lib/device/light.js
+++ b/lib/device/light.js
@@ -4,10 +4,41 @@ const cns = require('./../constants')
const convert = require('color-convert')
const utils = require('./../utils')
module.exports = class deviceLight {
- constructor (platform) {
+ constructor (platform, accessory) {
this.platform = platform
Service = platform.api.hap.Service
Characteristic = platform.api.hap.Characteristic
+ const lightService = accessory.getService(Service.Lightbulb) || accessory.addService(Service.Lightbulb)
+ lightService
+ .getCharacteristic(Characteristic.On)
+ .on('set', (value, callback) => this.internalUpdate(accessory, 'onoff', value, callback))
+ if (cns.devicesBrightable.includes(accessory.context.eweUIID)) {
+ lightService.getCharacteristic(Characteristic.Brightness).on('set', (value, callback) => {
+ if (value > 0) {
+ if (!lightService.getCharacteristic(Characteristic.On).value) {
+ this.internalUpdate(accessory, 'onoff', true, function () {})
+ }
+ this.internalUpdate(accessory, 'brightness', value, callback)
+ } else {
+ this.internalUpdate(accessory, 'onoff', false, callback)
+ }
+ })
+ } else if (cns.devicesColourable.includes(accessory.context.eweUIID)) {
+ lightService.getCharacteristic(Characteristic.Brightness).on('set', (value, callback) => {
+ if (value > 0) {
+ if (!lightService.getCharacteristic(Characteristic.On).value) {
+ this.internalUpdate(accessory, 'onoff', true, function () {})
+ }
+ this.internalUpdate(accessory, 'c_brightness', value, callback)
+ } else {
+ this.internalUpdate(accessory, 'onoff', false, callback)
+ }
+ })
+ lightService
+ .getCharacteristic(Characteristic.Hue)
+ .on('set', (value, callback) => this.internalUpdate(accessory, 'c_hue', value, callback))
+ lightService.getCharacteristic(Characteristic.Saturation).on('set', (value, callback) => callback())
+ }
}
async internalUpdate (accessory, type, value, callback) {
diff --git a/lib/device/lock.js b/lib/device/lock.js
index 8a4972be..b335b281 100644
--- a/lib/device/lock.js
+++ b/lib/device/lock.js
@@ -2,10 +2,14 @@
let Characteristic, Service
const utils = require('./../utils')
module.exports = class deviceLock {
- constructor (platform) {
+ constructor (platform, accessory) {
this.platform = platform
Service = platform.api.hap.Service
Characteristic = platform.api.hap.Characteristic
+ const lmService = accessory.getService(Service.LockMechanism) || accessory.addService(Service.LockMechanism)
+ lmService
+ .getCharacteristic(Characteristic.LockTargetState)
+ .on('set', (value, callback) => this.internalUpdate(accessory, value, callback))
}
async internalUpdate (accessory, value, callback) {
diff --git a/lib/device/outlet.js b/lib/device/outlet.js
index 56e31434..9941c0ee 100644
--- a/lib/device/outlet.js
+++ b/lib/device/outlet.js
@@ -1,12 +1,107 @@
'use strict'
-let Characteristic, EveService, Service
+let Characteristic, EveHistoryService, EveService, Service
+const corrInterval = require('correcting-interval')
+const fakegato = require('fakegato-history')
const hbLib = require('homebridge-lib')
module.exports = class deviceOutlet {
- constructor (platform, homebridge) {
+ constructor (platform, accessory) {
this.platform = platform
Service = platform.api.hap.Service
Characteristic = platform.api.hap.Characteristic
EveService = new hbLib.EveHomeKitTypes(platform.api)
+ EveHistoryService = fakegato(platform.api)
+ let outletService
+ if (!(outletService = accessory.getService(Service.Outlet))) {
+ accessory.addService(Service.Outlet)
+ outletService = accessory.getService(Service.Outlet)
+ if (accessory.context.eweModel !== 'S26' && !this.platform.config.disableEveLogging) {
+ outletService.addCharacteristic(EveService.Characteristics.Voltage)
+ outletService.addCharacteristic(EveService.Characteristics.CurrentConsumption)
+ outletService.addCharacteristic(EveService.Characteristics.ElectricCurrent)
+ outletService.addCharacteristic(EveService.Characteristics.TotalConsumption)
+ outletService.addCharacteristic(EveService.Characteristics.ResetTotal)
+ accessory.context = {
+ ...accessory.context,
+ ...{
+ extraPersistedData: {},
+ lastReset: 0,
+ totalEnergy: 0,
+ totalEnergyTemp: 0
+ }
+ }
+ }
+ }
+ outletService
+ .getCharacteristic(Characteristic.On)
+ .on('set', (value, callback) => this.internalUpdate(accessory, value, callback))
+ if (accessory.context.eweModel !== 'S26' && !this.platform.config.disableEveLogging) {
+ accessory.log = this.platform.log
+ accessory.eveLogger = new EveHistoryService('energy', accessory, {
+ storage: 'fs',
+ minutes: 5,
+ path: this.platform.eveLogPath
+ })
+ corrInterval.setCorrectingInterval(() => {
+ const isOn = outletService.getCharacteristic(Characteristic.On).value
+ const currentWatt = isOn
+ ? outletService.getCharacteristic(EveService.Characteristics.CurrentConsumption).value
+ : 0
+ if (accessory.eveLogger.isHistoryLoaded()) {
+ accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData()
+ if (accessory.context.extraPersistedData !== undefined) {
+ accessory.context.totalEnergy =
+ accessory.context.extraPersistedData.totalenergy +
+ accessory.context.totalEnergyTemp +
+ (currentWatt * 10) / 3600 / 1000
+ accessory.eveLogger.setExtraPersistedData({
+ totalenergy: accessory.context.totalEnergy,
+ lastReset: accessory.context.extraPersistedData.lastReset
+ })
+ } else {
+ accessory.context.totalEnergy = accessory.context.totalEnergyTemp + (currentWatt * 10) / 3600 / 1000
+ accessory.eveLogger.setExtraPersistedData({
+ totalenergy: accessory.context.totalEnergy,
+ lastReset: 0
+ })
+ }
+ accessory.context.totalEnergytemp = 0
+ } else {
+ accessory.context.totalEnergyTemp += (currentWatt * 10) / 3600 / 1000
+ accessory.context.totalEnergy = accessory.context.totalEnergyTemp
+ }
+ accessory.eveLogger.addEntry({
+ time: Date.now(),
+ power: currentWatt
+ })
+ }, 300000)
+ outletService
+ .getCharacteristic(EveService.Characteristics.TotalConsumption)
+ .on('get', callback => {
+ accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData()
+ if (accessory.context.extraPersistedData !== undefined) {
+ accessory.context.totalEnergy = accessory.context.extraPersistedData.totalPower
+ }
+ callback(null, accessory.context.totalEnergy)
+ })
+ outletService
+ .getCharacteristic(EveService.Characteristics.ResetTotal)
+ .on('set', (value, callback) => {
+ accessory.context.totalEnergy = 0
+ accessory.context.lastReset = value
+ accessory.eveLogger.setExtraPersistedData({
+ totalPower: 0,
+ lastReset: value
+ })
+ callback()
+ })
+ .on('get', callback => {
+ accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData()
+ if (accessory.context.extraPersistedData !== undefined) {
+ accessory.context.lastReset = accessory.context.extraPersistedData.lastReset
+ }
+ callback(null, accessory.context.lastReset)
+ })
+ }
}
async internalUpdate (accessory, value, callback) {
diff --git a/lib/device/rf-bridge.js b/lib/device/rf-bridge.js
index 2e988d4c..59f267ce 100644
--- a/lib/device/rf-bridge.js
+++ b/lib/device/rf-bridge.js
@@ -2,10 +2,44 @@
let Characteristic, Service
const utils = require('./../utils')
module.exports = class deviceRFBridge {
- constructor (platform) {
+ constructor (platform, accessory) {
this.platform = platform
Service = platform.api.hap.Service
Characteristic = platform.api.hap.Characteristic
+ switch (accessory.context.subType) {
+ case 'water':
+ accessory.getService(Service.LeakSensor) || accessory.addService(Service.LeakSensor)
+ break
+ case 'fire':
+ case 'smoke':
+ accessory.getService(Service.SmokeSensor) || accessory.addService(Service.SmokeSensor)
+ break
+ case 'co':
+ accessory.getService(Service.CarbonMonoxideSensor) || accessory.addService(Service.CarbonMonoxideSensor)
+ break
+ case 'co2':
+ accessory.getService(Service.CarbonDioxideSensor) || accessory.addService(Service.CarbonDioxideSensor)
+ break
+ case 'contact':
+ accessory.getService(Service.ContactSensor) || accessory.addService(Service.ContactSensor)
+ break
+ case 'occupancy':
+ accessory.getService(Service.OccupancySensor) || accessory.addService(Service.OccupancySensor)
+ break
+ default:
+ accessory.getService(Service.MotionSensor) || accessory.addService(Service.MotionSensor)
+ break
+ case 'button':
+ Object.entries(accessory.context.buttons).forEach(([chan, name]) => {
+ accessory.getService(name) || accessory.addService(Service.Switch, name, 'switch' + chan)
+ accessory.getService(name).updateCharacteristic(Characteristic.On, false)
+ accessory.getService(name).getCharacteristic(Characteristic.On)
+ .on('set', (value, callback) => {
+ value ? this.internalUpdate(accessory, chan, name, callback) : callback()
+ })
+ })
+ break
+ }
}
async internalUpdate (accessory, rfChl, service, callback) {
diff --git a/lib/device/scm.js b/lib/device/scm.js
index 98dc1357..577c2e69 100644
--- a/lib/device/scm.js
+++ b/lib/device/scm.js
@@ -2,10 +2,14 @@
let Characteristic, Service
const cns = require('./../constants')
module.exports = class deviceSCM {
- constructor (platform) {
+ constructor (platform, accessory) {
this.platform = platform
Service = platform.api.hap.Service
Characteristic = platform.api.hap.Characteristic
+ const scmService = accessory.getService(Service.Switch) || accessory.addService(Service.Switch)
+ scmService
+ .getCharacteristic(Characteristic.On)
+ .on('set', (value, callback) => this.internalUpdate(accessory, value, callback))
}
async internalUpdate (accessory, value, callback) {
diff --git a/lib/device/sensor.js b/lib/device/sensor.js
index 47a4bd2b..5c3741b4 100644
--- a/lib/device/sensor.js
+++ b/lib/device/sensor.js
@@ -1,10 +1,12 @@
'use strict'
let Characteristic, Service
module.exports = class deviceSensor {
- constructor (platform) {
+ constructor (platform, accessory) {
this.platform = platform
Service = platform.api.hap.Service
Characteristic = platform.api.hap.Characteristic
+ accessory.getService(Service.ContactSensor) || accessory.addService(Service.ContactSensor)
+ accessory.getService(Service.BatteryService) || accessory.addService(Service.BatteryService)
}
externalUpdate (accessory, params) {
diff --git a/lib/device/switch.js b/lib/device/switch.js
index a7422968..19c7a331 100644
--- a/lib/device/switch.js
+++ b/lib/device/switch.js
@@ -2,10 +2,14 @@
let Characteristic, Service
const cns = require('./../constants')
module.exports = class deviceSwitch {
- constructor (platform) {
+ constructor (platform, accessory) {
this.platform = platform
Service = platform.api.hap.Service
Characteristic = platform.api.hap.Characteristic
+ const switchService = accessory.getService(Service.Switch) || accessory.addService(Service.Switch)
+ switchService
+ .getCharacteristic(Characteristic.On)
+ .on('set', (value, callback) => this.internalUpdate(accessory, value, callback))
}
async internalUpdate (accessory, value, callback) {
diff --git a/lib/device/thermostat.js b/lib/device/thermostat.js
index b987d601..ed36e577 100644
--- a/lib/device/thermostat.js
+++ b/lib/device/thermostat.js
@@ -1,10 +1,42 @@
'use strict'
-let Characteristic, Service
+let Characteristic, EveHistoryService, Service
+const corrInterval = require('correcting-interval')
+const fakegato = require('fakegato-history')
module.exports = class deviceThermostat {
- constructor (platform) {
+ constructor (platform, accessory) {
this.platform = platform
Service = platform.api.hap.Service
Characteristic = platform.api.hap.Characteristic
+ EveHistoryService = fakegato(platform.api)
+ const tempService = accessory.getService(Service.TemperatureSensor) || accessory.addService(Service.TemperatureSensor)
+ let humiService = false
+ if (accessory.context.sensorType !== 'DS18B20') {
+ humiService = accessory.getService(Service.HumiditySensor) || accessory.addService(Service.HumiditySensor)
+ }
+ if (!this.platform.config.hideTHSwitch) {
+ const switchService = accessory.getService(Service.Switch) || accessory.addService(Service.Switch)
+ switchService
+ .getCharacteristic(Characteristic.On)
+ .on('set', (value, callback) => this.internalUpdate(accessory, value, callback))
+ }
+ if (!this.platform.config.disableEveLogging) {
+ accessory.log = this.platform.log
+ accessory.eveLogger = new EveHistoryService('weather', accessory, {
+ storage: 'fs',
+ minutes: 5,
+ path: this.platform.eveLogPath
+ })
+ corrInterval.setCorrectingInterval(() => {
+ const dataToAdd = {
+ time: Date.now(),
+ temp: tempService.getCharacteristic(Characteristic.CurrentTemperature).value
+ }
+ if (humiService) {
+ dataToAdd.humidity = humiService.getCharacteristic(Characteristic.CurrentRelativeHumidity).value
+ }
+ accessory.eveLogger.addEntry(dataToAdd)
+ }, 300000)
+ }
}
async internalUpdate (accessory, value, callback) {
diff --git a/lib/device/usb.js b/lib/device/usb.js
index a2305136..13a2c87b 100644
--- a/lib/device/usb.js
+++ b/lib/device/usb.js
@@ -2,10 +2,14 @@
let Characteristic, Service
const cns = require('./../constants')
module.exports = class deviceUSB {
- constructor (platform) {
+ constructor (platform, accessory) {
this.platform = platform
Service = platform.api.hap.Service
Characteristic = platform.api.hap.Characteristic
+ const usbService = accessory.getService(Service.Outlet) || accessory.addService(Service.Outlet)
+ usbService
+ .getCharacteristic(Characteristic.On)
+ .on('set', (value, callback) => this.internalUpdate(accessory, value, callback))
}
async internalUpdate (accessory, value, callback) {
diff --git a/lib/device/valve.js b/lib/device/valve.js
index 8522fd19..8363706d 100644
--- a/lib/device/valve.js
+++ b/lib/device/valve.js
@@ -1,9 +1,39 @@
'use strict'
-let Characteristic
+let Characteristic, Service
module.exports = class deviceValve {
- constructor (platform) {
+ constructor (platform, accessory) {
this.platform = platform
+ Service = platform.api.hap.Service
Characteristic = platform.api.hap.Characteristic
+ const arr = ['A', 'B']
+ arr.forEach(v => {
+ let valveService
+ if (!(valveService = accessory.getService('Valve ' + v))) {
+ accessory
+ .addService(Service.Valve, 'Valve ' + v, 'valve' + v.toLowerCase())
+ .setCharacteristic(Characteristic.Active, 0)
+ .setCharacteristic(Characteristic.InUse, 0)
+ .setCharacteristic(Characteristic.ValveType, 1)
+ .setCharacteristic(Characteristic.SetDuration, Math.round((accessory.context.operationTime || 1200) / 10))
+ .addCharacteristic(Characteristic.RemainingDuration)
+ valveService = accessory.getService('Valve ' + v)
+ }
+ valveService
+ .getCharacteristic(Characteristic.Active)
+ .on('set', (value, callback) =>
+ this.internalUpdate(accessory, 'Valve ' + v, value, callback)
+ )
+ valveService.getCharacteristic(Characteristic.SetDuration).on('set', (value, callback) => {
+ if (valveService.getCharacteristic(Characteristic.InUse).value) {
+ valveService.updateCharacteristic(Characteristic.RemainingDuration, value)
+ clearTimeout(valveService.timer)
+ valveService.timer = setTimeout(() => {
+ valveService.setCharacteristic(Characteristic.Active, 0)
+ }, value * 1000)
+ }
+ callback()
+ })
+ })
}
async internalUpdate (accessory, valve, value, callback) {
diff --git a/lib/device/zb-dev.js b/lib/device/zb-dev.js
index d4e9cec5..21c309a2 100644
--- a/lib/device/zb-dev.js
+++ b/lib/device/zb-dev.js
@@ -1,10 +1,54 @@
'use strict'
-let Characteristic, Service
+let Characteristic, Service, EveHistoryService
+const corrInterval = require('correcting-interval')
+const fakegato = require('fakegato-history')
module.exports = class deviceZBDev {
- constructor (platform) {
+ constructor (platform, accessory) {
this.platform = platform
Service = platform.api.hap.Service
Characteristic = platform.api.hap.Characteristic
+ EveHistoryService = fakegato(platform.api)
+ accessory.getService(Service.BatteryService) || accessory.addService(Service.BatteryService)
+ switch (accessory.context.eweUIID) {
+ case 1000: {
+ const zbspsService =
+ accessory.getService(Service.StatelessProgrammableSwitch) ||
+ accessory.addService(Service.StatelessProgrammableSwitch)
+ if (this.platform.config.hideZBLDPress) {
+ zbspsService.getCharacteristic(Characteristic.ProgrammableSwitchEvent).setProps({
+ validValues: [0]
+ })
+ }
+ break
+ }
+ case 1770: {
+ const zbTempService =
+ accessory.getService(Service.TemperatureSensor) || accessory.addService(Service.TemperatureSensor)
+ const zbHumiService =
+ accessory.getService(Service.HumiditySensor) || accessory.addService(Service.HumiditySensor)
+ accessory.log = this.platform.log
+ accessory.eveLogger = new EveHistoryService('weather', accessory, {
+ storage: 'fs',
+ minutes: 5,
+ path: this.platform.eveLogPath
+ })
+ corrInterval.setCorrectingInterval(() => {
+ const dataToAdd = {
+ time: Date.now(),
+ temp: zbTempService.getCharacteristic(Characteristic.CurrentTemperature).value,
+ humidity: zbHumiService.getCharacteristic(Characteristic.CurrentRelativeHumidity).value
+ }
+ accessory.eveLogger.addEntry(dataToAdd)
+ }, 300000)
+ break
+ }
+ case 2026:
+ accessory.getService(Service.MotionSensor) || accessory.addService(Service.MotionSensor)
+ break
+ case 3026:
+ accessory.getService(Service.ContactSensor) || accessory.addService(Service.ContactSensor)
+ break
+ }
}
externalUpdate (accessory, params) {
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index fa86bde0..cc2310a3 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -1,7 +1,6 @@
'use strict'
-let Accessory, Characteristic, EveService, EveHistoryService, Service
+let Characteristic, Service
const cns = require('./constants')
-const corrInterval = require('correcting-interval')
const DeviceCurtain = require('./device/curtain')
const DeviceBlind = require('./device/blind')
const DeviceGarage = require('./device/garage')
@@ -21,8 +20,6 @@ const DeviceZBDev = require('./device/zb-dev')
const EWeLinkHTTP = require('./eWeLinkHTTP')
const EWeLinkWS = require('./eWeLinkWS')
const EWeLinkLAN = require('./eWeLinkLAN')
-const fakegato = require('fakegato-history')
-const hbLib = require('homebridge-lib')
const promInterval = require('interval-promise')
const utils = require('./utils')
class eWeLink {
@@ -164,7 +161,10 @@ class eWeLink {
} else if (this.cusG.has(device.deviceid + 'SWX') && this.cusG.get(device.deviceid + 'SWX').type === 'valve') {
accessory = this.devicesInHB.has(device.deviceid + 'SWX')
? this.devicesInHB.get(device.deviceid + 'SWX')
- : this.addAccessory(device, device.deviceid + 'SWX', 'valve')
+ : this.addAccessory(device, device.deviceid + 'SWX', 'valve', false, {
+ operationTime: this.cusG.get(device.deviceid + 'SWX').operationTime
+ })
+ accessory.context.operationTime = this.cusG.get(device.deviceid + 'SWX').operationTime
} else if (cns.devicesSensor.includes(device.extra.uiid)) {
accessory = this.devicesInHB.has(device.deviceid + 'SWX')
? this.devicesInHB.get(device.deviceid + 'SWX')
@@ -206,7 +206,7 @@ class eWeLink {
}
this.hiddenMasters.push(device.deviceid)
accessory = this.addAccessory(device, device.deviceid + 'SW0', 'light', true)
- accessory.control = new DeviceLight(this)
+ accessory.control = new DeviceLight(this, accessory)
} else {
accessory = this.devicesInHB.has(device.deviceid + 'SW0')
? this.devicesInHB.get(device.deviceid + 'SW0')
@@ -240,7 +240,7 @@ class eWeLink {
}
this.hiddenMasters.push(device.deviceid)
accessory = this.addAccessory(device, device.deviceid + 'SW0', 'switch', true)
- accessory.control = new DeviceSwitch(this)
+ accessory.control = new DeviceSwitch(this, accessory)
} else {
accessory = this.devicesInHB.has(device.deviceid + 'SW0')
? this.devicesInHB.get(device.deviceid + 'SW0')
@@ -280,7 +280,7 @@ class eWeLink {
: this.addAccessory(device, device.deviceid + 'SW0', 'rf_pri', true, {
rfMap
})
- accessory.control = new DeviceRFBridge(this)
+ accessory.control = new DeviceRFBridge(this, accessory)
this.hiddenMasters.push(device.deviceid)
rfMap.forEach(subDevice => {
const swNumber = rfChlCounter + 1
@@ -383,7 +383,7 @@ class eWeLink {
newDeviceName = this.config.nameOverride[hbDeviceId]
}
try {
- const accessory = new Accessory(newDeviceName, this.api.hap.uuid.generate(hbDeviceId).toString())
+ const accessory = new this.api.platformAccessory(newDeviceName, this.api.hap.uuid.generate(hbDeviceId).toString())
if (!hidden) {
accessory
.getService(Service.AccessoryInformation)
@@ -424,407 +424,54 @@ class eWeLink {
accessory.context.reachableWAN = true
accessory.context.reachableLAN = true
switch (accessory.context.type) {
- case 'curtain': {
- accessory.control = new DeviceCurtain(this)
- let cService
- if (!(cService = accessory.getService(Service.WindowCovering))) {
- accessory
- .addService(Service.WindowCovering)
- .setCharacteristic(Characteristic.CurrentPosition, 0)
- .setCharacteristic(Characteristic.TargetPosition, 0)
- .setCharacteristic(Characteristic.PositionState, 2)
- cService = accessory.getService(Service.WindowCovering)
- }
- cService
- .getCharacteristic(Characteristic.TargetPosition)
- .on('set', (value, callback) => accessory.control.internalUpdate(accessory, value, callback))
+ case 'curtain':
+ accessory.control = new DeviceCurtain(this, accessory)
break
- }
- case 'blind': {
- accessory.control = new DeviceBlind(this)
- let wcService
- if (!(wcService = accessory.getService(Service.WindowCovering))) {
- accessory
- .addService(Service.WindowCovering)
- .setCharacteristic(Characteristic.CurrentPosition, 0)
- .setCharacteristic(Characteristic.TargetPosition, 0)
- .setCharacteristic(Characteristic.PositionState, 2)
- wcService = accessory.getService(Service.WindowCovering)
- }
- wcService
- .getCharacteristic(Characteristic.TargetPosition)
- .on('set', (value, callback) => accessory.control.internalUpdate(accessory, value, callback))
+ case 'blind':
+ accessory.control = new DeviceBlind(this, accessory)
break
- }
- case 'garage': {
- accessory.control = new DeviceGarage(this)
- let gdService
- if (!(gdService = accessory.getService(Service.GarageDoorOpener))) {
- accessory
- .addService(Service.GarageDoorOpener)
- .setCharacteristic(Characteristic.CurrentDoorState, 1)
- .setCharacteristic(Characteristic.TargetDoorState, 1)
- .setCharacteristic(Characteristic.ObstructionDetected, false)
- gdService = accessory.getService(Service.GarageDoorOpener)
- }
- gdService
- .getCharacteristic(Characteristic.TargetDoorState)
- .on('set', (value, callback) => accessory.control.internalUpdate(accessory, value, callback))
+ case 'garage':
+ accessory.control = new DeviceGarage(this, accessory)
break
- }
- case 'garage_eachen': {
- accessory.control = new DeviceGarageEachen(this)
- let gdeService
- if (!(gdeService = accessory.getService(Service.GarageDoorOpener))) {
- accessory
- .addService(Service.GarageDoorOpener)
- .setCharacteristic(Characteristic.CurrentDoorState, 1)
- .setCharacteristic(Characteristic.TargetDoorState, 1)
- .setCharacteristic(Characteristic.ObstructionDetected, false)
- gdeService = accessory.getService(Service.GarageDoorOpener)
- }
- gdeService
- .getCharacteristic(Characteristic.TargetDoorState)
- .on('set', (value, callback) => accessory.control.internalUpdate(accessory, value, callback))
+ case 'garage_eachen':
+ accessory.control = new DeviceGarageEachen(this, accessory)
break
- }
- case 'lock': {
- accessory.control = new DeviceLock(this)
- const lmService = accessory.getService(Service.LockMechanism) || accessory.addService(Service.LockMechanism)
- lmService
- .getCharacteristic(Characteristic.LockTargetState)
- .on('set', (value, callback) => accessory.control.internalUpdate(accessory, value, callback))
+ case 'lock':
+ accessory.control = new DeviceLock(this, accessory)
break
- }
- case 'valve': {
- accessory.control = new DeviceValve(this)
- const valveConfig = this.cusG.get(accessory.context.hbDeviceId)
- const arr = ['A', 'B']
- arr.forEach(v => {
- let valveService
- if (!(valveService = accessory.getService('Valve ' + v))) {
- accessory
- .addService(Service.Valve, 'Valve ' + v, 'valve' + v.toLowerCase())
- .setCharacteristic(Characteristic.Active, 0)
- .setCharacteristic(Characteristic.InUse, 0)
- .setCharacteristic(Characteristic.ValveType, 1)
- .setCharacteristic(Characteristic.SetDuration, Math.round(valveConfig.operationTime / 10) || 120)
- .addCharacteristic(Characteristic.RemainingDuration)
- valveService = accessory.getService('Valve ' + v)
- }
- valveService
- .getCharacteristic(Characteristic.Active)
- .on('set', (value, callback) =>
- accessory.control.internalUpdate(accessory, 'Valve ' + v, value, callback)
- )
- valveService.getCharacteristic(Characteristic.SetDuration).on('set', (value, callback) => {
- if (valveService.getCharacteristic(Characteristic.InUse).value) {
- valveService.updateCharacteristic(Characteristic.RemainingDuration, value)
- clearTimeout(valveService.timer)
- valveService.timer = setTimeout(() => {
- valveService.setCharacteristic(Characteristic.Active, 0)
- }, value * 1000)
- }
- callback()
- })
- })
+ case 'valve':
+ accessory.control = new DeviceValve(this, accessory)
break
- }
- case 'sensor': {
- accessory.control = new DeviceSensor(this)
- accessory.getService(Service.ContactSensor) || accessory.addService(Service.ContactSensor)
- accessory.getService(Service.BatteryService) || accessory.addService(Service.BatteryService)
+ case 'sensor':
+ accessory.control = new DeviceSensor(this, accessory)
break
- }
- case 'fan': {
- accessory.control = new DeviceFan(this)
- const fanService = accessory.getService(Service.Fanv2) || accessory.addService(Service.Fanv2)
- const fanLightService = accessory.getService(Service.Lightbulb) || accessory.addService(Service.Lightbulb)
- fanService
- .getCharacteristic(Characteristic.Active)
- .on('set', (value, callback) => accessory.control.internalUpdate(accessory, 'power', value, callback))
- fanService
- .getCharacteristic(Characteristic.RotationSpeed)
- .on('set', (value, callback) => accessory.control.internalUpdate(accessory, 'speed', value, callback))
- .setProps({
- minStep: 33
- })
- fanLightService
- .getCharacteristic(Characteristic.On)
- .on('set', (value, callback) => accessory.control.internalUpdate(accessory, 'light', value, callback))
+ case 'fan':
+ accessory.control = new DeviceFan(this, accessory)
break
- }
- case 'thermostat': {
- accessory.control = new DeviceThermostat(this)
- const tempService = accessory.getService(Service.TemperatureSensor) || accessory.addService(Service.TemperatureSensor)
- let humiService = false
- if (accessory.context.sensorType !== 'DS18B20') {
- humiService = accessory.getService(Service.HumiditySensor) || accessory.addService(Service.HumiditySensor)
- }
- if (!this.config.hideTHSwitch) {
- const switchService = accessory.getService(Service.Switch) || accessory.addService(Service.Switch)
- switchService
- .getCharacteristic(Characteristic.On)
- .on('set', (value, callback) => accessory.control.internalUpdate(accessory, value, callback))
- }
- if (!this.config.disableEveLogging) {
- accessory.log = this.log
- accessory.eveLogger = new EveHistoryService('weather', accessory, {
- storage: 'fs',
- minutes: 5,
- path: this.eveLogPath
- })
- corrInterval.setCorrectingInterval(() => {
- const dataToAdd = {
- time: Date.now(),
- temp: tempService.getCharacteristic(Characteristic.CurrentTemperature).value
- }
- if (humiService) {
- dataToAdd.humidity = humiService.getCharacteristic(Characteristic.CurrentRelativeHumidity).value
- }
- accessory.eveLogger.addEntry(dataToAdd)
- }, 300000)
- }
+ case 'thermostat':
+ accessory.control = new DeviceThermostat(this, accessory)
break
- }
- case 'outlet': {
- accessory.control = new DeviceOutlet(this)
- let outletService
- if (!(outletService = accessory.getService(Service.Outlet))) {
- accessory.addService(Service.Outlet)
- outletService = accessory.getService(Service.Outlet)
- if (accessory.context.eweModel !== 'S26' && !this.config.disableEveLogging) {
- outletService.addCharacteristic(EveService.Characteristics.Voltage)
- outletService.addCharacteristic(EveService.Characteristics.CurrentConsumption)
- outletService.addCharacteristic(EveService.Characteristics.ElectricCurrent)
- outletService.addCharacteristic(EveService.Characteristics.TotalConsumption)
- outletService.addCharacteristic(EveService.Characteristics.ResetTotal)
- accessory.context = {
- ...accessory.context,
- ...{
- extraPersistedData: {},
- lastReset: 0,
- totalEnergy: 0,
- totalEnergyTemp: 0
- }
- }
- }
- }
- outletService
- .getCharacteristic(Characteristic.On)
- .on('set', (value, callback) => accessory.control.internalUpdate(accessory, value, callback))
- if (accessory.context.eweModel !== 'S26' && !this.config.disableEveLogging) {
- accessory.log = this.log
- accessory.eveLogger = new EveHistoryService('energy', accessory, {
- storage: 'fs',
- minutes: 5,
- path: this.eveLogPath
- })
- corrInterval.setCorrectingInterval(() => {
- const isOn = outletService.getCharacteristic(Characteristic.On).value
- const currentWatt = isOn
- ? outletService.getCharacteristic(EveService.Characteristics.CurrentConsumption).value
- : 0
- if (accessory.eveLogger.isHistoryLoaded()) {
- accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData()
- if (accessory.context.extraPersistedData !== undefined) {
- accessory.context.totalEnergy =
- accessory.context.extraPersistedData.totalenergy +
- accessory.context.totalEnergyTemp +
- (currentWatt * 10) / 3600 / 1000
- accessory.eveLogger.setExtraPersistedData({
- totalenergy: accessory.context.totalEnergy,
- lastReset: accessory.context.extraPersistedData.lastReset
- })
- } else {
- accessory.context.totalEnergy = accessory.context.totalEnergyTemp + (currentWatt * 10) / 3600 / 1000
- accessory.eveLogger.setExtraPersistedData({
- totalenergy: accessory.context.totalEnergy,
- lastReset: 0
- })
- }
- accessory.context.totalEnergytemp = 0
- } else {
- accessory.context.totalEnergyTemp += (currentWatt * 10) / 3600 / 1000
- accessory.context.totalEnergy = accessory.context.totalEnergyTemp
- }
- accessory.eveLogger.addEntry({
- time: Date.now(),
- power: currentWatt
- })
- }, 300000)
- outletService
- .getCharacteristic(EveService.Characteristics.TotalConsumption)
- .on('get', callback => {
- accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData()
- if (accessory.context.extraPersistedData !== undefined) {
- accessory.context.totalEnergy = accessory.context.extraPersistedData.totalPower
- }
- callback(null, accessory.context.totalEnergy)
- })
- outletService
- .getCharacteristic(EveService.Characteristics.ResetTotal)
- .on('set', (value, callback) => {
- accessory.context.totalEnergy = 0
- accessory.context.lastReset = value
- accessory.eveLogger.setExtraPersistedData({
- totalPower: 0,
- lastReset: value
- })
- callback()
- })
- .on('get', callback => {
- accessory.context.extraPersistedData = accessory.eveLogger.getExtraPersistedData()
- if (accessory.context.extraPersistedData !== undefined) {
- accessory.context.lastReset = accessory.context.extraPersistedData.lastReset
- }
- callback(null, accessory.context.lastReset)
- })
- }
+ case 'outlet':
+ accessory.control = new DeviceOutlet(this, accessory)
break
- }
- case 'usb': {
- accessory.control = new DeviceUSB(this)
- const usbService = accessory.getService(Service.Outlet) || accessory.addService(Service.Outlet)
- usbService
- .getCharacteristic(Characteristic.On)
- .on('set', (value, callback) => accessory.control.internalUpdate(accessory, value, callback))
+ case 'usb':
+ accessory.control = new DeviceUSB(this, accessory)
break
- }
- case 'scm': {
- accessory.control = new DeviceSCM(this)
- const scmService = accessory.getService(Service.Switch) || accessory.addService(Service.Switch)
- scmService
- .getCharacteristic(Characteristic.On)
- .on('set', (value, callback) => accessory.control.internalUpdate(accessory, value, callback))
+ case 'scm':
+ accessory.control = new DeviceSCM(this, accessory)
break
- }
- case 'light': {
- accessory.control = new DeviceLight(this)
- const lightService = accessory.getService(Service.Lightbulb) || accessory.addService(Service.Lightbulb)
- lightService
- .getCharacteristic(Characteristic.On)
- .on('set', (value, callback) => accessory.control.internalUpdate(accessory, 'onoff', value, callback))
- if (cns.devicesBrightable.includes(accessory.context.eweUIID)) {
- lightService.getCharacteristic(Characteristic.Brightness).on('set', (value, callback) => {
- if (value > 0) {
- if (!lightService.getCharacteristic(Characteristic.On).value) {
- accessory.control.internalUpdate(accessory, 'onoff', true, function () {})
- }
- accessory.control.internalUpdate(accessory, 'brightness', value, callback)
- } else {
- accessory.control.internalUpdate(accessory, 'onoff', false, callback)
- }
- })
- } else if (cns.devicesColourable.includes(accessory.context.eweUIID)) {
- lightService.getCharacteristic(Characteristic.Brightness).on('set', (value, callback) => {
- if (value > 0) {
- if (!lightService.getCharacteristic(Characteristic.On).value) {
- accessory.control.internalUpdate(accessory, 'onoff', true, function () {})
- }
- accessory.control.internalUpdate(accessory, 'c_brightness', value, callback)
- } else {
- accessory.control.internalUpdate(accessory, 'onoff', false, callback)
- }
- })
- lightService
- .getCharacteristic(Characteristic.Hue)
- .on('set', (value, callback) => accessory.control.internalUpdate(accessory, 'c_hue', value, callback))
- lightService.getCharacteristic(Characteristic.Saturation).on('set', (value, callback) => callback())
- }
+ case 'light':
+ accessory.control = new DeviceLight(this, accessory)
break
- }
- case 'switch': {
- accessory.control = new DeviceSwitch(this)
- const switchService = accessory.getService(Service.Switch) || accessory.addService(Service.Switch)
- switchService
- .getCharacteristic(Characteristic.On)
- .on('set', (value, callback) => accessory.control.internalUpdate(accessory, value, callback))
+ case 'switch':
+ accessory.control = new DeviceSwitch(this, accessory)
break
- }
- case 'rf_sub': {
- accessory.control = new DeviceRFBridge(this)
- switch (accessory.context.subType) {
- case 'water':
- accessory.getService(Service.LeakSensor) || accessory.addService(Service.LeakSensor)
- break
- case 'fire':
- case 'smoke':
- accessory.getService(Service.SmokeSensor) || accessory.addService(Service.SmokeSensor)
- break
- case 'co':
- accessory.getService(Service.CarbonMonoxideSensor) || accessory.addService(Service.CarbonMonoxideSensor)
- break
- case 'co2':
- accessory.getService(Service.CarbonDioxideSensor) || accessory.addService(Service.CarbonDioxideSensor)
- break
- case 'contact':
- accessory.getService(Service.ContactSensor) || accessory.addService(Service.ContactSensor)
- break
- case 'occupancy':
- accessory.getService(Service.OccupancySensor) || accessory.addService(Service.OccupancySensor)
- break
- default:
- accessory.getService(Service.MotionSensor) || accessory.addService(Service.MotionSensor)
- break
- case 'button':
- Object.entries(accessory.context.buttons).forEach(([chan, name]) => {
- accessory.getService(name) || accessory.addService(Service.Switch, name, 'switch' + chan)
- accessory.getService(name).updateCharacteristic(Characteristic.On, false)
- accessory.getService(name).getCharacteristic(Characteristic.On)
- .on('set', (value, callback) => {
- value ? accessory.control.internalUpdate(accessory, chan, name, callback) : callback()
- })
- })
- break
- }
+ case 'rf_sub':
+ accessory.control = new DeviceRFBridge(this, accessory)
break
- }
- case 'zb_dev': { //* ** credit @tasict ***\\
- accessory.control = new DeviceZBDev(this)
- accessory.getService(Service.BatteryService) || accessory.addService(Service.BatteryService)
- switch (accessory.context.eweUIID) {
- case 1000: {
- const zbspsService =
- accessory.getService(Service.StatelessProgrammableSwitch) ||
- accessory.addService(Service.StatelessProgrammableSwitch)
- if (this.config.hideZBLDPress) {
- zbspsService.getCharacteristic(Characteristic.ProgrammableSwitchEvent).setProps({
- validValues: [0]
- })
- }
- break
- }
- case 1770: {
- const zbTempService =
- accessory.getService(Service.TemperatureSensor) || accessory.addService(Service.TemperatureSensor)
- const zbHumiService =
- accessory.getService(Service.HumiditySensor) || accessory.addService(Service.HumiditySensor)
- accessory.log = this.log
- accessory.eveLogger = new EveHistoryService('weather', accessory, {
- storage: 'fs',
- minutes: 5,
- path: this.eveLogPath
- })
- corrInterval.setCorrectingInterval(() => {
- const dataToAdd = {
- time: Date.now(),
- temp: zbTempService.getCharacteristic(Characteristic.CurrentTemperature).value,
- humidity: zbHumiService.getCharacteristic(Characteristic.CurrentRelativeHumidity).value
- }
- accessory.eveLogger.addEntry(dataToAdd)
- }, 300000)
- break
- }
- case 2026:
- accessory.getService(Service.MotionSensor) || accessory.addService(Service.MotionSensor)
- break
- case 3026:
- accessory.getService(Service.ContactSensor) || accessory.addService(Service.ContactSensor)
- break
- }
+ case 'zb_dev': //* ** credit @tasict ***\\
+ accessory.control = new DeviceZBDev(this, accessory)
break
- }
}
this.devicesInHB.set(accessory.context.hbDeviceId, accessory)
} catch (err) {
@@ -944,10 +591,7 @@ class eWeLink {
}
}
module.exports = function (homebridge) {
- Accessory = homebridge.platformAccessory
Characteristic = homebridge.hap.Characteristic
- EveService = new hbLib.EveHomeKitTypes(homebridge)
- EveHistoryService = fakegato(homebridge)
Service = homebridge.hap.Service
return eWeLink
}
From ad4de39b217648e6f5f7c501d9a034b1caf66ce5 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Thu, 1 Oct 2020 16:15:57 +0100
Subject: [PATCH 0288/3183] code overhaul
---
lib/constants.js | 18 +-
lib/device/valve.js | 3 +-
lib/eWeLink.js | 547 ++++++++++++++++++++------------------------
3 files changed, 251 insertions(+), 317 deletions(-)
diff --git a/lib/constants.js b/lib/constants.js
index 0f618fb6..b23eb05b 100644
--- a/lib/constants.js
+++ b/lib/constants.js
@@ -7,39 +7,23 @@ module.exports = {
devicesHideable: ['switch', 'light'],
devicesNonLAN: [22, 28, 59, 102],
devicesSingleSwitch: [1, 5, 6, 14, 15, 22, 24, 27, 32, 36, 44, 59],
- devicesSingleSwitchParams: ['switch'],
- devicesSingleSwitchOutlet: ['Sonoff Pow', 'S26'],
devicesMultiSwitch: [2, 3, 4, 7, 8, 9, 29, 30, 31, 34, 41],
- devicesMultiSwitchParams: ['switches'],
devicesSingleSwitchLight: ['T1 1C', 'L1', 'B1', 'B1_R2', 'TX1C', 'D1', 'D1R1', 'KING-M4', 'Slampher', 'GTTA59'],
- devicesSingleSwitchLightParams: ['switch', 'state', 'bright', 'colorR', 'brightness', 'channel0', 'channel2', 'xyz_mode'],
devicesMultiSwitchLight: ['T1 2C', 'T1 3C', 'TX2C', 'TX3C'],
- devicesMultiSwitchLightParams: ['switches'],
+ devicesSingleSwitchOutlet: ['Sonoff Pow', 'S26'],
devicesBrightable: [36, 44],
devicesColourable: [22, 59],
devicesCurtain: [11],
- devicesCurtainParams: ['switch', 'setclose'],
devicesSensor: [102],
- devicesSensorParams: ['switch', 'battery'],
devicesThermostat: [15],
- devicesThermostatParams: ['currentTemperature', 'currentHumidity', 'switch', 'masterSwitch'],
devicesFan: [34],
- devicesFanParams: ['switches', 'light', 'fan', 'speed'],
devicesOutlet: [32],
- devicesOutletParams: ['switch', 'power', 'voltage', 'current'],
devicesCamera: [87],
devicesUSB: [77],
- devicesUSBParams: ['switches'],
devicesSCM: [78],
- devicesSCMParams: ['switches'],
devicesRFBridge: [28],
- devicesRFBridgeParams: ['cmd'],
devicesZBBridge: [66],
- devicesZBBridgeParams: ['key', 'temperature', 'humidity', 'motion', 'lock', 'trigTime', 'battery'],
devicesZB: [1000, 1770, 2026, 3026],
- devicesValveParams: ['switches'],
- devicesGarageParams: ['switch', 'switches'],
- devicesLockParams: ['switch'],
paramsToKeep: ['battery', 'bright', 'brightness', 'channel', 'cmd', 'colorB', 'colorG', 'colorR', 'current', 'currentHumidity', 'currentTemperature', 'fan', 'humidity', 'key', 'light', 'lock', 'mainSwitch', 'mode', 'motion', 'online', 'power', 'rfChl', 'rfList', 'rfTrig', 'sensorType', 'setclose', 'speed', 'state', 'switch', 'switches', 'temperature', 'trigTime', 'type', 'voltage', 'zyx_mode'],
defaultMultiSwitchOff: [{
switch: 'off',
diff --git a/lib/device/valve.js b/lib/device/valve.js
index 8363706d..9aab7584 100644
--- a/lib/device/valve.js
+++ b/lib/device/valve.js
@@ -8,13 +8,14 @@ module.exports = class deviceValve {
const arr = ['A', 'B']
arr.forEach(v => {
let valveService
+ const valveConfig = this.platform.cusG.get(accessory.context.hbDeviceId)
if (!(valveService = accessory.getService('Valve ' + v))) {
accessory
.addService(Service.Valve, 'Valve ' + v, 'valve' + v.toLowerCase())
.setCharacteristic(Characteristic.Active, 0)
.setCharacteristic(Characteristic.InUse, 0)
.setCharacteristic(Characteristic.ValveType, 1)
- .setCharacteristic(Characteristic.SetDuration, Math.round((accessory.context.operationTime || 1200) / 10))
+ .setCharacteristic(Characteristic.SetDuration, Math.round((valveConfig.operationTime || 1200) / 10))
.addCharacteristic(Characteristic.RemainingDuration)
valveService = accessory.getService('Valve ' + v)
}
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index cc2310a3..2e4d277d 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -94,10 +94,7 @@ class eWeLink {
this.log.warn(this.debug ? err : err.message)
}
}
- },
- 1800000, {
- stopOnError: false
- }
+ }, 1800000, { stopOnError: false }
)
this.log("eWeLink sync complete. Don't forget to âī¸ this plugin on GitHub if you're finding it useful!")
if (this.config.debugReqRes) {
@@ -129,247 +126,257 @@ class eWeLink {
initialiseDevice (device) {
let accessory
- if (cns.devicesCurtain.includes(device.extra.uiid)) {
- accessory = this.devicesInHB.has(device.deviceid + 'SWX')
- ? this.devicesInHB.get(device.deviceid + 'SWX')
- : this.addAccessory(device, device.deviceid + 'SWX', 'curtain', false, {
- cacheCurrentPosition: 0
- })
- } else if (this.cusG.has(device.deviceid + 'SWX') && this.cusG.get(device.deviceid + 'SWX').type === 'blind') {
- accessory = this.devicesInHB.has(device.deviceid + 'SWX')
- ? this.devicesInHB.get(device.deviceid + 'SWX')
- : this.addAccessory(device, device.deviceid + 'SWX', 'blind', false, {
- cacheCurrentPosition: 0,
- cachePositionState: 2,
- cacheTargetPosition: 0
- })
- } else if (this.cusG.has(device.deviceid + 'SWX') && this.cusG.get(device.deviceid + 'SWX').type === 'garage') {
- accessory = this.devicesInHB.has(device.deviceid + 'SWX')
- ? this.devicesInHB.get(device.deviceid + 'SWX')
- : this.addAccessory(device, device.deviceid + 'SWX', 'garage', false, {
- cacheCurrentDoorState: 1,
- cacheTargetDoorState: 1
- })
- } else if (this.cusG.has(device.deviceid + 'SWX') && this.cusG.get(device.deviceid + 'SWX').type === 'garage_eachen') {
- accessory = this.devicesInHB.has(device.deviceid + 'SWX')
- ? this.devicesInHB.get(device.deviceid + 'SWX')
- : this.addAccessory(device, device.deviceid + 'SWX', 'garage_eachen')
- } else if (this.cusG.has(device.deviceid + 'SWX') && this.cusG.get(device.deviceid + 'SWX').type === 'lock') {
- accessory = this.devicesInHB.has(device.deviceid + 'SWX')
- ? this.devicesInHB.get(device.deviceid + 'SWX')
- : this.addAccessory(device, device.deviceid + 'SWX', 'lock')
- } else if (this.cusG.has(device.deviceid + 'SWX') && this.cusG.get(device.deviceid + 'SWX').type === 'valve') {
- accessory = this.devicesInHB.has(device.deviceid + 'SWX')
- ? this.devicesInHB.get(device.deviceid + 'SWX')
- : this.addAccessory(device, device.deviceid + 'SWX', 'valve', false, {
- operationTime: this.cusG.get(device.deviceid + 'SWX').operationTime
- })
- accessory.context.operationTime = this.cusG.get(device.deviceid + 'SWX').operationTime
- } else if (cns.devicesSensor.includes(device.extra.uiid)) {
- accessory = this.devicesInHB.has(device.deviceid + 'SWX')
- ? this.devicesInHB.get(device.deviceid + 'SWX')
- : this.addAccessory(device, device.deviceid + 'SWX', 'sensor')
- } else if (cns.devicesFan.includes(device.extra.uiid)) {
- accessory = this.devicesInHB.has(device.deviceid + 'SWX')
- ? this.devicesInHB.get(device.deviceid + 'SWX')
- : this.addAccessory(device, device.deviceid + 'SWX', 'fan')
- } else if (cns.devicesThermostat.includes(device.extra.uiid)) {
- accessory = this.devicesInHB.has(device.deviceid + 'SWX')
- ? this.devicesInHB.get(device.deviceid + 'SWX')
- : this.addAccessory(device, device.deviceid + 'SWX', 'thermostat', false, {
- sensorType: device.params.sensorType
- })
- if (accessory.context.sensorType !== device.params.sensorType) {
- accessory.context.sensorType = device.params.sensorType
- this.devicesInHB.set(accessory.context.hbDeviceId, accessory)
- }
- } else if (cns.devicesOutlet.includes(device.extra.uiid) || (cns.devicesSingleSwitch.includes(device.extra.uiid) && cns.devicesSingleSwitchOutlet.includes(device.productModel))) {
- accessory = this.devicesInHB.has(device.deviceid + 'SWX')
- ? this.devicesInHB.get(device.deviceid + 'SWX')
- : this.addAccessory(device, device.deviceid + 'SWX', 'outlet')
- } else if (cns.devicesUSB.includes(device.extra.uiid)) {
- accessory = this.devicesInHB.has(device.deviceid + 'SWX')
- ? this.devicesInHB.get(device.deviceid + 'SWX')
- : this.addAccessory(device, device.deviceid + 'SWX', 'usb')
- } else if (cns.devicesSCM.includes(device.extra.uiid)) {
- accessory = this.devicesInHB.has(device.deviceid + 'SWX')
- ? this.devicesInHB.get(device.deviceid + 'SWX')
- : this.addAccessory(device, device.deviceid + 'SWX', 'scm')
- } else if (cns.devicesSingleSwitch.includes(device.extra.uiid) && cns.devicesSingleSwitchLight.includes(device.productModel)) {
- accessory = this.devicesInHB.has(device.deviceid + 'SWX')
- ? this.devicesInHB.get(device.deviceid + 'SWX')
- : this.addAccessory(device, device.deviceid + 'SWX', 'light')
- } else if (cns.devicesMultiSwitch.includes(device.extra.uiid) && cns.devicesMultiSwitchLight.includes(device.productModel)) {
- if (this.config.hideMasters) {
- if (this.devicesInHB.has(device.deviceid + 'SW0')) {
- this.removeAccessory(this.devicesInHB.get(device.deviceid + 'SW0'))
+ try {
+ if (cns.devicesCurtain.includes(device.extra.uiid)) {
+ accessory = this.devicesInHB.has(device.deviceid + 'SWX')
+ ? this.devicesInHB.get(device.deviceid + 'SWX')
+ : this.addAccessory(device, device.deviceid + 'SWX', false, { cacheCurrentPosition: 0 })
+ accessory.control = new DeviceCurtain(this, accessory)
+ } else if (this.cusG.has(device.deviceid + 'SWX') && this.cusG.get(device.deviceid + 'SWX').type === 'blind') {
+ accessory = this.devicesInHB.has(device.deviceid + 'SWX')
+ ? this.devicesInHB.get(device.deviceid + 'SWX')
+ : this.addAccessory(device, device.deviceid + 'SWX', false, {
+ cacheCurrentPosition: 0,
+ cachePositionState: 2,
+ cacheTargetPosition: 0
+ })
+ accessory.control = new DeviceBlind(this, accessory)
+ } else if (this.cusG.has(device.deviceid + 'SWX') && this.cusG.get(device.deviceid + 'SWX').type === 'garage') {
+ accessory = this.devicesInHB.has(device.deviceid + 'SWX')
+ ? this.devicesInHB.get(device.deviceid + 'SWX')
+ : this.addAccessory(device, device.deviceid + 'SWX', false, {
+ cacheCurrentDoorState: 1,
+ cacheTargetDoorState: 1
+ })
+ accessory.control = new DeviceGarage(this, accessory)
+ } else if (this.cusG.has(device.deviceid + 'SWX') && this.cusG.get(device.deviceid + 'SWX').type === 'garage_eachen') {
+ accessory = this.devicesInHB.has(device.deviceid + 'SWX')
+ ? this.devicesInHB.get(device.deviceid + 'SWX')
+ : this.addAccessory(device, device.deviceid + 'SWX')
+ accessory.control = new DeviceGarageEachen(this, accessory)
+ } else if (this.cusG.has(device.deviceid + 'SWX') && this.cusG.get(device.deviceid + 'SWX').type === 'lock') {
+ accessory = this.devicesInHB.has(device.deviceid + 'SWX')
+ ? this.devicesInHB.get(device.deviceid + 'SWX')
+ : this.addAccessory(device, device.deviceid + 'SWX')
+ accessory.control = new DeviceLock(this, accessory)
+ } else if (this.cusG.has(device.deviceid + 'SWX') && this.cusG.get(device.deviceid + 'SWX').type === 'valve') {
+ accessory = this.devicesInHB.has(device.deviceid + 'SWX')
+ ? this.devicesInHB.get(device.deviceid + 'SWX')
+ : this.addAccessory(device, device.deviceid + 'SWX')
+ accessory.control = new DeviceValve(this, accessory)
+ } else if (cns.devicesSensor.includes(device.extra.uiid)) {
+ accessory = this.devicesInHB.has(device.deviceid + 'SWX')
+ ? this.devicesInHB.get(device.deviceid + 'SWX')
+ : this.addAccessory(device, device.deviceid + 'SWX', false, { type: 'sensor' })
+ accessory.control = new DeviceSensor(this, accessory)
+ } else if (cns.devicesFan.includes(device.extra.uiid)) {
+ accessory = this.devicesInHB.has(device.deviceid + 'SWX')
+ ? this.devicesInHB.get(device.deviceid + 'SWX')
+ : this.addAccessory(device, device.deviceid + 'SWX')
+ accessory.control = new DeviceFan(this, accessory)
+ } else if (cns.devicesThermostat.includes(device.extra.uiid)) {
+ accessory = this.devicesInHB.has(device.deviceid + 'SWX')
+ ? this.devicesInHB.get(device.deviceid + 'SWX')
+ : this.addAccessory(device, device.deviceid + 'SWX', false, {
+ sensorType: device.params.sensorType
+ })
+ if (accessory.context.sensorType !== device.params.sensorType) {
+ accessory.context.sensorType = device.params.sensorType
}
- this.hiddenMasters.push(device.deviceid)
- accessory = this.addAccessory(device, device.deviceid + 'SW0', 'light', true)
+ accessory.control = new DeviceThermostat(this, accessory)
+ } else if (cns.devicesOutlet.includes(device.extra.uiid) || (cns.devicesSingleSwitch.includes(device.extra.uiid) && cns.devicesSingleSwitchOutlet.includes(device.productModel))) {
+ accessory = this.devicesInHB.has(device.deviceid + 'SWX')
+ ? this.devicesInHB.get(device.deviceid + 'SWX')
+ : this.addAccessory(device, device.deviceid + 'SWX')
+ accessory.control = new DeviceOutlet(this, accessory)
+ } else if (cns.devicesUSB.includes(device.extra.uiid)) {
+ accessory = this.devicesInHB.has(device.deviceid + 'SWX')
+ ? this.devicesInHB.get(device.deviceid + 'SWX')
+ : this.addAccessory(device, device.deviceid + 'SWX')
+ accessory.control = new DeviceUSB(this, accessory)
+ } else if (cns.devicesSCM.includes(device.extra.uiid)) {
+ accessory = this.devicesInHB.has(device.deviceid + 'SWX')
+ ? this.devicesInHB.get(device.deviceid + 'SWX')
+ : this.addAccessory(device, device.deviceid + 'SWX')
+ accessory.control = new DeviceSCM(this, accessory)
+ } else if (cns.devicesSingleSwitch.includes(device.extra.uiid) && cns.devicesSingleSwitchLight.includes(device.productModel)) {
+ accessory = this.devicesInHB.has(device.deviceid + 'SWX')
+ ? this.devicesInHB.get(device.deviceid + 'SWX')
+ : this.addAccessory(device, device.deviceid + 'SWX')
accessory.control = new DeviceLight(this, accessory)
- } else {
- accessory = this.devicesInHB.has(device.deviceid + 'SW0')
- ? this.devicesInHB.get(device.deviceid + 'SW0')
- : this.addAccessory(device, device.deviceid + 'SW0', 'light')
- }
- for (let i = 1; i <= cns.chansFromUiid[device.extra.uiid]; i++) {
- if ((this.config.hideFromHB || '').includes(device.deviceid + 'SW' + i)) {
- if (this.devicesInHB.has(device.deviceid + 'SW' + i)) {
- this.removeAccessory(this.devicesInHB.get(device.deviceid + 'SW' + i))
+ } else if (cns.devicesMultiSwitch.includes(device.extra.uiid) && cns.devicesMultiSwitchLight.includes(device.productModel)) {
+ if (this.config.hideMasters) {
+ if (this.devicesInHB.has(device.deviceid + 'SW0')) {
+ this.removeAccessory(this.devicesInHB.get(device.deviceid + 'SW0'))
}
+ this.hiddenMasters.push(device.deviceid)
+ accessory = this.addAccessory(device, device.deviceid + 'SW0', true)
} else {
- const oAccessory = this.devicesInHB.has(device.deviceid + 'SW' + i)
- ? this.devicesInHB.get(device.deviceid + 'SW' + i)
- : this.addAccessory(device, device.deviceid + 'SW' + i, 'light')
- oAccessory
- .getService(Service.AccessoryInformation)
- .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion)
- oAccessory.context.reachableWAN = device.online
- oAccessory.context.reachableLAN = this.lanDevices.get(device.deviceid).online || false
- this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory)
+ accessory = this.devicesInHB.has(device.deviceid + 'SW0')
+ ? this.devicesInHB.get(device.deviceid + 'SW0')
+ : this.addAccessory(device, device.deviceid + 'SW0')
}
- }
- } else if (cns.devicesSingleSwitch.includes(device.extra.uiid)) {
- accessory = this.devicesInHB.has(device.deviceid + 'SWX')
- ? this.devicesInHB.get(device.deviceid + 'SWX')
- : this.addAccessory(device, device.deviceid + 'SWX', 'switch')
- } else if (cns.devicesMultiSwitch.includes(device.extra.uiid)) {
- if (this.config.hideMasters) {
- if (this.devicesInHB.has(device.deviceid + 'SW0')) {
- this.removeAccessory(this.devicesInHB.get(device.deviceid + 'SW0'))
+ accessory.control = new DeviceLight(this, accessory)
+ for (let i = 1; i <= cns.chansFromUiid[device.extra.uiid]; i++) {
+ if ((this.config.hideFromHB || '').includes(device.deviceid + 'SW' + i)) {
+ if (this.devicesInHB.has(device.deviceid + 'SW' + i)) {
+ this.removeAccessory(this.devicesInHB.get(device.deviceid + 'SW' + i))
+ }
+ } else {
+ const oAccessory = this.devicesInHB.has(device.deviceid + 'SW' + i)
+ ? this.devicesInHB.get(device.deviceid + 'SW' + i)
+ : this.addAccessory(device, device.deviceid + 'SW' + i)
+ oAccessory
+ .getService(Service.AccessoryInformation)
+ .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion)
+ oAccessory.context.reachableWAN = device.online
+ oAccessory.context.reachableLAN = this.lanDevices.get(device.deviceid).online || false
+ this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory)
+ oAccessory.control = new DeviceLight(this, oAccessory)
+ }
}
- this.hiddenMasters.push(device.deviceid)
- accessory = this.addAccessory(device, device.deviceid + 'SW0', 'switch', true)
+ } else if (cns.devicesSingleSwitch.includes(device.extra.uiid)) {
+ accessory = this.devicesInHB.has(device.deviceid + 'SWX')
+ ? this.devicesInHB.get(device.deviceid + 'SWX')
+ : this.addAccessory(device, device.deviceid + 'SWX')
accessory.control = new DeviceSwitch(this, accessory)
- } else {
- accessory = this.devicesInHB.has(device.deviceid + 'SW0')
- ? this.devicesInHB.get(device.deviceid + 'SW0')
- : this.addAccessory(device, device.deviceid + 'SW0', 'switch')
- }
- for (let i = 1; i <= cns.chansFromUiid[device.extra.uiid]; i++) {
- if ((this.config.hideFromHB || '').includes(device.deviceid + 'SW' + i)) {
- if (this.devicesInHB.has(device.deviceid + 'SW' + i)) {
- this.removeAccessory(this.devicesInHB.get(device.deviceid + 'SW' + i))
+ } else if (cns.devicesMultiSwitch.includes(device.extra.uiid)) {
+ if (this.config.hideMasters) {
+ if (this.devicesInHB.has(device.deviceid + 'SW0')) {
+ this.removeAccessory(this.devicesInHB.get(device.deviceid + 'SW0'))
}
+ this.hiddenMasters.push(device.deviceid)
+ accessory = this.addAccessory(device, device.deviceid + 'SW0', true)
} else {
- const oAccessory = this.devicesInHB.has(device.deviceid + 'SW' + i)
- ? this.devicesInHB.get(device.deviceid + 'SW' + i)
- : this.addAccessory(device, device.deviceid + 'SW' + i, 'switch')
- oAccessory
- .getService(Service.AccessoryInformation)
- .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion)
- oAccessory.context.reachableWAN = device.online
- oAccessory.context.reachableLAN = this.lanDevices.get(device.deviceid).online || false
- this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory)
+ accessory = this.devicesInHB.has(device.deviceid + 'SW0')
+ ? this.devicesInHB.get(device.deviceid + 'SW0')
+ : this.addAccessory(device, device.deviceid + 'SW0')
}
- }
- } else if (cns.devicesRFBridge.includes(device.extra.uiid)) {
- let rfChlCounter = 0
- const rfMap = []
- if (Object.prototype.hasOwnProperty.call(device, 'tags') && Object.prototype.hasOwnProperty.call(device.tags, 'zyx_info')) {
- device.tags.zyx_info.forEach(remote =>
- rfMap.push({
- name: remote.name,
- type: remote.remote_type,
- buttons: Object.assign({}, ...remote.buttonName)
- })
- )
- }
- const accessory = this.devicesInHB.has(device.deviceid + 'SW0')
- ? this.devicesInHB.get(device.deviceid + 'SW0')
- : this.addAccessory(device, device.deviceid + 'SW0', 'rf_pri', true, {
- rfMap
- })
- accessory.control = new DeviceRFBridge(this, accessory)
- this.hiddenMasters.push(device.deviceid)
- rfMap.forEach(subDevice => {
- const swNumber = rfChlCounter + 1
- let subAccessory
- let subType
- let subExtraContext = {}
- switch (subDevice.type) {
- case '1':
- case '2':
- case '3':
- case '4':
- subType = 'button'
- break
- case '6':
- subType = this.cusS.has(device.deviceid + 'SW' + swNumber)
- ? this.cusS.get(device.deviceid + 'SW' + swNumber).type
- : 'motion'
- break
- default:
- return
+ accessory.control = new DeviceSwitch(this, accessory)
+ for (let i = 1; i <= cns.chansFromUiid[device.extra.uiid]; i++) {
+ if ((this.config.hideFromHB || '').includes(device.deviceid + 'SW' + i)) {
+ if (this.devicesInHB.has(device.deviceid + 'SW' + i)) {
+ this.removeAccessory(this.devicesInHB.get(device.deviceid + 'SW' + i))
+ }
+ } else {
+ const oAccessory = this.devicesInHB.has(device.deviceid + 'SW' + i)
+ ? this.devicesInHB.get(device.deviceid + 'SW' + i)
+ : this.addAccessory(device, device.deviceid + 'SW' + i)
+ oAccessory
+ .getService(Service.AccessoryInformation)
+ .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion)
+ oAccessory.context.reachableWAN = device.online
+ oAccessory.context.reachableLAN = this.lanDevices.get(device.deviceid).online || false
+ this.devicesInHB.set(oAccessory.context.hbDeviceId, oAccessory)
+ oAccessory.control = new DeviceSwitch(this, oAccessory)
+ }
}
- subExtraContext = {
- buttons: subDevice.buttons,
- subType,
- swNumber
+ } else if (cns.devicesRFBridge.includes(device.extra.uiid)) {
+ let rfChlCounter = 0
+ const rfMap = []
+ if (Object.prototype.hasOwnProperty.call(device, 'tags') && Object.prototype.hasOwnProperty.call(device.tags, 'zyx_info')) {
+ device.tags.zyx_info.forEach(remote =>
+ rfMap.push({
+ name: remote.name,
+ type: remote.remote_type,
+ buttons: Object.assign({}, ...remote.buttonName)
+ })
+ )
}
- if ((subAccessory = this.devicesInHB.get(device.deviceid + 'SW' + swNumber))) {
- if (subAccessory.context.subType !== subType || subAccessory.context.swNumber !== swNumber) {
- this.removeAccessory(subAccessory)
+ accessory = this.devicesInHB.has(device.deviceid + 'SW0')
+ ? this.devicesInHB.get(device.deviceid + 'SW0')
+ : this.addAccessory(device, device.deviceid + 'SW0', true, {
+ rfMap
+ }, 'rf_pri')
+ accessory.control = new DeviceRFBridge(this, accessory)
+ this.hiddenMasters.push(device.deviceid)
+ rfMap.forEach(subDevice => {
+ const swNumber = rfChlCounter + 1
+ let subAccessory
+ let subType
+ let subExtraContext = {}
+ switch (subDevice.type) {
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ subType = 'button'
+ break
+ case '6':
+ subType = this.cusS.has(device.deviceid + 'SW' + swNumber)
+ ? this.cusS.get(device.deviceid + 'SW' + swNumber).type
+ : 'motion'
+ break
+ default:
+ return
}
- }
- subAccessory = this.devicesInHB.has(device.deviceid + 'SW' + swNumber)
- ? this.devicesInHB.get(device.deviceid + 'SW' + swNumber)
- : this.addAccessory(device, device.deviceid + 'SW' + swNumber, 'rf_sub', false, subExtraContext)
- subAccessory
+ subExtraContext = {
+ buttons: subDevice.buttons,
+ subType,
+ swNumber
+ }
+ if ((subAccessory = this.devicesInHB.get(device.deviceid + 'SW' + swNumber))) {
+ if (subAccessory.context.subType !== subType || subAccessory.context.swNumber !== swNumber) {
+ this.removeAccessory(subAccessory)
+ }
+ }
+ subAccessory = this.devicesInHB.has(device.deviceid + 'SW' + swNumber)
+ ? this.devicesInHB.get(device.deviceid + 'SW' + swNumber)
+ : this.addAccessory(device, device.deviceid + 'SW' + swNumber, false, subExtraContext, 'rf_sub')
+ subAccessory
+ .getService(Service.AccessoryInformation)
+ .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion)
+ subAccessory.context.reachableWAN = device.online
+ subAccessory.context.reachableLAN = false
+ this.devicesInHB.set(subAccessory.context.hbDeviceId, subAccessory)
+ subAccessory.control = new DeviceRFBridge(this, subAccessory)
+ rfChlCounter += Object.keys(subDevice.buttons || {}).length
+ })
+ accessory.context.channelCount = rfChlCounter
+ this.devicesInHB.set(accessory.context.hbDeviceId, accessory)
+ } else if (cns.devicesZB.includes(device.extra.uiid)) {
+ accessory = this.devicesInHB.has(device.deviceid + 'SWX')
+ ? this.devicesInHB.get(device.deviceid + 'SWX')
+ : this.addAccessory(device, device.deviceid + 'SWX')
+ accessory.control = new DeviceZBDev(this, accessory)
+ } else if (cns.devicesCamera.includes(device.extra.uiid)) {
+ this.log.warn(' â [%s] please see the homebridge-ewelink wiki for details to enable the camera', device.name)
+ return
+ } else if (!cns.devicesZBBridge.includes(device.extra.uiid)) {
+ this.log.warn(' â [%s] has not been added as it is not supported. Please make a GitHub issue request.', device.name)
+ return
+ }
+ if (!this.hiddenMasters.includes(device.deviceid)) {
+ accessory
.getService(Service.AccessoryInformation)
.setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion)
- subAccessory.context.reachableWAN = device.online
- subAccessory.context.reachableLAN = false
- this.devicesInHB.set(subAccessory.context.hbDeviceId, subAccessory)
- rfChlCounter += Object.keys(subDevice.buttons || {}).length
- })
- accessory.context.channelCount = rfChlCounter
- this.devicesInHB.set(accessory.context.hbDeviceId, accessory)
- } else if (cns.devicesZB.includes(device.extra.uiid)) {
- accessory = this.devicesInHB.has(device.deviceid + 'SWX')
- ? this.devicesInHB.get(device.deviceid + 'SWX')
- : this.addAccessory(device, device.deviceid + 'SWX', 'zb_dev')
- } else if (cns.devicesCamera.includes(device.extra.uiid)) {
- this.log.warn(' â [%s] please see the homebridge-ewelink wiki for details to enable the camera', device.name)
- return
- } else if (!cns.devicesZBBridge.includes(device.extra.uiid)) {
- this.log.warn(' â [%s] has not been added as it is not supported. Please make a GitHub issue request.', device.name)
- return
- }
- if (!accessory) return
- if (!this.hiddenMasters.includes(device.deviceid)) {
- accessory
- .getService(Service.AccessoryInformation)
- .setCharacteristic(Characteristic.FirmwareRevision, device.params.fwVersion)
- }
- accessory.context.reachableWAN = device.online
- accessory.context.reachableLAN = this.lanDevices.has(device.deviceid)
- ? this.lanDevices.get(device.deviceid).online
- : false
- accessory.context.inUse = false
- let str = accessory.context.reachableLAN
- ? 'and found locally with IP [' + this.lanDevices.get(device.deviceid).ip + ']'
- : 'but LAN mode unavailable as device '
- if (!accessory.context.reachableLAN) {
- if (cns.devicesNonLAN.includes(device.extra.uiid)) {
- str += "doesn't support it"
- } else if (Object.prototype.hasOwnProperty.call(device, 'sharedBy') && Object.prototype.hasOwnProperty.call(device.sharedBy, 'email')) {
- str += 'is shared (' + device.sharedBy.email + ')'
- } else {
- str += 'is unreachable'
}
- }
- this.log(' â [%s] initialised %s.', device.name, str)
- this.devicesInHB.set(accessory.context.hbDeviceId, accessory)
- if (this.config.disableHTTPRefresh) return
- try {
- accessory.control.externalUpdate(accessory, device.params)
+ accessory.context.reachableWAN = device.online
+ accessory.context.reachableLAN = this.lanDevices.has(device.deviceid)
+ ? this.lanDevices.get(device.deviceid).online
+ : false
+ accessory.context.inUse = false
+ let str = accessory.context.reachableLAN
+ ? 'and found locally with IP [' + this.lanDevices.get(device.deviceid).ip + ']'
+ : 'but LAN mode unavailable as device '
+ if (!accessory.context.reachableLAN) {
+ if (cns.devicesNonLAN.includes(device.extra.uiid)) {
+ str += "doesn't support it"
+ } else if (Object.prototype.hasOwnProperty.call(device, 'sharedBy') && Object.prototype.hasOwnProperty.call(device.sharedBy, 'email')) {
+ str += 'is shared (' + device.sharedBy.email + ')'
+ } else {
+ str += 'is unreachable'
+ }
+ }
+ if (!this.config.disableHTTPRefresh) accessory.control.externalUpdate(accessory, device.params)
+ this.devicesInHB.set(accessory.context.hbDeviceId, accessory)
+ this.log(' â [%s] initialised %s.', device.name, str)
} catch (err) {
this.log.warn('[%s] could not be initialised as %s.', accessory.displayName, this.debug ? err : err.message)
}
}
- addAccessory (device, hbDeviceId, type, hidden = false, extraContext = {}) {
+ addAccessory (device, hbDeviceId, hidden = false, extraContext = {}, type = '') {
const switchNumber = hbDeviceId.substr(-1).toString()
let newDeviceName = type === 'rf_sub' ? device.tags.zyx_info[switchNumber - 1].name : device.name
const channelCount =
@@ -401,14 +408,12 @@ class eWeLink {
eweModel: device.productModel,
eweApiKey: device.apikey,
switchNumber,
- channelCount,
- type
+ channelCount
},
...extraContext
}
if (!hidden) {
this.api.registerPlatformAccessories('homebridge-ewelink', 'eWeLink', [accessory])
- this.configureAccessory(accessory)
this.log(' â [%s] has been added to Homebridge.', newDeviceName)
}
return accessory
@@ -418,77 +423,6 @@ class eWeLink {
}
}
- configureAccessory (accessory) {
- if (!this.log) return
- try {
- accessory.context.reachableWAN = true
- accessory.context.reachableLAN = true
- switch (accessory.context.type) {
- case 'curtain':
- accessory.control = new DeviceCurtain(this, accessory)
- break
- case 'blind':
- accessory.control = new DeviceBlind(this, accessory)
- break
- case 'garage':
- accessory.control = new DeviceGarage(this, accessory)
- break
- case 'garage_eachen':
- accessory.control = new DeviceGarageEachen(this, accessory)
- break
- case 'lock':
- accessory.control = new DeviceLock(this, accessory)
- break
- case 'valve':
- accessory.control = new DeviceValve(this, accessory)
- break
- case 'sensor':
- accessory.control = new DeviceSensor(this, accessory)
- break
- case 'fan':
- accessory.control = new DeviceFan(this, accessory)
- break
- case 'thermostat':
- accessory.control = new DeviceThermostat(this, accessory)
- break
- case 'outlet':
- accessory.control = new DeviceOutlet(this, accessory)
- break
- case 'usb':
- accessory.control = new DeviceUSB(this, accessory)
- break
- case 'scm':
- accessory.control = new DeviceSCM(this, accessory)
- break
- case 'light':
- accessory.control = new DeviceLight(this, accessory)
- break
- case 'switch':
- accessory.control = new DeviceSwitch(this, accessory)
- break
- case 'rf_sub':
- accessory.control = new DeviceRFBridge(this, accessory)
- break
- case 'zb_dev': //* ** credit @tasict ***\\
- accessory.control = new DeviceZBDev(this, accessory)
- break
- }
- this.devicesInHB.set(accessory.context.hbDeviceId, accessory)
- } catch (err) {
- this.log.warn('[%s] could not be configured as %s.', accessory.displayName, err)
- }
- }
-
- removeAccessory (accessory) {
- try {
- this.api.unregisterPlatformAccessories('homebridge-ewelink', 'eWeLink', [accessory])
- this.devicesInHB.delete(accessory.context.hbDeviceId)
- this.log(' â [%s] was removed from Homebridge.', accessory.displayName)
- } catch (err) {
- this.log.warn(" â [%s] wasn't removed as %s.", accessory.displayName, err)
- }
- }
-
async sendDeviceUpdate (accessory, params) {
const payload = {
apikey: accessory.context.eweApiKey,
@@ -571,7 +505,7 @@ class eWeLink {
this.lanClient.addDeviceToMap(newDevice)
}
} catch (err) {
- this.log.warn('[%s] error getting info [%s]. Restart Homebeidge to add device.', deviceId, err.message)
+ this.log.warn('[%s] error getting info [%s]. Restart Homebridge to add device.', deviceId, err.message)
}
}
}
@@ -589,6 +523,21 @@ class eWeLink {
}
}
}
+
+ configureAccessory (accessory) {
+ if (!this.log) return
+ this.devicesInHB.set(accessory.context.hbDeviceId, accessory)
+ }
+
+ removeAccessory (accessory) {
+ try {
+ this.api.unregisterPlatformAccessories('homebridge-ewelink', 'eWeLink', [accessory])
+ this.devicesInHB.delete(accessory.context.hbDeviceId)
+ this.log(' â [%s] was removed from Homebridge.', accessory.displayName)
+ } catch (err) {
+ this.log.warn(" â [%s] wasn't removed as %s.", accessory.displayName, err)
+ }
+ }
}
module.exports = function (homebridge) {
Characteristic = homebridge.hap.Characteristic
From 2642cd19bccc3d2984a90e1c8156f6bf5f7beecc Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Thu, 1 Oct 2020 16:20:03 +0100
Subject: [PATCH 0289/3183] 3.2.0-2
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 463b984a..5290496b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.2.0-1",
+ "version": "3.2.0-2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index fd2e214f..58aea4f0 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.2.0-1",
+ "version": "3.2.0-2",
"author": "bwp91",
"contributors": [
"gbro115",
From c5ebf8f03c32fdc61e57136b976ff3c9c9f7cc63 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Thu, 1 Oct 2020 17:32:38 +0100
Subject: [PATCH 0290/3183] 3.2.0
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 5290496b..832f0d92 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.2.0-2",
+ "version": "3.2.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 58aea4f0..f11902c2 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.2.0-2",
+ "version": "3.2.0",
"author": "bwp91",
"contributors": [
"gbro115",
From 690f5c48890216f64df9ac42afd3d070557a8589 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Thu, 1 Oct 2020 19:13:20 +0100
Subject: [PATCH 0291/3183] rename section
---
config.schema.json | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/config.schema.json b/config.schema.json
index 5732a4f1..fe60e161 100644
--- a/config.schema.json
+++ b/config.schema.json
@@ -312,7 +312,6 @@
"inUsePowerThreshold",
"sensorTimeLength",
"sensorTimeDifference",
- "valveTimeLength",
"hideTHSwitch",
"hideZBLDPress"
]
@@ -320,7 +319,7 @@
{
"key": "groups",
"expandable": true,
- "title": "Custom Device Simulations",
+ "title": "Custom Accessory Simulations",
"add": "Add Another Type",
"type": "array",
"items": [
From dcbec76d7d5790dca81e2f1083bd7e82b51ed565 Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Thu, 1 Oct 2020 19:14:32 +0100
Subject: [PATCH 0292/3183] Update README.md
---
README.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/README.md b/README.md
index 33b6d570..138c863d 100644
--- a/README.md
+++ b/README.md
@@ -24,6 +24,7 @@
* [Beta Version](https://github.com/bwp91/homebridge-ewelink/wiki/Beta-Version)
### Features
* [Supported Devices](https://github.com/bwp91/homebridge-ewelink/wiki/Supported-Devices)
+* [Custom Accessory Simulations](https://github.com/bwp91/homebridge-ewelink/wiki/Custom-Accessory-Simulations)
* [Connection Methods](https://github.com/bwp91/homebridge-ewelink/wiki/Connection-Methods)
### How-to Guides
* [How to set up RF Bridge sensors](https://github.com/bwp91/homebridge-ewelink/wiki/How-to-set-up-RF-Bridge-sensors)
From 1c1c6cd614cca80c5de425cc6d99579713f0c786 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Thu, 1 Oct 2020 19:16:41 +0100
Subject: [PATCH 0293/3183] Update config.schema.json
---
config.schema.json | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/config.schema.json b/config.schema.json
index fe60e161..74ce6699 100644
--- a/config.schema.json
+++ b/config.schema.json
@@ -110,7 +110,7 @@
},
"groups": {
"type": "array",
- "title": "Custom Device Types",
+ "title": "Accessory Simulations",
"description": "You can use this setting to set up custom simulated HomeKit accessories from a generic single/multi-switch device.",
"items": {
"type": "object",
@@ -319,7 +319,7 @@
{
"key": "groups",
"expandable": true,
- "title": "Custom Accessory Simulations",
+ "title": "Accessory Simulations",
"add": "Add Another Type",
"type": "array",
"items": [
From e361c0cb49af9691c8ecef78aea4aca3278b8661 Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Thu, 1 Oct 2020 19:17:43 +0100
Subject: [PATCH 0294/3183] Update README.md
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 138c863d..4f0e0eb3 100644
--- a/README.md
+++ b/README.md
@@ -24,7 +24,7 @@
* [Beta Version](https://github.com/bwp91/homebridge-ewelink/wiki/Beta-Version)
### Features
* [Supported Devices](https://github.com/bwp91/homebridge-ewelink/wiki/Supported-Devices)
-* [Custom Accessory Simulations](https://github.com/bwp91/homebridge-ewelink/wiki/Custom-Accessory-Simulations)
+* [Accessory Simulations](https://github.com/bwp91/homebridge-ewelink/wiki/Accessory-Simulations)
* [Connection Methods](https://github.com/bwp91/homebridge-ewelink/wiki/Connection-Methods)
### How-to Guides
* [How to set up RF Bridge sensors](https://github.com/bwp91/homebridge-ewelink/wiki/How-to-set-up-RF-Bridge-sensors)
From ab0099437af5681d08b733bc502f2cd6bdb91c2b Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Thu, 1 Oct 2020 19:45:08 +0100
Subject: [PATCH 0295/3183] Update config.schema.json
---
config.schema.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/config.schema.json b/config.schema.json
index 74ce6699..d28e2210 100644
--- a/config.schema.json
+++ b/config.schema.json
@@ -55,7 +55,7 @@
"hideFromHB": {
"type": "string",
"title": "Hide Device Channels",
- "description": "A list of SW1, SW2, SW3 and SW4 to hide from Homebridge. For example '10009553c8SW1' or multiple channels separated with a comma '10009553c8SW1,10009553c9SW2'. Only channels from switches and lights can be hidden. This setting cannot be used to hide master devices (SW0).",
+ "description": "A list of SW1, SW2, SW3 and SW4 to hide from Homebridge. For example '10009553c8SW1' or multiple channels separated with a comma '10009553c8SW1,10009553c9SW2'. Only channels from lights and switches can be hidden.",
"default": ""
},
"disableHTTPRefresh": {
From 6b608ae5ccb7acc2211135136aef2687f9673e4d Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Thu, 1 Oct 2020 21:06:16 +0100
Subject: [PATCH 0296/3183] .
---
lib/eWeLink.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 2e4d277d..a2adc494 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -340,7 +340,7 @@ class eWeLink {
: this.addAccessory(device, device.deviceid + 'SWX')
accessory.control = new DeviceZBDev(this, accessory)
} else if (cns.devicesCamera.includes(device.extra.uiid)) {
- this.log.warn(' â [%s] please see the homebridge-ewelink wiki for details to enable the camera', device.name)
+ this.log.warn(' â [%s] please see the homebridge-ewelink wiki for details to enable the camera.', device.name)
return
} else if (!cns.devicesZBBridge.includes(device.extra.uiid)) {
this.log.warn(' â [%s] has not been added as it is not supported. Please make a GitHub issue request.', device.name)
From cb9b3a4db7f41434f5c7fbece358e7d73c6f3d6d Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Thu, 1 Oct 2020 22:34:38 +0100
Subject: [PATCH 0297/3183] keywords
---
package.json | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/package.json b/package.json
index f11902c2..7abb45cf 100644
--- a/package.json
+++ b/package.json
@@ -27,9 +27,13 @@
"keywords": [
"homebridge",
"homebridge-plugin",
- "homekit",
"sonoff",
- "ewelink"
+ "homekit",
+ "siri",
+ "ewelink",
+ "homebridge-ewelink",
+ "hoobs",
+ "eachen"
],
"engines": {
"node": ">=10.0.0",
From 60097185629f3d8cbd537f43c8d324f086e6fd80 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Fri, 2 Oct 2020 11:48:56 +0100
Subject: [PATCH 0298/3183] log ws message
---
lib/eWeLinkWS.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/lib/eWeLinkWS.js b/lib/eWeLinkWS.js
index 3c305920..5d585aa8 100644
--- a/lib/eWeLinkWS.js
+++ b/lib/eWeLinkWS.js
@@ -196,15 +196,15 @@ module.exports = class eWeLinkWS {
}
if (this.wsp && this.wsIsOpen) {
try {
- const device = await this.wsp.sendRequest(jsonToSend, {
- requestId: sequence
- })
if (this.debugReqRes) {
const msg = JSON.stringify(json, null, 2).replace(json.apikey, '**hidden**').replace(json.apiKey, '**hidden**').replace(json.deviceid, '**hidden**')
this.log.warn('WS message sent. This text is yellow for clarity.\n%s', msg)
} else if (this.debug) {
this.log('WS message sent.')
}
+ const device = await this.wsp.sendRequest(jsonToSend, {
+ requestId: sequence
+ })
device.error = Object.prototype.hasOwnProperty.call(device, 'error') ? device.error : 504
switch (device.error) {
case 0:
From d830462b5756c6a58c4d5c113b707cec72bf1137 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Fri, 2 Oct 2020 11:49:08 +0100
Subject: [PATCH 0299/3183] button fixes
---
lib/device/rf-bridge.js | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/lib/device/rf-bridge.js b/lib/device/rf-bridge.js
index 59f267ce..b2124215 100644
--- a/lib/device/rf-bridge.js
+++ b/lib/device/rf-bridge.js
@@ -50,10 +50,10 @@ module.exports = class deviceRFBridge {
rfChl: parseInt(rfChl)
}
const rfService = accessory.getService(service)
- await this.platform.sendDeviceUpdate(accessory, params)
rfService.updateCharacteristic(Characteristic.On, true)
- await utils.sleep(3000)
+ await utils.sleep(1000)
rfService.updateCharacteristic(Characteristic.On, false)
+ await this.platform.sendDeviceUpdate(accessory, params)
} catch (err) {
this.platform.deviceUpdateError(accessory, err, true)
}
@@ -68,6 +68,7 @@ module.exports = class deviceRFBridge {
this.platform.devicesInHB.forEach(acc => {
if (
acc.context.eweDeviceId === accessory.context.eweDeviceId &&
+ Object.prototype.hasOwnProperty.call(acc.context, 'buttons') &&
Object.prototype.hasOwnProperty.call(acc.context.buttons, params.rfChl.toString())
) {
oAccessory = acc
@@ -107,7 +108,7 @@ module.exports = class deviceRFBridge {
if (diff < (this.platform.config.sensorTimeDifference || 120)) {
switch (oAccessory.context.subType) {
case 'button':
- break
+ return
case 'water':
serv = Service.LeakSensor
char = Characteristic.LeakDetected
From a6c1f448b889366620432c2c2c03930aa023296b Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Fri, 2 Oct 2020 11:52:21 +0100
Subject: [PATCH 0300/3183] 3.2.1
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 832f0d92..bed97bc7 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.2.0",
+ "version": "3.2.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 7abb45cf..1ffe3219 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.2.0",
+ "version": "3.2.1",
"author": "bwp91",
"contributors": [
"gbro115",
From 70cf1b69b40ff00db6126563f77f6fbb760c8aa2 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Fri, 2 Oct 2020 14:41:55 +0100
Subject: [PATCH 0301/3183] remove old switches on change to custom
---
lib/eWeLink.js | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index a2adc494..b602d7a4 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -127,6 +127,16 @@ class eWeLink {
initialiseDevice (device) {
let accessory
try {
+ if (this.cusG.has(device.deviceid + 'SWX')) {
+ const all = ['X', '0', '1', '2', '3', '4']
+ all.forEach(v => {
+ if (this.devicesInHB.has(device.deviceid + 'SW' + v)) {
+ if (this.devicesInHB.get(device.deviceid + 'SW' + v).getService(Service.Switch)) {
+ this.removeAccessory(this.devicesInHB.get(device.deviceid + 'SW' + v))
+ }
+ }
+ })
+ }
if (cns.devicesCurtain.includes(device.extra.uiid)) {
accessory = this.devicesInHB.has(device.deviceid + 'SWX')
? this.devicesInHB.get(device.deviceid + 'SWX')
From 8063075bf73f14c297c648d687cbb6827a14a9e1 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Fri, 2 Oct 2020 16:44:17 +0100
Subject: [PATCH 0302/3183] catch no displayName
---
lib/eWeLink.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index b602d7a4..b862c315 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -382,7 +382,7 @@ class eWeLink {
this.devicesInHB.set(accessory.context.hbDeviceId, accessory)
this.log(' â [%s] initialised %s.', device.name, str)
} catch (err) {
- this.log.warn('[%s] could not be initialised as %s.', accessory.displayName, this.debug ? err : err.message)
+ this.log.warn('[%s] could not be initialised as %s.', accessory.displayName || device.name, this.debug ? err : err.message)
}
}
From bfc574ec967fa31593196090efb3ac3c672635f9 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Fri, 2 Oct 2020 16:44:30 +0100
Subject: [PATCH 0303/3183] remove outlet switch if exists
---
lib/constants.js | 2 +-
lib/device/outlet.js | 12 ++++++++----
2 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/lib/constants.js b/lib/constants.js
index b23eb05b..27f4f0ce 100644
--- a/lib/constants.js
+++ b/lib/constants.js
@@ -10,7 +10,7 @@ module.exports = {
devicesMultiSwitch: [2, 3, 4, 7, 8, 9, 29, 30, 31, 34, 41],
devicesSingleSwitchLight: ['T1 1C', 'L1', 'B1', 'B1_R2', 'TX1C', 'D1', 'D1R1', 'KING-M4', 'Slampher', 'GTTA59'],
devicesMultiSwitchLight: ['T1 2C', 'T1 3C', 'TX2C', 'TX3C'],
- devicesSingleSwitchOutlet: ['Sonoff Pow', 'S26'],
+ devicesSingleSwitchOutlet: ['Sonoff Pow', 'S20', 'S26', 'S55'],
devicesBrightable: [36, 44],
devicesColourable: [22, 59],
devicesCurtain: [11],
diff --git a/lib/device/outlet.js b/lib/device/outlet.js
index 9941c0ee..29cd1938 100644
--- a/lib/device/outlet.js
+++ b/lib/device/outlet.js
@@ -1,5 +1,6 @@
'use strict'
let Characteristic, EveHistoryService, EveService, Service
+const cns = require('./../constants')
const corrInterval = require('correcting-interval')
const fakegato = require('fakegato-history')
const hbLib = require('homebridge-lib')
@@ -10,11 +11,14 @@ module.exports = class deviceOutlet {
Characteristic = platform.api.hap.Characteristic
EveService = new hbLib.EveHomeKitTypes(platform.api)
EveHistoryService = fakegato(platform.api)
+ if (accessory.getService(Service.Switch)) {
+ accessory.removeService(Service.Switch)
+ }
let outletService
if (!(outletService = accessory.getService(Service.Outlet))) {
accessory.addService(Service.Outlet)
outletService = accessory.getService(Service.Outlet)
- if (accessory.context.eweModel !== 'S26' && !this.platform.config.disableEveLogging) {
+ if (!cns.devicesSingleSwitchOutlet.includes(accessory.context.eweModel) && !this.platform.config.disableEveLogging) {
outletService.addCharacteristic(EveService.Characteristics.Voltage)
outletService.addCharacteristic(EveService.Characteristics.CurrentConsumption)
outletService.addCharacteristic(EveService.Characteristics.ElectricCurrent)
@@ -34,7 +38,7 @@ module.exports = class deviceOutlet {
outletService
.getCharacteristic(Characteristic.On)
.on('set', (value, callback) => this.internalUpdate(accessory, value, callback))
- if (accessory.context.eweModel !== 'S26' && !this.platform.config.disableEveLogging) {
+ if (!cns.devicesSingleSwitchOutlet.includes(accessory.context.eweModel) && !this.platform.config.disableEveLogging) {
accessory.log = this.platform.log
accessory.eveLogger = new EveHistoryService('energy', accessory, {
storage: 'fs',
@@ -123,13 +127,13 @@ module.exports = class deviceOutlet {
const outletService = accessory.getService(Service.Outlet)
if (Object.prototype.hasOwnProperty.call(params, 'switch')) {
outletService.updateCharacteristic(Characteristic.On, params.switch === 'on')
- if (accessory.context.eweModel === 'S26' || this.platform.config.disableEveLogging) {
+ if (cns.devicesSingleSwitchOutlet.includes(accessory.context.eweModel) || this.platform.config.disableEveLogging) {
outletService.updateCharacteristic(Characteristic.OutletInUse, params.switch === 'on')
}
}
if (Object.prototype.hasOwnProperty.call(params, 'power')) {
outletService.updateCharacteristic(EveService.Characteristics.CurrentConsumption, parseFloat(params.power))
- if (accessory.context.eweModel !== 'S26' && !this.platform.config.disableEveLogging) {
+ if (!cns.devicesSingleSwitchOutlet.includes(accessory.context.eweModel) && !this.platform.config.disableEveLogging) {
outletService.updateCharacteristic(
Characteristic.OutletInUse,
parseFloat(params.power) > (this.platform.config.inUsePowerThreshold || 0)
From 125713f62b8cded77b023a1fbf50b6f467dbb13a Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Fri, 2 Oct 2020 16:46:33 +0100
Subject: [PATCH 0304/3183] 3.2.2
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index bed97bc7..64f8b6ec 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.2.1",
+ "version": "3.2.2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 1ffe3219..434c0146 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.2.1",
+ "version": "3.2.2",
"author": "bwp91",
"contributors": [
"gbro115",
From 997d2b4c2555ace7d218f522565619f2a2d7778d Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Fri, 2 Oct 2020 17:16:31 +0100
Subject: [PATCH 0305/3183] Update eWeLink.js
---
lib/eWeLink.js | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index b862c315..c7e8ee8c 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -382,7 +382,10 @@ class eWeLink {
this.devicesInHB.set(accessory.context.hbDeviceId, accessory)
this.log(' â [%s] initialised %s.', device.name, str)
} catch (err) {
- this.log.warn('[%s] could not be initialised as %s.', accessory.displayName || device.name, this.debug ? err : err.message)
+ const deviceName = accessory && Object.prototype.hasOwnProperty.call(accessory, 'displayName')
+ ? accessory.displayName
+ : device.name
+ this.log.warn('[%s] could not be initialised as %s.', deviceName, this.debug ? err : err.message)
}
}
From ac2a6127de415e30125d6c0214d8c74ee54b9949 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Fri, 2 Oct 2020 17:16:55 +0100
Subject: [PATCH 0306/3183] 3.2.3
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 64f8b6ec..a1f6ebb6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.2.2",
+ "version": "3.2.3",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 434c0146..41507cb7 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.2.2",
+ "version": "3.2.3",
"author": "bwp91",
"contributors": [
"gbro115",
From 38288f2a787e36563bfc20d795e4bfcd1eccaa97 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sat, 3 Oct 2020 14:21:22 +0100
Subject: [PATCH 0307/3183] remove outlet switch fix
---
lib/device/outlet.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/device/outlet.js b/lib/device/outlet.js
index 29cd1938..bb86951d 100644
--- a/lib/device/outlet.js
+++ b/lib/device/outlet.js
@@ -12,7 +12,7 @@ module.exports = class deviceOutlet {
EveService = new hbLib.EveHomeKitTypes(platform.api)
EveHistoryService = fakegato(platform.api)
if (accessory.getService(Service.Switch)) {
- accessory.removeService(Service.Switch)
+ accessory.removeService(accessory.getService(Service.Switch))
}
let outletService
if (!(outletService = accessory.getService(Service.Outlet))) {
From 3dd376b7d9b9f4d374db0fe730e7bf5ca4491de9 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sat, 3 Oct 2020 14:22:26 +0100
Subject: [PATCH 0308/3183] code format
---
lib/device/garage-eachen.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/lib/device/garage-eachen.js b/lib/device/garage-eachen.js
index 91bd7e81..3d08ba86 100644
--- a/lib/device/garage-eachen.js
+++ b/lib/device/garage-eachen.js
@@ -62,9 +62,9 @@ module.exports = class deviceGarageEachen {
if (garageConfig.type !== 'garage_eachen') {
throw new Error('improper configuration')
}
- const gdService = accessory.getService(Service.GarageDoorOpener)
- gdService.updateCharacteristic(Characteristic.CurrentDoorState, params.switch === 'on' ? 0 : 1)
- gdService.updateCharacteristic(Characteristic.TargetDoorState, params.switch === 'on' ? 0 : 1)
+ accessory.getService(Service.GarageDoorOpener)
+ .updateCharacteristic(Characteristic.CurrentDoorState, params.switch === 'on' ? 0 : 1)
+ .updateCharacteristic(Characteristic.TargetDoorState, params.switch === 'on' ? 0 : 1)
} catch (err) {
this.platform.deviceUpdateError(accessory, err, false)
}
From e97e178c350454a49c0f0062624d372342435657 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sat, 3 Oct 2020 14:33:43 +0100
Subject: [PATCH 0309/3183] remove zb bridge device check
---
lib/eWeLink.js | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index c7e8ee8c..c054ee19 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -344,6 +344,10 @@ class eWeLink {
})
accessory.context.channelCount = rfChlCounter
this.devicesInHB.set(accessory.context.hbDeviceId, accessory)
+ } else if (cns.devicesZBBridge.includes(device.extra.uiid)) {
+ if (this.devicesInHB.has(device.deviceid + 'SW0')) {
+ this.removeAccessory(this.devicesInHB.get(device.deviceid + 'SW0'))
+ }
} else if (cns.devicesZB.includes(device.extra.uiid)) {
accessory = this.devicesInHB.has(device.deviceid + 'SWX')
? this.devicesInHB.get(device.deviceid + 'SWX')
@@ -352,7 +356,7 @@ class eWeLink {
} else if (cns.devicesCamera.includes(device.extra.uiid)) {
this.log.warn(' â [%s] please see the homebridge-ewelink wiki for details to enable the camera.', device.name)
return
- } else if (!cns.devicesZBBridge.includes(device.extra.uiid)) {
+ } else {
this.log.warn(' â [%s] has not been added as it is not supported. Please make a GitHub issue request.', device.name)
return
}
From 3a860f7859498d6860cf63c357b61778d1fbe68e Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sat, 3 Oct 2020 14:44:26 +0100
Subject: [PATCH 0310/3183] 3.2.4
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index a1f6ebb6..51a19856 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.2.3",
+ "version": "3.2.4",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 41507cb7..4a18f3e2 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.2.3",
+ "version": "3.2.4",
"author": "bwp91",
"contributors": [
"gbro115",
From a88b9316997c2a122c89d629f88ceacad9e2de2d Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sat, 3 Oct 2020 19:28:23 +0100
Subject: [PATCH 0311/3183] lan-> ws improvements
---
lib/eWeLink.js | 9 ++---
lib/eWeLinkLAN.js | 95 +++++++++++++++++++++++++----------------------
2 files changed, 54 insertions(+), 50 deletions(-)
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index c054ee19..57d8470c 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -446,13 +446,12 @@ class eWeLink {
deviceid: accessory.context.eweDeviceId,
params
}
- try {
- await utils.sleep(Math.random() * 100 + 200)
- await this.lanClient.sendUpdate(payload)
- } catch (err) {
+ await utils.sleep(Math.random() * 100 + 200)
+ const res = await this.lanClient.sendUpdate(payload)
+ if (res !== 'ok') {
if (accessory.context.reachableWAN) {
if (this.debug) {
- this.log.warn('[%s] Reverting to web socket as LAN mode warning - %s.', accessory.displayName, this.debug ? err : err.message)
+ this.log('[%s] Reverting to web socket as %s.', accessory.displayName, res)
}
await this.wsClient.sendUpdate(payload)
} else {
diff --git a/lib/eWeLinkLAN.js b/lib/eWeLinkLAN.js
index 67bfbae3..df0655c6 100644
--- a/lib/eWeLinkLAN.js
+++ b/lib/eWeLinkLAN.js
@@ -107,54 +107,59 @@ module.exports = class eWeLinkLAN {
}
async sendUpdate (json) {
- if (!this.deviceMap.get(json.deviceid).online) {
- throw new Error("device isn't reachable via LAN mode")
- }
- let apiKey
- let suffix
- const params = {}
- if (Object.prototype.hasOwnProperty.call(json.params, 'switches')) {
- params.switches = json.params.switches
- suffix = 'switches'
- } else if (Object.prototype.hasOwnProperty.call(json.params, 'switch')) {
- params.switch = json.params.switch
- suffix = 'switch'
- } else {
- throw new Error("device isn't reachable via LAN mode")
- }
- if ((apiKey = this.deviceMap.get(json.deviceid).apiKey)) {
- const key = crypto.createHash('md5').update(Buffer.from(apiKey, 'utf8')).digest()
- const iv = crypto.randomBytes(16)
- const enc = crypto.createCipheriv('aes-128-cbc', key, iv)
- const data = {
- data: Buffer.concat([enc.update(JSON.stringify(params)), enc.final()]).toString('base64'),
- deviceid: json.deviceid,
- encrypt: true,
- iv: iv.toString('base64'),
- selfApikey: '123',
- sequence: Date.now().toString()
+ try {
+ if (!this.deviceMap.get(json.deviceid).online) {
+ throw new Error("device isn't reachable via LAN mode")
}
- if (this.debugReqRes) {
- const msg = JSON.stringify(json, null, 2)
- .replace(json.apikey, '**hidden**')
- .replace(json.apikey, '**hidden**')
- .replace(json.deviceid, '**hidden**')
- this.log.warn('LAN message sent. This text is yellow for clarity.\n%s', msg)
- } else if (this.debug) {
- this.log('LAN message sent.')
+ let apiKey
+ let suffix
+ const params = {}
+ if (Object.prototype.hasOwnProperty.call(json.params, 'switches')) {
+ params.switches = json.params.switches
+ suffix = 'switches'
+ } else if (Object.prototype.hasOwnProperty.call(json.params, 'switch')) {
+ params.switch = json.params.switch
+ suffix = 'switch'
+ } else {
+ throw new Error("device isn't reachable via LAN mode")
}
- const res = await axios({
- method: 'post',
- url: 'http://' + this.deviceMap.get(json.deviceid).ip + ':8081/zeroconf/' + suffix,
- headers: {
- Accept: 'application/json',
- 'Content-Type': 'application/json'
- },
- data
- })
- if (!Object.prototype.hasOwnProperty.call(res.data, 'error') || res.data.error !== 0) {
- throw new Error(res.data)
+ if ((apiKey = this.deviceMap.get(json.deviceid).apiKey)) {
+ const key = crypto.createHash('md5').update(Buffer.from(apiKey, 'utf8')).digest()
+ const iv = crypto.randomBytes(16)
+ const enc = crypto.createCipheriv('aes-128-cbc', key, iv)
+ const data = {
+ data: Buffer.concat([enc.update(JSON.stringify(params)), enc.final()]).toString('base64'),
+ deviceid: json.deviceid,
+ encrypt: true,
+ iv: iv.toString('base64'),
+ selfApikey: '123',
+ sequence: Date.now().toString()
+ }
+ if (this.debugReqRes) {
+ const msg = JSON.stringify(json, null, 2)
+ .replace(json.apikey, '**hidden**')
+ .replace(json.apikey, '**hidden**')
+ .replace(json.deviceid, '**hidden**')
+ this.log.warn('LAN message sent. This text is yellow for clarity.\n%s', msg)
+ } else if (this.debug) {
+ this.log('LAN message sent.')
+ }
+ const res = await axios({
+ method: 'post',
+ url: 'http://' + this.deviceMap.get(json.deviceid).ip + ':8081/zeroconf/' + suffix,
+ headers: {
+ Accept: 'application/json',
+ 'Content-Type': 'application/json'
+ },
+ data
+ })
+ if (!Object.prototype.hasOwnProperty.call(res.data, 'error') || res.data.error !== 0) {
+ throw new Error(res.data)
+ }
+ return 'ok'
}
+ } catch (err) {
+ return err.message
}
}
From 7ffabbbc26b1c5db4d2fdeb826c8aa61613b59da Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sat, 3 Oct 2020 19:50:37 +0100
Subject: [PATCH 0312/3183] hide custom SW0
---
config.schema.json | 10 +++++-----
lib/eWeLink.js | 4 ++--
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/config.schema.json b/config.schema.json
index d28e2210..7e27b86d 100644
--- a/config.schema.json
+++ b/config.schema.json
@@ -43,19 +43,19 @@
"hideDevFromHB": {
"type": "string",
"title": "Hide Devices",
- "description": "A list of eWeLink devices to hide from Homebridge. For example '10009553c8' or multiple devices separated with a comma '10009553c8,10009553c9'.",
+ "description": "A list of eWeLink devices to hide from Homebridge. For example '10009553c8' or multiple separated with a comma '10009553c8,10009553c9'.",
"default": ""
},
"hideMasters": {
- "type": "boolean",
- "title": "Hide Master Switches",
- "description": "If enabled, the 'SW0' accessory of multi-channel light and switch devices will be hidden from Homebridge.",
+ "type": "string",
+ "title": "Hide Master Lights/Switches",
+ "description": "A list of SW0 lights/switches to hide from Homebridge. For example '10009553c8' or multiple separated with a comma '10009553c8,10009553c9'.",
"default": false
},
"hideFromHB": {
"type": "string",
"title": "Hide Device Channels",
- "description": "A list of SW1, SW2, SW3 and SW4 to hide from Homebridge. For example '10009553c8SW1' or multiple channels separated with a comma '10009553c8SW1,10009553c9SW2'. Only channels from lights and switches can be hidden.",
+ "description": "A list of SW1, SW2, SW3 and SW4 channels to hide from Homebridge. For example '10009553c8SW1' or multiple separated with a comma '10009553c8SW1,10009553c9SW2'.",
"default": ""
},
"disableHTTPRefresh": {
diff --git a/lib/eWeLink.js b/lib/eWeLink.js
index 57d8470c..8ef86134 100644
--- a/lib/eWeLink.js
+++ b/lib/eWeLink.js
@@ -215,7 +215,7 @@ class eWeLink {
: this.addAccessory(device, device.deviceid + 'SWX')
accessory.control = new DeviceLight(this, accessory)
} else if (cns.devicesMultiSwitch.includes(device.extra.uiid) && cns.devicesMultiSwitchLight.includes(device.productModel)) {
- if (this.config.hideMasters) {
+ if ((this.config.hideMasters || '').includes(device.deviceid)) {
if (this.devicesInHB.has(device.deviceid + 'SW0')) {
this.removeAccessory(this.devicesInHB.get(device.deviceid + 'SW0'))
}
@@ -251,7 +251,7 @@ class eWeLink {
: this.addAccessory(device, device.deviceid + 'SWX')
accessory.control = new DeviceSwitch(this, accessory)
} else if (cns.devicesMultiSwitch.includes(device.extra.uiid)) {
- if (this.config.hideMasters) {
+ if ((this.config.hideMasters || '').includes(device.deviceid)) {
if (this.devicesInHB.has(device.deviceid + 'SW0')) {
this.removeAccessory(this.devicesInHB.get(device.deviceid + 'SW0'))
}
From 2f3fe0cc2ef239bb561a081e41efa7d67c19cea5 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sat, 3 Oct 2020 20:38:02 +0100
Subject: [PATCH 0313/3183] 3.3.0
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 51a19856..249642de 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.2.4",
+ "version": "3.3.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 4a18f3e2..733f7ef9 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.2.4",
+ "version": "3.3.0",
"author": "bwp91",
"contributors": [
"gbro115",
From 66d0c93eb8b00439ef3a29fd109aa3ad6c5fe07b Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sat, 3 Oct 2020 21:57:34 +0100
Subject: [PATCH 0314/3183] notifications fix
---
lib/device/garage-eachen.js | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/lib/device/garage-eachen.js b/lib/device/garage-eachen.js
index 3d08ba86..85953acb 100644
--- a/lib/device/garage-eachen.js
+++ b/lib/device/garage-eachen.js
@@ -41,7 +41,7 @@ module.exports = class deviceGarageEachen {
.updateCharacteristic(Characteristic.CurrentDoorState, newPos + 2)
params.switch = value === 0 ? 'on' : 'off'
await this.platform.sendDeviceUpdate(accessory, params)
- await utils.sleep(garageConfig.operationTime * 100)
+ await utils.sleep(Math.max(garageConfig.operationTime * 100, 1000))
gdService.updateCharacteristic(Characteristic.CurrentDoorState, newPos)
accessory.context.inUse = false
} catch (err) {
@@ -50,7 +50,7 @@ module.exports = class deviceGarageEachen {
}
}
- externalUpdate (accessory, params) {
+ async externalUpdate (accessory, params) {
try {
if (!Object.prototype.hasOwnProperty.call(params, 'switch') || accessory.context.inUse) {
return
@@ -62,9 +62,10 @@ module.exports = class deviceGarageEachen {
if (garageConfig.type !== 'garage_eachen') {
throw new Error('improper configuration')
}
- accessory.getService(Service.GarageDoorOpener)
- .updateCharacteristic(Characteristic.CurrentDoorState, params.switch === 'on' ? 0 : 1)
- .updateCharacteristic(Characteristic.TargetDoorState, params.switch === 'on' ? 0 : 1)
+ const gdService = accessory.getService(Service.GarageDoorOpener)
+ gdService.updateCharacteristic(Characteristic.TargetDoorState, params.switch === 'on' ? 0 : 1)
+ await utils.sleep(1000)
+ gdService.updateCharacteristic(Characteristic.CurrentDoorState, params.switch === 'on' ? 0 : 1)
} catch (err) {
this.platform.deviceUpdateError(accessory, err, false)
}
From c25269676751e26dd146d613b791992675e4d137 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sat, 3 Oct 2020 21:58:32 +0100
Subject: [PATCH 0315/3183] 3.3.1-0
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 249642de..e421ac5d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.3.0",
+ "version": "3.3.1-0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 733f7ef9..1d63b615 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.3.0",
+ "version": "3.3.1-0",
"author": "bwp91",
"contributors": [
"gbro115",
From a28c15d69dfa491bbf613aae98ffff6b3423fda2 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sat, 3 Oct 2020 22:30:10 +0100
Subject: [PATCH 0316/3183] async externalUpdate
---
lib/device/blind.js | 2 +-
lib/device/curtain.js | 2 +-
lib/device/fan.js | 2 +-
lib/device/garage.js | 21 ++++++++++-----------
lib/device/light.js | 2 +-
lib/device/lock.js | 15 +++++++--------
lib/device/outlet.js | 2 +-
lib/device/rf-bridge.js | 2 +-
lib/device/scm.js | 2 +-
lib/device/sensor.js | 14 +++++++-------
lib/device/switch.js | 2 +-
lib/device/thermostat.js | 2 +-
lib/device/usb.js | 2 +-
lib/device/valve.js | 2 +-
lib/device/zb-dev.js | 2 +-
15 files changed, 36 insertions(+), 38 deletions(-)
diff --git a/lib/device/blind.js b/lib/device/blind.js
index 242eeaaf..3259d21a 100644
--- a/lib/device/blind.js
+++ b/lib/device/blind.js
@@ -80,7 +80,7 @@ module.exports = class deviceBlind {
}
}
- externalUpdate (accessory, params) {
+ async externalUpdate (accessory, params) {
return true
}
}
diff --git a/lib/device/curtain.js b/lib/device/curtain.js
index d96de66a..2f5f7c6c 100644
--- a/lib/device/curtain.js
+++ b/lib/device/curtain.js
@@ -46,7 +46,7 @@ module.exports = class deviceCurtain {
}
}
- externalUpdate (accessory, params) {
+ async externalUpdate (accessory, params) {
try {
const cService = accessory.getService(Service.WindowCovering)
if (!Object.prototype.hasOwnProperty.call(params, 'switch') && !Object.prototype.hasOwnProperty.call(params, 'setclose')) {
diff --git a/lib/device/fan.js b/lib/device/fan.js
index 2eac5d9b..045e0b64 100644
--- a/lib/device/fan.js
+++ b/lib/device/fan.js
@@ -63,7 +63,7 @@ module.exports = class deviceFan {
}
}
- externalUpdate (accessory, params) {
+ async externalUpdate (accessory, params) {
try {
let light
let status
diff --git a/lib/device/garage.js b/lib/device/garage.js
index 599316e7..5341153c 100644
--- a/lib/device/garage.js
+++ b/lib/device/garage.js
@@ -73,7 +73,7 @@ module.exports = class deviceGarage {
break
}
await this.platform.sendDeviceUpdate(accessory, params)
- await utils.sleep(garageConfig.operationTime * 100)
+ await utils.sleep(Math.max(garageConfig.operationTime * 100, 1000))
if (!sAccessory) {
gdService.updateCharacteristic(Characteristic.CurrentDoorState, newPos)
accessory.context.cacheCurrentDoorState = newPos
@@ -84,7 +84,7 @@ module.exports = class deviceGarage {
}
}
- externalUpdate (accessory, params) {
+ async externalUpdate (accessory, params) {
try {
if (!Object.prototype.hasOwnProperty.call(params, 'switch') && !Object.prototype.hasOwnProperty.call(params, 'switches')) {
return
@@ -118,20 +118,19 @@ module.exports = class deviceGarage {
break
}
accessory.context.inUse = true
- if (!garageConfig.sensorId) {
+ if (garageConfig.sensorId) {
+ await utils.sleep(Math.max(garageConfig.operationTime * 100, 1000))
+ } else {
gcService
- .updateCharacteristic(Characteristic.CurrentDoorState, newPos)
.updateCharacteristic(Characteristic.TargetDoorState, newPos - 2)
+ .updateCharacteristic(Characteristic.CurrentDoorState, newPos)
accessory.context.cacheCurrentDoorState = newPos
accessory.context.cacheTargetDoorState = newPos - 2
- setTimeout(() => {
- gcService.updateCharacteristic(Characteristic.CurrentDoorState, newPos - 2)
- accessory.context.cacheCurrentDoorState = newPos - 2
- }, parseInt(garageConfig.operationTime) * 100)
+ await utils.sleep(Math.max(garageConfig.operationTime * 100, 1000))
+ gcService.updateCharacteristic(Characteristic.CurrentDoorState, newPos - 2)
+ accessory.context.cacheCurrentDoorState = newPos - 2
}
- setTimeout(() => {
- accessory.context.inUse = false
- }, parseInt(garageConfig.operationTime) * 100)
+ accessory.context.inUse = false
} catch (err) {
accessory.context.inUse = false
this.platform.deviceUpdateError(accessory, err, false)
diff --git a/lib/device/light.js b/lib/device/light.js
index 7d67c7d0..066b0daf 100644
--- a/lib/device/light.js
+++ b/lib/device/light.js
@@ -206,7 +206,7 @@ module.exports = class deviceLight {
}
}
- externalUpdate (accessory, params) {
+ async externalUpdate (accessory, params) {
try {
if (
cns.devicesSingleSwitch.includes(accessory.context.eweUIID) &&
diff --git a/lib/device/lock.js b/lib/device/lock.js
index b335b281..6996f00b 100644
--- a/lib/device/lock.js
+++ b/lib/device/lock.js
@@ -31,7 +31,7 @@ module.exports = class deviceLock {
lmService
.updateCharacteristic(Characteristic.LockTargetState, 0)
.updateCharacteristic(Characteristic.LockCurrentState, 0)
- await utils.sleep(lockConfig.operationTime * 100)
+ await utils.sleep(Math.max(lockConfig.operationTime * 100, 1000))
lmService
.updateCharacteristic(Characteristic.LockTargetState, 1)
.updateCharacteristic(Characteristic.LockCurrentState, 1)
@@ -41,7 +41,7 @@ module.exports = class deviceLock {
}
}
- externalUpdate (accessory, params) {
+ async externalUpdate (accessory, params) {
try {
if (!Object.prototype.hasOwnProperty.call(params, 'switch')) return
let lockConfig
@@ -59,12 +59,11 @@ module.exports = class deviceLock {
lmService
.updateCharacteristic(Characteristic.LockCurrentState, 0)
.updateCharacteristic(Characteristic.LockTargetState, 0)
- setTimeout(() => {
- lmService
- .updateCharacteristic(Characteristic.LockCurrentState, 1)
- .updateCharacteristic(Characteristic.LockTargetState, 1)
- accessory.context.inUse = false
- }, parseInt(lockConfig.operationTime) * 100)
+ await utils.sleep(Math.max(lockConfig.operationTime * 100, 1000))
+ lmService
+ .updateCharacteristic(Characteristic.LockCurrentState, 1)
+ .updateCharacteristic(Characteristic.LockTargetState, 1)
+ accessory.context.inUse = false
} catch (err) {
accessory.context.inUse = false
this.platform.deviceUpdateError(accessory, err, false)
diff --git a/lib/device/outlet.js b/lib/device/outlet.js
index bb86951d..fe05aebe 100644
--- a/lib/device/outlet.js
+++ b/lib/device/outlet.js
@@ -122,7 +122,7 @@ module.exports = class deviceOutlet {
}
}
- externalUpdate (accessory, params) {
+ async externalUpdate (accessory, params) {
try {
const outletService = accessory.getService(Service.Outlet)
if (Object.prototype.hasOwnProperty.call(params, 'switch')) {
diff --git a/lib/device/rf-bridge.js b/lib/device/rf-bridge.js
index b2124215..0f60a023 100644
--- a/lib/device/rf-bridge.js
+++ b/lib/device/rf-bridge.js
@@ -59,7 +59,7 @@ module.exports = class deviceRFBridge {
}
}
- externalUpdate (accessory, params) {
+ async externalUpdate (accessory, params) {
try {
if (!Object.prototype.hasOwnProperty.call(params, 'updateSource')) return
const timeNow = new Date()
diff --git a/lib/device/scm.js b/lib/device/scm.js
index 577c2e69..8c62b37f 100644
--- a/lib/device/scm.js
+++ b/lib/device/scm.js
@@ -27,7 +27,7 @@ module.exports = class deviceSCM {
}
}
- externalUpdate (accessory, params) {
+ async externalUpdate (accessory, params) {
try {
if (!Object.prototype.hasOwnProperty.call(params, 'switches')) return
accessory.getService(Service.Switch).updateCharacteristic(Characteristic.On, params.switches[0].switch === 'on')
diff --git a/lib/device/sensor.js b/lib/device/sensor.js
index 5c3741b4..83d4cd5e 100644
--- a/lib/device/sensor.js
+++ b/lib/device/sensor.js
@@ -1,5 +1,6 @@
'use strict'
let Characteristic, Service
+const utils = require('./../utils')
module.exports = class deviceSensor {
constructor (platform, accessory) {
this.platform = platform
@@ -9,7 +10,7 @@ module.exports = class deviceSensor {
accessory.getService(Service.BatteryService) || accessory.addService(Service.BatteryService)
}
- externalUpdate (accessory, params) {
+ async externalUpdate (accessory, params) {
try {
if (Object.prototype.hasOwnProperty.call(params, 'battery')) {
const batteryService =
@@ -37,12 +38,11 @@ module.exports = class deviceSensor {
.updateCharacteristic(Characteristic.CurrentDoorState, 1)
break
case 1:
- setTimeout(() => {
- oAccessory
- .getService(Service.GarageDoorOpener)
- .updateCharacteristic(Characteristic.TargetDoorState, 0)
- .updateCharacteristic(Characteristic.CurrentDoorState, 0)
- }, group.operationTime * 100)
+ await utils.sleep(Math.max(group.operationTime * 100, 1000))
+ oAccessory
+ .getService(Service.GarageDoorOpener)
+ .updateCharacteristic(Characteristic.TargetDoorState, 0)
+ .updateCharacteristic(Characteristic.CurrentDoorState, 0)
break
}
}
diff --git a/lib/device/switch.js b/lib/device/switch.js
index 19c7a331..97ee0293 100644
--- a/lib/device/switch.js
+++ b/lib/device/switch.js
@@ -86,7 +86,7 @@ module.exports = class deviceSwitch {
}
}
- externalUpdate (accessory, params) {
+ async externalUpdate (accessory, params) {
try {
if (cns.devicesSingleSwitch.includes(accessory.context.eweUIID)) {
if (!Object.prototype.hasOwnProperty.call(params, 'switch')) return
diff --git a/lib/device/thermostat.js b/lib/device/thermostat.js
index ed36e577..5fd997ac 100644
--- a/lib/device/thermostat.js
+++ b/lib/device/thermostat.js
@@ -54,7 +54,7 @@ module.exports = class deviceThermostat {
}
}
- externalUpdate (accessory, params) {
+ async externalUpdate (accessory, params) {
try {
if (
!this.platform.config.hideTHSwitch &&
diff --git a/lib/device/usb.js b/lib/device/usb.js
index 13a2c87b..6c230010 100644
--- a/lib/device/usb.js
+++ b/lib/device/usb.js
@@ -27,7 +27,7 @@ module.exports = class deviceUSB {
}
}
- externalUpdate (accessory, params) {
+ async externalUpdate (accessory, params) {
try {
if (!Object.prototype.hasOwnProperty.call(params, 'switches')) return
accessory.getService(Service.Outlet).updateCharacteristic(Characteristic.On, params.switches[0].switch === 'on')
diff --git a/lib/device/valve.js b/lib/device/valve.js
index 9aab7584..67bf6d30 100644
--- a/lib/device/valve.js
+++ b/lib/device/valve.js
@@ -85,7 +85,7 @@ module.exports = class deviceValve {
}
}
- externalUpdate (accessory, params) {
+ async externalUpdate (accessory, params) {
try {
if (!Object.prototype.hasOwnProperty.call(params, 'switches')) return
let valveConfig
diff --git a/lib/device/zb-dev.js b/lib/device/zb-dev.js
index 21c309a2..478544b1 100644
--- a/lib/device/zb-dev.js
+++ b/lib/device/zb-dev.js
@@ -51,7 +51,7 @@ module.exports = class deviceZBDev {
}
}
- externalUpdate (accessory, params) {
+ async externalUpdate (accessory, params) {
try {
//* ** credit @tasict ***\\
if (Object.prototype.hasOwnProperty.call(params, 'battery')) {
From f2355e3bfa438c3991d5046789afeae2c4c964e4 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 4 Oct 2020 11:05:47 +0100
Subject: [PATCH 0317/3183] double notifications fix
---
lib/device/garage-eachen.js | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/lib/device/garage-eachen.js b/lib/device/garage-eachen.js
index 85953acb..4a4af8be 100644
--- a/lib/device/garage-eachen.js
+++ b/lib/device/garage-eachen.js
@@ -62,11 +62,14 @@ module.exports = class deviceGarageEachen {
if (garageConfig.type !== 'garage_eachen') {
throw new Error('improper configuration')
}
+ accessory.context.inUse = true
const gdService = accessory.getService(Service.GarageDoorOpener)
gdService.updateCharacteristic(Characteristic.TargetDoorState, params.switch === 'on' ? 0 : 1)
- await utils.sleep(1000)
+ await utils.sleep(1500)
gdService.updateCharacteristic(Characteristic.CurrentDoorState, params.switch === 'on' ? 0 : 1)
+ accessory.context.inUse = false
} catch (err) {
+ accessory.context.inUse = false
this.platform.deviceUpdateError(accessory, err, false)
}
}
From 5275e07be5df1a7a1aa9f9570fdc58b470aa4275 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 4 Oct 2020 11:06:34 +0100
Subject: [PATCH 0318/3183] 3.3.1-1
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index e421ac5d..65ca6ac4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.3.1-0",
+ "version": "3.3.1-1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 1d63b615..cc2fd61d 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.3.1-0",
+ "version": "3.3.1-1",
"author": "bwp91",
"contributors": [
"gbro115",
From 9fa831eaf8df07ab83df21d101c4f72fc525dbde Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 4 Oct 2020 11:14:26 +0100
Subject: [PATCH 0319/3183] Update garage-eachen.js
---
lib/device/garage-eachen.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/device/garage-eachen.js b/lib/device/garage-eachen.js
index 4a4af8be..584319c2 100644
--- a/lib/device/garage-eachen.js
+++ b/lib/device/garage-eachen.js
@@ -65,7 +65,7 @@ module.exports = class deviceGarageEachen {
accessory.context.inUse = true
const gdService = accessory.getService(Service.GarageDoorOpener)
gdService.updateCharacteristic(Characteristic.TargetDoorState, params.switch === 'on' ? 0 : 1)
- await utils.sleep(1500)
+ await utils.sleep(Math.max(garageConfig.operationTime * 100, 1000))
gdService.updateCharacteristic(Characteristic.CurrentDoorState, params.switch === 'on' ? 0 : 1)
accessory.context.inUse = false
} catch (err) {
From 32ded0523a2181749047528031c1106adc2259b8 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 4 Oct 2020 11:15:28 +0100
Subject: [PATCH 0320/3183] 3.3.1-2
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 65ca6ac4..9593ffe4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.3.1-1",
+ "version": "3.3.1-2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index cc2fd61d..0bf467e4 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.3.1-1",
+ "version": "3.3.1-2",
"author": "bwp91",
"contributors": [
"gbro115",
From a819f2c51d28eb3b036ec60b573f475c1d11b40a Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 4 Oct 2020 11:23:01 +0100
Subject: [PATCH 0321/3183] Update sensor.js
---
lib/device/sensor.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/device/sensor.js b/lib/device/sensor.js
index 83d4cd5e..dac9afc2 100644
--- a/lib/device/sensor.js
+++ b/lib/device/sensor.js
@@ -27,7 +27,7 @@ module.exports = class deviceSensor {
let oAccessory = false
const contactService = accessory.getService(Service.ContactSensor)
contactService.updateCharacteristic(Characteristic.ContactSensorState, newState)
- this.platform.cusG.forEach(group => {
+ this.platform.cusG.forEach(async group => {
if (group.sensorId === accessory.context.eweDeviceId && group.type === 'garage') {
if ((oAccessory = this.platform.devicesInHB.get(group.deviceId + 'SWX'))) {
switch (newState) {
From a2bb9ccf0cb2e663cf989b753f8a6fb55a399d16 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 4 Oct 2020 11:23:31 +0100
Subject: [PATCH 0322/3183] 3.3.1-3
---
package-lock.json | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 9593ffe4..38a4ffea 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.3.1-2",
+ "version": "3.3.1-3",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 0bf467e4..7334fd6b 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homebridge-ewelink",
- "version": "3.3.1-2",
+ "version": "3.3.1-3",
"author": "bwp91",
"contributors": [
"gbro115",
From 737f54d5591b29ea36959e0442bb23d178f7e3bc Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 4 Oct 2020 13:36:35 +0100
Subject: [PATCH 0323/3183] settimeout to await
---
lib/device/rf-bridge.js | 7 +++----
lib/eWeLinkWS.js | 10 ++++++----
2 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/lib/device/rf-bridge.js b/lib/device/rf-bridge.js
index 0f60a023..a791b1ef 100644
--- a/lib/device/rf-bridge.js
+++ b/lib/device/rf-bridge.js
@@ -90,7 +90,7 @@ module.exports = class deviceRFBridge {
//* ** RF Sensor ***\\
Object.keys(params)
.filter(name => /rfTrig/.test(name))
- .forEach(chan => {
+ .forEach(async chan => {
this.platform.devicesInHB.forEach(acc => {
if (
acc.context.eweDeviceId === accessory.context.eweDeviceId &&
@@ -140,9 +140,8 @@ module.exports = class deviceRFBridge {
break
}
oAccessory.getService(serv).updateCharacteristic(char, 1)
- setTimeout(() => {
- oAccessory.getService(serv).updateCharacteristic(char, 0)
- }, (this.platform.config.sensorTimeLength || 2) * 1000)
+ await utils.sleep((this.platform.config.sensorTimeLength || 2) * 1000)
+ oAccessory.getService(serv).updateCharacteristic(char, 0)
}
}
})
diff --git a/lib/eWeLinkWS.js b/lib/eWeLinkWS.js
index 5d585aa8..91633aef 100644
--- a/lib/eWeLinkWS.js
+++ b/lib/eWeLinkWS.js
@@ -155,13 +155,14 @@ module.exports = class eWeLinkWS {
}
}
})
- this.wsp.onClose.addListener(e => {
+ this.wsp.onClose.addListener(async e => {
this.wsIsOpen = false
if (e !== 1005) {
this.log.warn('Web socket closed [%s].', e)
if (e !== 1000) {
this.log('Web socket will try to reconnect in five seconds.')
- setTimeout(() => this.login(), 5000)
+ await utils.sleep(5000)
+ this.login()
} else {
this.log('Please try restarting Homebridge so that this plugin can work again.')
}
@@ -172,12 +173,13 @@ module.exports = class eWeLinkWS {
}
this.wsp.removeAllListeners()
})
- this.wsp.onError.addListener(e => {
+ this.wsp.onError.addListener(async e => {
this.log.warn('Web socket error - [%s].', e)
if (e.code === 'ECONNREFUSED') {
this.log.warn('Web socket will try to reconnect in five seconds then try the command again.')
this.wsp.removeAllListeners()
- setTimeout(() => this.login(), 5000)
+ await utils.sleep(5000)
+ this.login()
} else {
this.log.warn('If this was unexpected then please try restarting Homebridge.')
}
From b2932c17cc2e1d69afa0a79dced046b7a1e95281 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 4 Oct 2020 13:54:21 +0100
Subject: [PATCH 0324/3183] Create i
---
docs/i | 0
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 docs/i
diff --git a/docs/i b/docs/i
new file mode 100644
index 00000000..e69de29b
From bac625c0c50dfddaefe47a5b3cbc223d64856526 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 4 Oct 2020 13:54:53 +0100
Subject: [PATCH 0325/3183] Delete i
---
docs/i | 0
1 file changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 docs/i
diff --git a/docs/i b/docs/i
deleted file mode 100644
index e69de29b..00000000
From 38eb388ad8024db3151415f92116762b9fa2f36a Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Sun, 4 Oct 2020 13:56:27 +0100
Subject: [PATCH 0326/3183] Create .gitkeep
---
docs/.gitkeep | 1 +
1 file changed, 1 insertion(+)
create mode 100644 docs/.gitkeep
diff --git a/docs/.gitkeep b/docs/.gitkeep
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/docs/.gitkeep
@@ -0,0 +1 @@
+
From 373e69d27da7ddda4bc3c1212e8a79a954112785 Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Sun, 4 Oct 2020 13:56:46 +0100
Subject: [PATCH 0327/3183] Set theme jekyll-theme-cayman
---
docs/_config.yml | 1 +
1 file changed, 1 insertion(+)
create mode 100644 docs/_config.yml
diff --git a/docs/_config.yml b/docs/_config.yml
new file mode 100644
index 00000000..c4192631
--- /dev/null
+++ b/docs/_config.yml
@@ -0,0 +1 @@
+theme: jekyll-theme-cayman
\ No newline at end of file
From f6dccd6129c5e3faeff8f2d430f9ea2db195b1c2 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 4 Oct 2020 14:04:30 +0100
Subject: [PATCH 0328/3183] Create index.md
---
docs/index.md | 40 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
create mode 100644 docs/index.md
diff --git a/docs/index.md b/docs/index.md
new file mode 100644
index 00000000..4f0e0eb3
--- /dev/null
+++ b/docs/index.md
@@ -0,0 +1,40 @@
+
+
+
+
+
+# homebridge-ewelink
+
+ Homebridge plugin to control eWeLink devices with original firmware.
+
+ [![verified-by-homebridge](https://badgen.net/badge/homebridge/verified/purple)](https://github.com/homebridge/homebridge/wiki/Verified-Plugins)
+ [![npm](https://img.shields.io/npm/v/homebridge-ewelink/latest?label=release)](https://www.npmjs.com/package/homebridge-ewelink)
+ [![npm](https://img.shields.io/npm/v/homebridge-ewelink/beta?label=beta)](https://www.npmjs.com/package/homebridge-ewelink)
+ [![npm](https://img.shields.io/npm/dt/homebridge-ewelink)](https://www.npmjs.com/package/homebridge-ewelink)
+ [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)
+ [![Discord](https://img.shields.io/discord/432663330281226270?color=728ED5&logo=discord&label=discord)](https://discord.com/channels/432663330281226270/742733745743855627)
+ [![Contribute](https://img.shields.io/badge/contribute-a%20drink-yellow)](https://ko-fi.com/bwp91)
+
+
+
+### Setup
+* [Installation (Homebridge)](https://github.com/bwp91/homebridge-ewelink/wiki/Installation-(Homebridge))
+* [Installation (HOOBS)](https://github.com/bwp91/homebridge-ewelink/wiki/Installation-(HOOBS))
+* [Configuration](https://github.com/bwp91/homebridge-ewelink/wiki/Configuration)
+* [Beta Version](https://github.com/bwp91/homebridge-ewelink/wiki/Beta-Version)
+### Features
+* [Supported Devices](https://github.com/bwp91/homebridge-ewelink/wiki/Supported-Devices)
+* [Accessory Simulations](https://github.com/bwp91/homebridge-ewelink/wiki/Accessory-Simulations)
+* [Connection Methods](https://github.com/bwp91/homebridge-ewelink/wiki/Connection-Methods)
+### How-to Guides
+* [How to set up RF Bridge sensors](https://github.com/bwp91/homebridge-ewelink/wiki/How-to-set-up-RF-Bridge-sensors)
+* [How to set up Sonoff Camera (GK-200MP2-B)](https://github.com/bwp91/homebridge-ewelink/wiki/How-to-set-up-Sonoff-Camera)
+* [How to copy Homebridge logs](https://github.com/bwp91/homebridge-ewelink/wiki/How-to-copy-Homebridge-logs)
+* [How to enable/disable plugin extended logging](https://github.com/bwp91/homebridge-ewelink/wiki/How-to-enable-disable-plugin-extended-logging)
+* [How to remove an accessory from the cache](https://github.com/bwp91/homebridge-ewelink/wiki/How-to-remove-an-accessory-from-the-cache)
+### About
+* [Support Request](https://github.com/bwp91/homebridge-ewelink/issues/new/choose)
+* [Roadmap](https://github.com/bwp91/homebridge-ewelink/wiki/Roadmap)
+* [Credits](https://github.com/bwp91/homebridge-ewelink/wiki/Credits)
+### Disclaimer
+I am in no way affiliated with eWeLink nor any of the device brands (like Sonoff) and this plugin is a personal project that I maintain in my free time.
From ee583f3d5a425579279163610f4fd8ae7a13c70a Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 4 Oct 2020 14:08:16 +0100
Subject: [PATCH 0329/3183] Create index.html
---
docs/index.html | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
create mode 100644 docs/index.html
diff --git a/docs/index.html b/docs/index.html
new file mode 100644
index 00000000..61e831cf
--- /dev/null
+++ b/docs/index.html
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
From b0a0cdf4084ae9b6999eefe460864eacf87a9957 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 4 Oct 2020 14:10:03 +0100
Subject: [PATCH 0330/3183] Delete .gitkeep
---
docs/.gitkeep | 1 -
1 file changed, 1 deletion(-)
delete mode 100644 docs/.gitkeep
diff --git a/docs/.gitkeep b/docs/.gitkeep
deleted file mode 100644
index 8b137891..00000000
--- a/docs/.gitkeep
+++ /dev/null
@@ -1 +0,0 @@
-
From c3c5dadc6297747a761b5e13ccd0483565689c7b Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 4 Oct 2020 14:10:05 +0100
Subject: [PATCH 0331/3183] Delete _config.yml
---
docs/_config.yml | 1 -
1 file changed, 1 deletion(-)
delete mode 100644 docs/_config.yml
diff --git a/docs/_config.yml b/docs/_config.yml
deleted file mode 100644
index c4192631..00000000
--- a/docs/_config.yml
+++ /dev/null
@@ -1 +0,0 @@
-theme: jekyll-theme-cayman
\ No newline at end of file
From d729ca3cac8dc2bdf64131af2536fb65002a784c Mon Sep 17 00:00:00 2001
From: Ben <43026681+bwp91@users.noreply.github.com>
Date: Sun, 4 Oct 2020 14:12:40 +0100
Subject: [PATCH 0332/3183] Create .nojekyll
---
docs/.nojekyll | 1 +
1 file changed, 1 insertion(+)
create mode 100644 docs/.nojekyll
diff --git a/docs/.nojekyll b/docs/.nojekyll
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/docs/.nojekyll
@@ -0,0 +1 @@
+
From 7d1ae2beb17bf4d06b4212167cef5cfa1cc19cc7 Mon Sep 17 00:00:00 2001
From: bwp91 <43026681+bwp91@users.noreply.github.com>
Date: Sun, 4 Oct 2020 14:14:48 +0100
Subject: [PATCH 0333/3183] Update index.html
---
docs/index.html | 1 -
1 file changed, 1 deletion(-)
diff --git a/docs/index.html b/docs/index.html
index 61e831cf..09e9f917 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -10,7 +10,6 @@
-
-