homebridge-tasmota-control 1.4.0 → 1.4.1-beta.2

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/index.js CHANGED
@@ -1,10 +1,11 @@
1
1
  import { join } from 'path';
2
2
  import { mkdirSync, existsSync, writeFileSync } from 'fs';
3
- import deviceinfo from './src/deviceinfo.js';
4
- import mielhvac from './src/mielhvac.js';
5
- import switches from './src/switches.js';
6
- import lights from './src/lights.js';
7
- import fans from './src/fans.js';
3
+ import DeviceInfo from './src/deviceinfo.js';
4
+ import MiElHvac from './src/mielhvac.js';
5
+ import Switches from './src/switches.js';
6
+ import Lights from './src/lights.js';
7
+ import Fans from './src/fans.js';
8
+ import Sensors from './src/sensors.js';
8
9
  import ImpulseGenerator from './src/impulsegenerator.js';
9
10
  import { PluginName, PlatformName } from './src/constants.js';
10
11
 
@@ -65,7 +66,7 @@ class tasmotaPlatform {
65
66
 
66
67
  try {
67
68
  //get device info
68
- const deviceInfo = new deviceinfo(url, auth, user, passwd, deviceName, loadNameFromDevice, enableDebugMode, refreshInterval);
69
+ const deviceInfo = new DeviceInfo(url, auth, user, passwd, deviceName, loadNameFromDevice, enableDebugMode, refreshInterval);
69
70
  deviceInfo.on('debug', (debug) => {
70
71
  const emitLog = !enableDebugMode ? false : log.info(`Device: ${host} ${deviceName}, debug: ${debug}.`);
71
72
  })
@@ -82,87 +83,97 @@ class tasmotaPlatform {
82
83
  return;
83
84
  }
84
85
 
85
- let deviceType;
86
- switch (info.deviceType) {
87
- case 0://mielhvac
88
- //check files exists, if not then create it
89
- try {
90
- const postFix = device.host.split('.').join('');
91
- info.defaultHeatingSetTemperatureFile = `${prefDir}/defaultHeatingSetTemperature_${postFix}`;
92
- info.defaultCoolingSetTemperatureFile = `${prefDir}/defaultCoolingSetTemperature_${postFix}`;
93
- const files = [
94
- info.defaultHeatingSetTemperatureFile,
95
- info.defaultCoolingSetTemperatureFile
96
- ];
97
-
98
- files.forEach((file, index) => {
99
- if (!existsSync(file)) {
100
- const data = ['20', '23'][index]
101
- writeFileSync(file, data);
102
- }
103
- });
104
- } catch (error) {
105
- log.error(`Device: ${host} ${deviceName}, Prepare files error: ${error}`);
86
+ let i = 0;
87
+ for (const type of info.deviceTypes) {
88
+ const serialNumber = i === 0 ? info.serialNumber : info.serialNumber + type;
89
+ info.serialNumber = serialNumber;
90
+
91
+ let deviceType;
92
+ switch (type) {
93
+ case 0://mielhvac
94
+ //check files exists, if not then create it
95
+ try {
96
+ const postFix = device.host.split('.').join('');
97
+ info.defaultHeatingSetTemperatureFile = `${prefDir}/defaultHeatingSetTemperature_${postFix}`;
98
+ info.defaultCoolingSetTemperatureFile = `${prefDir}/defaultCoolingSetTemperature_${postFix}`;
99
+ const files = [
100
+ info.defaultHeatingSetTemperatureFile,
101
+ info.defaultCoolingSetTemperatureFile
102
+ ];
103
+
104
+ files.forEach((file, index) => {
105
+ if (!existsSync(file)) {
106
+ const data = ['20', '23'][index]
107
+ writeFileSync(file, data);
108
+ }
109
+ });
110
+ } catch (error) {
111
+ log.error(`Device: ${host} ${deviceName}, Prepare files error: ${error}`);
112
+ return;
113
+ }
114
+
115
+ deviceType = new MiElHvac(api, device, info, refreshInterval);
116
+ break;
117
+ case 1: //switches
118
+ deviceType = new Switches(api, device, info, refreshInterval);
119
+ break;
120
+ case 2: //lights
121
+ deviceType = new Lights(api, device, info, refreshInterval);
122
+ break;
123
+ case 3: //fans
124
+ deviceType = new Fans(api, device, info, refreshInterval);
125
+ break;
126
+ case 4: //sensors
127
+ deviceType = new Sensors(api, device, info, refreshInterval);
128
+ break;
129
+ default:
130
+ const emitLog = disableLogWarn ? false : log.warn(`Device: ${host} ${deviceName}, unknown device: ${info.deviceTypes}.`);
106
131
  return;
107
- }
108
-
109
- deviceType = new mielhvac(api, device, info, refreshInterval);
110
- break;
111
- case 1://switches
112
- deviceType = new switches(api, device, info, refreshInterval);
113
- break;
114
- case 2://lights
115
- deviceType = new lights(api, device, info, refreshInterval);
116
- break;
117
- case 3://fans
118
- deviceType = new fans(api, device, info, refreshInterval);
119
- break;
120
- default:
121
- const emitLog = disableLogWarn ? false : log.warn(`Device: ${host} ${deviceName}, unknown device: ${info.deviceType}.`);
122
- return;
123
- }
132
+ }
124
133
 
125
- deviceType.on('publishAccessory', (accessory) => {
126
- api.publishExternalAccessories(PluginName, [accessory]);
127
- const emitLog = disableLogSuccess ? false : log.success(`Device: ${host} ${deviceName}, Published as external accessory.`);
128
- })
129
- .on('devInfo', (devInfo) => {
130
- const emitLog = disableLogDeviceInfo ? false : log.info(devInfo);
131
- })
132
- .on('success', (success) => {
133
- const emitLog = disableLogSuccess ? false : log.success(`Device: ${host} ${deviceName}, ${success}.`);
134
- })
135
- .on('info', (info) => {
136
- const emitLog = disableLogInfo ? false : log.info(`Device: ${host} ${deviceName}, ${info}.`);
137
- })
138
- .on('debug', (debug) => {
139
- const emitLog = !enableDebugMode ? false : log.info(`Device: ${host} ${deviceName}, debug: ${debug}.`);
140
- })
141
- .on('warn', (warn) => {
142
- const emitLog = disableLogWarn ? false : log.warn(`Device: ${host} ${deviceName}, ${warn}.`);
134
+ deviceType.on('publishAccessory', (accessory) => {
135
+ api.publishExternalAccessories(PluginName, [accessory]);
136
+ const emitLog = disableLogSuccess ? false : log.success(`Device: ${host} ${deviceName}, Published as external accessory.`);
143
137
  })
144
- .on('error', (error) => {
145
- const emitLog = disableLogError ? false : log.error(`Device: ${host} ${deviceName}, ${error}.`);
146
- });
138
+ .on('devInfo', (devInfo) => {
139
+ const emitLog = disableLogDeviceInfo ? false : log.info(devInfo);
140
+ })
141
+ .on('success', (success) => {
142
+ const emitLog = disableLogSuccess ? false : log.success(`Device: ${host} ${deviceName}, ${success}.`);
143
+ })
144
+ .on('info', (info) => {
145
+ const emitLog = disableLogInfo ? false : log.info(`Device: ${host} ${deviceName}, ${info}.`);
146
+ })
147
+ .on('debug', (debug) => {
148
+ const emitLog = !enableDebugMode ? false : log.info(`Device: ${host} ${deviceName}, debug: ${debug}.`);
149
+ })
150
+ .on('warn', (warn) => {
151
+ const emitLog = disableLogWarn ? false : log.warn(`Device: ${host} ${deviceName}, ${warn}.`);
152
+ })
153
+ .on('error', (error) => {
154
+ const emitLog = disableLogError ? false : log.error(`Device: ${host} ${deviceName}, ${error}.`);
155
+ });
156
+
157
+ //create impulse generator
158
+ const impulseGenerator = new ImpulseGenerator();
159
+ impulseGenerator.on('start', async () => {
160
+ try {
161
+ const startDone = await deviceType.start();
162
+ const stopImpulseGenerator = startDone ? await impulseGenerator.stop() : false;
147
163
 
148
- //create impulse generator
149
- const impulseGenerator = new ImpulseGenerator();
150
- impulseGenerator.on('start', async () => {
151
- try {
152
- const startDone = await deviceType.start();
153
- const stopImpulseGenerator = startDone ? await impulseGenerator.stop() : false;
154
-
155
- //start impulse generator
156
- const startImpulseGenerator = stopImpulseGenerator ? await deviceType.startImpulseGenerator() : false
157
- } catch (error) {
158
- const emitLog = disableLogError ? false : log.error(`Device: ${host} ${deviceName}, ${error}, trying again.`);
159
- }
160
- }).on('state', (state) => {
161
- const emitLog = !enableDebugMode ? false : state ? log.info(`Device: ${host} ${deviceName}, Start impulse generator started.`) : log.info(`Device: ${host} ${deviceName}, Start impulse generator stopped.`);
162
- });
164
+ //start impulse generator
165
+ const startImpulseGenerator = stopImpulseGenerator ? await deviceType.startImpulseGenerator() : false
166
+ } catch (error) {
167
+ const emitLog = disableLogError ? false : log.error(`Device: ${host} ${deviceName}, ${error}, trying again.`);
168
+ }
169
+ }).on('state', (state) => {
170
+ const emitLog = !enableDebugMode ? false : state ? log.info(`Device: ${host} ${deviceName}, Start impulse generator started.`) : log.info(`Device: ${host} ${deviceName}, Start impulse generator stopped.`);
171
+ });
163
172
 
164
- //start impulse generator
165
- await impulseGenerator.start([{ name: 'start', sampling: 45000 }]);
173
+ //start impulse generator
174
+ await impulseGenerator.start([{ name: 'start', sampling: 45000 }]);
175
+ i++;
176
+ }
166
177
  } catch (error) {
167
178
  const emitLog = disableLogError ? false : log.error(`Device: ${host} ${deviceName}, Did finish launching error: ${error}.`);
168
179
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "displayName": "Tasmota Control",
3
3
  "name": "homebridge-tasmota-control",
4
- "version": "1.4.0",
4
+ "version": "1.4.1-beta.2",
5
5
  "description": "Homebridge plugin to control Tasmota flashed devices.",
6
6
  "license": "MIT",
7
7
  "author": "grzegorz914",
package/src/constants.js CHANGED
@@ -229,8 +229,7 @@ export const SensorKeys = [
229
229
  "TC74",
230
230
  "VEML7700",
231
231
  "PIR",
232
- "ENERGY",
233
- "MiElHVAC"
232
+ "ENERGY"
234
233
  ];
235
234
 
236
235
  export const SensorPropertiesKeys = [
package/src/deviceinfo.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import axios from 'axios';
2
2
  import EventEmitter from 'events';
3
- import { ApiCommands, LightKeys } from './constants.js';
3
+ import { ApiCommands, LightKeys, SensorKeys } from './constants.js';
4
4
 
5
5
  class DeviceInfo extends EventEmitter {
6
6
  constructor(url, auth, user, passwd, deviceName, loadNameFromDevice, enableDebugMode, refreshInterval) {
@@ -58,9 +58,16 @@ class DeviceInfo extends EventEmitter {
58
58
  //status STS
59
59
  const statusSts = deviceInfo.StatusSTS ?? {};
60
60
  const statusStsKeys = Object.keys(statusSts);
61
- const deviceType = statusSnsKeys.includes('MiElHVAC') ? 0 : statusStsKeys.some(key => LightKeys.includes(key)) ? 2 : statusStsKeys.includes('FanSpeed') ? 3 : 1;
61
+
62
+ //device types
63
+ const types = [];
64
+ const mielhvac = statusSnsKeys.includes('MiElHVAC') ? types.push(0) : false;
65
+ const lights = statusStsKeys.some(key => LightKeys.includes(key)) ? types.push(2) : false;
66
+ const fans = statusStsKeys.includes('FanSpeed') ? types.push(3) : false;
67
+ const sensors = statusSnsKeys.some(key => SensorKeys.includes(key)) ? types.push(4) : false;
68
+ const switches = !mielhvac && !lights && !fans && !sensors ? types.push(1) : false
62
69
  const obj = {
63
- deviceType: deviceType,
70
+ deviceTypes: types,
64
71
  deviceName: deviceName,
65
72
  friendlyNames: friendlyNames,
66
73
  modelName: modelName,
package/src/fans.js CHANGED
@@ -2,7 +2,7 @@ import { promises as fsPromises } from 'fs';
2
2
  import axios from 'axios';
3
3
  import EventEmitter from 'events';
4
4
  import ImpulseGenerator from './impulsegenerator.js';
5
- import { ApiCommands, SensorKeys } from './constants.js';
5
+ import { ApiCommands } from './constants.js';
6
6
  let Accessory, Characteristic, Service, Categories, AccessoryUUID;
7
7
 
8
8
  class Fans extends EventEmitter {
@@ -21,26 +21,11 @@ class Fans extends EventEmitter {
21
21
  //other config
22
22
  this.lightsNamePrefix = config.lightsNamePrefix || false;
23
23
  this.fansNamePrefix = config.fansNamePrefix || false;
24
- this.sensorsNamePrefix = config.sensorsNamePrefix || false;
25
24
  this.enableDebugMode = config.enableDebugMode || false;
26
25
  this.disableLogInfo = config.disableLogInfo || false;
27
26
  this.disableLogDeviceInfo = config.disableLogDeviceInfo || false;
28
27
  this.refreshInterval = refreshInterval;
29
28
 
30
- //sensors
31
- this.sensorsCount = 0;
32
- this.sensorsTemperatureCount = 0;
33
- this.sensorsReferenceTemperatureCount = 0;
34
- this.sensorsObjTemperatureCount = 0;
35
- this.sensorsAmbTemperatureCount = 0;
36
- this.sensorsHumidityCount = 0;
37
- this.sensorsDewPointTemperatureCount = 0;
38
- this.sensorsPressureCount = 0;
39
- this.sensorsGasCount = 0;
40
- this.sensorsCarbonDioxydeCount = 0;
41
- this.sensorsAmbientLightCount = 0;
42
- this.sensorsMotionCount = 0;
43
-
44
29
  //variable
45
30
  this.startPrepareAccessory = true;
46
31
 
@@ -87,10 +72,6 @@ class Fans extends EventEmitter {
87
72
  //sensor status keys
88
73
  const sensorStatusKeys = Object.keys(sensorStatus);
89
74
 
90
- //status SNS
91
- const statusSnsSupported = sensorStatusKeys.includes('StatusSNS');
92
- const statusSns = statusSnsSupported ? sensorStatus.StatusSNS : {};
93
-
94
75
  //status STS
95
76
  const statusStsSupported = sensorStatusKeys.includes('StatusSTS');
96
77
  const statusSts = statusStsSupported ? sensorStatus.StatusSTS : {};
@@ -152,160 +133,6 @@ class Fans extends EventEmitter {
152
133
  }
153
134
  }
154
135
 
155
- //status SNS
156
- if (statusSnsSupported) {
157
- this.sensorsName = [];
158
- this.sensorsTemperature = [];
159
- this.sensorsReferenceTemperature = [];
160
- this.sensorsObjTemperature = [];
161
- this.sensorsAmbTemperature = [];
162
- this.sensorsDewPointTemperature = [];
163
- this.sensorsHumidity = [];
164
- this.sensorsPressure = [];
165
- this.sensorsGas = [];
166
- this.sensorsCarbonDioxyde = [];
167
- this.sensorsAmbientLight = [];
168
- this.sensorsMotion = [];
169
-
170
- const sensor = Object.entries(statusSns)
171
- .filter(([key]) => SensorKeys.some(type => key.includes(type)))
172
- .reduce((obj, [key, value]) => {
173
- obj[key] = value;
174
- return obj;
175
- }, {});
176
-
177
- for (const [key, value] of Object.entries(sensor)) {
178
- const sensorName = key ?? `Sensor`;
179
- const sensorData = value;
180
-
181
- //sensors
182
- const temperature = sensorData.Temperature ?? false;
183
- const referenceTemperature = sensorData.ReferenceTemperature ?? false;
184
- const objTemperature = sensorData.OBJTMP ?? false;
185
- const ambTemperature = sensorData.AMBTMP ?? false;
186
- const dewPointTemperature = sensorData.DewPoint ?? false;
187
- const humidity = sensorData.Humidity ?? false;
188
- const pressure = sensorData.Pressure ?? false;
189
- const gas = sensorData.Gas ?? false;
190
- const carbonDioxyde = sensorData.CarbonDioxyde ?? false;
191
- const ambientLight = sensorData.Ambient ?? false;
192
- const motion = sensorData === 'ON';
193
-
194
- //energy
195
- const energyTotalStartTime = sensorData.TotalStartTime ?? '';
196
- const energyTotal = sensorData.Total ?? 0;
197
- const energyPeriod = sensorData.Period ?? 0;
198
- const energyYesterday = sensorData.Yesterday ?? 0;
199
- const energyToday = sensorData.Today ?? 0;
200
- const power = sensorData.Power ?? 0;
201
- const apparentPower = sensorData.ApparentPower ?? 0;
202
- const reactivePower = sensorData.ReactivePower ?? 0;
203
- const factor = sensorData.Factor ?? 0;
204
- const voltage = sensorData.Voltage ?? 0;
205
- const current = sensorData.Current ?? 0;
206
- const load = sensorData.Load ?? 0;
207
-
208
- //push to array
209
- this.sensorsName.push(sensorName);
210
- const push1 = temperature ? this.sensorsTemperature.push(temperature) : false;
211
- const push2 = referenceTemperature ? this.sensorsReferenceTemperature.push(referenceTemperature) : false;
212
- const push3 = objTemperature ? this.sensorsAmbTemperature.push(objTemperature) : false;
213
- const push4 = ambTemperature ? this.sensorsAmbTemperature.push(ambTemperature) : false;
214
- const push5 = dewPointTemperature ? this.sensorsDewPointTemperature.push(dewPointTemperature) : false;
215
- const push6 = humidity ? this.sensorsHumidity.push(humidity) : false;
216
- const push7 = pressure ? this.sensorsPressure.push(pressure) : false;
217
- const push8 = gas ? this.sensorsGas.push(gas) : false;
218
- const push9 = carbonDioxyde ? this.sensorsCarbonDioxyde.push(carbonDioxyde) : false;
219
- const push10 = ambientLight ? this.sensorsAmbientLight.push(ambientLight) : false;
220
- const push11 = motion ? this.sensorsMotion.push(motion) : false;
221
- }
222
-
223
- this.time = sensorStatus.Time ?? '';
224
- this.tempUnit = sensorStatus.TempUnit === 'C' ? '°C' : 'F';
225
- this.pressureUnit = sensorStatus.PressureUnit ?? 'hPa';
226
- this.sensorsTemperatureCount = this.sensorsTemperature.length;
227
- this.sensorsReferenceTemperatureCount = this.sensorsReferenceTemperature.length;
228
- this.sensorsObjTemperatureCount = this.sensorsObjTemperature.length;
229
- this.sensorsAmbTemperatureCount = this.sensorsAmbTemperature.length;
230
- this.sensorsDewPointTemperatureCount = this.sensorsDewPointTemperature.length;
231
- this.sensorsHumidityCount = this.sensorsHumidity.length;
232
- this.sensorsPressureCount = this.sensorsPressure.length;
233
- this.sensorsGasCount = this.sensorsGas.length;
234
- this.sensorsCarbonDioxydeCount = this.sensorsCarbonDioxyde.length;
235
- this.sensorsAmbientLightCount = this.sensorsAmbientLight.length;
236
- this.sensorsMotionCount = this.sensorsMotion.length;
237
- this.sensorsCount = this.sensorsName.length;
238
-
239
-
240
- //update characteristics
241
- if (this.sensorTemperatureServices) {
242
- for (let i = 0; i < this.sensorsTemperatureCount; i++) {
243
- const value = this.sensorsTemperature[i];
244
- this.sensorTemperatureServices[i].updateCharacteristic(Characteristic.CurrentTemperature, value);
245
- }
246
- }
247
-
248
- if (this.sensorReferenceTemperatureServices) {
249
- for (let i = 0; i < this.sensorsReferenceTemperatureCount; i++) {
250
- const value = this.sensorsReferenceTemperature[i];
251
- this.sensorReferenceTemperatureServices[i].updateCharacteristic(Characteristic.CurrentTemperature, value);
252
- }
253
- }
254
-
255
- if (this.sensorObjTemperatureServices) {
256
- for (let i = 0; i < this.sensorsObjTemperatureCount; i++) {
257
- const value = this.sensorsObjTemperature[i];
258
- this.sensorObjTemperatureServices[i].updateCharacteristic(Characteristic.CurrentTemperature, value);
259
- }
260
- }
261
-
262
- if (this.sensorAmbTemperatureServices) {
263
- for (let i = 0; i < this.sensorsAmbTemperatureCount; i++) {
264
- const value = this.sensorsAmbTemperature[i];
265
- this.sensorAmbTemperatureServices[i].updateCharacteristic(Characteristic.CurrentTemperature, value);
266
- }
267
- }
268
-
269
- if (this.sensorDewPointTemperatureServices) {
270
- for (let i = 0; i < this.sensorsDewPointTemperatureCount; i++) {
271
- const value = this.sensorsDewPointTemperature[i];
272
- this.sensorDewPointTemperatureServices[i].updateCharacteristic(Characteristic.CurrentTemperature, value);
273
- }
274
- }
275
-
276
- if (this.sensorHumidityServices) {
277
- for (let i = 0; i < this.sensorsHumidityCount; i++) {
278
- const value = this.sensorsHumidity[i];
279
- this.sensorHumidityServices[i].updateCharacteristic(Characteristic.CurrentRelativeHumidity, value);
280
- }
281
- }
282
-
283
- if (this.sensorCarbonDioxydeServices) {
284
- for (let i = 0; i < this.sensorsCarbonDioxydeCount; i++) {
285
- const state = this.sensorsCarbonDioxyde[i] > 1000;
286
- const value = this.sensorsCarbonDioxyde[i];
287
- this.sensorCarbonDioxydeServices[i]
288
- .updateCharacteristic(Characteristic.CarbonDioxideDetected, state)
289
- .updateCharacteristic(Characteristic.CarbonDioxideLevel, value)
290
- .updateCharacteristic(Characteristic.CarbonDioxidePeakLevel, value);
291
- }
292
- }
293
-
294
- if (this.sensorAmbientLightServices) {
295
- for (let i = 0; i < this.sensorsAmbientLightCount; i++) {
296
- const value = this.sensorsAmbientLight[i];
297
- this.sensorAmbientLightServices[i].updateCharacteristic(Characteristic.CurrentAmbientLightLevel, value);
298
- }
299
- }
300
-
301
- if (this.sensorMotionServices) {
302
- for (let i = 0; i < this.sensorsMotionCount; i++) {
303
- const state = this.sensorsMotion[i];
304
- this.sensorMotionServices[i].updateCharacteristic(Characteristic.MotionDetected, state);
305
- }
306
- }
307
- }
308
-
309
136
  return true;
310
137
  } catch (error) {
311
138
  throw new Error(`Check state error: ${error}`);