homebridge-tasmota-control 0.7.2 → 0.9.0-beta.0
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/CHANGELOG.md +7 -0
- package/README.md +15 -7
- package/config.schema.json +50 -0
- package/package.json +1 -1
- package/src/constans.json +15 -1
- package/src/tasmotadevice.js +283 -21
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
5
5
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [0.9.0] - (xx.02.2024)
|
|
8
|
+
## Changes
|
|
9
|
+
- add support for Light Bulb (On/Off, Brightness, Color Temperature, Hue, Saturation)
|
|
10
|
+
- add possibility to disable/enable name prefix for relays, sensors
|
|
11
|
+
- config schema updated
|
|
12
|
+
- cleanu
|
|
13
|
+
|
|
7
14
|
## [0.8.0] - (03.02.2024)
|
|
8
15
|
## Changes
|
|
9
16
|
- add support for Ambient Light and Carbon Dioxyde Sensors
|
package/README.md
CHANGED
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
<span align="center">
|
|
6
6
|
|
|
7
7
|
# Homebridge Tasmota Control
|
|
8
|
+
|
|
8
9
|
[](https://github.com/homebridge/homebridge/wiki/Verified-Plugins)
|
|
9
|
-
[](https://www.npmjs.com/package/homebridge-tasmota-control)
|
|
10
|
+
[](https://www.npmjs.com/package/homebridge-tasmota-control)
|
|
10
11
|
[](https://www.npmjs.com/package/homebridge-tasmota-control)
|
|
11
12
|
[](https://www.npmjs.com/package/homebridge-tasmota-control)
|
|
12
13
|
[](https://github.com/grzegorz914/homebridge-tasmota-control/pulls)
|
|
@@ -26,32 +27,39 @@ Homebridge plugin for Tasmota flashed devices.
|
|
|
26
27
|
|
|
27
28
|
## About The Plugin
|
|
28
29
|
|
|
29
|
-
* Plugin work witch Tasmota falshed devices
|
|
30
|
-
* Control devices:
|
|
31
|
-
*
|
|
30
|
+
* Plugin work witch Tasmota falshed devices.
|
|
31
|
+
* Control relay devices:
|
|
32
|
+
* Light - `Power ON/OFF`, `Dimmer`, `Color Temperature`, `Hue`, `Saturation`
|
|
33
|
+
* Outlet - `Power ON/OFF`
|
|
34
|
+
* Switch - `Power ON/OFF`
|
|
32
35
|
* Read Sensors:
|
|
33
36
|
* Temperature
|
|
34
37
|
* Humidity
|
|
35
38
|
* Dew Point
|
|
39
|
+
* Carbon Dioxyde
|
|
40
|
+
* Ambient Light
|
|
36
41
|
|
|
37
42
|
### Configuration
|
|
38
43
|
|
|
39
44
|
* Run this plugin as a [Child Bridge](https://github.com/homebridge/homebridge/wiki/Child-Bridges) (Highly Recommended), this prevent crash Homebridge if plugin crashes.
|
|
40
|
-
* Install and use [Homebridge Config UI X](https://github.com/homebridge/homebridge-config-ui-x/wiki) to configure this plugin (Highly Recommended).
|
|
41
|
-
* The `sample-config.json` can be edited and used as an alternative.
|
|
45
|
+
* Install and use [Homebridge Config UI X](https://github.com/homebridge/homebridge-config-ui-x/wiki) to configure this plugin (Highly Recommended).
|
|
46
|
+
* The `sample-config.json` can be edited and used as an alternative.
|
|
42
47
|
* Be sure to always make a backup copy of your config.json file before making any changes to it.
|
|
43
48
|
|
|
44
49
|
<p align="center">
|
|
45
50
|
<a href="https://github.com/grzegorz914/homebridge-tasmota-control"><img src="https://raw.githubusercontent.com/grzegorz914/homebridge-tasmota-control/master/graphics/ustawienia.png" width="840"></a>
|
|
46
51
|
</p>
|
|
47
52
|
|
|
48
|
-
| Key | Description |
|
|
53
|
+
| Key | Description |
|
|
49
54
|
| --- | --- |
|
|
50
55
|
| `name` | Here set the accessory *Name* to be displayed in *Homebridge/HomeKit*. |
|
|
51
56
|
| `host` | Here set the *Hsostname or Address IP* of the Device.|
|
|
52
57
|
| `auth` | If enabled, authorizatins credentials will be used for login. |
|
|
53
58
|
| `user` | Here set the authorization *Username*. |
|
|
54
59
|
| `passwd` | Here set the authorization *Password*. |
|
|
60
|
+
| `relaysNamePrefix` | Here enable/disable the accessory name as a prefix for relays name. |
|
|
61
|
+
| `relaysDisplayType` | Here select characteristic display type for relays which are exposed in the HomeKit app. |
|
|
62
|
+
| `sensorsNamePrefix` | Here enable/disable the accessory name as a prefix for sensors name. |
|
|
55
63
|
| `enableDebugMode` | This enable debug log in homebridge console. |
|
|
56
64
|
| `disableLogInfo` | This disable log info, all values and state will not be displayed in Homebridge log console. |
|
|
57
65
|
| `disableLogDeviceInfo` | If enabled, add ability to disable log device info by every connections device to the network. |
|
package/config.schema.json
CHANGED
|
@@ -51,6 +51,41 @@
|
|
|
51
51
|
"functionBody": "return model.devices[arrayIndices].auth === true;"
|
|
52
52
|
}
|
|
53
53
|
},
|
|
54
|
+
"relaysNamePrefix": {
|
|
55
|
+
"title": "Name Prefix",
|
|
56
|
+
"type": "boolean",
|
|
57
|
+
"description": "Here enable/disable the accessory name as a prefix for relays name.",
|
|
58
|
+
"required": true
|
|
59
|
+
},
|
|
60
|
+
"relaysDisplayType": {
|
|
61
|
+
"title": "Display Type",
|
|
62
|
+
"type": "integer",
|
|
63
|
+
"minimum": 0,
|
|
64
|
+
"maximum": 1,
|
|
65
|
+
"default": 0,
|
|
66
|
+
"oneOf": [
|
|
67
|
+
{
|
|
68
|
+
"title": "Outlet",
|
|
69
|
+
"enum": [
|
|
70
|
+
0
|
|
71
|
+
]
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"title": "Switch",
|
|
75
|
+
"enum": [
|
|
76
|
+
1
|
|
77
|
+
]
|
|
78
|
+
}
|
|
79
|
+
],
|
|
80
|
+
"description": "Here select characteristic display type for relays which are exposed in the HomeKit app.",
|
|
81
|
+
"required": true
|
|
82
|
+
},
|
|
83
|
+
"sensorsNamePrefix": {
|
|
84
|
+
"title": "Name Prefix",
|
|
85
|
+
"type": "boolean",
|
|
86
|
+
"description": "Here enable/disable the accessory name as a prefix for sensors name.",
|
|
87
|
+
"required": true
|
|
88
|
+
},
|
|
54
89
|
"refreshInterval": {
|
|
55
90
|
"title": "Refresh Interval (sec)",
|
|
56
91
|
"type": "integer",
|
|
@@ -106,6 +141,21 @@
|
|
|
106
141
|
"type": "tabarray",
|
|
107
142
|
"title": "{{ value.title }}",
|
|
108
143
|
"items": [
|
|
144
|
+
{
|
|
145
|
+
"key": "devices[]",
|
|
146
|
+
"title": "Relays",
|
|
147
|
+
"items": [
|
|
148
|
+
"devices[].relaysDisplayType",
|
|
149
|
+
"devices[].relaysNamePrefix"
|
|
150
|
+
]
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
"key": "devices[]",
|
|
154
|
+
"title": "Sensors",
|
|
155
|
+
"items": [
|
|
156
|
+
"devices[].sensorsNamePrefix"
|
|
157
|
+
]
|
|
158
|
+
},
|
|
109
159
|
{
|
|
110
160
|
"key": "devices[]",
|
|
111
161
|
"title": "Authorization",
|
package/package.json
CHANGED
package/src/constans.json
CHANGED
|
@@ -5,11 +5,22 @@
|
|
|
5
5
|
"Status": "Status 0",
|
|
6
6
|
"PowerStatus": "Power0",
|
|
7
7
|
"Power": "Power",
|
|
8
|
+
"PowerOn": "Power%20on",
|
|
9
|
+
"PowerOff": "Power%20off",
|
|
8
10
|
"Off": "%20off",
|
|
9
11
|
"On": "%20on",
|
|
10
12
|
"Toggle": "%20toggle",
|
|
11
13
|
"Blink": "%20blink",
|
|
12
|
-
"BlinkOff": "%20blinkoff"
|
|
14
|
+
"BlinkOff": "%20blinkoff",
|
|
15
|
+
"Dimmer": "Dimmer",
|
|
16
|
+
"DimmerAllChannels": "Dimmer1",
|
|
17
|
+
"DimmerForRgbChannels": "Dimmer2",
|
|
18
|
+
"DimmerForWhiteChannels": "Dimmer3",
|
|
19
|
+
"ColorTemperature": "CT",
|
|
20
|
+
"HSBColor": "HSBColor",
|
|
21
|
+
"HSBHue": "HSBColor1",
|
|
22
|
+
"HSBSaturation": "HSBColor2",
|
|
23
|
+
"HSBBrightness": "HSBColor3"
|
|
13
24
|
},
|
|
14
25
|
"StatusSNS": [
|
|
15
26
|
"AZ7798",
|
|
@@ -31,8 +42,11 @@
|
|
|
31
42
|
"SCD30",
|
|
32
43
|
"SCD40",
|
|
33
44
|
"SCD41",
|
|
45
|
+
"SHT1X",
|
|
34
46
|
"SHT10",
|
|
47
|
+
"SHT3X",
|
|
35
48
|
"SHT30",
|
|
49
|
+
"SHT4X",
|
|
36
50
|
"SHT40"
|
|
37
51
|
],
|
|
38
52
|
"StatusSNSProperties": [
|
package/src/tasmotadevice.js
CHANGED
|
@@ -21,6 +21,10 @@ class TasmotaDevice {
|
|
|
21
21
|
this.user = config.user;
|
|
22
22
|
this.passwd = config.passwd;
|
|
23
23
|
this.auth = config.auth || false;
|
|
24
|
+
this.relaysNamePrefix = config.relaysNamePrefix || false;
|
|
25
|
+
this.relaysDisplayType = config.relaysDisplayType || 0;
|
|
26
|
+
this.lightsNamePrefix = config.lightsNamePrefix || false;
|
|
27
|
+
this.sensorsNamePrefix = config.sensorsNamePrefix || false;
|
|
24
28
|
this.refreshInterval = config.refreshInterval || 5;
|
|
25
29
|
this.enableDebugMode = config.enableDebugMode || false;
|
|
26
30
|
this.disableLogInfo = config.disableLogInfo || false;
|
|
@@ -36,6 +40,10 @@ class TasmotaDevice {
|
|
|
36
40
|
this.relaysFriendlyNames = [];
|
|
37
41
|
this.relaysCount = 0;
|
|
38
42
|
|
|
43
|
+
//lights
|
|
44
|
+
this.lightsFriendlyNames = [];
|
|
45
|
+
this.lightsCount = 0;
|
|
46
|
+
|
|
39
47
|
//sensors
|
|
40
48
|
this.sensors = [];
|
|
41
49
|
this.sensorsCount = 0;
|
|
@@ -44,6 +52,8 @@ class TasmotaDevice {
|
|
|
44
52
|
this.sensorsDewPointCount = 0;
|
|
45
53
|
this.sensorsPressureCount = 0;
|
|
46
54
|
this.sensorsGasCount = 0;
|
|
55
|
+
this.sensorsCarbonDioxydeCount = 0;
|
|
56
|
+
this.sensorsAmbientLightCount = 0;
|
|
47
57
|
|
|
48
58
|
//variable
|
|
49
59
|
this.startPrepareAccessory = true;
|
|
@@ -107,12 +117,14 @@ class TasmotaDevice {
|
|
|
107
117
|
//keys
|
|
108
118
|
const deviceInfoKeys = Object.keys(deviceInfo);
|
|
109
119
|
|
|
110
|
-
//
|
|
120
|
+
//relays
|
|
121
|
+
const deviceType = deviceInfo.Status.Module ?? 'Tasmota';
|
|
111
122
|
const deviceName = deviceInfo.Status.DeviceName ?? 'Tasmota';
|
|
112
|
-
const
|
|
123
|
+
const friendlyNames = Array.isArray(deviceInfo.Status.FriendlyName) ? deviceInfo.Status.FriendlyName : [deviceInfo.Status.FriendlyName];
|
|
124
|
+
const relaysCount = friendlyNames.length ?? 0;
|
|
113
125
|
for (let i = 0; i < relaysCount; i++) {
|
|
114
|
-
const friendlyName =
|
|
115
|
-
|
|
126
|
+
const friendlyName = friendlyNames[i] ?? `Unknown Nmae ${i}`;
|
|
127
|
+
this.relaysFriendlyNames.push(friendlyName);
|
|
116
128
|
};
|
|
117
129
|
|
|
118
130
|
//status fwr
|
|
@@ -160,6 +172,7 @@ class TasmotaDevice {
|
|
|
160
172
|
this.serialNumber = addressMac;
|
|
161
173
|
this.firmwareRevision = firmwareRevision;
|
|
162
174
|
this.relaysCount = relaysCount;
|
|
175
|
+
this.lightsCount = relaysCount;
|
|
163
176
|
this.sensorsCount = sensorsCount;
|
|
164
177
|
|
|
165
178
|
resolve(addressMac)
|
|
@@ -196,6 +209,69 @@ class TasmotaDevice {
|
|
|
196
209
|
};
|
|
197
210
|
};
|
|
198
211
|
|
|
212
|
+
//lights
|
|
213
|
+
const lightsCount = this.lightsCount;
|
|
214
|
+
if (lightsCount > 0) {
|
|
215
|
+
this.lightsStete = [];
|
|
216
|
+
this.lightsBrightnessSupported = [];
|
|
217
|
+
this.lightsBrightness = [];
|
|
218
|
+
this.lightsColorTemperatueSupported = [];
|
|
219
|
+
this.lightsColorTemperatue = [];
|
|
220
|
+
this.lightsHueSupported = [];
|
|
221
|
+
this.lightsHue = [];
|
|
222
|
+
this.lightsSaturationSupported = [];
|
|
223
|
+
this.lightsSaturation = [];
|
|
224
|
+
|
|
225
|
+
const lightsStatusData = await this.axiosInstance(CONSTANS.ApiCommands.PowerStatus);
|
|
226
|
+
const lightsStatus = lightsStatusData.data;
|
|
227
|
+
const debug = this.enableDebugMode ? this.log(`Device: ${this.host} ${this.name}, debug ${lightsCount === 1 ? 'light' : 'lights'} status: ${JSON.stringify(lightsStatus, null, 2)}`) : false;
|
|
228
|
+
|
|
229
|
+
for (let i = 0; i < lightsCount; i++) {
|
|
230
|
+
const powerStatusKey = lightsCount === 1 ? 'POWER' : 'POWER' + (i + 1);
|
|
231
|
+
const status = lightsStatus[powerStatusKey] === 'ON' ?? false;
|
|
232
|
+
|
|
233
|
+
const statusKeys = Object.keys(lightsStatus);
|
|
234
|
+
const brightnessSupported = statusKeys.includes('Dimmer');
|
|
235
|
+
const brightness = lightsStatus.Dimmer ?? false;
|
|
236
|
+
const colorTemperatureSupported = statusKeys.includes('CT');
|
|
237
|
+
const colorTemperature = lightsStatus.CT ?? false;
|
|
238
|
+
const hueSupported = statusKeys.includes('HSBColor1');
|
|
239
|
+
const hue = lightsStatus.HSBColor1 ?? false;
|
|
240
|
+
const saturationSupported = statusKeys.includes('HSBColor2');
|
|
241
|
+
const saturation = lightsStatus.HSBColor2 ?? false;
|
|
242
|
+
|
|
243
|
+
this.lightsStete.push(status);
|
|
244
|
+
this.lightsBrightnessSupported.push(brightnessSupported)
|
|
245
|
+
const push = brightnessSupported ? this.lightsBrightness.push(brightness) : false;
|
|
246
|
+
this.lightsColorTemperatueSupported.push(colorTemperatureSupported)
|
|
247
|
+
const push1 = colorTemperatureSupported ? this.lightsColorTemperatue.push(colorTemperature) : false;
|
|
248
|
+
this.lightsHueSupported.push(hueSupported)
|
|
249
|
+
const push2 = hueSupported ? this.lightsHue.push(hue) : false;
|
|
250
|
+
this.lightsSaturationSupported.push(saturationSupported)
|
|
251
|
+
const push3 = saturationSupported ? this.lightsHue.push(saturation) : false;
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
//update characteristics
|
|
255
|
+
if (this.lightServices) {
|
|
256
|
+
this.lightServices[i].updateCharacteristic(Characteristic.On, status);
|
|
257
|
+
|
|
258
|
+
if (brightnessSupported) {
|
|
259
|
+
this.lightServices[i].updateCharacteristic(Characteristic.Brightness, brightness);
|
|
260
|
+
};
|
|
261
|
+
if (colorTemperatureSupported) {
|
|
262
|
+
const value = colorTemperature > 153 ? colorTemperature : 140;
|
|
263
|
+
this.lightServices[i].updateCharacteristic(Characteristic.ColorTemperature, value);
|
|
264
|
+
};
|
|
265
|
+
if (hueSupported) {
|
|
266
|
+
this.lightServices[i].updateCharacteristic(Characteristic.Hue, hue);
|
|
267
|
+
};
|
|
268
|
+
if (saturationSupported) {
|
|
269
|
+
this.lightServices[i].updateCharacteristic(Characteristic.Saturation, saturation);
|
|
270
|
+
};
|
|
271
|
+
};
|
|
272
|
+
};
|
|
273
|
+
};
|
|
274
|
+
|
|
199
275
|
//sensors
|
|
200
276
|
const sensorsCount = this.sensorsCount;
|
|
201
277
|
if (sensorsCount > 0) {
|
|
@@ -205,6 +281,8 @@ class TasmotaDevice {
|
|
|
205
281
|
this.sensorsDewPoint = [];
|
|
206
282
|
this.sensorsPressure = [];
|
|
207
283
|
this.sensorsGas = [];
|
|
284
|
+
this.sensorsCarbonDioxyde = [];
|
|
285
|
+
this.sensorsAmbientLight = [];
|
|
208
286
|
|
|
209
287
|
const sensorsStatusData = await this.axiosInstance(CONSTANS.ApiCommands.Status);
|
|
210
288
|
const sensorsStatus = sensorsStatusData.data.StatusSNS;
|
|
@@ -227,6 +305,8 @@ class TasmotaDevice {
|
|
|
227
305
|
const push3 = dewPoint !== false && dewPoint !== undefined && dewPoint !== null ? this.sensorsDewPoint.push(dewPoint) : false;
|
|
228
306
|
const push4 = pressure !== false && pressure !== undefined && pressure !== null ? this.sensorsPressure.push(pressure) : false;
|
|
229
307
|
const push5 = gas !== false && gas !== undefined && gas !== null ? this.sensorsGas.push(gas) : false;
|
|
308
|
+
const push6 = carbonDioxyde !== false && carbonDioxyde !== undefined && carbonDioxyde !== null ? this.sensorsCarbonDioxyde.push(carbonDioxyde) : false;
|
|
309
|
+
const push7 = ambientLight !== false && ambientLight !== undefined && ambientLight !== null ? this.sensorsAmbientLight.push(ambientLight) : false;
|
|
230
310
|
};
|
|
231
311
|
|
|
232
312
|
this.sensorsTemperatureCount = this.sensorsTemperature.length;
|
|
@@ -234,6 +314,8 @@ class TasmotaDevice {
|
|
|
234
314
|
this.sensorsDewPointCount = this.sensorsDewPoint.length;
|
|
235
315
|
this.sensorsPressureCount = this.sensorsPressure.length;
|
|
236
316
|
this.sensorsGasCount = this.sensorsGas.length;
|
|
317
|
+
this.sensorsCarbonDioxydeCount = this.sensorsCarbonDioxyde.length;
|
|
318
|
+
this.sensorsAmbientLightCount = this.sensorsAmbientLight.length;
|
|
237
319
|
this.tempUnit = sensorsStatus.TempUnit ?? 'C';
|
|
238
320
|
this.pressureUnit = sensorsStatus.PressureUnit ?? 'hPa';
|
|
239
321
|
|
|
@@ -262,6 +344,25 @@ class TasmotaDevice {
|
|
|
262
344
|
.updateCharacteristic(Characteristic.CurrentTemperature, dewPoint);
|
|
263
345
|
};
|
|
264
346
|
};
|
|
347
|
+
|
|
348
|
+
if (this.sensorCarbonDioxydeServices && this.sensorsCarbonDioxydeCount > 0) {
|
|
349
|
+
for (let i = 0; i < this.sensorsCarbonDioxydeCount; i++) {
|
|
350
|
+
const carbonDioxydeDetected = this.sensorsCarbonDioxyde[i] > 1000;
|
|
351
|
+
const carbonDioxydeLevel = this.sensorsCarbonDioxyde[i];
|
|
352
|
+
this.sensorCarbonDioxydeServices[i]
|
|
353
|
+
.updateCharacteristic(Characteristic.CarbonDioxideDetected, carbonDioxydeDetected)
|
|
354
|
+
.updateCharacteristic(Characteristic.CarbonDioxideLevel, carbonDioxydeLevel)
|
|
355
|
+
.updateCharacteristic(Characteristic.CarbonDioxidePeakLevel, carbonDioxydeLevel);
|
|
356
|
+
};
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
if (this.sensorAmbientLightServices && this.sensorsAmbientLightCount > 0) {
|
|
360
|
+
for (let i = 0; i < this.sensorsAmbientLightCount; i++) {
|
|
361
|
+
const ambientLight = this.sensorsAmbientLight[i];
|
|
362
|
+
this.sensorAmbientLightServices[i]
|
|
363
|
+
.updateCharacteristic(Characteristic.CurrentAmbientLightLevel, ambientLight);
|
|
364
|
+
};
|
|
365
|
+
};
|
|
265
366
|
};
|
|
266
367
|
|
|
267
368
|
resolve();
|
|
@@ -293,33 +394,36 @@ class TasmotaDevice {
|
|
|
293
394
|
//Prepare services
|
|
294
395
|
const debug2 = this.enableDebugMode ? this.log('Prepare Services') : false;
|
|
295
396
|
|
|
296
|
-
//
|
|
397
|
+
//switches, outlets
|
|
297
398
|
const relaysCount = this.relaysCount;
|
|
298
399
|
if (relaysCount > 0) {
|
|
299
400
|
const debug = this.enableDebugMode ? this.log('Prepare Relay Services') : false;
|
|
300
401
|
this.relayServices = [];
|
|
301
402
|
for (let i = 0; i < relaysCount; i++) {
|
|
302
|
-
const
|
|
303
|
-
const
|
|
304
|
-
const
|
|
305
|
-
const
|
|
403
|
+
const relayName = this.relaysFriendlyNames[i];
|
|
404
|
+
const relayLogName = relaysCount > 1 ? `${accessoryName}, relay: ${relayName}` : relayName
|
|
405
|
+
const serviceName = this.relaysNamePrefix ? `${accessoryName} ${relayName}` : relayName;
|
|
406
|
+
const serviceType = [Service.Outlet, Service.Switch][this.relaysDisplayType];
|
|
407
|
+
const relayService = new serviceType(serviceName, `Relay ${[i]}`);
|
|
306
408
|
relayService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
307
409
|
relayService.setCharacteristic(Characteristic.ConfiguredName, serviceName);
|
|
308
410
|
relayService.getCharacteristic(Characteristic.On)
|
|
309
411
|
.onGet(async () => {
|
|
310
412
|
const state = this.relaysStete[i] ?? false;
|
|
311
|
-
const logInfo = this.disableLogInfo ? false : this.log(`Device: ${this.host} ${
|
|
413
|
+
const logInfo = this.disableLogInfo ? false : this.log(`Device: ${this.host} ${relayLogName}, state: ${state ? 'ON' : 'OFF'}`);
|
|
312
414
|
return state;
|
|
313
415
|
})
|
|
314
416
|
.onSet(async (state) => {
|
|
315
|
-
const powerOn = relaysCount === 1 ? CONSTANS.ApiCommands.Power + CONSTANS.ApiCommands.On : CONSTANS.ApiCommands.Power + (i + 1) + CONSTANS.ApiCommands.On;
|
|
316
|
-
const powerOff = relaysCount === 1 ? CONSTANS.ApiCommands.Power + CONSTANS.ApiCommands.Off : CONSTANS.ApiCommands.Power + (i + 1) + CONSTANS.ApiCommands.Off;
|
|
317
|
-
state = state ? powerOn : powerOff;
|
|
318
417
|
try {
|
|
418
|
+
const relayNr = i + 1;
|
|
419
|
+
const relayOn = relaysCount === 1 ? CONSTANS.ApiCommands.PowerOn : `${CONSTANS.ApiCommands.Power}${relayNr}${CONSTANS.ApiCommands.On}`;
|
|
420
|
+
const relayOff = relaysCount === 1 ? CONSTANS.ApiCommands.PowerOff : `${CONSTANS.ApiCommands.Power}${relayNr}${CONSTANS.ApiCommands.Off}`;
|
|
421
|
+
state = state ? relayOn : relayOff;
|
|
422
|
+
|
|
319
423
|
await this.axiosInstance(state);
|
|
320
|
-
const logInfo = this.disableLogInfo ? false : this.log(`Device: ${this.host} ${
|
|
424
|
+
const logInfo = this.disableLogInfo ? false : this.log(`Device: ${this.host} ${relayLogName}, set state: ${state ? 'ON' : 'OFF'}`);
|
|
321
425
|
} catch (error) {
|
|
322
|
-
this.log.error(`Device: ${this.host} ${
|
|
426
|
+
this.log.error(`Device: ${this.host} ${relayLogName}, set state error: ${error}`);
|
|
323
427
|
}
|
|
324
428
|
});
|
|
325
429
|
this.relayServices.push(relayService);
|
|
@@ -327,6 +431,111 @@ class TasmotaDevice {
|
|
|
327
431
|
};
|
|
328
432
|
}
|
|
329
433
|
|
|
434
|
+
//lights
|
|
435
|
+
const lightsCount = this.lightsCount;
|
|
436
|
+
if (lightsCount > 0) {
|
|
437
|
+
const debug = this.enableDebugMode ? this.log('Prepare Light Services') : false;
|
|
438
|
+
this.lightServices = [];
|
|
439
|
+
for (let i = 0; i < lightsCount; i++) {
|
|
440
|
+
const lightName = this.lightsFriendlyNames[i];
|
|
441
|
+
const lightLogName = lightsCount > 1 ? `${accessoryName}, light: ${lightName}` : lightName
|
|
442
|
+
const serviceName = this.lightsNamePrefix ? `${accessoryName} ${lightName}` : lightName;
|
|
443
|
+
const lightService = new Service.Lightbulb(serviceName, `Light ${[i]}`);
|
|
444
|
+
lightService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
445
|
+
lightService.setCharacteristic(Characteristic.ConfiguredName, serviceName);
|
|
446
|
+
lightService.getCharacteristic(Characteristic.On)
|
|
447
|
+
.onGet(async () => {
|
|
448
|
+
const state = this.lightsStete[i] ?? false;
|
|
449
|
+
const logInfo = this.disableLogInfo ? false : this.log(`Device: ${this.host} ${lightLogName}, state: ${state ? 'ON' : 'OFF'}`);
|
|
450
|
+
return state;
|
|
451
|
+
})
|
|
452
|
+
.onSet(async (state) => {
|
|
453
|
+
try {
|
|
454
|
+
const lightNr = i + 1;
|
|
455
|
+
const lightOn = lightsCount === 1 ? CONSTANS.ApiCommands.PowerOn : `${CONSTANS.ApiCommands.Power}${lightNr}${CONSTANS.ApiCommands.On}`;
|
|
456
|
+
const lightOff = lightsCount === 1 ? CONSTANS.ApiCommands.PowerOff : `${CONSTANS.ApiCommands.Power}${lightNr}${CONSTANS.ApiCommands.Off}`
|
|
457
|
+
state = state ? lightOn : lightOff;
|
|
458
|
+
|
|
459
|
+
await this.axiosInstance(state);
|
|
460
|
+
const logInfo = this.disableLogInfo ? false : this.log(`Device: ${this.host} ${lightLogName}, set state: ${state ? 'ON' : 'OFF'}`);
|
|
461
|
+
} catch (error) {
|
|
462
|
+
this.log.error(`Device: ${this.host} ${lightLogName}, set state error: ${error}`);
|
|
463
|
+
}
|
|
464
|
+
});
|
|
465
|
+
if (this.lightsBrightnessSupported[i]) {
|
|
466
|
+
lightService.getCharacteristic(Characteristic.Brightness)
|
|
467
|
+
.onGet(async () => {
|
|
468
|
+
const value = this.lightsBrightness[i] ?? 0;
|
|
469
|
+
const logInfo = this.disableLogInfo ? false : this.log(`Device: ${this.host} ${lightLogName}, brightness: ${value} %`);
|
|
470
|
+
return value;
|
|
471
|
+
})
|
|
472
|
+
.onSet(async (value) => {
|
|
473
|
+
try {
|
|
474
|
+
const brightness = `${CONSTANS.ApiCommands.Dimmer}${value}`; //0..100
|
|
475
|
+
await this.axiosInstance(brightness);
|
|
476
|
+
const logInfo = this.disableLogInfo ? false : this.log(`Device: ${this.host} ${lightLogName}, set brightness: ${value} %`);
|
|
477
|
+
} catch (error) {
|
|
478
|
+
this.log.error(`Device: ${this.host} ${lightLogName}, set brightness error: ${error}`);
|
|
479
|
+
}
|
|
480
|
+
});
|
|
481
|
+
};
|
|
482
|
+
if (this.lightsColorTemperatueSupported[i]) {
|
|
483
|
+
lightService.getCharacteristic(Characteristic.ColorTemperature)
|
|
484
|
+
.onGet(async () => {
|
|
485
|
+
const value = this.lightsColorTemperature[i] > 153 ? this.lightsColorTemperature[i] : 140;
|
|
486
|
+
const logInfo = this.disableLogInfo ? false : this.log(`Device: ${this.host} ${lightLogName}, color temperatur: ${value}`);
|
|
487
|
+
return value;
|
|
488
|
+
})
|
|
489
|
+
.onSet(async (value) => {
|
|
490
|
+
try {
|
|
491
|
+
value = value < 153 ? 153 : value;
|
|
492
|
+
const colorTemperature = `${CONSTANS.ApiCommands.ColorTemperature}${value}`; //140..500
|
|
493
|
+
await this.axiosInstance(colorTemperature);
|
|
494
|
+
const logInfo = this.disableLogInfo ? false : this.log(`Device: ${this.host} ${lightLogName}, set brightness: ${value} °`);
|
|
495
|
+
} catch (error) {
|
|
496
|
+
this.log.error(`Device: ${this.host} ${lightLogName}, set color temperatur error: ${error}`);
|
|
497
|
+
}
|
|
498
|
+
});
|
|
499
|
+
};
|
|
500
|
+
if (this.lightsHueSupported[i]) {
|
|
501
|
+
lightService.getCharacteristic(Characteristic.Hue)
|
|
502
|
+
.onGet(async () => {
|
|
503
|
+
const value = this.lightsHue[i] ?? 0;
|
|
504
|
+
const logInfo = this.disableLogInfo ? false : this.log(`Device: ${this.host} ${lightLogName}, hue: ${value} %`);
|
|
505
|
+
return value;
|
|
506
|
+
})
|
|
507
|
+
.onSet(async (value) => {
|
|
508
|
+
try {
|
|
509
|
+
const hue = `${CONSTANS.ApiCommands.HSBHue}${value}`; //0..360
|
|
510
|
+
await this.axiosInstance(hue);
|
|
511
|
+
const logInfo = this.disableLogInfo ? false : this.log(`Device: ${this.host} ${lightLogName}, set hue: ${value} °`);
|
|
512
|
+
} catch (error) {
|
|
513
|
+
this.log.error(`Device: ${this.host} ${lightLogName}, set hue error: ${error}`);
|
|
514
|
+
}
|
|
515
|
+
});
|
|
516
|
+
};
|
|
517
|
+
if (this.lightsSaturationSupported[i]) {
|
|
518
|
+
lightService.getCharacteristic(Characteristic.Saturation)
|
|
519
|
+
.onGet(async () => {
|
|
520
|
+
const value = this.lightsSaturation[i] ?? 0;
|
|
521
|
+
const logInfo = this.disableLogInfo ? false : this.log(`Device: ${this.host} ${lightLogName}, saturation: ${value} %`);
|
|
522
|
+
return value;
|
|
523
|
+
})
|
|
524
|
+
.onSet(async (value) => {
|
|
525
|
+
try {
|
|
526
|
+
const saturation = `${CONSTANS.ApiCommands.HSBSaturation}${value}`; //0..100
|
|
527
|
+
await this.axiosInstance(saturation);
|
|
528
|
+
const logInfo = this.disableLogInfo ? false : this.log(`Device: ${this.host} ${lightLogName}, set saturation: ${value} °`);
|
|
529
|
+
} catch (error) {
|
|
530
|
+
this.log.error(`Device: ${this.host} ${lightLogName}, set saturation error: ${error}`);
|
|
531
|
+
}
|
|
532
|
+
});
|
|
533
|
+
};
|
|
534
|
+
this.lightServices.push(lightService);
|
|
535
|
+
accessory.addService(lightService);
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
|
|
330
539
|
//sensors
|
|
331
540
|
const sensorsCount = this.sensorsCount;
|
|
332
541
|
if (sensorsCount > 0) {
|
|
@@ -339,8 +548,8 @@ class TasmotaDevice {
|
|
|
339
548
|
this.sensorTemperatureServices = [];
|
|
340
549
|
for (let i = 0; i < sensorsTemperatureCount; i++) {
|
|
341
550
|
const sensorName = this.sensorsName[i];
|
|
342
|
-
const serviceName = `${accessoryName} ${sensorName} Temperature`;
|
|
343
|
-
const sensorTemperatureService = new Service.TemperatureSensor(serviceName, `Temperature Sensor${i}`);
|
|
551
|
+
const serviceName = this.sensorsNamePrefix ? `${accessoryName} ${sensorName} Temperature` : `${sensorName} Temperature`;
|
|
552
|
+
const sensorTemperatureService = new Service.TemperatureSensor(serviceName, `Temperature Sensor ${i}`);
|
|
344
553
|
sensorTemperatureService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
345
554
|
sensorTemperatureService.setCharacteristic(Characteristic.ConfiguredName, serviceName);
|
|
346
555
|
sensorTemperatureService.getCharacteristic(Characteristic.CurrentTemperature)
|
|
@@ -361,8 +570,8 @@ class TasmotaDevice {
|
|
|
361
570
|
this.sensorHumidityServices = [];
|
|
362
571
|
for (let i = 0; i < sensorsHumidityCount; i++) {
|
|
363
572
|
const sensorName = this.sensorsName[i];
|
|
364
|
-
const serviceName = `${accessoryName} ${sensorName} Humidity`;
|
|
365
|
-
const sensorHumidityService = new Service.HumiditySensor(serviceName, `Humidity Sensor${i}`);
|
|
573
|
+
const serviceName = this.sensorsNamePrefix ? `${accessoryName} ${sensorName} Humidity` : `${sensorName} Humidity`;
|
|
574
|
+
const sensorHumidityService = new Service.HumiditySensor(serviceName, `Humidity Sensor ${i}`);
|
|
366
575
|
sensorHumidityService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
367
576
|
sensorHumidityService.setCharacteristic(Characteristic.ConfiguredName, serviceName);
|
|
368
577
|
sensorHumidityService.getCharacteristic(Characteristic.CurrentRelativeHumidity)
|
|
@@ -383,8 +592,8 @@ class TasmotaDevice {
|
|
|
383
592
|
this.sensorDewPointServices = [];
|
|
384
593
|
for (let i = 0; i < sensorsDewPointCount; i++) {
|
|
385
594
|
const sensorName = this.sensorsName[i];
|
|
386
|
-
const serviceName = `${accessoryName} ${sensorName} Dew Point`;
|
|
387
|
-
const sensorDewPointService = new Service.TemperatureSensor(serviceName, `Dew Point Sensor${i}`);
|
|
595
|
+
const serviceName = this.sensorsNamePrefix ? `${accessoryName} ${sensorName} Dew Point` : `${sensorName} Dew Point`;
|
|
596
|
+
const sensorDewPointService = new Service.TemperatureSensor(serviceName, `Dew Point Sensor ${i}`);
|
|
388
597
|
sensorDewPointService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
389
598
|
sensorDewPointService.setCharacteristic(Characteristic.ConfiguredName, serviceName);
|
|
390
599
|
sensorDewPointService.getCharacteristic(Characteristic.CurrentTemperature)
|
|
@@ -403,7 +612,60 @@ class TasmotaDevice {
|
|
|
403
612
|
//gas
|
|
404
613
|
|
|
405
614
|
//carbon dioxyde
|
|
615
|
+
const sensorsCarbonDioxydeCount = this.sensorsCarbonDioxydeCount;
|
|
616
|
+
if (sensorsCarbonDioxydeCount > 0) {
|
|
617
|
+
const debug = this.enableDebugMode ? this.log('Prepare Carbon Dioxyde Sensor Services') : false;
|
|
618
|
+
this.sensorCarbonDioxydeServices = [];
|
|
619
|
+
for (let i = 0; i < sensorsCarbonDioxydeCount; i++) {
|
|
620
|
+
const sensorName = this.sensorsName[i];
|
|
621
|
+
const serviceName = this.sensorsNamePrefix ? `${accessoryName} ${sensorName} Carbon Dioxyde` : `${sensorName} Carbon Dioxyde`;
|
|
622
|
+
const sensorCarbonDioxydeService = new Service.CarbonDioxideSensor(serviceName, `Carbon Dioxyde Sensor ${i}`);
|
|
623
|
+
sensorCarbonDioxydeService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
624
|
+
sensorCarbonDioxydeService.setCharacteristic(Characteristic.ConfiguredName, serviceName);
|
|
625
|
+
sensorCarbonDioxydeService.getCharacteristic(Characteristic.CarbonDioxideDetected)
|
|
626
|
+
.onGet(async () => {
|
|
627
|
+
const state = this.sensorsCarbonDioxyde[i] > 1000;
|
|
628
|
+
const logInfo = this.disableLogInfo ? false : this.log(`Device: ${this.host}, ${accessoryName}, sensor: ${sensorName} carbon dioxyde detected: ${state ? 'Yes' : 'No'}`);
|
|
629
|
+
return state;
|
|
630
|
+
});
|
|
631
|
+
sensorCarbonDioxydeService.getCharacteristic(Characteristic.CarbonDioxideLevel)
|
|
632
|
+
.onGet(async () => {
|
|
633
|
+
const value = this.sensorsCarbonDioxyde[i];
|
|
634
|
+
const logInfo = this.disableLogInfo ? false : this.log(`Device: ${this.host}, ${accessoryName}, sensor: ${sensorName} carbon dioxyde level: ${value} ppm`);
|
|
635
|
+
return value;
|
|
636
|
+
});
|
|
637
|
+
sensorCarbonDioxydeService.getCharacteristic(Characteristic.CarbonDioxidePeakLevel)
|
|
638
|
+
.onGet(async () => {
|
|
639
|
+
const value = this.sensorsCarbonDioxyde[i];
|
|
640
|
+
const logInfo = this.disableLogInfo ? false : this.log(`Device: ${this.host}, ${accessoryName}, sensor: ${sensorName} carbon dioxyde peak level: ${value} ppm`);
|
|
641
|
+
return value;
|
|
642
|
+
});
|
|
643
|
+
this.sensorCarbonDioxydeServices.push(sensorCarbonDioxydeService);
|
|
644
|
+
accessory.addService(sensorCarbonDioxydeService);
|
|
645
|
+
};
|
|
646
|
+
}
|
|
406
647
|
|
|
648
|
+
//ambient light
|
|
649
|
+
const sensorsAmbientLightCount = this.sensorsAmbientLightCount;
|
|
650
|
+
if (sensorsAmbientLightCount > 0) {
|
|
651
|
+
const debug = this.enableDebugMode ? this.log('Prepare Ambient Light Sensor Services') : false;
|
|
652
|
+
this.sensorAmbientLightServices = [];
|
|
653
|
+
for (let i = 0; i < sensorsAmbientLightCount; i++) {
|
|
654
|
+
const sensorName = this.sensorsName[i];
|
|
655
|
+
const serviceName = this.sensorsNamePrefix ? `${accessoryName} ${sensorName} Ambient Light` : `${sensorName} Ambient Light`;
|
|
656
|
+
const sensorAmbientLightService = new Service.LightSensor(serviceName, `Ambient Light Sensor ${i}`);
|
|
657
|
+
sensorAmbientLightService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
658
|
+
sensorAmbientLightService.setCharacteristic(Characteristic.ConfiguredName, serviceName);
|
|
659
|
+
sensorAmbientLightService.getCharacteristic(Characteristic.CurrentAmbientLightLevel)
|
|
660
|
+
.onGet(async () => {
|
|
661
|
+
const value = this.sensorsAmbientLight[i];
|
|
662
|
+
const logInfo = this.disableLogInfo ? false : this.log(`Device: ${this.host}, ${accessoryName}, sensor: ${sensorName} ambient light: ${value} lx`);
|
|
663
|
+
return value;
|
|
664
|
+
});
|
|
665
|
+
this.sensorAmbientLightServices.push(sensorAmbientLightService);
|
|
666
|
+
accessory.addService(sensorAmbientLightService);
|
|
667
|
+
};
|
|
668
|
+
}
|
|
407
669
|
};
|
|
408
670
|
|
|
409
671
|
resolve(accessory);
|