@petro-kushchak/homebridge-tuya-eve 1.0.11 → 1.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.eslintrc ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "parser": "@typescript-eslint/parser",
3
+ "extends": [
4
+ "eslint:recommended",
5
+ "plugin:@typescript-eslint/eslint-recommended",
6
+ "plugin:@typescript-eslint/recommended" // uses the recommended rules from the @typescript-eslint/eslint-plugin
7
+ ],
8
+ "parserOptions": {
9
+ "ecmaVersion": 2018,
10
+ "sourceType": "module"
11
+ },
12
+ "ignorePatterns": [
13
+ "dist"
14
+ ],
15
+ "rules": {
16
+ "quotes": ["warn", "single"],
17
+ "indent": ["warn", 4, { "SwitchCase": 1 }],
18
+ "semi": ["off"],
19
+ "comma-dangle": ["warn", "always-multiline"],
20
+ "dot-notation": "off",
21
+ "eqeqeq": "warn",
22
+ "curly": ["warn", "all"],
23
+ "brace-style": ["warn"],
24
+ "prefer-arrow-callback": ["warn"],
25
+ "max-len": ["warn", 140],
26
+ "no-console": ["warn"], // use the provided Homebridge log method instead
27
+ "no-non-null-assertion": ["off"],
28
+ "comma-spacing": ["error"],
29
+ "no-multi-spaces": ["warn", { "ignoreEOLComments": true }],
30
+ "no-trailing-spaces": ["warn"],
31
+ "lines-between-class-members": ["warn", "always", {"exceptAfterSingleLine": true}],
32
+ "@typescript-eslint/explicit-function-return-type": "off",
33
+ "@typescript-eslint/no-non-null-assertion": "off",
34
+ "@typescript-eslint/explicit-module-boundary-types": "off",
35
+ "@typescript-eslint/semi": ["warn"],
36
+ "@typescript-eslint/member-delimiter-style": ["warn"]
37
+ }
38
+ }
package/.prettierrc CHANGED
@@ -1,6 +1,9 @@
1
1
  {
2
+ "bracketSpacing": true,
3
+ "printWidth": 120,
2
4
  "semi": true,
3
- "trailingComma": "all",
4
5
  "singleQuote": true,
5
- "printWidth": 80
6
+ "tabWidth": 4,
7
+ "useTabs": false,
8
+ "trailingComma": "all"
6
9
  }
package/dist/index.js CHANGED
@@ -1,228 +1,6 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- const eveHistoryService_1 = require("./lib/eveHistoryService");
6
- const tuyapi_1 = __importDefault(require("tuyapi"));
7
- const EnergyCharacteristics_1 = __importDefault(require("./lib/EnergyCharacteristics"));
8
- const homebridgeCallbacks_1 = require("./lib/homebridgeCallbacks");
9
- let hap;
10
- const ONOFF_DP = '1';
11
- const AMP_DP = '18';
12
- const WATT_DP = '19';
13
- const VOLT_DP = '20';
14
- const kHour = 60 * 60 * 1000;
15
- /**
16
- * Platform Accessory
17
- * An instance of this class is created for each accessory your platform registers
18
- * Each accessory may expose multiple services of different service types.
19
- */
20
- class TuyaSwitchAccessoryAccessory {
21
- constructor(logger, config, api) {
22
- this.logger = logger;
23
- this.config = config;
24
- this.api = api;
25
- this.amperes = 0;
26
- this.watts = 0;
27
- this.volts = 0;
28
- this.inUse = false;
29
- this.totalConsumption = 0;
30
- this.resetTotal = 0;
31
- hap = api.hap;
32
- this.log = logger;
33
- this.name = config.name;
34
- this.displayName = this.name;
35
- this.serial = config.serial;
36
- this.id = config.id;
37
- this.key = config.key;
38
- this.model = config.model || 'TuyaSwitch';
39
- this.updateInterval = config.updateInterval || 5000;
40
- this.EnergyCharacteristics = EnergyCharacteristics_1.default.create(hap.Characteristic);
41
- this.device = new tuyapi_1.default({
42
- id: this.id,
43
- key: this.key,
44
- issueRefreshOnConnect: true,
45
- });
46
- // Set AccessoryInformation
47
- this.informationService = new hap.Service.AccessoryInformation()
48
- .setCharacteristic(hap.Characteristic.Name, this.name)
49
- .setCharacteristic(hap.Characteristic.Manufacturer, 'Tuya')
50
- .setCharacteristic(hap.Characteristic.Model, this.model)
51
- .setCharacteristic(hap.Characteristic.SerialNumber, this.serial);
52
- // create a new Thermostat service
53
- this.service = new hap.Service.Switch(this.name);
54
- this.service
55
- .getCharacteristic(hap.Characteristic.On)
56
- .on("get" /* CharacteristicEventTypes.GET */, (0, homebridgeCallbacks_1.callbackify)(this.getPowerOnOff.bind(this)))
57
- .on("set" /* CharacteristicEventTypes.SET */, (0, homebridgeCallbacks_1.callbackify)(this.setPowerOnOff.bind(this)));
58
- this.service.addOptionalCharacteristic(this.EnergyCharacteristics.Volts);
59
- this.service.addOptionalCharacteristic(this.EnergyCharacteristics.Amperes);
60
- this.service.addOptionalCharacteristic(this.EnergyCharacteristics.Watts);
61
- this.service.addOptionalCharacteristic(this.EnergyCharacteristics.TotalConsumption);
62
- this.service.addOptionalCharacteristic(this.EnergyCharacteristics.ResetTotal);
63
- this.service
64
- .getCharacteristic(this.EnergyCharacteristics.Volts)
65
- .on('get', this.getVoltage.bind(this))
66
- .updateValue(this.volts);
67
- this.service
68
- .getCharacteristic(this.EnergyCharacteristics.Amperes)
69
- .on('get', this.getCurrent.bind(this))
70
- .updateValue(this.amperes);
71
- this.service
72
- .getCharacteristic(this.EnergyCharacteristics.Watts)
73
- .on('get', this.getConsumption.bind(this))
74
- .updateValue(this.watts);
75
- this.service
76
- .getCharacteristic(this.EnergyCharacteristics.TotalConsumption)
77
- .on('get', this.getTotalConsumption.bind(this));
78
- // create handlers for required characteristics
79
- this.historyService = new eveHistoryService_1.EveHistoryService(this, this.api, 'energy',
80
- // this.historyFilename,
81
- this.logger);
82
- this.readTotalConsumption();
83
- //device events
84
- setTimeout(async () => {
85
- this.device.on('connected', () => {
86
- this.log('Connected to device!');
87
- const lastTime = new Date().getTime();
88
- setInterval(async () => {
89
- const now = new Date().getTime();
90
- const delta = (now - lastTime) / 1000;
91
- const state = await this.device.get({ schema: true });
92
- this.log(`Device state: ${JSON.stringify(state)}`);
93
- this.updateState(state.dps);
94
- const consumption = this.watts * delta; // W/s
95
- this.totalConsumption += consumption / kHour;
96
- this.historyService.addEntry({ time: now / 1000, power: this.watts });
97
- const extra = this.historyService.getExtraPersistedData();
98
- if (!extra) {
99
- this.historyService.setExtraPersistedData({
100
- totalConsumption: this.totalConsumption,
101
- resetTotal: this.resetTotal,
102
- });
103
- }
104
- else if (extra.totalConsumption !== this.totalConsumption ||
105
- extra.resetTotal !== this.resetTotal) {
106
- extra.totalConsumption = this.totalConsumption;
107
- extra.resetTotal = this.resetTotal;
108
- this.historyService.setExtraPersistedData(extra);
109
- }
110
- }, this.updateInterval);
111
- });
112
- this.device.on('disconnected', () => {
113
- this.log('Disconnected to device!');
114
- });
115
- this.device.on('error', (error) => {
116
- this.log(`Error ${error}!`);
117
- });
118
- this.device.on('data', (data) => {
119
- this.log(`DATA ${JSON.stringify(data)}!`);
120
- this.updateState(data.dps);
121
- });
122
- this.device.on('dp-refresh', (data) => {
123
- this.log(`REFRESH ${JSON.stringify(data)}!`);
124
- this.updateState(data.dps);
125
- });
126
- //device find&connect
127
- await this.device.find();
128
- await this.device.connect();
129
- }, 1000);
130
- }
131
- getTotalConsumption(callback) {
132
- callback(null, this.totalConsumption);
133
- }
134
- getResetTotal(callback) {
135
- callback(null, this.resetTotal);
136
- }
137
- setResetTotal(value, callback) {
138
- this.log.info(`setResetTotal: ${value}`);
139
- this.resetTotal = value;
140
- this.totalConsumption = 0;
141
- callback(null, this.resetTotal);
142
- }
143
- getVoltage(callback) {
144
- // this.updateState(this.device.state);
145
- callback(null, this.volts);
146
- }
147
- getCurrent(callback) {
148
- // this.updateState(this.device.state);
149
- callback(null, this.amperes);
150
- }
151
- getConsumption(callback) {
152
- // this.updateState(this.device.state);
153
- callback(null, this.watts);
154
- }
155
- updateState(dps) {
156
- this.amperes = dps[AMP_DP] ? dps[AMP_DP] / 1000 : 0;
157
- this.watts = dps[WATT_DP] ? dps[WATT_DP] / 10 : 0;
158
- this.volts = dps[VOLT_DP] ? dps[VOLT_DP] / 10 : 0;
159
- this.inUse = dps[ONOFF_DP] ? dps[ONOFF_DP] : false;
160
- this.log.info(`updated a:${this.amperes} w:${this.watts} v:${this.volts} on: ${this.inUse}`);
161
- }
162
- async setPowerOnOff(value) {
163
- this.log.info(`SET ON: ${value}`);
164
- await this.device.set({ set: value, dps: '1' });
165
- }
166
- async getPowerOnOff() {
167
- const status = await this.device.get();
168
- this.log.info(`GET ON: ${status.dps[1]}`);
169
- return status.dps[1];
170
- }
171
- readTotalConsumption() {
172
- this.historyService.readHistory((lastEntry, history, extra) => {
173
- const lastItem = history.pop();
174
- if (lastItem) {
175
- this.log.info('History: last item: %s', lastItem);
176
- }
177
- else {
178
- this.log.info('History: no data');
179
- }
180
- this.log.info('History: extra: %s', extra);
181
- const totalConsumption = extra.totalConsumption
182
- ? extra.totalConsumption
183
- : 0.0;
184
- const resetTotal = extra.resetTotal
185
- ? extra.resetTotal
186
- : 0; // Math.floor(Date.now() / 1000) - 978307200 // seconds since 01.01.2001
187
- this.log.info(`totalConsumption: ${totalConsumption} resetTotal: ${resetTotal}`);
188
- this.totalConsumption = totalConsumption;
189
- this.resetTotal = resetTotal;
190
- });
191
- // try {
192
- // const filepath = this.api ? this.api.user.storagePath() : './config';
193
- // const filename = path.join(filepath, this.historyFilename);
194
- // this.log.info(`Reading history: ${filename}`);
195
- // const data = fs.readFileSync(filename, 'utf8');
196
- // const jsonData = typeof data === 'object' ? data : JSON.parse(data);
197
- // const totalConsumption =
198
- // jsonData.extra && jsonData.extra.totalConsumption
199
- // ? jsonData.extra.totalConsumption
200
- // : 0.0;
201
- // const resetTotal =
202
- // jsonData.extra && jsonData.extra.resetTotal
203
- // ? jsonData.extra.resetTotal
204
- // : 0; // Math.floor(Date.now() / 1000) - 978307200 // seconds since 01.01.2001
205
- // this.log.info(
206
- // `totalConsumption: ${totalConsumption} resetTotal: ${resetTotal}`,
207
- // );
208
- // this.totalConsumption = totalConsumption;
209
- // this.resetTotal = resetTotal;
210
- // } catch (err) {
211
- // this.log.error(`readTotalConsumption error: ${err}`);
212
- // this.totalConsumption = 0;
213
- // this.resetTotal = 0;
214
- // }
215
- }
216
- getServices() {
217
- return [
218
- this.informationService,
219
- this.service,
220
- this.historyService.getService(),
221
- ];
222
- }
223
- }
2
+ const tuyaSwitchAccessory_1 = require("./tuyaSwitchAccessory");
224
3
  module.exports = (api) => {
225
- hap = api.hap;
226
- api.registerAccessory('homebridge-tuya-eve', 'TuyaSwitchEve', TuyaSwitchAccessoryAccessory);
4
+ api.registerAccessory('homebridge-tuya-eve', 'TuyaSwitchEve', tuyaSwitchAccessory_1.TuyaSwitchAccessory);
227
5
  };
228
6
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,+DAA4D;AAK5D,iBAAS,CAAC,GAAQ,EAAE,EAAE;IAClB,GAAG,CAAC,iBAAiB,CAAC,qBAAqB,EAAE,eAAe,EAAE,yCAAmB,CAAC,CAAC;AACvF,CAAC,CAAC"}
@@ -12,7 +12,10 @@ class EveHistoryService {
12
12
  this.serviceType = serviceType;
13
13
  this.logger = logger;
14
14
  const FakeGatoHistoryService = (0, fakegato_history_1.default)(api);
15
- this.historyService = new FakeGatoHistoryService(this.serviceType, this.accessory, { storage: 'fs', log: this.logger });
15
+ this.historyService = new FakeGatoHistoryService(this.serviceType, this.accessory, {
16
+ storage: 'fs',
17
+ log: this.logger,
18
+ });
16
19
  }
17
20
  getService() {
18
21
  return this.historyService;
@@ -27,8 +30,7 @@ class EveHistoryService {
27
30
  this.historyService.addEntry(entry);
28
31
  }
29
32
  readHistory(lastEntryHandler) {
30
- const storage = this.api
31
- .globalFakeGatoStorage;
33
+ const storage = this.api.globalFakeGatoStorage;
32
34
  if (!storage) {
33
35
  this.logger.debug('Failed to access globalFakeGatoStorage');
34
36
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"eveHistoryService.js","sourceRoot":"","sources":["../../src/lib/eveHistoryService.ts"],"names":[],"mappings":";;;;;;AAAA,wEAAwC;AAwBxC,MAAa,iBAAiB;IAG5B,YACU,SAA0B,EAC1B,GAAQ,EACR,WAAmB,EACnB,MAAe;QAHf,cAAS,GAAT,SAAS,CAAiB;QAC1B,QAAG,GAAH,GAAG,CAAK;QACR,gBAAW,GAAX,WAAW,CAAQ;QACnB,WAAM,GAAN,MAAM,CAAS;QAEvB,MAAM,sBAAsB,GAAG,IAAA,0BAAQ,EAAC,GAAG,CAAC,CAAC;QAC7C,IAAI,CAAC,cAAc,GAAG,IAAI,sBAAsB,CAC9C,IAAI,CAAC,WAAW,EAChB,IAAI,CAAC,SAAS,EACd,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,CACpC,CAAC;IACJ,CAAC;IAED,UAAU;QACR,OAAO,IAAI,CAAC,cAAyB,CAAC;IACxC,CAAC;IAED,qBAAqB,CAAC,KAAK;QACxB,IAAI,CAAC,cAAiC,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC;IACvE,CAAC;IAED,qBAAqB;QACnB,OAAQ,IAAI,CAAC,cAAiC,CAAC,qBAAqB,EAAE,CAAC;IACzE,CAAC;IAED,QAAQ,CAAC,KAA0B;QAChC,IAAI,CAAC,cAAiC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC1D,CAAC;IAED,WAAW,CACT,gBAIS;QAET,MAAM,OAAO,GAAK,IAAI,CAAC,GAAyC;aAC7D,qBAAqB,CAAC;QAEzB,IAAI,CAAC,OAAO,EAAE;YACZ,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC;YAC5D,OAAO;SACR;QAED,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;QACjE,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC;QACrC,OAAO,CAAC,IAAI,CAAC;YACX,OAAO,EAAE,IAAI,CAAC,cAAc;YAC5B,QAAQ,EAAE,UAAU,GAAG,EAAE,IAAI;gBAC3B,IAAI,CAAC,GAAG,EAAE;oBACR,IAAI,IAAI,EAAE;wBACR,IAAI;4BACF,MAAM,aAAa,GACjB,MAAM,IAAI,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC;4BAClE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,EAAE,aAAa,CAAC,CAAC;4BACnD,MAAM,QAAQ,GACZ,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;4BACrD,gBAAgB,CACd,QAAQ,CAAC,SAAS,EAClB,QAAQ,CAAC,OAAgC,EACzC,QAAQ,CAAC,KAA4B,CACtC,CAAC;yBACH;wBAAC,OAAO,CAAC,EAAE;4BACV,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,qEAAqE,EACrE,CAAC,CACF,CAAC;yBACH;qBACF;iBACF;qBAAM;oBACL,oBAAoB;oBACpB,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,oDAAoD,EACpD,GAAG,CACJ,CAAC;iBACH;YACH,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;SACb,CAAC,CAAC;IACL,CAAC;CACF;AAnFD,8CAmFC"}
1
+ {"version":3,"file":"eveHistoryService.js","sourceRoot":"","sources":["../../src/lib/eveHistoryService.ts"],"names":[],"mappings":";;;;;;AAAA,wEAAwC;AAwBxC,MAAa,iBAAiB;IAG1B,YACY,SAA0B,EAC1B,GAAQ,EACR,WAAmB,EACnB,MAAe;QAHf,cAAS,GAAT,SAAS,CAAiB;QAC1B,QAAG,GAAH,GAAG,CAAK;QACR,gBAAW,GAAX,WAAW,CAAQ;QACnB,WAAM,GAAN,MAAM,CAAS;QAEvB,MAAM,sBAAsB,GAAG,IAAA,0BAAQ,EAAC,GAAG,CAAC,CAAC;QAC7C,IAAI,CAAC,cAAc,GAAG,IAAI,sBAAsB,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,EAAE;YAC/E,OAAO,EAAE,IAAI;YACb,GAAG,EAAE,IAAI,CAAC,MAAM;SACnB,CAAC,CAAC;IACP,CAAC;IAED,UAAU;QACN,OAAO,IAAI,CAAC,cAAyB,CAAC;IAC1C,CAAC;IAED,qBAAqB,CAAC,KAAK;QACtB,IAAI,CAAC,cAAiC,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC;IACzE,CAAC;IAED,qBAAqB;QACjB,OAAQ,IAAI,CAAC,cAAiC,CAAC,qBAAqB,EAAE,CAAC;IAC3E,CAAC;IAED,QAAQ,CAAC,KAA0B;QAC9B,IAAI,CAAC,cAAiC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC5D,CAAC;IAED,WAAW,CACP,gBAAyG;QAEzG,MAAM,OAAO,GAAK,IAAI,CAAC,GAAyC,CAAC,qBAAqB,CAAC;QAEvF,IAAI,CAAC,OAAO,EAAE;YACV,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC;YAC5D,OAAO;SACV;QAED,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;QACjE,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC;QACrC,OAAO,CAAC,IAAI,CAAC;YACT,OAAO,EAAE,IAAI,CAAC,cAAc;YAC5B,QAAQ,EAAE,UAAU,GAAG,EAAE,IAAI;gBACzB,IAAI,CAAC,GAAG,EAAE;oBACN,IAAI,IAAI,EAAE;wBACN,IAAI;4BACA,MAAM,aAAa,GAAG,MAAM,IAAI,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC;4BACtF,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,EAAE,aAAa,CAAC,CAAC;4BACnD,MAAM,QAAQ,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;4BACpE,gBAAgB,CACZ,QAAQ,CAAC,SAAS,EAClB,QAAQ,CAAC,OAAgC,EACzC,QAAQ,CAAC,KAA4B,CACxC,CAAC;yBACL;wBAAC,OAAO,CAAC,EAAE;4BACR,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,qEAAqE,EAAE,CAAC,CAAC,CAAC;yBAC/F;qBACJ;iBACJ;qBAAM;oBACH,oBAAoB;oBACpB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,oDAAoD,EAAE,GAAG,CAAC,CAAC;iBAChF;YACL,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;SACf,CAAC,CAAC;IACP,CAAC;CACJ;AArED,8CAqEC"}
@@ -0,0 +1,266 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.TuyaSwitchAccessory = void 0;
7
+ const eveHistoryService_1 = require("./lib/eveHistoryService");
8
+ const tuyapi_1 = __importDefault(require("tuyapi"));
9
+ const EnergyCharacteristics_1 = __importDefault(require("./lib/EnergyCharacteristics"));
10
+ const homebridgeCallbacks_1 = require("./lib/homebridgeCallbacks");
11
+ const ONOFF_DP = '1';
12
+ const AMP_DP = '18';
13
+ const WATT_DP = '19';
14
+ const VOLT_DP = '20';
15
+ const kHour = 60 * 60 * 1000;
16
+ /**
17
+ * Platform Accessory
18
+ * An instance of this class is created for each accessory your platform registers
19
+ * Each accessory may expose multiple services of different service types.
20
+ */
21
+ class TuyaSwitchAccessory {
22
+ constructor(logger, config, api) {
23
+ this.logger = logger;
24
+ this.config = config;
25
+ this.api = api;
26
+ this.amperes = 0;
27
+ this.watts = 0;
28
+ this.volts = 0;
29
+ this.inUse = false;
30
+ this.totalConsumption = 0;
31
+ this.resetTotal = 0;
32
+ this.log = logger;
33
+ this.name = config.name;
34
+ this.displayName = this.name;
35
+ this.serial = config.serial;
36
+ this.id = config.id;
37
+ this.key = config.key;
38
+ this.model = config.model || 'TuyaSwitch';
39
+ this.updateInterval = config.updateInterval || 5000;
40
+ this.type = config.type || 'switch';
41
+ this.device = new tuyapi_1.default({
42
+ id: this.id,
43
+ key: this.key,
44
+ issueRefreshOnConnect: true,
45
+ });
46
+ // Set AccessoryInformation
47
+ this.informationService = new api.hap.Service.AccessoryInformation()
48
+ .setCharacteristic(api.hap.Characteristic.Name, this.name)
49
+ .setCharacteristic(api.hap.Characteristic.Manufacturer, 'Tuya')
50
+ .setCharacteristic(api.hap.Characteristic.Model, this.model)
51
+ .setCharacteristic(api.hap.Characteristic.SerialNumber, this.serial);
52
+ this.EnergyCharacteristics = EnergyCharacteristics_1.default.create(api.hap.Characteristic);
53
+ switch (this.type) {
54
+ case 'switch':
55
+ this.service = new api.hap.Service.Switch(this.name);
56
+ break;
57
+ case 'valve':
58
+ this.service = new api.hap.Service.Valve(this.name);
59
+ break;
60
+ }
61
+ this.setupAccessoryServices();
62
+ this.service
63
+ .getCharacteristic(api.hap.Characteristic.On)
64
+ .on("get" /* CharacteristicEventTypes.GET */, (0, homebridgeCallbacks_1.callbackify)(this.getPowerOnOff.bind(this)))
65
+ .on("set" /* CharacteristicEventTypes.SET */, (0, homebridgeCallbacks_1.callbackify)(this.setPowerOnOff.bind(this)));
66
+ this.historyService = new eveHistoryService_1.EveHistoryService(this, this.api, 'energy',
67
+ // this.historyFilename,
68
+ this.logger);
69
+ //device events
70
+ this.setupTimeout = setInterval(async () => {
71
+ this.setupDevice();
72
+ }, 1000);
73
+ }
74
+ energyMonitoringEnabled() {
75
+ return this.type === 'switch';
76
+ }
77
+ setupAccessoryServices() {
78
+ if (!this.energyMonitoringEnabled()) {
79
+ return;
80
+ }
81
+ this.service.addOptionalCharacteristic(this.EnergyCharacteristics.Volts);
82
+ this.service.addOptionalCharacteristic(this.EnergyCharacteristics.Amperes);
83
+ this.service.addOptionalCharacteristic(this.EnergyCharacteristics.Watts);
84
+ this.service.addOptionalCharacteristic(this.EnergyCharacteristics.TotalConsumption);
85
+ this.service.addOptionalCharacteristic(this.EnergyCharacteristics.ResetTotal);
86
+ this.service
87
+ .getCharacteristic(this.EnergyCharacteristics.Volts)
88
+ .on('get', this.getVoltage.bind(this))
89
+ .updateValue(this.volts);
90
+ this.service
91
+ .getCharacteristic(this.EnergyCharacteristics.Amperes)
92
+ .on('get', this.getCurrent.bind(this))
93
+ .updateValue(this.amperes);
94
+ this.service
95
+ .getCharacteristic(this.EnergyCharacteristics.Watts)
96
+ .on('get', this.getConsumption.bind(this))
97
+ .updateValue(this.watts);
98
+ this.service
99
+ .getCharacteristic(this.EnergyCharacteristics.TotalConsumption)
100
+ .on('get', this.getTotalConsumption.bind(this));
101
+ // create handlers for required characteristics
102
+ this.readTotalConsumption();
103
+ }
104
+ async setupDevice() {
105
+ if (!this.setupTimeout) {
106
+ this.log('Connected to device!');
107
+ return;
108
+ }
109
+ this.device.on('connected', () => {
110
+ this.log('Connected to device!');
111
+ const lastTime = new Date().getTime();
112
+ setInterval(async () => {
113
+ try {
114
+ const state = await this.device.get({ schema: true });
115
+ this.log(`Device state: ${JSON.stringify(state)}`);
116
+ this.updateState(state.dps);
117
+ }
118
+ catch (ex) {
119
+ this.log(`Device state error: ${ex}`);
120
+ if (!this.device.isConnected()) {
121
+ this.log('Device disconnected... trying to reconnect');
122
+ await this.device.connect();
123
+ return;
124
+ }
125
+ }
126
+ if (this.energyMonitoringEnabled()) {
127
+ this.updateEnergyConsumption(lastTime);
128
+ }
129
+ }, this.updateInterval);
130
+ });
131
+ this.device.on('disconnected', () => {
132
+ this.log('Disconnected from device!');
133
+ });
134
+ this.device.on('error', (error) => {
135
+ this.log(`Error ${error}!`);
136
+ });
137
+ this.device.on('data', (data) => {
138
+ this.log(`DATA ${JSON.stringify(data)}!`);
139
+ this.updateState(data.dps);
140
+ });
141
+ this.device.on('dp-refresh', (data) => {
142
+ this.log(`REFRESH ${JSON.stringify(data)}!`);
143
+ this.updateState(data.dps);
144
+ });
145
+ try {
146
+ //device find&connect
147
+ await this.device.find();
148
+ await this.device.connect();
149
+ clearInterval(this.setupTimeout);
150
+ this.setupTimeout = null;
151
+ }
152
+ catch (ex) {
153
+ this.log(`Device connect error: ${ex}`);
154
+ if (!this.device.isConnected()) {
155
+ this.log('Device disconnected... trying to reconnect');
156
+ return;
157
+ }
158
+ }
159
+ }
160
+ updateEnergyConsumption(lastTime) {
161
+ const now = new Date().getTime();
162
+ const delta = (now - lastTime) / 1000;
163
+ const consumption = this.watts * delta; // W/s
164
+ this.totalConsumption += consumption / kHour;
165
+ this.historyService.addEntry({ time: now / 1000, power: this.watts });
166
+ const extra = this.historyService.getExtraPersistedData();
167
+ if (!extra) {
168
+ this.historyService.setExtraPersistedData({
169
+ totalConsumption: this.totalConsumption,
170
+ resetTotal: this.resetTotal,
171
+ });
172
+ }
173
+ else if (extra.totalConsumption !== this.totalConsumption || extra.resetTotal !== this.resetTotal) {
174
+ extra.totalConsumption = this.totalConsumption;
175
+ extra.resetTotal = this.resetTotal;
176
+ this.historyService.setExtraPersistedData(extra);
177
+ }
178
+ }
179
+ getTotalConsumption(callback) {
180
+ callback(null, this.totalConsumption);
181
+ }
182
+ getResetTotal(callback) {
183
+ callback(null, this.resetTotal);
184
+ }
185
+ setResetTotal(value, callback) {
186
+ this.log.info(`setResetTotal: ${value}`);
187
+ this.resetTotal = value;
188
+ this.totalConsumption = 0;
189
+ callback(null, this.resetTotal);
190
+ }
191
+ getVoltage(callback) {
192
+ // this.updateState(this.device.state);
193
+ callback(null, this.volts);
194
+ }
195
+ getCurrent(callback) {
196
+ // this.updateState(this.device.state);
197
+ callback(null, this.amperes);
198
+ }
199
+ getConsumption(callback) {
200
+ // this.updateState(this.device.state);
201
+ callback(null, this.watts);
202
+ }
203
+ updateState(dps) {
204
+ this.amperes = dps[AMP_DP] ? dps[AMP_DP] / 1000 : 0;
205
+ this.watts = dps[WATT_DP] ? dps[WATT_DP] / 10 : 0;
206
+ this.volts = dps[VOLT_DP] ? dps[VOLT_DP] / 10 : 0;
207
+ this.inUse = dps[ONOFF_DP] ? dps[ONOFF_DP] : false;
208
+ this.log.info(`updated a:${this.amperes} w:${this.watts} v:${this.volts} on: ${this.inUse}`);
209
+ }
210
+ async setPowerOnOff(value) {
211
+ this.log.info(`SET ON: ${value}`);
212
+ await this.device.set({ set: value, dps: '1' });
213
+ }
214
+ async getPowerOnOff() {
215
+ const status = await this.device.get();
216
+ this.log.info(`GET ON: ${status.dps[1]}`);
217
+ return status.dps[1];
218
+ }
219
+ readTotalConsumption() {
220
+ this.historyService.readHistory((lastEntry, history, extra) => {
221
+ const lastItem = history.pop();
222
+ if (lastItem) {
223
+ this.log.info('History: last item: %s', lastItem);
224
+ }
225
+ else {
226
+ this.log.info('History: no data');
227
+ }
228
+ this.log.info('History: extra: %s', extra);
229
+ const totalConsumption = extra.totalConsumption ? extra.totalConsumption : 0.0;
230
+ // Math.floor(Date.now() / 1000) - 978307200 // seconds since 01.01.2001
231
+ const resetTotal = extra.resetTotal ? extra.resetTotal : 0;
232
+ this.log.info(`totalConsumption: ${totalConsumption} resetTotal: ${resetTotal}`);
233
+ this.totalConsumption = totalConsumption;
234
+ this.resetTotal = resetTotal;
235
+ });
236
+ // try {
237
+ // const filepath = this.api ? this.api.user.storagePath() : './config';
238
+ // const filename = path.join(filepath, this.historyFilename);
239
+ // this.log.info(`Reading history: ${filename}`);
240
+ // const data = fs.readFileSync(filename, 'utf8');
241
+ // const jsonData = typeof data === 'object' ? data : JSON.parse(data);
242
+ // const totalConsumption =
243
+ // jsonData.extra && jsonData.extra.totalConsumption
244
+ // ? jsonData.extra.totalConsumption
245
+ // : 0.0;
246
+ // const resetTotal =
247
+ // jsonData.extra && jsonData.extra.resetTotal
248
+ // ? jsonData.extra.resetTotal
249
+ // : 0; // Math.floor(Date.now() / 1000) - 978307200 // seconds since 01.01.2001
250
+ // this.log.info(
251
+ // `totalConsumption: ${totalConsumption} resetTotal: ${resetTotal}`,
252
+ // );
253
+ // this.totalConsumption = totalConsumption;
254
+ // this.resetTotal = resetTotal;
255
+ // } catch (err) {
256
+ // this.log.error(`readTotalConsumption error: ${err}`);
257
+ // this.totalConsumption = 0;
258
+ // this.resetTotal = 0;
259
+ // }
260
+ }
261
+ getServices() {
262
+ return [this.informationService, this.service, this.historyService.getService()];
263
+ }
264
+ }
265
+ exports.TuyaSwitchAccessory = TuyaSwitchAccessory;
266
+ //# sourceMappingURL=tuyaSwitchAccessory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tuyaSwitchAccessory.js","sourceRoot":"","sources":["../src/tuyaSwitchAccessory.ts"],"names":[],"mappings":"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"}
@@ -13,7 +13,8 @@
13
13
  "model": "Model=",
14
14
  "id": "00000000000000000000",
15
15
  "key": "0000000000000000",
16
- "updateInterval": 10000
16
+ "updateInterval": 10000,
17
+ "type": "switch"
17
18
  }
18
19
  ]
19
20
  }
package/nodemon.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "watch": [
3
+ "src"
4
+ ],
5
+ "ext": "ts",
6
+ "ignore": [],
7
+ "exec": "tsc && homebridge -I -D",
8
+ "signal": "SIGTERM",
9
+ "env": {
10
+ "NODE_OPTIONS": "--trace-warnings"
11
+ }
12
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "displayName": "Homebridge Tuya Eve",
3
3
  "name": "@petro-kushchak/homebridge-tuya-eve",
4
- "version": "1.0.11",
4
+ "version": "1.0.12",
5
5
  "description": "Homebridge plugin for TuyAPI (with Eve app energy consumption monitoring)",
6
6
  "license": "MIT",
7
7
  "repository": {
@@ -21,17 +21,17 @@
21
21
  },
22
22
  "keywords": [
23
23
  "homebridge-plugin",
24
- "air conditioning",
25
- "cooper&hunter ac",
26
- "homebridge heatercooler",
24
+ "tuya",
25
+ "tuyapi",
26
+ "valve",
27
27
  "eve",
28
28
  "fakegato"
29
29
  ],
30
30
  "devDependencies": {
31
31
  "@types/node": "^14.14.31",
32
- "@typescript-eslint/eslint-plugin": "^4.16.1",
33
- "@typescript-eslint/parser": "^4.16.1",
34
- "eslint": "^7.21.0",
32
+ "@typescript-eslint/eslint-plugin": "^5.0",
33
+ "@typescript-eslint/parser": "^5.0",
34
+ "eslint": "^8.15.0",
35
35
  "homebridge": "^1.3.1",
36
36
  "nodemon": "^2.0.7",
37
37
  "rimraf": "^3.0.2",
package/src/index.ts ADDED
@@ -0,0 +1,9 @@
1
+ import { API } from 'homebridge';
2
+ import { TuyaSwitchAccessory } from './tuyaSwitchAccessory';
3
+
4
+ /*
5
+ * Initializer function called when the plugin is loaded.
6
+ */
7
+ export = (api: API) => {
8
+ api.registerAccessory('homebridge-tuya-eve', 'TuyaSwitchEve', TuyaSwitchAccessory);
9
+ };
@@ -0,0 +1,103 @@
1
+ // Thanks to homebridge-tplink-smarthome
2
+
3
+ class EnergyCharacteristicFactory {
4
+ create(Characteristic) {
5
+ class EnergyCharacteristic extends Characteristic {
6
+ constructor(displayName, UUID, props) {
7
+ super(displayName, UUID);
8
+ this.setProps(Object.assign({
9
+ format: Characteristic.Formats.FLOAT,
10
+ minValue: 0,
11
+ maxValue: 65535,
12
+ perms: [Characteristic.Perms.READ, Characteristic.Perms.NOTIFY],
13
+ }, props));
14
+ this.value = this.getDefaultValue();
15
+ }
16
+ }
17
+
18
+ class Amperes extends EnergyCharacteristic {
19
+ constructor() {
20
+ super('Amperes', Amperes.UUID, {
21
+ unit: 'A',
22
+ minStep: 0.001,
23
+ });
24
+ }
25
+ }
26
+
27
+ Amperes.UUID = 'E863F126-079E-48FF-8F27-9C2605A29F52';
28
+
29
+ class TotalConsumption extends EnergyCharacteristic {
30
+ constructor() {
31
+ super('Total Consumption', TotalConsumption.UUID, {
32
+ unit: 'kWh',
33
+ minStep: 0.001,
34
+ });
35
+ }
36
+ }
37
+
38
+ TotalConsumption.UUID = 'E863F10C-079E-48FF-8F27-9C2605A29F52';
39
+
40
+ class KilowattVoltAmpereHour extends EnergyCharacteristic {
41
+ constructor() {
42
+ super('Apparent Energy', KilowattVoltAmpereHour.UUID, {
43
+ format: Characteristic.Formats.UINT32,
44
+ unit: 'kVAh',
45
+ minStep: 1,
46
+ });
47
+ }
48
+ }
49
+
50
+ KilowattVoltAmpereHour.UUID = 'E863F127-079E-48FF-8F27-9C2605A29F52';
51
+
52
+ class VoltAmperes extends EnergyCharacteristic {
53
+ constructor() {
54
+ super('Apparent Power', VoltAmperes.UUID, {
55
+ format: Characteristic.Formats.UINT16,
56
+ unit: 'VA',
57
+ minStep: 1,
58
+ });
59
+ }
60
+ }
61
+
62
+ VoltAmperes.UUID = 'E863F110-079E-48FF-8F27-9C2605A29F52';
63
+
64
+ class Volts extends EnergyCharacteristic {
65
+ constructor() {
66
+ super('Volts', Volts.UUID, {
67
+ unit: 'V',
68
+ minStep: 0.1,
69
+ });
70
+ }
71
+ }
72
+
73
+ Volts.UUID = 'E863F10A-079E-48FF-8F27-9C2605A29F52';
74
+
75
+ class Watts extends EnergyCharacteristic {
76
+ constructor() {
77
+ super('Consumption', Watts.UUID, {
78
+ unit: 'W',
79
+ minStep: 0.1,
80
+ });
81
+ }
82
+ }
83
+
84
+ Watts.UUID = 'E863F10D-079E-48FF-8F27-9C2605A29F52';
85
+
86
+
87
+ class ResetTotal extends EnergyCharacteristic {
88
+ constructor() {
89
+ super('Reset Total', ResetTotal.UUID, {
90
+ format: Characteristic.Formats.UINT32,
91
+ unit: Characteristic.Units.seconds,
92
+ perms: [Characteristic.Perms.READ, Characteristic.Perms.NOTIFY, Characteristic.Perms.WRITE],
93
+ });
94
+ }
95
+ }
96
+
97
+ ResetTotal.UUID = 'E863F112-079E-48FF-8F27-9C2605A29F52';
98
+
99
+ return { Amperes, KilowattVoltAmpereHour, VoltAmperes, Volts, Watts, TotalConsumption, ResetTotal };
100
+ }
101
+ }
102
+
103
+ export default new EnergyCharacteristicFactory();
@@ -0,0 +1,94 @@
1
+ import fakegato from 'fakegato-history';
2
+ import { AccessoryPlugin, API, Logging, Service } from 'homebridge';
3
+
4
+ export interface HistoryServiceEntry extends Record<string, number> {
5
+ time: number;
6
+ }
7
+
8
+ export interface HistoryService {
9
+ getExtraPersistedData(): any;
10
+ setExtraPersistedData(extra: any): unknown;
11
+ addEntry(entry: HistoryServiceEntry): void;
12
+ }
13
+
14
+ export interface HistoryServiceStorageReaderOptions {
15
+ service: unknown;
16
+ callback: (err: unknown, data: string) => void;
17
+ }
18
+
19
+ export interface HistoryServiceStorage {
20
+ globalFakeGatoStorage: {
21
+ read: (options: HistoryServiceStorageReaderOptions) => void;
22
+ };
23
+ }
24
+
25
+ export class EveHistoryService {
26
+ private readonly historyService: unknown;
27
+
28
+ constructor(
29
+ private accessory: AccessoryPlugin,
30
+ private api: API,
31
+ private serviceType: string,
32
+ private logger: Logging,
33
+ ) {
34
+ const FakeGatoHistoryService = fakegato(api);
35
+ this.historyService = new FakeGatoHistoryService(this.serviceType, this.accessory, {
36
+ storage: 'fs',
37
+ log: this.logger,
38
+ });
39
+ }
40
+
41
+ getService(): Service {
42
+ return this.historyService as Service;
43
+ }
44
+
45
+ setExtraPersistedData(extra) {
46
+ (this.historyService as HistoryService).setExtraPersistedData(extra);
47
+ }
48
+
49
+ getExtraPersistedData() {
50
+ return (this.historyService as HistoryService).getExtraPersistedData();
51
+ }
52
+
53
+ addEntry(entry: HistoryServiceEntry) {
54
+ (this.historyService as HistoryService).addEntry(entry);
55
+ }
56
+
57
+ readHistory(
58
+ lastEntryHandler: (lastEntry: string, history: HistoryServiceEntry[], extra: HistoryServiceEntry) => void,
59
+ ) {
60
+ const storage = ((this.api as unknown) as HistoryServiceStorage).globalFakeGatoStorage;
61
+
62
+ if (!storage) {
63
+ this.logger.debug('Failed to access globalFakeGatoStorage');
64
+ return;
65
+ }
66
+
67
+ this.logger.debug('Reading data from globalFakeGatoStorage ...');
68
+ const thisAccessory = this.accessory;
69
+ storage.read({
70
+ service: this.historyService,
71
+ callback: function (err, data) {
72
+ if (!err) {
73
+ if (data) {
74
+ try {
75
+ const accessoryName = 'name' in thisAccessory ? thisAccessory['name'] : thisAccessory;
76
+ this.logger.debug('read data from', accessoryName);
77
+ const jsonFile = typeof data === 'object' ? data : JSON.parse(data);
78
+ lastEntryHandler(
79
+ jsonFile.lastEntry,
80
+ jsonFile.history as HistoryServiceEntry[],
81
+ jsonFile.extra as HistoryServiceEntry,
82
+ );
83
+ } catch (e) {
84
+ this.logger.debug('**ERROR fetching persisting data restart from zero - invalid JSON**', e);
85
+ }
86
+ }
87
+ } else {
88
+ // file don't exists
89
+ this.logger.debug('**ERROR fetching persisting data: file dont exists', err);
90
+ }
91
+ }.bind(this),
92
+ });
93
+ }
94
+ }
@@ -0,0 +1,21 @@
1
+ /* eslint-disable @typescript-eslint/ban-types */
2
+ export function callbackify(task: (...taskArgs: any[]) => Promise<any>): any {
3
+ return (...args: any[]) => {
4
+ const onlyArgs: any[] = [];
5
+ let callback: Function = undefined;
6
+
7
+ for (const arg of args) {
8
+ if (typeof arg === 'function') {
9
+ callback = arg;
10
+ break;
11
+ }
12
+ onlyArgs.push(arg);
13
+ }
14
+ if (!callback) {
15
+ throw new Error('Missing callback parameter!');
16
+ }
17
+ task(...onlyArgs)
18
+ .then((data: any) => callback(undefined, data))
19
+ .catch((err: any) => callback(err));
20
+ };
21
+ }
@@ -0,0 +1,336 @@
1
+ import {
2
+ Service,
3
+ Logging,
4
+ AccessoryConfig,
5
+ API,
6
+ AccessoryPlugin,
7
+ CharacteristicValue,
8
+ CharacteristicEventTypes,
9
+ } from 'homebridge';
10
+ import { EveHistoryService, HistoryServiceEntry } from './lib/eveHistoryService';
11
+
12
+ import TuyaDevice from 'tuyapi';
13
+ import EnergyCharacteristicFactory from './lib/EnergyCharacteristics';
14
+ import { callbackify } from './lib/homebridgeCallbacks';
15
+
16
+ const ONOFF_DP = '1';
17
+ const AMP_DP = '18';
18
+ const WATT_DP = '19';
19
+ const VOLT_DP = '20';
20
+ const kHour = 60 * 60 * 1000;
21
+
22
+ /**
23
+ * Platform Accessory
24
+ * An instance of this class is created for each accessory your platform registers
25
+ * Each accessory may expose multiple services of different service types.
26
+ */
27
+ export class TuyaSwitchAccessory implements AccessoryPlugin {
28
+ private readonly name: string;
29
+ private readonly serial: string;
30
+ private readonly model: string;
31
+ private readonly id: string;
32
+ private readonly key: string;
33
+ private readonly updateInterval: number;
34
+ private readonly log: Logging;
35
+ private readonly displayName: string;
36
+
37
+ private readonly service: Service;
38
+ private readonly informationService: Service;
39
+ private readonly historyService: EveHistoryService;
40
+
41
+ private readonly device: TuyaDevice;
42
+
43
+ private readonly EnergyCharacteristics;
44
+
45
+ private amperes = 0;
46
+ private watts = 0;
47
+ private volts = 0;
48
+ private inUse = false;
49
+
50
+ private totalConsumption = 0;
51
+ private resetTotal = 0;
52
+
53
+ private setupTimeout: NodeJS.Timeout;
54
+ private readonly type: string;
55
+
56
+ constructor(private logger: Logging, private config: AccessoryConfig, private api: API) {
57
+ this.log = logger;
58
+
59
+ this.name = config.name;
60
+ this.displayName = this.name;
61
+ this.serial = config.serial;
62
+ this.id = config.id;
63
+ this.key = config.key;
64
+ this.model = config.model || 'TuyaSwitch';
65
+ this.updateInterval = config.updateInterval || 5000;
66
+ this.type = config.type || 'switch';
67
+
68
+ this.device = new TuyaDevice({
69
+ id: this.id,
70
+ key: this.key,
71
+ issueRefreshOnConnect: true,
72
+ });
73
+
74
+ // Set AccessoryInformation
75
+ this.informationService = new api.hap.Service.AccessoryInformation()
76
+ .setCharacteristic(api.hap.Characteristic.Name, this.name)
77
+ .setCharacteristic(api.hap.Characteristic.Manufacturer, 'Tuya')
78
+ .setCharacteristic(api.hap.Characteristic.Model, this.model)
79
+ .setCharacteristic(api.hap.Characteristic.SerialNumber, this.serial);
80
+
81
+ this.EnergyCharacteristics = EnergyCharacteristicFactory.create(api.hap.Characteristic);
82
+
83
+ switch (this.type) {
84
+ case 'switch':
85
+ this.service = new api.hap.Service.Switch(this.name);
86
+ break;
87
+ case 'valve':
88
+ this.service = new api.hap.Service.Valve(this.name);
89
+ break;
90
+ }
91
+
92
+ this.setupAccessoryServices();
93
+
94
+ this.service
95
+ .getCharacteristic(api.hap.Characteristic.On)
96
+ .on(CharacteristicEventTypes.GET, callbackify(this.getPowerOnOff.bind(this)))
97
+ .on(CharacteristicEventTypes.SET, callbackify(this.setPowerOnOff.bind(this)));
98
+
99
+ this.historyService = new EveHistoryService(
100
+ this,
101
+ this.api,
102
+ 'energy',
103
+ // this.historyFilename,
104
+ this.logger,
105
+ );
106
+
107
+ //device events
108
+ this.setupTimeout = setInterval(async () => {
109
+ this.setupDevice();
110
+ }, 1000);
111
+ }
112
+
113
+ private energyMonitoringEnabled(): boolean {
114
+ return this.type === 'switch';
115
+ }
116
+
117
+ setupAccessoryServices() {
118
+ if (!this.energyMonitoringEnabled()) {
119
+ return;
120
+ }
121
+
122
+ this.service.addOptionalCharacteristic(this.EnergyCharacteristics.Volts);
123
+ this.service.addOptionalCharacteristic(this.EnergyCharacteristics.Amperes);
124
+ this.service.addOptionalCharacteristic(this.EnergyCharacteristics.Watts);
125
+ this.service.addOptionalCharacteristic(this.EnergyCharacteristics.TotalConsumption);
126
+ this.service.addOptionalCharacteristic(this.EnergyCharacteristics.ResetTotal);
127
+
128
+ this.service
129
+ .getCharacteristic(this.EnergyCharacteristics.Volts)
130
+ .on('get', this.getVoltage.bind(this))
131
+ .updateValue(this.volts);
132
+ this.service
133
+ .getCharacteristic(this.EnergyCharacteristics.Amperes)
134
+ .on('get', this.getCurrent.bind(this))
135
+ .updateValue(this.amperes);
136
+ this.service
137
+ .getCharacteristic(this.EnergyCharacteristics.Watts)
138
+ .on('get', this.getConsumption.bind(this))
139
+ .updateValue(this.watts);
140
+
141
+ this.service
142
+ .getCharacteristic(this.EnergyCharacteristics.TotalConsumption)
143
+ .on('get', this.getTotalConsumption.bind(this));
144
+
145
+ // create handlers for required characteristics
146
+
147
+ this.readTotalConsumption();
148
+ }
149
+
150
+ async setupDevice() {
151
+ if (!this.setupTimeout) {
152
+ this.log('Connected to device!');
153
+ return;
154
+ }
155
+
156
+ this.device.on('connected', () => {
157
+ this.log('Connected to device!');
158
+
159
+ const lastTime = new Date().getTime();
160
+ setInterval(async () => {
161
+ try {
162
+ const state = await this.device.get({ schema: true });
163
+ this.log(`Device state: ${JSON.stringify(state)}`);
164
+ this.updateState(state.dps);
165
+ } catch (ex) {
166
+ this.log(`Device state error: ${ex}`);
167
+ if (!this.device.isConnected()) {
168
+ this.log('Device disconnected... trying to reconnect');
169
+ await this.device.connect();
170
+ return;
171
+ }
172
+ }
173
+
174
+ if (this.energyMonitoringEnabled()) {
175
+ this.updateEnergyConsumption(lastTime);
176
+ }
177
+ }, this.updateInterval);
178
+ });
179
+
180
+ this.device.on('disconnected', () => {
181
+ this.log('Disconnected from device!');
182
+ });
183
+
184
+ this.device.on('error', (error) => {
185
+ this.log(`Error ${error}!`);
186
+ });
187
+
188
+ this.device.on('data', (data) => {
189
+ this.log(`DATA ${JSON.stringify(data)}!`);
190
+ this.updateState(data.dps);
191
+ });
192
+
193
+ this.device.on('dp-refresh', (data) => {
194
+ this.log(`REFRESH ${JSON.stringify(data)}!`);
195
+ this.updateState(data.dps);
196
+ });
197
+
198
+ try {
199
+ //device find&connect
200
+ await this.device.find();
201
+ await this.device.connect();
202
+ clearInterval(this.setupTimeout);
203
+ this.setupTimeout = null;
204
+ } catch (ex) {
205
+ this.log(`Device connect error: ${ex}`);
206
+ if (!this.device.isConnected()) {
207
+ this.log('Device disconnected... trying to reconnect');
208
+ return;
209
+ }
210
+ }
211
+ }
212
+
213
+ private updateEnergyConsumption(lastTime: number) {
214
+ const now = new Date().getTime();
215
+ const delta = (now - lastTime) / 1000;
216
+
217
+ const consumption = this.watts * delta; // W/s
218
+ this.totalConsumption += consumption / kHour;
219
+
220
+ this.historyService.addEntry({ time: now / 1000, power: this.watts });
221
+
222
+ const extra = this.historyService.getExtraPersistedData();
223
+ if (!extra) {
224
+ this.historyService.setExtraPersistedData({
225
+ totalConsumption: this.totalConsumption,
226
+ resetTotal: this.resetTotal,
227
+ });
228
+ } else if (extra.totalConsumption !== this.totalConsumption || extra.resetTotal !== this.resetTotal) {
229
+ extra.totalConsumption = this.totalConsumption;
230
+ extra.resetTotal = this.resetTotal;
231
+ this.historyService.setExtraPersistedData(extra);
232
+ }
233
+ }
234
+
235
+ getTotalConsumption(callback) {
236
+ callback(null, this.totalConsumption);
237
+ }
238
+
239
+ getResetTotal(callback) {
240
+ callback(null, this.resetTotal);
241
+ }
242
+
243
+ setResetTotal(value, callback) {
244
+ this.log.info(`setResetTotal: ${value}`);
245
+ this.resetTotal = value;
246
+ this.totalConsumption = 0;
247
+ callback(null, this.resetTotal);
248
+ }
249
+
250
+ getVoltage(callback) {
251
+ // this.updateState(this.device.state);
252
+ callback(null, this.volts);
253
+ }
254
+
255
+ getCurrent(callback) {
256
+ // this.updateState(this.device.state);
257
+ callback(null, this.amperes);
258
+ }
259
+
260
+ getConsumption(callback) {
261
+ // this.updateState(this.device.state);
262
+ callback(null, this.watts);
263
+ }
264
+
265
+ updateState(dps) {
266
+ this.amperes = dps[AMP_DP] ? dps[AMP_DP] / 1000 : 0;
267
+ this.watts = dps[WATT_DP] ? dps[WATT_DP] / 10 : 0;
268
+ this.volts = dps[VOLT_DP] ? dps[VOLT_DP] / 10 : 0;
269
+ this.inUse = dps[ONOFF_DP] ? dps[ONOFF_DP] : false;
270
+
271
+ this.log.info(`updated a:${this.amperes} w:${this.watts} v:${this.volts} on: ${this.inUse}`);
272
+ }
273
+
274
+ async setPowerOnOff(value: CharacteristicValue): Promise<void> {
275
+ this.log.info(`SET ON: ${value}`);
276
+ await this.device.set({ set: value, dps: '1' });
277
+ }
278
+
279
+ async getPowerOnOff(): Promise<CharacteristicValue> {
280
+ const status = await this.device.get();
281
+ this.log.info(`GET ON: ${status.dps[1]}`);
282
+ return status.dps[1];
283
+ }
284
+
285
+ readTotalConsumption() {
286
+ this.historyService.readHistory(
287
+ (lastEntry: string, history: HistoryServiceEntry[], extra: HistoryServiceEntry) => {
288
+ const lastItem = history.pop();
289
+ if (lastItem) {
290
+ this.log.info('History: last item: %s', lastItem);
291
+ } else {
292
+ this.log.info('History: no data');
293
+ }
294
+ this.log.info('History: extra: %s', extra);
295
+
296
+ const totalConsumption = extra.totalConsumption ? extra.totalConsumption : 0.0;
297
+ // Math.floor(Date.now() / 1000) - 978307200 // seconds since 01.01.2001
298
+ const resetTotal = extra.resetTotal ? extra.resetTotal : 0;
299
+
300
+ this.log.info(`totalConsumption: ${totalConsumption} resetTotal: ${resetTotal}`);
301
+ this.totalConsumption = totalConsumption;
302
+ this.resetTotal = resetTotal;
303
+ },
304
+ );
305
+
306
+ // try {
307
+ // const filepath = this.api ? this.api.user.storagePath() : './config';
308
+ // const filename = path.join(filepath, this.historyFilename);
309
+ // this.log.info(`Reading history: ${filename}`);
310
+ // const data = fs.readFileSync(filename, 'utf8');
311
+ // const jsonData = typeof data === 'object' ? data : JSON.parse(data);
312
+ // const totalConsumption =
313
+ // jsonData.extra && jsonData.extra.totalConsumption
314
+ // ? jsonData.extra.totalConsumption
315
+ // : 0.0;
316
+ // const resetTotal =
317
+ // jsonData.extra && jsonData.extra.resetTotal
318
+ // ? jsonData.extra.resetTotal
319
+ // : 0; // Math.floor(Date.now() / 1000) - 978307200 // seconds since 01.01.2001
320
+
321
+ // this.log.info(
322
+ // `totalConsumption: ${totalConsumption} resetTotal: ${resetTotal}`,
323
+ // );
324
+ // this.totalConsumption = totalConsumption;
325
+ // this.resetTotal = resetTotal;
326
+ // } catch (err) {
327
+ // this.log.error(`readTotalConsumption error: ${err}`);
328
+ // this.totalConsumption = 0;
329
+ // this.resetTotal = 0;
330
+ // }
331
+ }
332
+
333
+ getServices(): Service[] {
334
+ return [this.informationService, this.service, this.historyService.getService()];
335
+ }
336
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "compilerOptions": {
3
+ "allowJs": true,
4
+ "target": "ES2018",
5
+ "module": "commonjs",
6
+ "lib": [
7
+ "ES2015",
8
+ "ES2016",
9
+ "ES2017",
10
+ "ES2018"
11
+ ],
12
+ "sourceMap": true,
13
+ "rootDir": "src",
14
+ "outDir": "dist",
15
+ "strict": false,
16
+ "esModuleInterop": true,
17
+ "forceConsistentCasingInFileNames": true,
18
+ "resolveJsonModule": true
19
+ },
20
+ "include": [
21
+ "src"
22
+ ]
23
+ }