homebridge-tasmota-control 0.0.28 → 0.3.35

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-outlet
@@ -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,16 +1,17 @@
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
- const PLATFORM_NAME = 'TasmotaControl';
14
+ const PLATFORM_NAME = 'tasmotaControl';
14
15
 
15
16
  let Accessory, Characteristic, Service, Categories, UUID;
16
17
 
@@ -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,167 @@ 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;
87
88
  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='
89
+ this.url = `http://${this.host}/cm?user=${this.user}&password=${this.passwd}&cmnd=`
90
90
 
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
- }
91
+ this.axiosInstance = axios.create({
92
+ method: 'GET',
93
+ baseURL: this.url,
94
+ timeout: 5000
95
+ });
95
96
 
96
97
  //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
- });
98
+ if (fs.existsSync(this.prefDir) == false) {
99
+ fsPromises.mkdir(this.prefDir);
105
100
  }
106
101
 
107
102
  //Check device state
108
103
  setInterval(function () {
109
104
  if (this.checkDeviceInfo) {
110
105
  this.getDeviceInfo();
111
- } else if (!this.checkDeviceInfo && this.checkDeviceState) {
106
+ }
107
+ if (this.checkDeviceState) {
112
108
  this.updateDeviceState();
113
109
  }
114
110
  }.bind(this), this.refreshInterval * 1000);
115
111
 
116
- this.getDeviceInfo()
112
+ //start prepare accessory
117
113
  }
118
114
 
119
115
  async getDeviceInfo() {
120
- var me = this;
116
+ this.log.debug('Device: %s %s, requesting Device Info.', this.host, this.name);
121
117
  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();
118
+ const response = await this.axiosInstance(STATUS);
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
+ this.updateDeviceState();
132
137
  } catch (error) {
133
- me.log.error('Device: %s, getDeviceInfo error: %s', me.name, error);
134
- me.checkDeviceInfo = true;
138
+ this.log.error('Device: %s %s, Device Info eror: %s, state: Offline, trying to reconnect', this.host, this.name, error);
139
+ this.checkDeviceInfo = true;
135
140
  }
136
141
  }
137
142
 
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');
143
+ async updateDeviceState() {
144
+ this.log.debug('Device: %s %s, requesting Device state.', this.host, this.name);
145
+ try {
146
+ for (let i = 0; i < this.channelsCount; i++) {
147
+ const channel = this.channelsCount == 1 ? 'POWER' : 'POWER' + i;
148
+ const response = await this.axiosInstance(channel);
149
+ const debug = this.enableDebugMode ? this.log('Device: %s %s, debug response: %s', this.host, this.name, response.data) : false;
150
+ const powerState = (response.data[channel] != undefined) ? (response.data[channel] == 'ON') : false;
151
+ if (this.tasmotaServices) {
152
+ this.tasmotaServices[i]
153
+ .updateCharacteristic(Characteristic.OutletInUse, powerState);
153
154
  }
154
- me.relayState = powerState;
155
- me.deviceDataOK = true;
156
155
  }
156
+ this.checkDeviceState = true;
157
157
 
158
- if (!me.checkDeviceState) {
159
- me.prepareAccessory();
158
+ if (this.startPrepareAccessory) {
159
+ this.prepareAccessory();
160
160
  }
161
- me.checkDeviceState = true;
162
- });
161
+ } catch (error) {
162
+ this.log.error('Device: %s %s, update Device state error: %s, state: Offline', this.host, this.name, error);
163
+ this.checkDeviceState = false;
164
+ this.checkDeviceInfo = true;
165
+ }
163
166
  }
164
167
 
165
168
  //Prepare accessory
166
169
  prepareAccessory() {
167
170
  this.log.debug('prepareAccessory');
168
171
  const accessoryName = this.name;
169
- const accessoryUUID = UUID.generate(accessoryName);
172
+ const accessoryUUID = UUID.generate(this.serialNumber);
170
173
  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
- }
174
+ const accessory = new Accessory(accessoryName, accessoryUUID, accessoryCategory);
179
175
 
180
- //Prepare information service
181
- prepareInformationService() {
176
+ //Prepare information service
182
177
  this.log.debug('prepareInformationService');
183
- this.getDeviceInfo();
178
+ const manufacturer = this.manufacturer;
179
+ const modelName = this.modelName;
180
+ const serialNumber = this.serialNumber;
181
+ const firmwareRevision = this.firmwareRevision;
184
182
 
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));
183
+ accessory.removeService(accessory.getService(Service.AccessoryInformation));
191
184
  const informationService = new Service.AccessoryInformation();
192
185
  informationService
193
- .setCharacteristic(Characteristic.Name, this.name)
186
+ .setCharacteristic(Characteristic.Name, accessoryName)
194
187
  .setCharacteristic(Characteristic.Manufacturer, manufacturer)
195
188
  .setCharacteristic(Characteristic.Model, modelName)
196
189
  .setCharacteristic(Characteristic.SerialNumber, serialNumber)
197
190
  .setCharacteristic(Characteristic.FirmwareRevision, firmwareRevision);
198
191
 
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);
192
+ accessory.addService(informationService);
193
+
194
+ //Prepare service
195
+ this.log.debug('prepareTasmotaService');
196
+ this.tasmotaServices = new Array();
197
+ for (let i = 0; i < this.channelsCount; i++) {
198
+ const tasmotaService = new Service.Outlet(accessoryName, `tasmotaService${[i]}`);
199
+ tasmotaService.getCharacteristic(Characteristic.On)
200
+ .onGet(async () => {
201
+ const channel = this.channelsCount == 1 ? 'POWER' : 'POWER' + i;
202
+ const response = await this.axiosInstance(channel);
203
+ const state = (response.data[channel] != undefined) ? (response.data[channel] == 'ON') : false;
204
+ const logInfo = this.disableLogInfo ? false : this.log('Device: %s, get state: %s', accessoryName, state ? 'ON' : 'OFF');
205
+ return state;
212
206
  })
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);
207
+ .onSet(async (state) => {
208
+ const powerOn = this.channelsCount == 1 ? POWER + ON : POWER + (i + 1) + ON;
209
+ const powerOff = this.channelsCount == 1 ? POWER + OFF : POWER + (i + 1) + OFF;
210
+ state = state ? powerOn : powerOff;
211
+ this.axiosInstance(state);
212
+ const logInfo = this.disableLogInfo ? false : this.log('Device: %s, set state: %s', accessoryName, state ? 'ON' : 'OFF');
218
213
  });
219
- this.accessory.addService(this.tasmotaService);
214
+ tasmotaService.getCharacteristic(Characteristic.OutletInUse)
215
+ .onGet(async () => {
216
+ const channel = this.channelsCount == 1 ? 'POWER' : 'POWER' + i;
217
+ const response = await this.axiosInstance(channel);
218
+ const state = (response.data[channel] != undefined) ? (response.data[channel] == 'ON') : false;
219
+ const logInfo = this.disableLogInfo ? false : this.log('Device: %s, in use: %s', accessoryName, state ? 'YES' : 'NO');
220
+ return state;
221
+ });
222
+ this.tasmotaServices.push(tasmotaService);
223
+ accessory.addService(this.tasmotaServices[i]);
220
224
  }
225
+
226
+ this.startPrepareAccessory = false;
227
+ this.log.debug('Device: %s %s, publishExternalAccessories.', this.host, accessoryName);
228
+ this.api.publishExternalAccessories(PLUGIN_NAME, [accessory]);
221
229
  }
222
230
  }
package/package.json CHANGED
@@ -1,49 +1,46 @@
1
1
  {
2
- "displayName": "Tasmota Contol",
3
- "name": "homebridge-tasmota-control",
4
- "version": "0.0.28",
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
- "gosund"
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.35",
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
  }