homebridge-tasmota-control 0.0.29 → 0.3.36

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 CHANGED
@@ -3,6 +3,6 @@ All notable changes to this project will be documented in this file.
3
3
 
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
- ## [0.0.1] - (05.02.2021)
6
+ ## [0.0.1] - (24.12.2021)
7
7
  ## Changs
8
8
  - initial release
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2020 Grzegorz
3
+ Copyright (c) 2021 Grzegorz
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,75 +1 @@
1
- <p align="center">
2
- <a href="https://github.com/grzegorz914/homebridge-tasmota-control"><img src="https://raw.githubusercontent.com/grzegorz914/homebridge-tasmota-control/master/graphics/tasmota.png" height="140"></a>
3
- </p>
4
-
5
- <span align="center">
6
-
7
- # Homebridge tasmota
8
- [![verified-by-homebridge](https://badgen.net/badge/homebridge/verified/purple)](https://github.com/homebridge/homebridge/wiki/Verified-Plugins)
9
- [![npm](https://badgen.net/npm/dt/homebridge-tasmota-control?color=purple)](https://www.npmjs.com/package/homebridge-tasmota-control) [![npm](https://badgen.net/npm/v/homebridge-tasmota-control?color=purple)](https://www.npmjs.com/package/homebridge-tasmota-control)
10
- [![GitHub pull requests](https://img.shields.io/github/issues-pr/grzegorz914/homebridge-tasmota-control.svg)](https://github.com/grzegorz914/homebridge-tasmota-control/pulls)
11
- [![GitHub issues](https://img.shields.io/github/issues/grzegorz914/homebridge-tasmota-control.svg)](https://github.com/grzegorz914/homebridge-tasmota-control/issues)
12
-
13
- Homebridge plugin to control tasmota devices using RESTFull API.
14
-
15
- </span>
16
-
17
- ## Package
18
- 1. [Homebridge](https://github.com/homebridge/homebridge)
19
- 2. [Homebridge Config UI X](https://github.com/oznu/homebridge-config-ui-x)
20
-
21
- ## Installation
22
- 1. Follow the step-by-step instructions on the [Homebridge Wiki](https://github.com/homebridge/homebridge/wiki) for how to install Homebridge.
23
- 2. Follow the step-by-step instructions on the [Homebridge Config UI X](https://github.com/oznu/homebridge-config-ui-x/wiki) for how to install Homebridge Config UI X.
24
- 3. Install homebridge-tasmota-control using: `npm install -g homebridge-tasmota-control` or search for `tasmota` in Config UI X.
25
-
26
- ## Know issues
27
- 1. If use with Hoobs possible config incompatibilty.
28
-
29
- ## HomeKit pairing
30
- 1. Each accessories needs to be manually paired.
31
- 2. Open the Home <img src='https://user-images.githubusercontent.com/3979615/78010622-4ea1d380-738e-11ea-8a17-e6a465eeec35.png' height='16.42px'> app on your device.
32
- 3. Tap the Home tab, then tap <img src='https://user-images.githubusercontent.com/3979615/78010869-9aed1380-738e-11ea-9644-9f46b3633026.png' height='16.42px'>.
33
- 4. Tap *Add Accessory*, and select *I Don't Have a Code or Cannot Scan*.
34
- 5. Enter the Homebridge PIN, this can be found under the QR code in Homebridge UI or your Homebridge logs, alternatively you can select *Use Camera* and scan the QR code again.
35
-
36
- ## Info
37
- 1. This plugin control ON/OFF Tasmota outlet.
38
- 2. More comming soon...
39
-
40
- ## Configuration
41
- 1. Use [Homebridge Config UI X](https://github.com/oznu/homebridge-config-ui-x) to configure the plugin (strongly recomended), or update your configuration file manually. See `sample-config.json` in this repository for a sample or add the bottom example to Your config.json file.
42
- 2. In `host` set the adres IP`
43
- 3. In `user` set the user.
44
- 4. In `passwd` set the password.
45
- 7. In `refreshInterval` set the data refresh time in seconds.
46
- 8. `manufacturer`, `model`, `serialNumber`, `firmwareRevision` - optional branding data displayed in Home.app
47
-
48
- <p align="left">
49
- <a href="https://github.com/grzegorz914/homebridge-tasmota-control"><img src="https://raw.githubusercontent.com/grzegorz914/homebridge-tasmota-control/master/graphics/ustawienia.png" height="150"></a>
50
- </p>
51
-
52
- ```json
53
- {
54
- "platform": "TasmotaControl",
55
- "devices": [
56
- {
57
- "name": "Gniazdo",
58
- "host": "192.169.1.60",
59
- "user": "user",
60
- "paswd": "password",
61
- "refreshInterval": 10,
62
- "manufacturer": "Manufacturer",
63
- "modelName": "Model",
64
- "serialNumber": "Serial Number",
65
- "firmwareRevision": "Firmware Revision"
66
- }
67
- ]
68
- }
69
- ```
70
-
71
- ## Whats new:
72
- https://github.com/grzegorz914/homebridge-tasmota-control/blob/master/CHANGELOG.md
73
-
74
- ## Development
75
- - Pull request and help in development highly appreciated.
1
+ # tasmota-control
@@ -1,9 +1,9 @@
1
1
  {
2
- "pluginAlias": "TasmotaControl",
2
+ "pluginAlias": "tasmotaControl",
3
3
  "pluginType": "platform",
4
4
  "singular": true,
5
- "headerDisplay": "This plugin works with Tasmota outlet devices and are exposed to HomeKit as separate accessories and each needs to be manually paired.\n\n1. Open the Home <img src='https://user-images.githubusercontent.com/3979615/78010622-4ea1d380-738e-11ea-8a17-e6a465eeec35.png' height='16.42px'> app on your device.\n2. Tap the Home tab, then tap <img src='https://user-images.githubusercontent.com/3979615/78010869-9aed1380-738e-11ea-9644-9f46b3633026.png' height='16.42px'>.\n3. Tap *Add Accessory*, and select *I Don't Have a Code or Cannot Scan*.\n4. Enter the Homebridge PIN, this can be found under the QR code in Homebridge UI or your Homebridge logs, alternatively you can select *Use Camera* and scan the QR code again.",
6
- "footerDisplay": "This plugin works with Tasmota devices which is available [here](https://github.com/grzegorz914/homebridge-tasmota-control).",
5
+ "headerDisplay": "This plugin works with Tasmota flashed devices and are exposed to HomeKit as separate accessories and each needs to be manually paired.\n\n1. Open the Home <img src='https://user-images.githubusercontent.com/3979615/78010622-4ea1d380-738e-11ea-8a17-e6a465eeec35.png' height='16.42px'> app on your device.\n2. Tap the Home tab, then tap <img src='https://user-images.githubusercontent.com/3979615/78010869-9aed1380-738e-11ea-9644-9f46b3633026.png' height='16.42px'>.\n3. Tap *Add Accessory*, and select *I Don't Have a Code or Cannot Scan*.\n4. Enter the Homebridge PIN, this can be found under the QR code in Homebridge UI or your Homebridge logs, alternatively you can select *Use Camera* and scan the QR code again.",
6
+ "footerDisplay": "This plugin is available [here](https://github.com/grzegorz914/homebridge-tasmota-control).",
7
7
  "schema": {
8
8
  "type": "object",
9
9
  "properties": {
@@ -22,14 +22,14 @@
22
22
  "host": {
23
23
  "title": "IP Address",
24
24
  "type": "string",
25
- "default": "192.168.1.60",
25
+ "default": "192.168.1.61",
26
26
  "required": true,
27
27
  "format": "hostname"
28
28
  },
29
29
  "user": {
30
30
  "title": "User",
31
31
  "type": "string",
32
- "default": "user",
32
+ "default": "admin",
33
33
  "required": true
34
34
  },
35
35
  "passwd": {
@@ -42,76 +42,60 @@
42
42
  "title": "Refresh interval (sec)",
43
43
  "type": "integer",
44
44
  "default": 10,
45
- "maximum": 3600,
45
+ "minimum": 0,
46
+ "maximum": 60,
46
47
  "required": true
47
48
  },
48
- "manufacturer": {
49
- "name": "Manufacturer",
50
- "type": "string",
51
- "placeholder": "Gosund",
52
- "description": "Set the manufacturer name.",
53
- "required": false
54
- },
55
- "modelName": {
56
- "name": "Model",
57
- "type": "string",
58
- "placeholder": "SP111",
59
- "description": "Set the model name.",
60
- "required": false
49
+ "channelsCount": {
50
+ "title": "Channels count",
51
+ "type": "number",
52
+ "default": 1,
53
+ "minimum": 1,
54
+ "maximum": 4,
55
+ "description": "Here set the number of channels.",
56
+ "required": true
61
57
  },
62
- "serialNumber": {
63
- "name": "Serial Number",
64
- "type": "string",
65
- "placeholder": "SerialNumber",
66
- "description": "Set the serial number.",
58
+ "enableDebugMode": {
59
+ "title": "Enable Debug Mode",
60
+ "type": "boolean",
61
+ "default": false,
62
+ "description": "This enable debug mode.",
67
63
  "required": false
68
64
  },
69
- "firmwareRevision": {
70
- "name": "Firmware Revision",
71
- "type": "string",
72
- "placeholder": "Firmware Revision",
73
- "description": "Set the firmware revision.",
74
- "required": false
65
+ "disableLogInfo": {
66
+ "title": "Disable log info",
67
+ "type": "boolean",
68
+ "default": false,
69
+ "required": false,
70
+ "description": "This disable log info, all values and state will not be displayed in Homebridge log console."
75
71
  }
76
72
  }
77
73
  }
78
74
  }
79
75
  }
80
76
  },
81
- "layout": [
82
- {
83
- "key": "devices",
84
- "type": "tabarray",
85
- "title": "{{ value.name || 'new device' }}",
86
- "items": [
87
- "devices[].name",
88
- "devices[].host",
89
- "devices[].refreshInterval",
90
- {
91
- "key": "devices[]",
92
- "type": "section",
93
- "title": "Advanced Settings",
94
- "expandable": true,
95
- "expanded": false,
96
- "items": [
97
- "devices[].user",
98
- "devices[].passwd"
99
- ]
100
- },
101
- {
102
- "key": "devices[]",
103
- "type": "section",
104
- "title": "Branding",
105
- "expandable": true,
106
- "expanded": false,
107
- "items": [
108
- "devices[].manufacturer",
109
- "devices[].modelName",
110
- "devices[].serialNumber",
111
- "devices[].firmwareRevision"
112
- ]
113
- }
114
- ]
115
- }
116
- ]
77
+ "layout": [{
78
+ "key": "devices",
79
+ "type": "tabarray",
80
+ "title": "{{ value.name || 'new device' }}",
81
+ "items": [
82
+ "devices[].name",
83
+ "devices[].host",
84
+ {
85
+ "key": "devices[]",
86
+ "type": "section",
87
+ "title": "Advanced Settings",
88
+ "expandable": true,
89
+ "expanded": false,
90
+ "items": [
91
+ "devices[].user",
92
+ "devices[].passwd",
93
+ "devices[].channelsCount",
94
+ "devices[].enableDebugMode",
95
+ "devices[].disableLogInfo",
96
+ "devices[].refreshInterval"
97
+ ]
98
+ }
99
+ ]
100
+ }]
117
101
  }
package/index.js CHANGED
@@ -1,13 +1,14 @@
1
1
  'use strict';
2
2
 
3
- const request = require('request');
4
- const axios = require('axios').default;
5
- const fs = require('fs');
6
3
  const path = require('path');
4
+ const axios = require('axios');
5
+ const fs = require('fs');
6
+ const fsPromises = require('fs').promises;
7
7
 
8
- const POWER_STATE = 'Power';
9
- const POWERON = '%20On';
10
- const POWEROFF = '%20Off';
8
+ const STATUS = 'Status0';
9
+ const POWER = 'Power';
10
+ const ON = '%20on'
11
+ const OFF = '%20off';
11
12
 
12
13
  const PLUGIN_NAME = 'homebridge-tasmota-control';
13
14
  const PLATFORM_NAME = 'tasmotaControl';
@@ -31,31 +32,31 @@ class tasmotaPlatform {
31
32
  return;
32
33
  }
33
34
  this.log = log;
34
- this.config = config;
35
35
  this.api = api;
36
36
  this.devices = config.devices || [];
37
+ this.accessories = [];
37
38
 
38
39
  this.api.on('didFinishLaunching', () => {
39
40
  this.log.debug('didFinishLaunching');
40
41
  for (let i = 0; i < this.devices.length; i++) {
41
- let deviceName = this.devices[i];
42
- if (!deviceName.name) {
42
+ const device = this.devices[i];
43
+ if (!device.name) {
43
44
  this.log.warn('Device Name Missing');
44
45
  } else {
45
- new tasmotaDevice(this.log, deviceName, this.api);
46
+ new tasmotaDevice(this.log, device, this.api);
46
47
  }
47
48
  }
48
49
  });
49
-
50
50
  }
51
51
 
52
- configureAccessory(platformAccessory) {
53
- this.log.debug('configurePlatformAccessory');
52
+ configureAccessory(accessory) {
53
+ this.log.debug('configureAccessory');
54
+ this.accessories.push(accessory);
54
55
  }
55
56
 
56
- removeAccessory(platformAccessory) {
57
- this.log.debug('removePlatformAccessory');
58
- this.api.unregisterPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [platformAccessory]);
57
+ removeAccessory(accessory) {
58
+ this.log.debug('removeAccessory');
59
+ this.api.unregisterPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
59
60
  }
60
61
  }
61
62
 
@@ -63,160 +64,165 @@ class tasmotaDevice {
63
64
  constructor(log, config, api) {
64
65
  this.log = log;
65
66
  this.api = api;
66
- this.config = config;
67
-
68
67
 
69
68
  //device configuration
70
69
  this.name = config.name;
71
70
  this.host = config.host;
72
71
  this.user = config.user;
73
72
  this.passwd = config.passwd;
74
- this.refreshInterval = config.refreshInterval || 10;
73
+ this.refreshInterval = config.refreshInterval || 5;
74
+ this.channelsCount = config.channelsCount || 1;
75
+ this.enableDebugMode = config.enableDebugMode || false;
76
+ this.disableLogInfo = config.disableLogInfo || true;
75
77
 
76
78
  //get Device info
77
- this.manufacturer = config.manufacturer || 'Gosund';
78
- this.modelName = config.modelName || 'SP111';
79
- this.serialNumber = config.serialNumber || 'Serial Number';
80
- this.firmwareRevision = config.firmwareRevision || 'Firmware Revision';
79
+ this.manufacturer = 'Tasmota';
80
+ this.modelName = 'Model Name';
81
+ this.serialNumber = 'Serial Number';
82
+ this.firmwareRevision = 'Firmware Revision';
81
83
 
82
84
  //setup variables
83
- this.checkDeviceInfo = false;
85
+ this.checkDeviceInfo = true;
84
86
  this.checkDeviceState = false;
85
- this.deviceDataOK = false;
86
- this.relayState = false;
87
+ this.startPrepareAccessory = true;
88
+
87
89
  this.prefDir = path.join(api.user.storagePath(), 'tasmota');
88
- this.auth_url = '?user=' + this.user + '&password=' + this.passwd;
89
- this.url = 'http://' + this.host + '/cm?' + this.auth_url + '&cmnd='
90
+ this.url = `http://${this.host}/cm?user=${this.user}&password=${this.passwd}&cmnd=`
90
91
 
91
- //check if prefs directory ends with a /, if not then add it
92
- if (this.prefDir.endsWith('/') === false) {
93
- this.prefDir = this.prefDir + '/';
94
- }
92
+ this.axiosInstance = axios.create({
93
+ method: 'GET',
94
+ baseURL: this.url,
95
+ timeout: 5000
96
+ });
95
97
 
96
98
  //check if the directory exists, if not then create it
97
- if (fs.existsSync(this.prefDir) === false) {
98
- fs.mkdir(this.prefDir, { recursive: false }, (error) => {
99
- if (error) {
100
- this.log.error('Device: %s , create directory: %s, error: %s', this.name, this.prefDir, error);
101
- } else {
102
- this.log.debug('Device: %s , create directory successful: %s', this.name, this.prefDir);
103
- }
104
- });
99
+ if (fs.existsSync(this.prefDir) == false) {
100
+ fsPromises.mkdir(this.prefDir);
105
101
  }
106
102
 
107
103
  //Check device state
108
104
  setInterval(function () {
109
105
  if (this.checkDeviceInfo) {
110
106
  this.getDeviceInfo();
111
- } else if (!this.checkDeviceInfo && this.checkDeviceState) {
107
+ } else {
112
108
  this.updateDeviceState();
113
109
  }
114
110
  }.bind(this), this.refreshInterval * 1000);
115
-
116
- this.getDeviceInfo()
117
111
  }
118
112
 
119
113
  async getDeviceInfo() {
120
- var me = this;
114
+ this.log.debug('Device: %s %s, requesting Device Info.', this.host, this.name);
121
115
  try {
122
- me.log.info('Device: %s, state: Online.', me.name);
123
- me.log('-------- %s --------', me.name);
124
- me.log('Manufacturer: %s', me.manufacturer);
125
- me.log('Model: %s', me.modelName);
126
- me.log('Serialnr: %s', me.serialNumber);
127
- me.log('Firmware: %s', me.firmwareRevision);
128
- me.log('----------------------------------');
129
-
130
- me.checkDeviceInfo = false;
131
- me.updateDeviceState();
116
+ const response = await this.axiosInstance(STATUS);
117
+ const debug = this.enableDebugMode ? this.log('Device: %s %s, debug response: %s', this.host, this.name, response.data) : false;
118
+
119
+ const deviceName = response.data.Status.DeviceName;
120
+ const modelName = response.data.StatusFWR.Hardware;
121
+ const addressMac = response.data.StatusNET.Mac;
122
+ const firmwareRevision = response.data.StatusFWR.Version;
123
+
124
+ this.log('-------- %s --------', deviceName);
125
+ this.log('Manufacturer: %s', this.manufacturer);
126
+ this.log('Hardware: %s', modelName);
127
+ this.log('Serialnr: %s', addressMac);
128
+ this.log('Firmware: %s', firmwareRevision);
129
+ this.log('----------------------------------');
130
+
131
+ this.modelName = modelName;
132
+ this.serialNumber = addressMac;
133
+ this.firmwareRevision = firmwareRevision;
134
+
135
+ this.checkDeviceInfo = false;
136
+ if (this.startPrepareAccessory) {
137
+ this.prepareAccessory();
138
+ }
132
139
  } catch (error) {
133
- me.log.error('Device: %s, getDeviceInfo error: %s', me.name, error);
134
- me.checkDeviceInfo = true;
140
+ this.log.error('Device: %s %s, Device Info eror: %s, state: Offline, trying to reconnect', this.host, this.name, error);
141
+ this.checkDeviceInfo = true;
135
142
  }
136
143
  }
137
144
 
138
- updateDeviceState() {
139
- var me = this;
140
- request(me.url + POWER_STATE, function (error, response, body) {
141
- if (error) {
142
- me.log.error('Device: %s, update status error: %s, state: Offline', me.name, error);
143
- me.checkDeviceState = false;
144
- me.checkDeviceInfo = true;
145
- }
146
- me.log.info('Device %s, get device status data: %s', me.name, body);
147
- var data = JSON.parse(body);
148
- if (data !== 'undefined') {
149
- let powerState = data.power;
150
- if (me.tasmotaService) {
151
- me.tasmotaService.updateCharacteristic(Characteristic.On, powerState);
152
- me.log.debug('Device: %s, state: %s', me.name, powerState ? 'ON' : 'OFF');
145
+ async updateDeviceState() {
146
+ this.log.debug('Device: %s %s, requesting Device state.', this.host, this.name);
147
+ try {
148
+ for (let i = 0; i < this.channelsCount; i++) {
149
+ const channel = this.channelsCount == 1 ? 'POWER' : 'POWER' + i;
150
+ const response = await this.axiosInstance(channel);
151
+ const debug = this.enableDebugMode ? this.log('Device: %s %s, debug response: %s', this.host, this.name, response.data) : false;
152
+ const powerState = (response.data[channel] != undefined) ? (response.data[channel] == 'ON') : false;
153
+ if (this.tasmotaServices) {
154
+ this.tasmotaServices[i]
155
+ .updateCharacteristic(Characteristic.OutletInUse, powerState);
153
156
  }
154
- me.relayState = powerState;
155
- me.deviceDataOK = true;
156
- }
157
-
158
- if (!me.checkDeviceState) {
159
- me.prepareAccessory();
160
157
  }
161
- me.checkDeviceState = true;
162
- });
158
+ this.checkDeviceState = true;
159
+ } catch (error) {
160
+ this.log.error('Device: %s %s, update Device state error: %s, state: Offline', this.host, this.name, error);
161
+ this.checkDeviceState = false;
162
+ this.checkDeviceInfo = true;
163
+ }
163
164
  }
164
165
 
165
166
  //Prepare accessory
166
167
  prepareAccessory() {
167
168
  this.log.debug('prepareAccessory');
168
169
  const accessoryName = this.name;
169
- const accessoryUUID = UUID.generate(accessoryName);
170
+ const accessoryUUID = UUID.generate(this.serialNumber);
170
171
  const accessoryCategory = Categories.OTHER;
171
- this.accessory = new Accessory(accessoryName, accessoryUUID, accessoryCategory);
172
-
173
- this.prepareInformationService();
174
- this.preparetasmotaService();
175
-
176
- this.log.debug('Device: %s %s, publishExternalAccessories.', this.host, accessoryName);
177
- this.api.publishExternalAccessories(PLUGIN_NAME, [this.accessory]);
178
- }
172
+ const accessory = new Accessory(accessoryName, accessoryUUID, accessoryCategory);
179
173
 
180
- //Prepare information service
181
- prepareInformationService() {
174
+ //Prepare information service
182
175
  this.log.debug('prepareInformationService');
183
- this.getDeviceInfo();
176
+ const manufacturer = this.manufacturer;
177
+ const modelName = this.modelName;
178
+ const serialNumber = this.serialNumber;
179
+ const firmwareRevision = this.firmwareRevision;
184
180
 
185
- let manufacturer = this.manufacturer;
186
- let modelName = this.modelName;
187
- let serialNumber = this.serialNumber;
188
- let firmwareRevision = this.firmwareRevision;
189
-
190
- this.accessory.removeService(this.accessory.getService(Service.AccessoryInformation));
181
+ accessory.removeService(accessory.getService(Service.AccessoryInformation));
191
182
  const informationService = new Service.AccessoryInformation();
192
183
  informationService
193
- .setCharacteristic(Characteristic.Name, this.name)
184
+ .setCharacteristic(Characteristic.Name, accessoryName)
194
185
  .setCharacteristic(Characteristic.Manufacturer, manufacturer)
195
186
  .setCharacteristic(Characteristic.Model, modelName)
196
187
  .setCharacteristic(Characteristic.SerialNumber, serialNumber)
197
188
  .setCharacteristic(Characteristic.FirmwareRevision, firmwareRevision);
198
189
 
199
- this.accessory.addService(informationService);
200
- }
201
-
202
- //Prepare service
203
- preparetasmotaService() {
204
- this.log.debug('preparetasmotaService');
205
- if (this.deviceDataOK) {
206
- this.tasmotaService = new Service.Outlet(this.name, 'tasmotaService');
207
- this.tasmotaService.getCharacteristic(Characteristic.On)
208
- .on('get', (callback) => {
209
- let state = this.relayState;
210
- this.log.info('Device: %s, state: %s', this.name, state ? 'ON' : 'OFF');
211
- callback(null, state);
190
+ accessory.addService(informationService);
191
+
192
+ //Prepare service
193
+ this.log.debug('prepareTasmotaService');
194
+ this.tasmotaServices = new Array();
195
+ for (let i = 0; i < this.channelsCount; i++) {
196
+ const tasmotaService = new Service.Outlet(accessoryName, `tasmotaService${[i]}`);
197
+ tasmotaService.getCharacteristic(Characteristic.On)
198
+ .onGet(async () => {
199
+ const channel = this.channelsCount == 1 ? 'POWER' : 'POWER' + i;
200
+ const response = await this.axiosInstance(channel);
201
+ const state = (response.data[channel] != undefined) ? (response.data[channel] == 'ON') : false;
202
+ const logInfo = this.disableLogInfo ? false : this.log('Device: %s, get state: %s', accessoryName, state ? 'ON' : 'OFF');
203
+ return state;
212
204
  })
213
- .on('set', (value, callback) => {
214
- let state = value ? POWERON : POWEROFF;
215
- request(this.url + state);
216
- this.log.info('Device: %s, state: %s', this.name, state ? 'ON' : 'OFF');
217
- callback(null);
205
+ .onSet(async (state) => {
206
+ const powerOn = this.channelsCount == 1 ? POWER + ON : POWER + (i + 1) + ON;
207
+ const powerOff = this.channelsCount == 1 ? POWER + OFF : POWER + (i + 1) + OFF;
208
+ state = state ? powerOn : powerOff;
209
+ this.axiosInstance(state);
210
+ const logInfo = this.disableLogInfo ? false : this.log('Device: %s, set state: %s', accessoryName, state ? 'ON' : 'OFF');
218
211
  });
219
- this.accessory.addService(this.tasmotaService);
212
+ tasmotaService.getCharacteristic(Characteristic.OutletInUse)
213
+ .onGet(async () => {
214
+ const channel = this.channelsCount == 1 ? 'POWER' : 'POWER' + i;
215
+ const response = await this.axiosInstance(channel);
216
+ const state = (response.data[channel] != undefined) ? (response.data[channel] == 'ON') : false;
217
+ const logInfo = this.disableLogInfo ? false : this.log('Device: %s, in use: %s', accessoryName, state ? 'YES' : 'NO');
218
+ return state;
219
+ });
220
+ this.tasmotaServices.push(tasmotaService);
221
+ accessory.addService(this.tasmotaServices[i]);
220
222
  }
223
+
224
+ this.startPrepareAccessory = false;
225
+ this.log.debug('Device: %s %s, publishExternalAccessories.', this.host, accessoryName);
226
+ this.api.publishExternalAccessories(PLUGIN_NAME, [accessory]);
221
227
  }
222
228
  }
package/package.json CHANGED
@@ -1,49 +1,46 @@
1
1
  {
2
- "displayName": "Tasmota Contol",
3
- "name": "homebridge-tasmota-control",
4
- "version": "0.0.29",
5
- "description": "Homebridge plugin (https://github.com/homebridge/homebridge) to control Tasmota devices.",
6
- "license": "MIT",
7
- "author": "grzegorz914",
8
- "homepage": "https://github.com/grzegorz914/homebridge-tasmota-control#readme",
9
- "repository": {
10
- "type": "git",
11
- "url": "git+https://github.com/grzegorz914/homebridge-tasmota-control.git"
12
- },
13
- "bugs": {
14
- "url": "https://github.com/grzegorz914/homebridge-tasmota-control/issues"
15
- },
16
- "funding": {
17
- "type": "paypal",
18
- "url": "https://paypal.me/GrzegorzKaczor"
19
- },
20
- "main": "index.js",
21
- "files": [
22
- "index.js",
23
- "config.schema.json",
24
- "package.json",
25
- "CHANGELOG.md",
26
- "README.md",
27
- "LICENSE"
28
- ],
29
- "engines": {
30
- "node": ">=12.0.0",
31
- "homebridge": ">=1.1.7"
32
- },
33
- "dependencies": {
34
- "axios": "^0.21.1",
35
- "request": "^2.88.2"
36
- },
37
- "keywords": [
38
- "homebridge",
39
- "homebridge-plugin",
40
- "homebridge-tasmota-control",
41
- "tasmota",
42
- "tasmotaControl"
43
- ],
44
- "contributors": [],
45
- "devDependencies": {},
46
- "scripts": {
47
- "test": "echo \"Error: no test specified\" && exit 1"
48
- }
2
+ "displayName": "Tasmota Control",
3
+ "name": "homebridge-tasmota-control",
4
+ "version": "0.3.36",
5
+ "description": "Homebridge plugin (https://github.com/homebridge/homebridge) to control Tasmota flashed devices.",
6
+ "license": "MIT",
7
+ "author": "grzegorz914",
8
+ "homepage": "https://github.com/grzegorz914/homebridge-tasmota-control#readme",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/grzegorz914/homebridge-tasmota-control.git"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/grzegorz914/homebridge-tasmota-control/issues"
15
+ },
16
+ "funding": {
17
+ "type": "paypal",
18
+ "url": "https://paypal.me/GrzegorzKaczor"
19
+ },
20
+ "main": "index.js",
21
+ "files": [
22
+ "index.js",
23
+ "config.schema.json",
24
+ "package.json",
25
+ "CHANGELOG.md",
26
+ "README.md",
27
+ "LICENSE"
28
+ ],
29
+ "engines": {
30
+ "node": ">=12.0.0",
31
+ "homebridge": ">=1.3.0"
32
+ },
33
+ "dependencies": {
34
+ "axios": ">=0.24.0"
35
+ },
36
+ "keywords": [
37
+ "homebridge",
38
+ "homebridge-plugin",
39
+ "homekit",
40
+ "tasmota"
41
+ ],
42
+ "contributors": [],
43
+ "scripts": {
44
+ "test": "echo \"Error: no test specified\" && exit 1"
45
+ }
49
46
  }