update documentation

This commit is contained in:
KarstenSiedentopp
2018-11-26 16:31:09 +01:00
parent e1be123c0a
commit d6f4df3e97
4 changed files with 35 additions and 253 deletions

179
README.md
View File

@@ -1,18 +1,16 @@
# openhab2 nodejs-tuyaapi
Openhab interface for Tuya home automation devices sold under various names.
This is a wrapper script for codetheweb/tuyapi. https://github.com/codetheweb/tuyapi
# TuyaAPI-MQTT Client
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
Its based on the exec-binding https://www.openhab.org/addons/bindings/exec/
Many thangs to https://github.com/unparagoned/njsTuya for the inspirations
This project provides an MQTT client for communication with the home automation devices.
## Instructions:
Download this project to your openhab2-script-folder "/etc/openhab2/scripts" and install tuyapi from the same folder that the tuya.js is in
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
```
cd /etc/openhab2/scripts
git clone git@github.com:codetheweb/tuyapi.git //or download
cd tuyaapi_openhab
git clone git@github.com:TheAgentK/tuyaapi_mqtt.git // this project
cd tuyaapi_mqtt
npm install //downloads codetheweb/tuyapi
```
@@ -20,158 +18,51 @@ Ignore all Warnings.
This involves MIM of the connection. Instructions can be found here: https://github.com/codetheweb/tuyapi/blob/master/docs/SETUP.md
Commands are
Start command
```
node tuya.js --ip=DEVICEIP --id=DEVICEID --key=DEVICEKEY COMMAND
--> Commands are ON, OFF, TOGGLE, STATE
node tuya-mqtt.js
e.g.
node tuya.js --ip=10.0.0.2 --id=213klj349sdfjl324po32 --key=342kljerw98 ON
// For debugging purpose
DEBUG=* tuya-mqtt.js
```
MQTT Topic
```
Current device state:
tuya/<tuyaAPI-type>/<tuyaAPI-id>/<tuyaAPI-key>/<tuyaAPI-ip>/state
Change device state:
tuya/<tuyaAPI-type>/<tuyaAPI-id>/<tuyaAPI-key>/<tuyaAPI-ip>/command/<STATE>
Example:
tuya/<tuyaAPI-type>/<tuyaAPI-id>/<tuyaAPI-key>/<tuyaAPI-ip>/command/on
tuya/<tuyaAPI-type>/<tuyaAPI-id>/<tuyaAPI-key>/<tuyaAPI-ip>/command/off
Color for lightbulb
Example:
tuya/lightbulb/<tuyaAPI-id>/<tuyaAPI-key>/<tuyaAPI-ip>/color // Color as Payload as hexColor
```
All commands return the state of the switch.
#### Issues
There are some reliability issues with tuyapi. Latest changes changed the syntax but still getting error maybe at an even higher rate.
## Example things and items
All questions regarding the TuyaAPI please ask in the project https://github.com/codetheweb/tuyapi .
### Things
#### create things-file
```
Thing exec:command:tuya_switch "Tuya Gateway" @ "System" [
command="node /etc/openhab2/scripts/tuyaapi_openhab/tuya.js %2$s",
transform="REGEX((.*?))",
interval=0,
timeout=1,
autorun=true]
```
## Example items
#### create items-file
```
Group:Switch gTuya "Tuya devices"
Group gTuyaDetails "Tuya details"
Group gTuyaConfigs "Tuya configs"
Group gTuyaSwitches "Tuya switches"
Switch tuya_kitchen_coffeemachine_mqtt "Steckdose Kaffeemaschine" <socket> (Kitchen, gTuya, gTuyaSwitches, GAtAwayOff) ["Switchable"] {mqtt="<[broker:tuya/<tuyaAPI-type>/<tuyaAPI-id>/<tuyaAPI-key>/<tuyaAPI-ip>/state:state:default:.*], >[broker:tuya/<tuyaAPI-type>/<tuyaAPI-id>/<tuyaAPI-key>/<tuyaAPI-ip>/command/on:command:ON:true], >[broker:tuya/<tuyaAPI-type>/<tuyaAPI-id>/<tuyaAPI-key>/<tuyaAPI-ip>/command/off:command:OFF:false]"}
Switch tuya { channel="exec:command:tuya_switch:run" }
String tuya_Args { channel="exec:command:tuya_switch:input" }
String tuya_Out { channel="exec:command:tuya_switch:output" }
String tuya_kitchen_waterheater_config "--id=<devId> --key=<devKey> --ip=<devIp>" (gTuya, gTuyaConfigs) //Config for execution
String tuya_kitchen_waterheater_trigger "tuya_kitchen_coffeemachine_switch" (gTuya, gTuyaConfigs) //trigger other switch with name "tuya_kitchen_coffeemachine_switch"
Switch tuya_kitchen_waterheater_switch "Steckdose Wasserkocher" <socket> (Kitchen, gTuya, gTuyaSwitches) ["Switchable"]
String tuya_kitchen_coffeemachine_config "--id=<devId> --key=<devKey> --ip=<devIp>" (gTuya, gTuyaConfigs) //Config for execution
String tuya_kitchen_coffeemachine_trigger "tuya_kitchen_waterheater_switch" (gTuya, gTuyaConfigs) //trigger other switch with name "tuya_kitchen_waterheater_switch"
Switch tuya_kitchen_coffeemachine_switch "Steckdose Kaffeemaschine" <socket> (Kitchen, gTuya, gTuyaSwitches) ["Switchable"]
Switch tuya_livingroom_ledstrip_tv "LED Regal" <lightbulb> (LivingDining, Wohnzimmer, gTuya, gTuyaLights, GAtAwayOff) ["Lighting"] {mqtt="<[broker:tuya/lightbulb/<tuyaAPI-id>/<tuyaAPI-key>/<tuyaAPI-ip>/state:state:default:.*], >[broker:tuya/lightbulb/<tuyaAPI-id>/<tuyaAPI-key>/<tuyaAPI-ip>/command/on:command:ON:true], >[broker:tuya/lightbulb/<tuyaAPI-id>/<tuyaAPI-key>/<tuyaAPI-ip>/command/off:command:OFF:false]"}
```
#### create rules-file
copy the file from this project "openhab2/rules/tuya-switch.rules" to your openhab rules foulder "/etc/openhab2/rules/
**This Rule only works since openHAB 2.3.0 Build #1212. Before that the Member of trigger was not availabel.**
```
import java.util.concurrent.locks.ReentrantLock
val ReentrantLock locktuya = new ReentrantLock
var db = true
rule "Tuya switcher"
when
Member of gTuyaSwitches received command
then
var appName = "tuya.switch";
logInfo(appName, "Member " + triggeringItem.name + " changed to " + receivedCommand);
try {
// Lock transmitter so other executed rules dont't use it at the same time.
// Concurrent calls of the rule will wait till the resource is free again.
locktuya.lock();
val name = triggeringItem.name.toString.split("_switch").get(0);
val config = name + "_config";
var relatedConfig = gTuyaConfigs.allMembers.filter [ conf | conf.name.contains(config.toString) ].head;
config = relatedConfig.label;
// send command to nodejs function
var args = config + " " + receivedCommand.toString;
tuya_Args.sendCommand(args);
// Wait for the command to complete
while(tuya.state != OFF){
Thread::sleep(100);
}
// Mulltiple trigger do not work if there is no break here
// maybe external skript needs some time to properly free resources.
Thread::sleep(400);
// Set related item
var trigger = name + "_trigger";
var relatedTrigger = gTuyaConfigs.allMembers.filter [ conf | conf.name.contains(trigger.toString) ].head;
if(relatedTrigger != null){
var triggerItem = gTuyaSwitches.allMembers.filter [ conf | conf.name.contains(relatedTrigger.label.toString) ].head;
logInfo(appName, "Triggered: " + triggerItem.name.toString);
triggerItem.postUpdate(receivedCommand);
}
var output = tuya_Out.state.toString.replaceAll("\r|\n"," ");
if(output != "ON" && output != "OFF"){
logError(appName, "State changed to " + output)
} else {
logInfo(appName, "State changed to " + output)
}
}catch(Throwable t) {
logInfo(appName, t);
}
finally {
// Free the resource for the next call.
locktuya.unlock()
}
end
```
Rules are also explained in the [tutorials](https://docs.openhab.org/tutorials/beginner/rules.html). Basic thing to get some action is tuya_Args.sendCommand(“--id=<devId> --key=<devKey> --ip=<devIp>”)” sending a command to the input channel. This will set the state of the item “tuya_Args to” “--id=<devId> --key=<devKey> --ip=<devIp>” and the autorun defined in the thing will cause an execution of the command line. While the thing is in action the state of the item “tuya” will reflect this by beeing “ON”. After the command is executed the item tuya_Out will contain the last return value of the executed command.
```
rule "Tuya status cron"
when
Time cron "0 0/5 * * * ?"
then
var appName = "tuya.cron";
logInfo(appName, "Cron status update");
if(!locktuya.isLocked()){
locktuya.lock();
var titerator = gTuyaSwitches.members.iterator
while(titerator.hasNext){
val det = titerator.next
val config = det.name.toString.split("_switch").get(0) + "_config";
var relatedConfig = gTuyaConfigs.allMembers.filter [ conf | conf.name.contains(config.toString) ].head;
config = relatedConfig.label;
var args = config + " now";
var output = executeCommandLine("node /etc/openhab2/scripts/tuyaapi_openhab/tuya.js " + args, 5000);
det.postUpdate(output);
if(output != "ON" && output != "OFF"){
logError(appName, "State changed to " + output)
} else {
logInfo(appName, "State changed to " + output)
}
if(db) { logInfo(appName, "Update [{}]", args)}
}
locktuya.unlock()
}
end
```
Time-based rule get the current state of the switch and set it manualy in openhab. This rule triggers every 5 minutes
## Useage
### Basic UI sitemap
```
Switch item=tuya_kitchen_waterheater_switch mappings=[ON="On", OFF="Off"]
Switch item=tuya_kitchen_coffeemachine_switch mappings=[ON="On", OFF="Off"]
Switch item=tuya_kitchen_coffeemachine_mqtt mappings=[ON="On", OFF="Off"]
Switch item=tuya_livingroom_ledstrip_tv mappings=[ON="On", OFF="Off"]
```
## Related Projects:

View File

@@ -1,16 +0,0 @@
Group:Switch gTuya "Tuya devices"
Group gTuyaDetails "Tuya details"
Group gTuyaConfigs "Tuya configs"
Group gTuyaSwitches "Tuya switches"
Switch tuya { channel="exec:command:tuya_switch:run" }
String tuya_Args { channel="exec:command:tuya_switch:input" }
String tuya_Out { channel="exec:command:tuya_switch:output" }
String tuya_kitchen_waterheater_config "--id=<devId> --key=<devKey> --ip=<devIp>" (gTuya, gTuyaConfigs) //Config for execution
String tuya_kitchen_waterheater_trigger "tuya_kitchen_coffeemachine_switch" (gTuya, gTuyaConfigs) //trigger other switch with name "tuya_kitchen_coffeemachine_switch"
Switch tuya_kitchen_waterheater_switch "Steckdose Wasserkocher" <socket> (Kitchen, gTuya, gTuyaSwitches) ["Switchable"]
String tuya_kitchen_coffeemachine_config "--id=<devId> --key=<devKey> --ip=<devIp>" (gTuya, gTuyaConfigs) //Config for execution
String tuya_kitchen_coffeemachine_trigger "tuya_kitchen_waterheater_switch" (gTuya, gTuyaConfigs) //trigger other switch with name "tuya_kitchen_waterheater_switch"
Switch tuya_kitchen_coffeemachine_switch "Steckdose Kaffeemaschine" <socket> (Kitchen, gTuya, gTuyaSwitches) ["Switchable"]

View File

@@ -1,87 +0,0 @@
import java.util.concurrent.locks.ReentrantLock
val ReentrantLock locktuya = new ReentrantLock
var db = true
rule "Tuya switcher"
when
Member of gTuyaSwitches received command
then
var appName = "tuya.switch";
logInfo(appName, "Member " + triggeringItem.name + " changed to " + receivedCommand);
try {
// Lock transmitter so other executed rules dont't use it at the same time.
// Concurrent calls of the rule will wait till the resource is free again.
locktuya.lock();
val name = triggeringItem.name.toString.split("_switch").get(0);
val config = name + "_config";
var relatedConfig = gTuyaConfigs.allMembers.filter [ conf | conf.name.contains(config.toString) ].head;
config = relatedConfig.label;
var args = config + " " + receivedCommand.toString;
tuya_Args.sendCommand(args);
// Wait for the command to complete
while(tuya.state != OFF){
Thread::sleep(100);
}
// Mulltiple trigger do not work if there is no break here
// maybe external skript needs some time to properly free resources.
Thread::sleep(400);
// Set related item
var trigger = name + "_trigger";
var relatedTrigger = gTuyaConfigs.allMembers.filter [ conf | conf.name.contains(trigger.toString) ].head;
if(relatedTrigger != null){
var triggerItem = gTuyaSwitches.allMembers.filter [ conf | conf.name.contains(relatedTrigger.label.toString) ].head;
logInfo(appName, "Triggered: " + triggerItem.name.toString);
triggerItem.postUpdate(receivedCommand);
}
var output = tuya_Out.state.toString.replaceAll("\r|\n"," ");
if(output != "ON" && output != "OFF"){
logError(appName, "State changed to " + output)
} else {
logInfo(appName, "State changed to " + output)
}
}catch(Throwable t) {
logInfo(appName, t);
}
finally {
// Free the resource for the next call.
locktuya.unlock()
}
end
rule "Tuya status cron"
when
Time cron "0 0/5 * * * ?"
then
var appName = "tuya.cron";
logInfo(appName, "Cron status update");
if(!locktuya.isLocked()){
locktuya.lock();
var titerator = gTuyaSwitches.members.iterator
while(titerator.hasNext){
val det = titerator.next
val config = det.name.toString.split("_switch").get(0) + "_config";
var relatedConfig = gTuyaConfigs.allMembers.filter [ conf | conf.name.contains(config.toString) ].head;
config = relatedConfig.label;
var args = config + " now";
var output = executeCommandLine("node /etc/openhab2/scripts/tuyaapi_openhab/tuya.js " + args, 5000);
det.postUpdate(output);
if(output != "ON" && output != "OFF"){
logError(appName, "State changed to " + output)
} else {
logInfo(appName, "State changed to " + output)
}
if(db) { logInfo(appName, "Update [{}]", args)}
}
locktuya.unlock()
}
end

View File

@@ -1,6 +0,0 @@
Thing exec:command:tuya_switch "Tuya Gateway" @ "System" [
command="node /etc/openhab2/scripts/tuyaapi_openhab/tuya.js %2$s",
transform="REGEX((.*?))",
interval=0,
timeout=1,
autorun=true]