mirror of
https://github.com/lehanspb/tuya-mqtt.git
synced 2025-12-16 09:44:36 +00:00
Release 2.1.0
* Merge protocol 3.3 support * Update TuyAPI to 5.3.1 * Fixes for color settings issues with some devices * Support to force device status update with schema query
This commit is contained in:
14
CHANGELOG.md
14
CHANGELOG.md
@@ -3,12 +3,22 @@ All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
|
||||
## [Unreleased]
|
||||
## [2.1.0]
|
||||
### Added
|
||||
- Added ability to update validate communicaton with device and update state topic by issuing { "schema": true } command
|
||||
- Added support for protocol 3.3 either via automatic device discovery or manual specification when using IP address
|
||||
|
||||
### Changed
|
||||
- Can specify "discover" instead of IP address to automatically find device (only works if device on same IP subnet as system running this script). This mode will also automatically detect 3.1 and 3.3 protocol devices
|
||||
- Can manually specific protocol via ver3.1/ver3.3 in topic line after tuya/
|
||||
- Bump Tuyapi version to v5.3.x
|
||||
- Bump MQTT version to v4.x.x
|
||||
- Moved openHAB config to it's own document since many users use this with other tools
|
||||
- Verious other fixes and cleanups
|
||||
|
||||
## [2.0.1]
|
||||
### Added
|
||||
- Added capability to set multiple dps values over MQTT-Command
|
||||
-
|
||||
- Custom Set-Function for TuyAPI-Class (added error handling for "index [1] not found" error)
|
||||
|
||||
### Changed
|
||||
|
||||
184
README.md
184
README.md
@@ -2,29 +2,17 @@
|
||||
MQTT interface for Tuya home automation devices sold under various names.
|
||||
This is a wrapper script for the Project codetheweb/tuyapi. https://github.com/codetheweb/tuyapi
|
||||
|
||||
This project provides an MQTT client for communication with the home automation devices.
|
||||
|
||||
:exclamation: There is a greate Step-By-Step guide from user HolgiHab at openhab community ([Step-By-Step Guide](
|
||||
https://community.openhab.org/t/step-by-step-guide-for-adding-tuya-bulbs-smart-life-to-oh2-using-tuya-mqtt-js-by-agentk/59371)). This guide is not only for light bulbs, but also applies to sockets. :exclamation:
|
||||
|
||||
:exclamation: This branch of tuya-mqtt provides initial support for Tuya devices using firmware that implements the 3.3 tuya protocol (fully encrypted communications). Because tuyapi requires specifying the protocol version when the device IP is specified directly, this required modifications to the script to either support setting the protocol version, or use the tuyapi auto discovery function. This code attempts to implement the minimum changes required to provide support for this protcol via a simple implementation of automatic device discovery.
|
||||
|
||||
To support this it is now possible replace the IP address in the topic (tuyAPI-key) with the word "discover" which will trigger the script to use the automatic device discovery capability. This has the added advantage that, if the IP of the device changes, no changes are required to the topic. To use automatic IP discovery the format of the topics are as follows:
|
||||
|
||||
```
|
||||
tuya/<tuyAPI-id>/<tuyAPI-key>/discover/state
|
||||
tuya/<tuyAPI-id>/<tuyAPI-key>/discover/command
|
||||
```
|
||||
:exclamation:
|
||||
This project provides an MQTT gateway for locally controlling home automation devices made by Tuya Inc. To use this script you will need to obtain the device ID and local keys for each of your devices after they are configured via the Tuya/Smart Life or other Tuya compatible app (there are many). With this information it is possible to communicate locally with Tuya devices using protocol 3.1 and 3.3, without using the Tuya Cloud service, however, getting the keys requires signing up for a Tuya IOT developer account or using one of several other alternative methods (such as dumping the memory of a Tuya based app running on Andriod). Acquiring keys is not part of this project, please see the instructions at the TuyAPI project (on which this script is based) available at https://github.com/codetheweb/tuyapi/blob/master/docs/SETUP.md.
|
||||
|
||||
## Instructions:
|
||||
|
||||
Download this project to your openhab2-script-folder "/etc/openhab2/scripts" and install tuyapi from the same folder that the tuya-mqtt.js is in
|
||||
Download this project to your system into any directory (example below uses /opt/tuya-mqtt) and install tuyapi from the same folder that the tuya-mqtt.js is in
|
||||
```
|
||||
cd /etc/openhab2/scripts
|
||||
// switch to opt directory
|
||||
cd /opt
|
||||
|
||||
// clone this project
|
||||
git clone git@github.com:TheAgentK/tuya-mqtt.git
|
||||
git clone https://github.com/TheAgentK/tuya-mqtt
|
||||
|
||||
// change directory to the project directory
|
||||
cd tuya-mqtt
|
||||
@@ -33,7 +21,7 @@ cd tuya-mqtt
|
||||
npm install
|
||||
```
|
||||
|
||||
See the setup instructions found here: https://github.com/codetheweb/tuyapi/blob/master/docs/SETUP.md
|
||||
This found here: https://github.com/codetheweb/tuyapi/blob/master/docs/SETUP.md
|
||||
|
||||
|
||||
## Basic Usage
|
||||
@@ -64,16 +52,18 @@ Set DEBUG=* & node c:/openhab2/userdata/etc/scripts/tuya-mqtt.js
|
||||
// on Windows machines at the cmd.exe command prompt, to turn OFF DEBUG:
|
||||
Set DEBUG=-* & node c:/openhab2/userdata/etc/scripts/tuya-mqtt.js
|
||||
```
|
||||
URL to install [DEBUG](https://www.npmjs.com/package/debug)
|
||||
|
||||
|
||||
|
||||
### MQTT Topic's (send data)
|
||||
|
||||
**-----IMPORTANT NOTE-----**
|
||||
|
||||
**It's possible to replace the device IP address \<tuyAPI-ip\> with the word "discover" to have the API attempt to automatically discover the device IP address. This capability allows support for 3.3 protocol devices without additional configuraiton but does require the system running this script to be on the same IP subnet as the Tuya device because discover relies on UDP broadcast from the devices.**
|
||||
|
||||
```
|
||||
tuya/<tuyAPI-id>/<tuyAPI-key>/discover/state
|
||||
tuya/<tuyAPI-id>/<tuyAPI-key>/discover/command
|
||||
```
|
||||
If discovery will not work for your case you can still use the IP address, but, to use protocol 3.3 you must specify it in the topic explicitly
|
||||
```
|
||||
tuya/ver3.3/<tuyAPI-id>/<tuyAPI-key>/<tuyAPI-ip/state
|
||||
tuya/ver3.3/<tuyAPI-id>/<tuyAPI-key>/<tuyAPI-ip>/command
|
||||
```
|
||||
Change device state (by topic):
|
||||
tuya/<tuyAPI-id>/<tuyAPI-key>/<tuyAPI-ip>/command/<STATE>
|
||||
@@ -139,150 +129,10 @@ Device DPS-Values:
|
||||
```
|
||||
|
||||
## Issues
|
||||
There are some reliability issues with tuyapi. Latest changes changed the syntax but still getting error maybe at an even higher rate.
|
||||
Not all Tuya protocols are supported. For example, some devices use protocol 3.2 which currently remains unsupported by the TuyAPI project due to lack of enough information to reverse engineer the protcol. If you are unable to control your devices with tuya-mqtt please verify that you can query and control them with tuya-cli first. If tuya-cli works, then this script should also work, if it doesn't then this script will not work either.
|
||||
|
||||
All questions regarding the tuyAPI please ask in the project https://github.com/codetheweb/tuyapi .
|
||||
|
||||
|
||||
## Example items for OpenHAB 1.x Bindings (still works with OH > 2.4 but only if legacy 1.x MQTT bindings are enabled)
|
||||
### simple switch on/off
|
||||
```
|
||||
|
||||
Switch tuya_kitchen_coffeemachine_mqtt "Steckdose Kaffeemaschine" <socket> (<GROUPS>) ["Switchable"] {
|
||||
mqtt="<[broker:tuya/<tuyAPI-id>/<tuyAPI-key>/<tuyAPI-ip>/state:state:default:.*],
|
||||
>[broker:tuya/<tuyAPI-id>/<tuyAPI-key>/<tuyAPI-ip>/command/on:command:ON:true],
|
||||
>[broker:tuya/<tuyAPI-id>/<tuyAPI-key>/<tuyAPI-ip>/command/off:command:OFF:false]"
|
||||
}
|
||||
|
||||
Switch tuya_livingroom_ledstrip_tv "LED Regal" <lightbulb> (<GROUPS>) ["Lighting"] {
|
||||
mqtt="<[broker:tuya/<tuyAPI-id>/<tuyAPI-key>/<tuyAPI-ip>/state:state:default:.*],
|
||||
>[broker:tuya/<tuyAPI-id>/<tuyAPI-key>/<tuyAPI-ip>/command/on:command:ON:true],
|
||||
>[broker:tuya/<tuyAPI-id>/<tuyAPI-key>/<tuyAPI-ip>/command/off:command:OFF:false]"
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### change color of lightbulb
|
||||
```
|
||||
|
||||
# .items
|
||||
Group gTuyaLivingColor "Tuya color group" <lightbulb>
|
||||
Color tuya_livingroom_colorpicker "Stehlampe farbe" (LivingDining)
|
||||
|
||||
String tuya_livingroom_ledstrip_tv_color "Set color [%s]" (gTuyaLivingColor, LivingDining) {
|
||||
mqtt=">[broker:tuya/<tuyAPI-id>/<tuyAPI-key>/<tuyAPI-ip>/color:command:*:default]"
|
||||
}
|
||||
|
||||
|
||||
|
||||
# .rules
|
||||
import org.openhab.core.library.types.HSBType;
|
||||
|
||||
rule "Set HSB value of item RGBLed to RGB color value"
|
||||
when
|
||||
Item tuya_livingroom_colorpicker received command
|
||||
then
|
||||
var appName = "Colorpicker.livingroom"
|
||||
var color = receivedCommand.toString;
|
||||
|
||||
// get all colors and send it via mqtt if light ist enabled
|
||||
gTuyaLivingColor.members.forEach[ i |
|
||||
var name = i.name;
|
||||
var stateName = name.toString.split("_color").get(0);
|
||||
var stateItem = gTuyaLights.allMembers.filter [ conf | conf.name.contains(stateName.toString) ].head;
|
||||
|
||||
if(stateItem.state == ON){
|
||||
logInfo(appName, name + " change to color: " + color);
|
||||
i.sendCommand(color);
|
||||
Thread::sleep(400);
|
||||
}
|
||||
]
|
||||
end
|
||||
|
||||
```
|
||||
|
||||
## Example items for OpenHAB 2.4 Bindings
|
||||
### simple switch on/off
|
||||
|
||||
With OpenHAB 2.X MQTT bindings you can add devices using a generic MQTT Thing via PaperUI or
|
||||
configuration files. For PaperUI simply at the generic MQTT Thing and set the state and
|
||||
command topics as follows:
|
||||
```
|
||||
|
||||
tuya/<tuyAPI-id>/<tuyAPI-key>/<tuyAPI-ip>/state
|
||||
|
||||
tuya/<tuyAPI-id>/<tuyAPI-key>/<tuyAPI-ip>/command
|
||||
|
||||
```
|
||||
|
||||
If you prefer using configuration files vs PaperUI, it should look something like this:
|
||||
See also OpenHAB 2.X MQTT binding [documentation](https://www.openhab.org/v2.4/addons/bindings/mqtt.generic/)
|
||||
|
||||
```
|
||||
|
||||
Bridge mqtt:broker:myUnsecureBroker [ host="localhost", secure=false ]
|
||||
{
|
||||
|
||||
Thing mqtt:topic:myCustomMQTT {
|
||||
Channels:
|
||||
Type switch : tuya_kitchen_coffeemachine_mqtt_channel "Kitchen Coffee Machine MQTT Channel" [
|
||||
stateTopic="tuya/<tuyAPI-id>/<tuyAPI-key>/<tuyAPI-ip>/state",
|
||||
commandTopic="tuya/<tuyAPI-id>/<tuyAPI-key>/<tuyAPI-ip>/command",
|
||||
|
||||
// optional custom mqtt-payloads for ON and OFF
|
||||
on="{ \"dps\": 1, \"set\": true }",
|
||||
off="0"
|
||||
]
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# *.item Example
|
||||
Switch tuya_kitchen_coffeemachine_mqtt "Kitchen Coffee Machine Switch" <socket> (gKitchen, gTuya) ["Switchable"] {
|
||||
channel="mqtt:topic:myUnsecureBroker:myCustomMQTT:tuya_kitchen_coffeemachine_mqtt_channel"
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
For one RGB bulb you would need a separate channel with the command topic set to
|
||||
`tuya/<tuyAPI-id>/<tuyAPI-key>/<tuyAPI-ip>/color` and link that to your color item.
|
||||
|
||||
```
|
||||
|
||||
Bridge mqtt:broker:myUnsecureBroker [ host="localhost", secure=false ]
|
||||
{
|
||||
Thing mqtt:topic:myCustomMQTT {
|
||||
Channels:
|
||||
Type colorHSB : livingroom_floorlamp_1_color "Livingroom floorlamp color MQTT Channel" [
|
||||
stateTopic="tuya/05200399bcddc2e02ec9/b58cf92e8bc5c899/192.168.178.49/state",
|
||||
commandTopic="tuya/05200399bcddc2e02ec9/b58cf92e8bc5c899/192.168.178.49/color"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
# *.item Example
|
||||
Color tuya_livingroom_colorpicker "Floorlamp colorpicker" (gLivingroom){
|
||||
channel="mqtt:topic:myUnsecureBroker:myCustomMQTT:livingroom_floorlamp_1_color"
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
#### Basic UI sitemap
|
||||
```
|
||||
|
||||
Switch item=tuya_kitchen_coffeemachine_mqtt
|
||||
|
||||
# turn the color bulb off or on
|
||||
Switch item=tuya_livingroom_colorpicker label="RGB lamp [%s]"
|
||||
|
||||
# pick the color level to send to the color bulb via MQTT color Channel
|
||||
Slider item=tuya_livingroom_colorpicker label="RGB lamp level [%s]" minValue=0 maxValue=100 step=1
|
||||
|
||||
# color picked and sent via MQTT Color channel
|
||||
Colorpicker item=tuya_livingroom_colorpicker label="RGB lamp color [%s]" icon="colorpicker" sendFrequency=30000
|
||||
|
||||
|
||||
```
|
||||
## Integration with other tools
|
||||
openHAB examples are (here)[docs/openHAB.md].
|
||||
|
||||
## Contributors
|
||||
- [TheAgentK](https://github.com/TheAgentK)
|
||||
|
||||
142
docs/openHAB.md
Normal file
142
docs/openHAB.md
Normal file
@@ -0,0 +1,142 @@
|
||||
:exclamation: There is a greate Step-By-Step guide from user HolgiHab at openhab community ([Step-By-Step Guide](
|
||||
https://community.openhab.org/t/step-by-step-guide-for-adding-tuya-bulbs-smart-life-to-oh2-using-tuya-mqtt-js-by-agentk/59371)). This guide is not only for light bulbs, but also applies to sockets. :exclamation:
|
||||
|
||||
## Example items for OpenHAB 1.x Bindings (still works with OH > 2.4 but only if legacy 1.x MQTT bindings are enabled)
|
||||
### simple switch on/off
|
||||
```
|
||||
|
||||
Switch tuya_kitchen_coffeemachine_mqtt "Steckdose Kaffeemaschine" <socket> (<GROUPS>) ["Switchable"] {
|
||||
mqtt="<[broker:tuya/<tuyAPI-id>/<tuyAPI-key>/<tuyAPI-ip>/state:state:default:.*],
|
||||
>[broker:tuya/<tuyAPI-id>/<tuyAPI-key>/<tuyAPI-ip>/command/on:command:ON:true],
|
||||
>[broker:tuya/<tuyAPI-id>/<tuyAPI-key>/<tuyAPI-ip>/command/off:command:OFF:false]"
|
||||
}
|
||||
|
||||
Switch tuya_livingroom_ledstrip_tv "LED Regal" <lightbulb> (<GROUPS>) ["Lighting"] {
|
||||
mqtt="<[broker:tuya/<tuyAPI-id>/<tuyAPI-key>/<tuyAPI-ip>/state:state:default:.*],
|
||||
>[broker:tuya/<tuyAPI-id>/<tuyAPI-key>/<tuyAPI-ip>/command/on:command:ON:true],
|
||||
>[broker:tuya/<tuyAPI-id>/<tuyAPI-key>/<tuyAPI-ip>/command/off:command:OFF:false]"
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### change color of lightbulb
|
||||
```
|
||||
|
||||
# .items
|
||||
Group gTuyaLivingColor "Tuya color group" <lightbulb>
|
||||
Color tuya_livingroom_colorpicker "Stehlampe farbe" (LivingDining)
|
||||
|
||||
String tuya_livingroom_ledstrip_tv_color "Set color [%s]" (gTuyaLivingColor, LivingDining) {
|
||||
mqtt=">[broker:tuya/<tuyAPI-id>/<tuyAPI-key>/<tuyAPI-ip>/color:command:*:default]"
|
||||
}
|
||||
|
||||
|
||||
|
||||
# .rules
|
||||
import org.openhab.core.library.types.HSBType;
|
||||
|
||||
rule "Set HSB value of item RGBLed to RGB color value"
|
||||
when
|
||||
Item tuya_livingroom_colorpicker received command
|
||||
then
|
||||
var appName = "Colorpicker.livingroom"
|
||||
var color = receivedCommand.toString;
|
||||
|
||||
// get all colors and send it via mqtt if light ist enabled
|
||||
gTuyaLivingColor.members.forEach[ i |
|
||||
var name = i.name;
|
||||
var stateName = name.toString.split("_color").get(0);
|
||||
var stateItem = gTuyaLights.allMembers.filter [ conf | conf.name.contains(stateName.toString) ].head;
|
||||
|
||||
if(stateItem.state == ON){
|
||||
logInfo(appName, name + " change to color: " + color);
|
||||
i.sendCommand(color);
|
||||
Thread::sleep(400);
|
||||
}
|
||||
]
|
||||
end
|
||||
|
||||
```
|
||||
|
||||
## Example items for OpenHAB 2.4 Bindings
|
||||
### simple switch on/off
|
||||
|
||||
With OpenHAB 2.X MQTT bindings you can add devices using a generic MQTT Thing via PaperUI or
|
||||
configuration files. For PaperUI simply at the generic MQTT Thing and set the state and
|
||||
command topics as follows:
|
||||
```
|
||||
|
||||
tuya/<tuyAPI-id>/<tuyAPI-key>/<tuyAPI-ip>/state
|
||||
|
||||
tuya/<tuyAPI-id>/<tuyAPI-key>/<tuyAPI-ip>/command
|
||||
|
||||
```
|
||||
|
||||
If you prefer using configuration files vs PaperUI, it should look something like this:
|
||||
See also OpenHAB 2.X MQTT binding [documentation](https://www.openhab.org/v2.4/addons/bindings/mqtt.generic/)
|
||||
|
||||
```
|
||||
|
||||
Bridge mqtt:broker:myUnsecureBroker [ host="localhost", secure=false ]
|
||||
{
|
||||
|
||||
Thing mqtt:topic:myCustomMQTT {
|
||||
Channels:
|
||||
Type switch : tuya_kitchen_coffeemachine_mqtt_channel "Kitchen Coffee Machine MQTT Channel" [
|
||||
stateTopic="tuya/<tuyAPI-id>/<tuyAPI-key>/<tuyAPI-ip>/state",
|
||||
commandTopic="tuya/<tuyAPI-id>/<tuyAPI-key>/<tuyAPI-ip>/command",
|
||||
|
||||
// optional custom mqtt-payloads for ON and OFF
|
||||
on="{ \"dps\": 1, \"set\": true }",
|
||||
off="0"
|
||||
]
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# *.item Example
|
||||
Switch tuya_kitchen_coffeemachine_mqtt "Kitchen Coffee Machine Switch" <socket> (gKitchen, gTuya) ["Switchable"] {
|
||||
channel="mqtt:topic:myUnsecureBroker:myCustomMQTT:tuya_kitchen_coffeemachine_mqtt_channel"
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
For one RGB bulb you would need a separate channel with the command topic set to
|
||||
`tuya/<tuyAPI-id>/<tuyAPI-key>/<tuyAPI-ip>/color` and link that to your color item.
|
||||
|
||||
```
|
||||
|
||||
Bridge mqtt:broker:myUnsecureBroker [ host="localhost", secure=false ]
|
||||
{
|
||||
Thing mqtt:topic:myCustomMQTT {
|
||||
Channels:
|
||||
Type colorHSB : livingroom_floorlamp_1_color "Livingroom floorlamp color MQTT Channel" [
|
||||
stateTopic="tuya/05200399bcddc2e02ec9/b58cf92e8bc5c899/192.168.178.49/state",
|
||||
commandTopic="tuya/05200399bcddc2e02ec9/b58cf92e8bc5c899/192.168.178.49/color"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
# *.item Example
|
||||
Color tuya_livingroom_colorpicker "Floorlamp colorpicker" (gLivingroom){
|
||||
channel="mqtt:topic:myUnsecureBroker:myCustomMQTT:livingroom_floorlamp_1_color"
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
#### Basic UI sitemap
|
||||
```
|
||||
|
||||
Switch item=tuya_kitchen_coffeemachine_mqtt
|
||||
|
||||
# turn the color bulb off or on
|
||||
Switch item=tuya_livingroom_colorpicker label="RGB lamp [%s]"
|
||||
|
||||
# pick the color level to send to the color bulb via MQTT color Channel
|
||||
Slider item=tuya_livingroom_colorpicker label="RGB lamp level [%s]" minValue=0 maxValue=100 step=1
|
||||
|
||||
# color picked and sent via MQTT Color channel
|
||||
Colorpicker item=tuya_livingroom_colorpicker label="RGB lamp color [%s]" icon="colorpicker" sendFrequency=30000
|
||||
|
||||
|
||||
```
|
||||
279
package-lock.json
generated
279
package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "tuya-mqtt",
|
||||
"version": "2.0.1",
|
||||
"version": "2.1.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@@ -9,23 +9,36 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz",
|
||||
"integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA=="
|
||||
},
|
||||
"async-limiter": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
|
||||
"integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg=="
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
|
||||
},
|
||||
"base64-js": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
|
||||
"integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g=="
|
||||
},
|
||||
"bl": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz",
|
||||
"integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==",
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz",
|
||||
"integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==",
|
||||
"requires": {
|
||||
"readable-stream": "^2.3.5",
|
||||
"safe-buffer": "^5.1.1"
|
||||
"buffer": "^5.5.0",
|
||||
"inherits": "^2.0.4",
|
||||
"readable-stream": "^3.4.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"readable-stream": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
||||
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
|
||||
"requires": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"brace-expansion": {
|
||||
@@ -37,6 +50,15 @@
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"buffer": {
|
||||
"version": "5.6.0",
|
||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz",
|
||||
"integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==",
|
||||
"requires": {
|
||||
"base64-js": "^1.0.2",
|
||||
"ieee754": "^1.1.4"
|
||||
}
|
||||
},
|
||||
"buffer-from": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
|
||||
@@ -52,17 +74,17 @@
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"requires": {
|
||||
"color-name": "1.1.3"
|
||||
"color-name": "~1.1.4"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
},
|
||||
"commist": {
|
||||
"version": "1.1.0",
|
||||
@@ -104,9 +126,9 @@
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"version": "3.2.6",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
|
||||
"integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
|
||||
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
@@ -123,21 +145,21 @@
|
||||
}
|
||||
},
|
||||
"end-of-stream": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
|
||||
"integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
|
||||
"version": "1.4.4",
|
||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
|
||||
"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
|
||||
"requires": {
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"es5-ext": {
|
||||
"version": "0.10.50",
|
||||
"resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.50.tgz",
|
||||
"integrity": "sha512-KMzZTPBkeQV/JcSQhI5/z6d9VWJ3EnQ194USTUwIYZ2ZbpN8+SGXQKt1h68EX44+qt+Fzr8DO17vnxrw7c3agw==",
|
||||
"version": "0.10.53",
|
||||
"resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz",
|
||||
"integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==",
|
||||
"requires": {
|
||||
"es6-iterator": "~2.0.3",
|
||||
"es6-symbol": "~3.1.1",
|
||||
"next-tick": "^1.0.0"
|
||||
"es6-symbol": "~3.1.3",
|
||||
"next-tick": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"es6-iterator": {
|
||||
@@ -173,15 +195,26 @@
|
||||
"es6-iterator": "~2.0.1",
|
||||
"es6-symbol": "3.1.1",
|
||||
"event-emitter": "~0.3.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"es6-symbol": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz",
|
||||
"integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=",
|
||||
"requires": {
|
||||
"d": "1",
|
||||
"es5-ext": "~0.10.14"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"es6-symbol": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz",
|
||||
"integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=",
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
|
||||
"integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
|
||||
"requires": {
|
||||
"d": "1",
|
||||
"es5-ext": "~0.10.14"
|
||||
"d": "^1.0.1",
|
||||
"ext": "^1.1.2"
|
||||
}
|
||||
},
|
||||
"event-emitter": {
|
||||
@@ -193,6 +226,21 @@
|
||||
"es5-ext": "~0.10.14"
|
||||
}
|
||||
},
|
||||
"ext": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz",
|
||||
"integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==",
|
||||
"requires": {
|
||||
"type": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"type": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/type/-/type-2.1.0.tgz",
|
||||
"integrity": "sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"extend": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||
@@ -204,9 +252,9 @@
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.1.4",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
|
||||
"integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
|
||||
"version": "7.1.6",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
|
||||
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
@@ -253,6 +301,11 @@
|
||||
"xtend": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"ieee754": {
|
||||
"version": "1.1.13",
|
||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
|
||||
"integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg=="
|
||||
},
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
@@ -263,9 +316,9 @@
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"is-absolute": {
|
||||
"version": "1.0.0",
|
||||
@@ -339,40 +392,41 @@
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
||||
},
|
||||
"mqtt": {
|
||||
"version": "2.18.8",
|
||||
"resolved": "https://registry.npmjs.org/mqtt/-/mqtt-2.18.8.tgz",
|
||||
"integrity": "sha512-3h6oHlPY/yWwtC2J3geraYRtVVoRM6wdI+uchF4nvSSafXPZnaKqF8xnX+S22SU/FcgEAgockVIlOaAX3fkMpA==",
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/mqtt/-/mqtt-4.2.1.tgz",
|
||||
"integrity": "sha512-Iv893r+jWlo5GkNcPOfCGwW8M49IixwHiKLFFYTociEymSibUVCORVEjPXWPGzSxhn7BdlUeHicbRmWiv0Crkg==",
|
||||
"requires": {
|
||||
"base64-js": "^1.3.0",
|
||||
"commist": "^1.0.0",
|
||||
"concat-stream": "^1.6.2",
|
||||
"debug": "^4.1.1",
|
||||
"end-of-stream": "^1.4.1",
|
||||
"es6-map": "^0.1.5",
|
||||
"help-me": "^1.0.1",
|
||||
"inherits": "^2.0.3",
|
||||
"minimist": "^1.2.0",
|
||||
"mqtt-packet": "^5.6.0",
|
||||
"minimist": "^1.2.5",
|
||||
"mqtt-packet": "^6.3.2",
|
||||
"pump": "^3.0.0",
|
||||
"readable-stream": "^2.3.6",
|
||||
"reinterval": "^1.1.0",
|
||||
"split2": "^2.1.1",
|
||||
"websocket-stream": "^5.1.2",
|
||||
"split2": "^3.1.0",
|
||||
"ws": "^7.3.1",
|
||||
"xtend": "^4.0.1"
|
||||
}
|
||||
},
|
||||
"mqtt-packet": {
|
||||
"version": "5.6.1",
|
||||
"resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-5.6.1.tgz",
|
||||
"integrity": "sha512-eaF9rO2uFrIYEHomJxziuKTDkbWW5psLBaIGCazQSKqYsTaB3n4SpvJ1PexKaDBiPnMLPIFWBIiTYT3IfEJfww==",
|
||||
"version": "6.6.0",
|
||||
"resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-6.6.0.tgz",
|
||||
"integrity": "sha512-LvghnKMFC70hKWMVykmhJarlO5e7lT3t9s9A2qPCUx+lazL3Mq55U+eCV0eLi7/nRRQYvEUWo/2tTo89EjnCJQ==",
|
||||
"requires": {
|
||||
"bl": "^1.2.1",
|
||||
"inherits": "^2.0.3",
|
||||
"process-nextick-args": "^2.0.0",
|
||||
"safe-buffer": "^5.1.0"
|
||||
"bl": "^4.0.2",
|
||||
"debug": "^4.1.1",
|
||||
"process-nextick-args": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
@@ -407,18 +461,18 @@
|
||||
"integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4="
|
||||
},
|
||||
"p-retry": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.1.0.tgz",
|
||||
"integrity": "sha512-oepllyG9gX1qH4Sm20YAKxg1GA7L7puhvGnTfimi31P07zSIj7SDV6YtuAx9nbJF51DES+2CIIRkXs8GKqWJxA==",
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.2.0.tgz",
|
||||
"integrity": "sha512-jPH38/MRh263KKcq0wBNOGFJbm+U6784RilTmHjB/HM9kH9V8WlCpVUcdOmip9cjXOh6MxZ5yk1z2SjDUJfWmA==",
|
||||
"requires": {
|
||||
"@types/retry": "^0.12.0",
|
||||
"retry": "^0.12.0"
|
||||
}
|
||||
},
|
||||
"p-timeout": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.1.0.tgz",
|
||||
"integrity": "sha512-C27DYI+tCroT8J8cTEyySGydl2B7FlxrGNF5/wmMbl1V+jeehUCzEE/BVgzRebdm2K3ZitKOKx8YbdFumDyYmw==",
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz",
|
||||
"integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==",
|
||||
"requires": {
|
||||
"p-finally": "^1.0.0"
|
||||
}
|
||||
@@ -434,9 +488,9 @@
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
|
||||
"integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw=="
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
|
||||
},
|
||||
"pump": {
|
||||
"version": "3.0.0",
|
||||
@@ -469,9 +523,9 @@
|
||||
}
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"version": "2.3.7",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
|
||||
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
|
||||
"requires": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.3",
|
||||
@@ -503,17 +557,29 @@
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||
},
|
||||
"split2": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz",
|
||||
"integrity": "sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw==",
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz",
|
||||
"integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==",
|
||||
"requires": {
|
||||
"through2": "^2.0.2"
|
||||
"readable-stream": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"readable-stream": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
||||
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
|
||||
"requires": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"stream-shift": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz",
|
||||
"integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI="
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz",
|
||||
"integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ=="
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
@@ -551,40 +617,25 @@
|
||||
}
|
||||
},
|
||||
"tuyapi": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/tuyapi/-/tuyapi-5.1.1.tgz",
|
||||
"integrity": "sha512-CHcyGPDtOMNt4sUUxKSm1KbaciqrMCIswTTLbqh90UFBeEyDHIwhFR70fyNuF3ez4KwbTI2UjfqjQb7dAUCAVw==",
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/tuyapi/-/tuyapi-5.3.1.tgz",
|
||||
"integrity": "sha512-l0bbWxe4L8J7/bAQn0bJtBVbVDAEglC1T3a/YKYM3UvDXaKgFQUDVKhfQfHFAt0bzXVq1TeqU0zG4WIrxgiTHg==",
|
||||
"requires": {
|
||||
"debug": "4.1.1",
|
||||
"p-retry": "4.1.0",
|
||||
"p-timeout": "3.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
|
||||
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
}
|
||||
"p-retry": "4.2.0",
|
||||
"p-timeout": "3.2.0"
|
||||
}
|
||||
},
|
||||
"type": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/type/-/type-1.0.1.tgz",
|
||||
"integrity": "sha512-MAM5dBMJCJNKs9E7JXo4CXRAansRfG0nlJxW7Wf6GZzSOvH31zClSaHdIMWLehe/EGMBkqeC55rrkaOr5Oo7Nw=="
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
|
||||
"integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg=="
|
||||
},
|
||||
"typedarray": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
|
||||
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
|
||||
},
|
||||
"ultron": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz",
|
||||
"integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og=="
|
||||
},
|
||||
"unc-path-regex": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz",
|
||||
@@ -604,38 +655,20 @@
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
||||
},
|
||||
"websocket-stream": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/websocket-stream/-/websocket-stream-5.5.0.tgz",
|
||||
"integrity": "sha512-EXy/zXb9kNHI07TIMz1oIUIrPZxQRA8aeJ5XYg5ihV8K4kD1DuA+FY6R96HfdIHzlSzS8HiISAfrm+vVQkZBug==",
|
||||
"requires": {
|
||||
"duplexify": "^3.5.1",
|
||||
"inherits": "^2.0.1",
|
||||
"readable-stream": "^2.3.3",
|
||||
"safe-buffer": "^5.1.2",
|
||||
"ws": "^3.2.0",
|
||||
"xtend": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
},
|
||||
"ws": {
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz",
|
||||
"integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==",
|
||||
"requires": {
|
||||
"async-limiter": "~1.0.0",
|
||||
"safe-buffer": "~5.1.0",
|
||||
"ultron": "~1.1.0"
|
||||
}
|
||||
"version": "7.3.1",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz",
|
||||
"integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA=="
|
||||
},
|
||||
"xtend": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
|
||||
"integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68="
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
|
||||
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
12
package.json
12
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "tuya-mqtt",
|
||||
"version": "2.0.3",
|
||||
"description": "",
|
||||
"version": "2.1.0",
|
||||
"description": "Control Tuya devices locally via MQTT",
|
||||
"homepage": "https://github.com/TheAgentK/tuya-mqtt#readme",
|
||||
"main": "tuya-mqtt.js",
|
||||
"scripts": {
|
||||
@@ -9,14 +9,14 @@
|
||||
},
|
||||
"author": {
|
||||
"name": "TheAgentK",
|
||||
"email": "lulatsch22@googlemail.com"
|
||||
"email": "lulattsch22@googlemail.com"
|
||||
},
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"color-convert": "^1.9.3",
|
||||
"color-convert": "^2.0.1",
|
||||
"debug": "^4.1.1",
|
||||
"mqtt": "^3.0.0",
|
||||
"tuyapi": "^5.1.2"
|
||||
"mqtt": "^4.2.1",
|
||||
"tuyapi": "^5.3.1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
96
tuya-mqtt.js
96
tuya-mqtt.js
@@ -1,4 +1,3 @@
|
||||
'use strict'
|
||||
const mqtt = require('mqtt');
|
||||
const TuyaDevice = require('./tuya-device');
|
||||
const debug = require('debug')('TuyAPI:mqtt');
|
||||
@@ -147,70 +146,6 @@ function getCommandFromTopic(_topic, _message) {
|
||||
return command;
|
||||
}
|
||||
|
||||
mqtt_client.on('message', function (topic, message) {
|
||||
try {
|
||||
message = message.toString();
|
||||
var action = getActionFromTopic(topic);
|
||||
var options = getDeviceFromTopic(topic);
|
||||
|
||||
debug("receive settings", JSON.stringify({
|
||||
topic: topic,
|
||||
action: action,
|
||||
message: message,
|
||||
options: options
|
||||
}));
|
||||
|
||||
var device = new TuyaDevice(options);
|
||||
device.then(function (params) {
|
||||
var device = params.device;
|
||||
|
||||
switch (action) {
|
||||
case "command":
|
||||
var command = getCommandFromTopic(topic, message);
|
||||
debug("receive command", command);
|
||||
if (command == "toggle") {
|
||||
device.switch(command).then((data) => {
|
||||
debug("set device status completed", data);
|
||||
});
|
||||
}
|
||||
if (command.schema === true) {
|
||||
// this command is very useful. IT IS A COMMAND. It's place under the command topic.
|
||||
// It's the ONLY command that does not use device.set to get a result.
|
||||
// You have to use device.get and send the get method an exact JSON string of { schema: true }
|
||||
// This schema command does NOT
|
||||
// change the state of the device, all it does is query the device
|
||||
// as a confirmation that all communications are working properly.
|
||||
// Otherwise you have to physically change the state of the device just to
|
||||
// find out if you can talk to it. If this command returns no errors than
|
||||
// we know we are have an established communication channel. This is a native TuyAPI call that
|
||||
// the TuyAPI interface defines (its only available via the GET command.
|
||||
// this call returns a object of results
|
||||
device.schema(command).then((data) => {
|
||||
});
|
||||
debug("get (schema) device status completed");
|
||||
} else {
|
||||
device.set(command).then((data) => {
|
||||
debug("set device status completed", data);
|
||||
});
|
||||
}
|
||||
break;
|
||||
case "color":
|
||||
var color = message.toLowerCase();
|
||||
debugColor("set color: ", color);
|
||||
device.setColor(color).then((data) => {
|
||||
debug("set device color completed", data);
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
}).catch((err) => {
|
||||
debugError(err);
|
||||
});
|
||||
} catch (e) {
|
||||
debugError(e);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Publish current TuyaDevice state to MQTT-Topic
|
||||
* @param {TuyaDevice} device
|
||||
@@ -334,7 +269,7 @@ function sleep(sec) {
|
||||
return new Promise(res => setTimeout(res, sec*1000));
|
||||
}
|
||||
|
||||
// Main code loop
|
||||
// Main code function
|
||||
const main = async() => {
|
||||
|
||||
try {
|
||||
@@ -401,22 +336,28 @@ const main = async() => {
|
||||
switch (action) {
|
||||
case "command":
|
||||
var command = getCommandFromTopic(topic, message);
|
||||
debug("receive command", command);
|
||||
debug("Received command: ", command);
|
||||
if (command == "toggle") {
|
||||
device.switch(command).then((data) => {
|
||||
debug("set device status completed", data);
|
||||
debug("Set device status completed: ", data);
|
||||
});
|
||||
} else {
|
||||
}
|
||||
if (command.schema === true) {
|
||||
// Trigger device schema update to update state
|
||||
device.schema(command).then((data) => {
|
||||
});
|
||||
debug("Get schema status command complete");
|
||||
} else {
|
||||
device.set(command).then((data) => {
|
||||
debug("set device status completed", data);
|
||||
debug("Set device status completed: ", data);
|
||||
});
|
||||
}
|
||||
break;
|
||||
case "color":
|
||||
var color = message.toLowerCase();
|
||||
debugColor("set color: ", color);
|
||||
debugColor("Set color: ", color);
|
||||
device.setColor(color).then((data) => {
|
||||
debug("set device color completed", data);
|
||||
debug("Set device color completed: ", data);
|
||||
});
|
||||
break;
|
||||
}
|
||||
@@ -428,16 +369,7 @@ const main = async() => {
|
||||
debugError(e);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// Call the main code
|
||||
main()
|
||||
|
||||
/**
|
||||
* Function call on script exit
|
||||
*/
|
||||
function onExit() {
|
||||
TuyaDevice.disconnectAll();
|
||||
if (tester) tester.destroy();
|
||||
};
|
||||
main()
|
||||
Reference in New Issue
Block a user