-
Notifications
You must be signed in to change notification settings - Fork 18
/
tuya-local.js
142 lines (125 loc) · 4.36 KB
/
tuya-local.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
const TuyaDev = require('tuyapi');
const {keyRename,getHumanTimeStamp,checkValidJSON,filterCommandByte} = require('./lib/utils');
module.exports = function(RED) {
function TuyaNode(config) {
RED.nodes.createNode(this,config);
var node = this;
var set_timeout = true
this.Name = config.devName;
this.Id = config.devId;
this.Key = config.devKey;
this.Ip = config.devIp;
this.version = config.protocolVer;
this.renameSchema = config.renameSchema;
this.filterCB = config.filterCB;
const dev_info = {name:this.Name,ip:this.Ip,id:this.Id};
const device = new TuyaDev({
id: this.Id,
key: this.Key,
ip: this.Ip,
version: this.version});
function connectToDevice(timeout,req) {
device.find({'options': {'timeout':timeout}}).then( () => {
node.status({fill:"yellow",shape:"dot",text:"connecting"});
node.log(req);
device.connect().then( () => {
}, (reason) => {
node.status({fill:"red",shape:"ring",text:"failed: " + reason});
});
});
}
function disconnectDevice(deleted) {
set_timeout = deleted ? false : true;
device.disconnect();
}
//
function setDevice(req) {
if ( req == "request" ) {
device.get({"schema":true});
} else if ( req == "connect" ) {
// node.log('Connection requested by input');
connectToDevice(10,'Connection requested by input for device: ' + this.Name );
} else if ( req == "disconnect" ) {
node.log("Disconnection requested by input for device: " + this.Name)
device.disconnect();
} else if (req == "toggle") {
device.toggle();
} else if ( typeof req == "boolean" ) {
device.set({set: req}).then( () => {
node.status({fill:"green",shape:"dot",text: 'set success at:' + getHumanTimeStamp()});
}, (reason) => {
node.status({fill:"red",shape:"dot",text: 'set state failed:' + reason});
});
} else if ( "dps" in req ) {
console.log(req)
device.set(req);
} else if ( "multiple" in req) {
device.set({
multiple:true,
data: req.data
});
}
}
connectToDevice(10,'Deploy connection request for device ' + this.Name);
device.on('disconnected', () => {
this.status({fill:"red",shape:"ring",text:"disconnected from device"});
dev_info.available = false
msg = {data:dev_info}
node.send(msg);
if (set_timeout) {
timeout = setTimeout(connectToDevice, 10000, 10, 'set timeout for re-connect');
}
});
device.on('connected', () => {
this.status({fill:"green",shape:"dot",text: this.Ip + " at " + getHumanTimeStamp()});
try {
clearTimeout(timeout)
} catch(e) {
node.log("No timeout defined for " + this.Name + ", probably NodeRED starting")
}
});
device.on('error', error => {
this.status({fill:"red",shape:"ring",text:"error: " + error});
node.warn(error + " device: " + this.Name);
if (error.toString().includes("Error from socket")){
try {
node.log("error: Trying to clear a possible timeout timer for device " + this.Name )
clearTimeout(timeout)
} catch(e) {
node.log("error: No timeout defined, device " + this.Name + " is probably not powered")
}
}
});
device.on('data', (data,commandByte) => {
if ("commandByte" !== null ) {
dev_info.available = true;
if (this.renameSchema !== undefined || this.renameSchema !== null) {
data.dps = checkValidJSON(this.renameSchema) ? keyRename(data.dps,JSON.parse(this.renameSchema)) : data.dps;
}
msg = {data:dev_info,commandByte:commandByte,payload:data};
if (this.filterCB !== "") {
node.send(filterCommandByte(msg,this.filterCB));
} else {
node.send(msg);
}
}
});
node.on('input', function(msg) {
setDevice(msg.payload);
});
this.on('close', function(removed, done) {
if (removed) {
// This node has been deleted disconnect device and not set a timeout for reconnection
node.log("Node removal, gracefully disconnect device: " + this.Name);
device.isConnected() ? disconnectDevice(true) : node.log("Device " + this.Name + "not connected on removal");
} else {
// this node is being restarted, disconnect the device gracefully or connection will fail. Do not set a timeout
node.log("Node de-deploy, gracefully disconnect device: " + this.Name);
device.isConnected() ? disconnectDevice(true) : node.log("Device " + this.Name + "not connected on re-deploy");
}
done();
});
//
}
RED.nodes.registerType("tuya-local",TuyaNode);
}