node-red-contrib-alice 2.2.4 → 2.2.5
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/nodes/alice-device.html +6 -1
- package/nodes/alice-get.html +91 -0
- package/nodes/alice-get.js +10 -0
- package/nodes/alice-sensor.html +0 -2
- package/nodes/alice-sensor.js +1 -1
- package/nodes/alice.js +134 -122
- package/package.json +23 -4
- package/src/alice-get.html +67 -6
- package/src/alice.html +242 -0
- package/src/alice.ts +296 -0
- package/tsconfig.json +1 -1
package/nodes/alice-device.html
CHANGED
|
@@ -16,7 +16,9 @@
|
|
|
16
16
|
types: [
|
|
17
17
|
{
|
|
18
18
|
options: [
|
|
19
|
-
{ value: "devices.types.light", label: "Light" },
|
|
19
|
+
{ value: "devices.types.light", label: "Light" },
|
|
20
|
+
{ value: "devices.types.light.ceiling", label: "Light Сeiling" },
|
|
21
|
+
{ value: "devices.types.light.strip", label: "Light Strip" },
|
|
20
22
|
{ value: "devices.types.socket", label: "Socket" },
|
|
21
23
|
{ value: "devices.types.switch", label: "Switch" },
|
|
22
24
|
{ value: "devices.types.thermostat", label: "Thermostat" },
|
|
@@ -32,8 +34,11 @@
|
|
|
32
34
|
{ value: "devices.types.cooking.multicooker", label: "Multicooker" },
|
|
33
35
|
{ value: "devices.types.openable", label: "Door, gate, window, shutters" },
|
|
34
36
|
{ value: "devices.types.openable.curtain", label: "Curtains, blinds" },
|
|
37
|
+
{ value: "devices.types.openable.valve", label: "Valve (ball valve)" },
|
|
35
38
|
{ value: "devices.types.humidifier", label: "Humidifier" },
|
|
36
39
|
{ value: "devices.types.purifier", label: "Air purifier" },
|
|
40
|
+
{ value: "devices.types.ventilation", label: "Ventilation" },
|
|
41
|
+
{ value: "devices.types.ventilation.fan", label: "Fan" },
|
|
37
42
|
{ value: "devices.types.vacuum_cleaner", label: "Vacuum cleaner robot" },
|
|
38
43
|
{ value: "devices.types.washing_machine", label: "Washing machine" },
|
|
39
44
|
{ value: "devices.types.dishwasher", label: "Dishwasher" },
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
<script type="text/javascript">
|
|
2
|
+
let udyaconfig={};
|
|
3
|
+
RED.nodes.registerType('Alice-Get',{
|
|
4
|
+
category: 'alice',
|
|
5
|
+
inputs:1,
|
|
6
|
+
outputs:1,
|
|
7
|
+
icon: "alice.png",
|
|
8
|
+
color: "#D8BFD8",
|
|
9
|
+
defaults:{
|
|
10
|
+
service: {value:"", type:"alice-service"},
|
|
11
|
+
device: {value:undefined}
|
|
12
|
+
},
|
|
13
|
+
label: function(){
|
|
14
|
+
return this.name || "Alice-Get";
|
|
15
|
+
},
|
|
16
|
+
oneditprepare: ()=>{
|
|
17
|
+
$("#node-input-service").change(function(e){
|
|
18
|
+
if (this.value &&this.value!='_ADD_'){
|
|
19
|
+
$.ajax({
|
|
20
|
+
url: "/noderedhome/"+this.value+"/getfullconfig",
|
|
21
|
+
type:"GET"
|
|
22
|
+
})
|
|
23
|
+
.done(result=>{
|
|
24
|
+
// RED.notify("Full Alice SmartHome config successfully retrieved", {type:"success"});
|
|
25
|
+
console.log(result);
|
|
26
|
+
udyaconfig=result;
|
|
27
|
+
updateHouse(result.households);
|
|
28
|
+
})
|
|
29
|
+
.fail(error=>{
|
|
30
|
+
RED.notify("Error when retrieve Alice SmartHome config", {type:"error"});
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
$('#node-input-home')
|
|
35
|
+
.prop('disabled', 'disabled')
|
|
36
|
+
.change((e)=>{
|
|
37
|
+
let val = $('#node-input-home').find(":selected").val();
|
|
38
|
+
console.log(val);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
$('#node-input-room').prop('disabled', 'disabled');
|
|
42
|
+
$('#node-input-device').prop('disabled', 'disabled');
|
|
43
|
+
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
function updateHouse(data){
|
|
47
|
+
$('#node-input-home')
|
|
48
|
+
.find('option')
|
|
49
|
+
.remove()
|
|
50
|
+
.end();
|
|
51
|
+
udyaconfig.households.forEach(h => {
|
|
52
|
+
$('#node-input-home')
|
|
53
|
+
.append('<option value="'+h.id+'">'+h.name+'</option>');
|
|
54
|
+
});
|
|
55
|
+
$('#node-input-home')
|
|
56
|
+
.prop('disabled', false);
|
|
57
|
+
};
|
|
58
|
+
function updaterooms(house){
|
|
59
|
+
$('#node-input-room')
|
|
60
|
+
.find('option')
|
|
61
|
+
.remove()
|
|
62
|
+
.end();
|
|
63
|
+
udyaconfig.households.forEach(h => {
|
|
64
|
+
if (h.household_id==house){
|
|
65
|
+
$('#node-input-room')
|
|
66
|
+
.append('<option value="'+h.id+'">'+h.name+'</option>');
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
$('#node-input-room').prop('disabled', false);
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
</script>
|
|
73
|
+
|
|
74
|
+
<script type="text/x-red" data-template-name="Alice-Get">
|
|
75
|
+
<div class="form-row">
|
|
76
|
+
<label for="node-input-service">Account</label>
|
|
77
|
+
<input id="node-input-service">
|
|
78
|
+
</div>
|
|
79
|
+
<div class="form-row">
|
|
80
|
+
<label for="node-input-home">Home</label>
|
|
81
|
+
<select id="node-input-home" style="width: 70%;"></select>
|
|
82
|
+
</div>
|
|
83
|
+
<div class="form-row">
|
|
84
|
+
<label for="node-input-room">Room</label>
|
|
85
|
+
<select id="node-input-room" style="width: 70%;"></select>
|
|
86
|
+
</div>
|
|
87
|
+
<div class="form-row">
|
|
88
|
+
<label for="node-input-device">Room</label>
|
|
89
|
+
<select id="node-input-device" style="width: 70%;"></select>
|
|
90
|
+
</div>
|
|
91
|
+
</script>
|
package/nodes/alice-sensor.html
CHANGED
package/nodes/alice-sensor.js
CHANGED
|
@@ -64,7 +64,7 @@ function AliceSensor(config){
|
|
|
64
64
|
if (done) {done();}
|
|
65
65
|
return;
|
|
66
66
|
};
|
|
67
|
-
if (unit == 'unit.temperature.celsius'){
|
|
67
|
+
if (unit == 'unit.temperature.celsius' || unit == 'unit.ampere'){
|
|
68
68
|
msg.payload = +msg.payload.toFixed(1);
|
|
69
69
|
}else {
|
|
70
70
|
msg.payload = +msg.payload.toFixed(0);
|
package/nodes/alice.js
CHANGED
|
@@ -1,125 +1,137 @@
|
|
|
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
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
const axios_1 = __importDefault(require("axios"));
|
|
6
|
+
const mqtt_1 = __importDefault(require("mqtt"));
|
|
7
|
+
;
|
|
8
|
+
;
|
|
9
|
+
;
|
|
10
|
+
module.exports = (RED) => {
|
|
11
|
+
function AliceService(config) {
|
|
12
|
+
RED.nodes.createNode(this, config);
|
|
13
|
+
this.debug("Starting Alice service... ID: " + this.id);
|
|
14
|
+
const email = this.credentials.email;
|
|
15
|
+
const login = this.credentials.id;
|
|
16
|
+
const password = this.credentials.password;
|
|
17
|
+
const token = this.credentials.token;
|
|
18
|
+
const suburl = Buffer.from(email).toString('base64');
|
|
19
|
+
RED.httpAdmin.get("/noderedhome/" + suburl + "/clearalldevice", (req, res) => {
|
|
20
|
+
const option = {
|
|
21
|
+
method: 'POST',
|
|
22
|
+
url: 'https://api.nodered-home.ru/gtw/device/clearallconfigs',
|
|
23
|
+
headers: {
|
|
24
|
+
'content-type': 'application/json',
|
|
25
|
+
'Authorization': "Bearer " + this.getToken()
|
|
26
|
+
},
|
|
27
|
+
data: {}
|
|
28
|
+
};
|
|
29
|
+
axios_1.default.request(option)
|
|
30
|
+
.then(result => {
|
|
31
|
+
this.trace("All devices configs deleted on gateway successfully");
|
|
32
|
+
res.sendStatus(200);
|
|
33
|
+
})
|
|
34
|
+
.catch(error => {
|
|
35
|
+
this.debug("Error when delete All devices configs deleted on gateway: " + error.message);
|
|
36
|
+
res.sendStatus(500);
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
RED.httpAdmin.get("/noderedhome/" + this.id + "/getfullconfig", (req, res) => {
|
|
40
|
+
const option = {
|
|
41
|
+
method: 'GET',
|
|
42
|
+
url: 'https://api.iot.yandex.net/v1.0/user/info',
|
|
43
|
+
headers: {
|
|
44
|
+
'content-type': 'application/json',
|
|
45
|
+
'Authorization': "Bearer " + this.getToken()
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
axios_1.default.request(option)
|
|
49
|
+
.then(result => {
|
|
50
|
+
this.trace("Full Alice SmartHome config successfully retrieved");
|
|
51
|
+
res.json(result.data);
|
|
52
|
+
})
|
|
53
|
+
.catch(error => {
|
|
54
|
+
this.debug("Error when retrieve Alice SmartHome config: " + error.message);
|
|
55
|
+
res.sendStatus(500);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
this.isOnline = false;
|
|
59
|
+
if (!token) {
|
|
60
|
+
this.error("Authentication is required!!!");
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
;
|
|
64
|
+
const mqttClient = mqtt_1.default.connect("mqtts://mqtt.cloud.yandex.net", {
|
|
65
|
+
port: 8883,
|
|
66
|
+
clientId: login,
|
|
67
|
+
rejectUnauthorized: false,
|
|
68
|
+
username: login,
|
|
69
|
+
password: password,
|
|
70
|
+
reconnectPeriod: 10000
|
|
71
|
+
});
|
|
72
|
+
mqttClient.on("message", (topic, payload) => {
|
|
73
|
+
const arrTopic = topic.split('/');
|
|
74
|
+
const data = JSON.parse(payload);
|
|
75
|
+
this.trace("Incoming:" + topic + " timestamp:" + new Date().getTime());
|
|
76
|
+
if (payload.length && typeof data === 'object') {
|
|
77
|
+
if (arrTopic[3] == 'message') {
|
|
78
|
+
this.warn(data.text);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
this.emit(arrTopic[3], data);
|
|
82
|
+
}
|
|
83
|
+
;
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
mqttClient.on("connect", () => {
|
|
87
|
+
this.debug("Yandex IOT client connected. ");
|
|
88
|
+
this.emit('online');
|
|
89
|
+
mqttClient.subscribe("$me/device/commands/+", _ => {
|
|
90
|
+
this.debug("Yandex IOT client subscribed to the command");
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
mqttClient.on("offline", () => {
|
|
94
|
+
this.debug("Yandex IOT client offline. ");
|
|
95
|
+
this.emit('offline');
|
|
96
|
+
});
|
|
97
|
+
mqttClient.on("disconnect", () => {
|
|
98
|
+
this.debug("Yandex IOT client disconnect.");
|
|
99
|
+
this.emit('offline');
|
|
100
|
+
});
|
|
101
|
+
mqttClient.on("reconnect", () => {
|
|
102
|
+
this.debug("Yandex IOT client reconnecting ...");
|
|
103
|
+
});
|
|
104
|
+
mqttClient.on("error", (err) => {
|
|
105
|
+
this.error("Yandex IOT client Error: " + err.message);
|
|
106
|
+
this.emit('offline');
|
|
107
|
+
});
|
|
108
|
+
this.on('offline', () => {
|
|
109
|
+
this.isOnline = false;
|
|
110
|
+
});
|
|
111
|
+
this.on('online', () => {
|
|
112
|
+
this.isOnline = true;
|
|
113
|
+
});
|
|
114
|
+
this.on('close', (done) => {
|
|
115
|
+
this.emit('offline');
|
|
116
|
+
setTimeout(() => {
|
|
117
|
+
mqttClient.end(false, done);
|
|
118
|
+
}, 500);
|
|
119
|
+
});
|
|
120
|
+
this.send2gate = (path, data, retain) => {
|
|
121
|
+
this.trace("Outgoing: " + path);
|
|
122
|
+
mqttClient.publish(path, data, { qos: 0, retain: retain });
|
|
123
|
+
};
|
|
124
|
+
this.getToken = () => {
|
|
125
|
+
return JSON.parse(token).access_token;
|
|
60
126
|
};
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
mqttClient.on("connect",()=>{
|
|
64
|
-
this.debug("Yandex IOT client connected. ");
|
|
65
|
-
this.emit('online');
|
|
66
|
-
// Подписываемся на получение комманд
|
|
67
|
-
mqttClient.subscribe("$me/device/commands/+",_=>{
|
|
68
|
-
this.debug("Yandex IOT client subscribed to the command");
|
|
69
|
-
});
|
|
70
|
-
});
|
|
71
|
-
mqttClient.on("offline",()=>{
|
|
72
|
-
this.debug("Yandex IOT client offline. ");
|
|
73
|
-
this.emit('offline');
|
|
74
|
-
});
|
|
75
|
-
mqttClient.on("disconnect",()=>{
|
|
76
|
-
this.debug("Yandex IOT client disconnect.");
|
|
77
|
-
this.emit('offline');
|
|
78
|
-
});
|
|
79
|
-
mqttClient.on("reconnect",(err)=>{
|
|
80
|
-
this.debug("Yandex IOT client reconnecting ...");
|
|
81
|
-
});
|
|
82
|
-
mqttClient.on("error",(err)=>{
|
|
83
|
-
this.error("Yandex IOT client Error: "+ err.message);
|
|
84
|
-
this.emit('offline');
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
this.on('offline', ()=>{
|
|
88
|
-
this.isOnline = false;
|
|
89
|
-
})
|
|
90
|
-
|
|
91
|
-
this.on('online', ()=>{
|
|
92
|
-
this.isOnline = true;
|
|
93
|
-
})
|
|
94
|
-
|
|
95
|
-
this.on('close',(done)=>{
|
|
96
|
-
this.emit('offline');
|
|
97
|
-
setTimeout(()=>{
|
|
98
|
-
mqttClient.end(false,done);
|
|
99
|
-
},500)
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
this.send2gate= (path,data,retain)=>{
|
|
103
|
-
// this.debug(path);
|
|
104
|
-
// this.debug(data);
|
|
105
|
-
this.trace("Outgoing: "+path);
|
|
106
|
-
mqttClient.publish(path, data ,{ qos: 0, retain: retain });
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
this.getToken = ()=>{
|
|
110
|
-
return JSON.parse(token).access_token;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
};
|
|
114
|
-
RED.nodes.registerType("alice-service",AliceService,{
|
|
115
|
-
credentials: {
|
|
116
|
-
email: {type: "text"},
|
|
117
|
-
password: {type: "password"},
|
|
118
|
-
token: {type: "password"},
|
|
119
|
-
id:{type:"text"}
|
|
120
127
|
}
|
|
121
|
-
|
|
128
|
+
;
|
|
129
|
+
RED.nodes.registerType("alice-service", AliceService, {
|
|
130
|
+
credentials: {
|
|
131
|
+
email: { type: "text" },
|
|
132
|
+
password: { type: "password" },
|
|
133
|
+
token: { type: "password" },
|
|
134
|
+
id: { type: "text" }
|
|
135
|
+
}
|
|
136
|
+
});
|
|
122
137
|
};
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
package/package.json
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-red-contrib-alice",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.5",
|
|
4
4
|
"description": "",
|
|
5
|
-
"main": "alice.js",
|
|
6
5
|
"scripts": {
|
|
7
6
|
"start": "npm run build && node-red",
|
|
8
7
|
"build": "tsc && npm run copy-html",
|
|
9
|
-
"copy-html": "cp ./src/*.html ./nodes/"
|
|
10
|
-
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
|
+
"copy-html": "cp ./src/*.html ./nodes/"
|
|
11
9
|
},
|
|
12
10
|
"repository": {
|
|
13
11
|
"type": "git",
|
|
@@ -50,11 +48,32 @@
|
|
|
50
48
|
},
|
|
51
49
|
"devDependencies": {
|
|
52
50
|
"@types/axios": "^0.14.0",
|
|
51
|
+
"@types/mqtt": "^2.5.0",
|
|
53
52
|
"@types/node": "^20.11.16",
|
|
54
53
|
"@types/node-red": "^1.3.4",
|
|
55
54
|
"@typescript-eslint/eslint-plugin": "^6.20.0",
|
|
56
55
|
"@typescript-eslint/parser": "^6.20.0",
|
|
57
56
|
"eslint": "^8.56.0",
|
|
57
|
+
"nodemon": "^3.0.3",
|
|
58
58
|
"typescript": "^5.3.3"
|
|
59
|
+
},
|
|
60
|
+
"nodemonConfig": {
|
|
61
|
+
"ignoreRoot" : [".git", "test"],
|
|
62
|
+
"restartable": "rs",
|
|
63
|
+
"ignore": [
|
|
64
|
+
"node_modules/**/node_modules",
|
|
65
|
+
"node_modules/**/test",
|
|
66
|
+
"*.log"
|
|
67
|
+
],
|
|
68
|
+
"verbose": true,
|
|
69
|
+
"delay": "1000",
|
|
70
|
+
"events": {
|
|
71
|
+
"restart": "echo ------ restarted due to: $FILENAME ------"
|
|
72
|
+
},
|
|
73
|
+
"watch": [
|
|
74
|
+
"src/",
|
|
75
|
+
"node_modules/node-red-*"
|
|
76
|
+
],
|
|
77
|
+
"ext": "js json htm html css"
|
|
59
78
|
}
|
|
60
79
|
}
|
package/src/alice-get.html
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script type="text/javascript">
|
|
2
|
+
let udyaconfig={};
|
|
2
3
|
RED.nodes.registerType('Alice-Get',{
|
|
3
4
|
category: 'alice',
|
|
4
5
|
inputs:1,
|
|
@@ -7,24 +8,84 @@
|
|
|
7
8
|
color: "#D8BFD8",
|
|
8
9
|
defaults:{
|
|
9
10
|
service: {value:"", type:"alice-service"},
|
|
10
|
-
|
|
11
|
+
device: {value:undefined}
|
|
11
12
|
},
|
|
12
13
|
label: function(){
|
|
13
14
|
return this.name || "Alice-Get";
|
|
14
15
|
},
|
|
15
16
|
oneditprepare: ()=>{
|
|
16
|
-
|
|
17
|
+
$("#node-input-service").change(function(e){
|
|
18
|
+
if (this.value &&this.value!='_ADD_'){
|
|
19
|
+
$.ajax({
|
|
20
|
+
url: "/noderedhome/"+this.value+"/getfullconfig",
|
|
21
|
+
type:"GET"
|
|
22
|
+
})
|
|
23
|
+
.done(result=>{
|
|
24
|
+
// RED.notify("Full Alice SmartHome config successfully retrieved", {type:"success"});
|
|
25
|
+
console.log(result);
|
|
26
|
+
udyaconfig=result;
|
|
27
|
+
updateHouse(result.households);
|
|
28
|
+
})
|
|
29
|
+
.fail(error=>{
|
|
30
|
+
RED.notify("Error when retrieve Alice SmartHome config", {type:"error"});
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
$('#node-input-home')
|
|
35
|
+
.prop('disabled', 'disabled')
|
|
36
|
+
.change((e)=>{
|
|
37
|
+
let val = $('#node-input-home').find(":selected").val();
|
|
38
|
+
console.log(val);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
$('#node-input-room').prop('disabled', 'disabled');
|
|
42
|
+
$('#node-input-device').prop('disabled', 'disabled');
|
|
43
|
+
|
|
17
44
|
}
|
|
18
|
-
})
|
|
45
|
+
});
|
|
46
|
+
function updateHouse(data){
|
|
47
|
+
$('#node-input-home')
|
|
48
|
+
.find('option')
|
|
49
|
+
.remove()
|
|
50
|
+
.end();
|
|
51
|
+
udyaconfig.households.forEach(h => {
|
|
52
|
+
$('#node-input-home')
|
|
53
|
+
.append('<option value="'+h.id+'">'+h.name+'</option>');
|
|
54
|
+
});
|
|
55
|
+
$('#node-input-home')
|
|
56
|
+
.prop('disabled', false);
|
|
57
|
+
};
|
|
58
|
+
function updaterooms(house){
|
|
59
|
+
$('#node-input-room')
|
|
60
|
+
.find('option')
|
|
61
|
+
.remove()
|
|
62
|
+
.end();
|
|
63
|
+
udyaconfig.households.forEach(h => {
|
|
64
|
+
if (h.household_id==house){
|
|
65
|
+
$('#node-input-room')
|
|
66
|
+
.append('<option value="'+h.id+'">'+h.name+'</option>');
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
$('#node-input-room').prop('disabled', false);
|
|
70
|
+
};
|
|
71
|
+
|
|
19
72
|
</script>
|
|
20
73
|
|
|
21
74
|
<script type="text/x-red" data-template-name="Alice-Get">
|
|
22
75
|
<div class="form-row">
|
|
23
|
-
<label for="node-input-service">
|
|
76
|
+
<label for="node-input-service">Account</label>
|
|
24
77
|
<input id="node-input-service">
|
|
25
78
|
</div>
|
|
26
79
|
<div class="form-row">
|
|
27
|
-
<label for="node-
|
|
28
|
-
<
|
|
80
|
+
<label for="node-input-home">Home</label>
|
|
81
|
+
<select id="node-input-home" style="width: 70%;"></select>
|
|
82
|
+
</div>
|
|
83
|
+
<div class="form-row">
|
|
84
|
+
<label for="node-input-room">Room</label>
|
|
85
|
+
<select id="node-input-room" style="width: 70%;"></select>
|
|
86
|
+
</div>
|
|
87
|
+
<div class="form-row">
|
|
88
|
+
<label for="node-input-device">Room</label>
|
|
89
|
+
<select id="node-input-device" style="width: 70%;"></select>
|
|
29
90
|
</div>
|
|
30
91
|
</script>
|
package/src/alice.html
ADDED
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
|
|
2
|
+
<script src="https://widget.cloudpayments.ru/bundles/cloudpayments.js"></script>
|
|
3
|
+
<script type="text/javascript">
|
|
4
|
+
RED.nodes.registerType('alice-service',{
|
|
5
|
+
category: 'config',
|
|
6
|
+
defaults: {
|
|
7
|
+
name: {value:null}
|
|
8
|
+
},
|
|
9
|
+
credentials:{
|
|
10
|
+
email: {type: "text", required:true},
|
|
11
|
+
password: {type: "password", required:true},
|
|
12
|
+
token: {type: "password", required:true},
|
|
13
|
+
id:{type:"text",required:true}
|
|
14
|
+
},
|
|
15
|
+
label: function() {
|
|
16
|
+
return this.name || "Alice-Credentials";
|
|
17
|
+
},
|
|
18
|
+
oneditprepare:function(){
|
|
19
|
+
$('#subscribe-status').text("checking ...");
|
|
20
|
+
let em = $('#node-config-input-email').val();
|
|
21
|
+
let idt = $('#node-config-input-id').val();
|
|
22
|
+
getSubscribeStatus(idt,em,"subscribe-status");
|
|
23
|
+
},
|
|
24
|
+
oneditsave: function(){
|
|
25
|
+
nodename = $('#node-config-input-email').val();
|
|
26
|
+
$('#node-config-input-name').val(nodename);
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
function getSubscribeStatus(id, email, contId){
|
|
30
|
+
if (email.length < 3 || id.length < 3){
|
|
31
|
+
return;
|
|
32
|
+
};
|
|
33
|
+
$.ajax({
|
|
34
|
+
url: "https://nodered-home.ru/payment/getsubscribestatus",
|
|
35
|
+
type:"POST",
|
|
36
|
+
headers: {
|
|
37
|
+
'Content-Type':'application/json'
|
|
38
|
+
},
|
|
39
|
+
crossDomain: true,
|
|
40
|
+
contentType:"application/json",
|
|
41
|
+
data: JSON.stringify({
|
|
42
|
+
id: id,
|
|
43
|
+
email: email
|
|
44
|
+
}),
|
|
45
|
+
dataType: "json",
|
|
46
|
+
format:"json"
|
|
47
|
+
})
|
|
48
|
+
.done(result=>{
|
|
49
|
+
// console.log(result);
|
|
50
|
+
$('#'+contId).text(result.data.text);
|
|
51
|
+
})
|
|
52
|
+
.fail(error=>{
|
|
53
|
+
console.log(error)
|
|
54
|
+
console.error(error.responseJSON);
|
|
55
|
+
RED.notify("Error : "+error.responseJSON.message, {type:"error"});
|
|
56
|
+
});
|
|
57
|
+
};
|
|
58
|
+
function GetToken(code){
|
|
59
|
+
console.log(this.id);
|
|
60
|
+
RED.notify("Request has been sent. Please, wait",{type:"compact"});
|
|
61
|
+
$('#verification_code').prop('disabled', true);
|
|
62
|
+
$('#submit_button').prop('disabled', true);
|
|
63
|
+
$.ajax({
|
|
64
|
+
url: "https://nodered-home.ru/api/v1/getyatoken",
|
|
65
|
+
type:"POST",
|
|
66
|
+
headers: {
|
|
67
|
+
'Content-Type':'application/json'
|
|
68
|
+
},
|
|
69
|
+
crossDomain: true,
|
|
70
|
+
contentType:"application/json",
|
|
71
|
+
data: JSON.stringify({code:code}),
|
|
72
|
+
dataType: "json",
|
|
73
|
+
format:"json"
|
|
74
|
+
})
|
|
75
|
+
.done(data=>{
|
|
76
|
+
RED.notify("Authentication data, received successfully", {type:"success"});
|
|
77
|
+
$('#node-config-input-email').val(data.email).trigger("change");
|
|
78
|
+
$('#node-config-input-id').val(data.id).trigger("input").trigger("change");
|
|
79
|
+
$('#node-config-input-password').val(data.password).trigger("change");
|
|
80
|
+
$('#node-config-input-token').val(JSON.stringify(data.token)).trigger("change");
|
|
81
|
+
}).fail(error=>{
|
|
82
|
+
console.error(error.responseJSON);
|
|
83
|
+
RED.notify("Error : "+error.responseJSON.message, {type:"error"});
|
|
84
|
+
$('#verification_code').prop('disabled', false);
|
|
85
|
+
$('#submit_button').prop('disabled', false);
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
function ClearDevicesConfigOnGateway(email) {
|
|
89
|
+
RED.notify("Request has been sent. Please, wait",{type:"compact"});
|
|
90
|
+
const suburl = btoa(email);
|
|
91
|
+
$.ajax({
|
|
92
|
+
url: "/noderedhome/"+suburl+"/clearalldevice",
|
|
93
|
+
type:"GET"
|
|
94
|
+
})
|
|
95
|
+
.done(result=>{
|
|
96
|
+
RED.notify("All configs have been successfully cleared", {type:"success"});
|
|
97
|
+
})
|
|
98
|
+
.fail(error=>{
|
|
99
|
+
RED.notify("Error when deleting configs on the gateway", {type:"error"});
|
|
100
|
+
})
|
|
101
|
+
};
|
|
102
|
+
function pay(id, email) {
|
|
103
|
+
console.log("Start pay");
|
|
104
|
+
if (!id || !email){
|
|
105
|
+
RED.notify("Please authorize before purchasing a subscription", {type:"error"});
|
|
106
|
+
return;
|
|
107
|
+
};
|
|
108
|
+
$('#subscribe-button').prop('disabled', true);
|
|
109
|
+
RED.notify("Request has been sent. Please, wait",{type:"compact"});
|
|
110
|
+
let paymentWidget = new cp.CloudPayments();
|
|
111
|
+
console.log("Start get pay confi");
|
|
112
|
+
$.ajax({
|
|
113
|
+
url: "https://nodered-home.ru/payment/create",
|
|
114
|
+
type:"POST",
|
|
115
|
+
headers: {
|
|
116
|
+
'Content-Type':'application/json'
|
|
117
|
+
},
|
|
118
|
+
crossDomain: true,
|
|
119
|
+
contentType:"application/json",
|
|
120
|
+
data: JSON.stringify({
|
|
121
|
+
id: id,
|
|
122
|
+
email: email
|
|
123
|
+
}),
|
|
124
|
+
dataType: "json",
|
|
125
|
+
format:"json"
|
|
126
|
+
})
|
|
127
|
+
.done(paydata=>{
|
|
128
|
+
console.log("pay config done");
|
|
129
|
+
console.log("Start widget");
|
|
130
|
+
paymentWidget.pay('auth', // или 'charge'
|
|
131
|
+
paydata,
|
|
132
|
+
{
|
|
133
|
+
onSuccess: function (result) { // success
|
|
134
|
+
//действие при успешной оплате
|
|
135
|
+
let em = $('#node-config-input-email').val();
|
|
136
|
+
let idt = $('#node-config-input-id').val();
|
|
137
|
+
$('#subscribe-status').text("checking ...");
|
|
138
|
+
setTimeout(() => {
|
|
139
|
+
getSubscribeStatus(idt,em,"subscribe-status");
|
|
140
|
+
}, 2000);
|
|
141
|
+
|
|
142
|
+
},
|
|
143
|
+
onFail: function (reason, options) { // fail
|
|
144
|
+
//действие при неуспешной оплате
|
|
145
|
+
},
|
|
146
|
+
onComplete: function (paymentResult, options) { //Вызывается как только виджет получает от api.cloudpayments ответ с результатом транзакции.
|
|
147
|
+
//например вызов вашей аналитики Facebook Pixel
|
|
148
|
+
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
);
|
|
152
|
+
$('#subscribe-button').prop('disabled', false);
|
|
153
|
+
})
|
|
154
|
+
.fail(error=>{
|
|
155
|
+
console.log(error)
|
|
156
|
+
console.error(error.responseJSON);
|
|
157
|
+
RED.notify("Error : "+error.responseJSON.message, {type:"error"});
|
|
158
|
+
$('#subscribe-button').prop('disabled', false);
|
|
159
|
+
})
|
|
160
|
+
};
|
|
161
|
+
</script>
|
|
162
|
+
|
|
163
|
+
<script type="text/x-red" data-template-name="alice-service">
|
|
164
|
+
<input type="hidden" id="node-config-input-name">
|
|
165
|
+
<div name="New Reg">
|
|
166
|
+
<div class="form-row"><b>Credentials</b></div>
|
|
167
|
+
<div class="form-row">
|
|
168
|
+
<p>1. Follow the link and confirm access</p>
|
|
169
|
+
<label>Authentication</label>
|
|
170
|
+
<button
|
|
171
|
+
onclick="window.open('https://oauth.yandex.ru/authorize?response_type=code&client_id=aa882e33283046fc83de54be20a2e5d8')"
|
|
172
|
+
class="ui-button">Yandex Authentication
|
|
173
|
+
</button>
|
|
174
|
+
</div>
|
|
175
|
+
|
|
176
|
+
<div class="form-row">
|
|
177
|
+
<p>2. Input the verification code and click submit</p>
|
|
178
|
+
<label>Code</label>
|
|
179
|
+
<input type="text" id="verification_code" style="width:auto">
|
|
180
|
+
<button id="submit_button" onclick="GetToken($('#verification_code').val())" class="ui-button">Submit</button>
|
|
181
|
+
</div>
|
|
182
|
+
<div class="form-tips" id="node-tip">
|
|
183
|
+
<span>Tip: Data request may take up to 15 seconds, please wait for success or error message.</span>
|
|
184
|
+
</div>
|
|
185
|
+
<hr>
|
|
186
|
+
<div class="form-row">
|
|
187
|
+
<p><b>Authentication result:</b></p>
|
|
188
|
+
</div>
|
|
189
|
+
<div class="form-row">
|
|
190
|
+
<label for="node-config-input-email">Email</label>
|
|
191
|
+
<input type="text" id="node-config-input-email" disabled>
|
|
192
|
+
</div>
|
|
193
|
+
<div class="form-row">
|
|
194
|
+
<label for="node-config-input-id">ID</label>
|
|
195
|
+
<input type="text" id="node-config-input-id" disabled>
|
|
196
|
+
</div>
|
|
197
|
+
<!-- <div class="form-row" style="visibility: hidden;">
|
|
198
|
+
<label for="node-config-input-password">Password</label> -->
|
|
199
|
+
<input type="hidden" id="node-config-input-password" disabled>
|
|
200
|
+
<!-- </div> -->
|
|
201
|
+
<div class="form-row" style="display: none;">
|
|
202
|
+
<label for="node-config-input-token">Token</label>
|
|
203
|
+
<input type="password" id="node-config-input-token" disabled>
|
|
204
|
+
</div>
|
|
205
|
+
</div>
|
|
206
|
+
<hr>
|
|
207
|
+
<div name="subcribtion">
|
|
208
|
+
<div class="form-row">
|
|
209
|
+
<p><b>Subscription:</b></p>
|
|
210
|
+
</div>
|
|
211
|
+
<div class="form-row">
|
|
212
|
+
<label for="node-config-input-token" style="width: 150px">Subscription status:</label> <span id="subscribe-status"></span>
|
|
213
|
+
<div class="form-tips" id="node-tip-subscribe-warn">
|
|
214
|
+
<span>Important:</span><br>
|
|
215
|
+
<span> - By purchasing a subscription, you agree to the terms of the <a href="https://nodered-home.ru/public_offer.pdf" target="_blank">public offer</a></span><br>
|
|
216
|
+
<span> - View and manage your subscriptions <a href="https://my.cloudpayments.ru/ru/unsubscribe" target="_blank">here</a></span>
|
|
217
|
+
<div style="text-align: end">
|
|
218
|
+
<button id="subscribe-button"
|
|
219
|
+
onclick="pay($('#node-config-input-id').val(), $('#node-config-input-email').val())"
|
|
220
|
+
class="ui-button">Buy a subscription
|
|
221
|
+
</button>
|
|
222
|
+
</div>
|
|
223
|
+
</div>
|
|
224
|
+
</div>
|
|
225
|
+
</div>
|
|
226
|
+
<hr>
|
|
227
|
+
<div name="Clearing">
|
|
228
|
+
<div class="form-row"><b>Сlear all data and configs on the gateway</b></div>
|
|
229
|
+
<div class="form-tips" id="node-tip">
|
|
230
|
+
<span>Tip: Сlear all data on the gateway may take up to 15 seconds, please wait for success or error message. When finished, make a full deployment to update the settings on the gateway.</span>
|
|
231
|
+
<div style="text-align: end">
|
|
232
|
+
<button
|
|
233
|
+
style="margin-left: 150px; margin-top: 10px;"
|
|
234
|
+
onclick="ClearDevicesConfigOnGateway($('#node-config-input-email').val())"
|
|
235
|
+
class="ui-button">
|
|
236
|
+
Сlear data on the gateway
|
|
237
|
+
</button>
|
|
238
|
+
</div>
|
|
239
|
+
</div>
|
|
240
|
+
</div>
|
|
241
|
+
</script>
|
|
242
|
+
|
package/src/alice.ts
ADDED
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
import {NodeAPI, Node, NodeDef, NodeCredentials, NodeCredential } from "node-red";
|
|
2
|
+
import axios from "axios";
|
|
3
|
+
import mqtt from "mqtt";
|
|
4
|
+
|
|
5
|
+
interface NodeAliceConfig
|
|
6
|
+
extends NodeDef {
|
|
7
|
+
name:string;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
interface NodeAliceCredentials
|
|
11
|
+
extends NodeCredential {
|
|
12
|
+
email:string;
|
|
13
|
+
id:string;
|
|
14
|
+
password:string;
|
|
15
|
+
token:string;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
interface AliceNode
|
|
19
|
+
extends Node {
|
|
20
|
+
credentials: NodeAliceCredentials;
|
|
21
|
+
isOnline:boolean;
|
|
22
|
+
getToken():string;
|
|
23
|
+
send2gate(topic:string,data:any,retain:boolean):void;
|
|
24
|
+
// on(event: 'hello', listener: (name: string) => void): this;
|
|
25
|
+
on(event: string, listener: Function): this;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export = (RED: NodeAPI):void =>{
|
|
29
|
+
function AliceService(this:AliceNode, config:NodeAliceConfig):void {
|
|
30
|
+
RED.nodes.createNode(this,config);
|
|
31
|
+
this.debug("Starting Alice service... ID: "+this.id);
|
|
32
|
+
|
|
33
|
+
const email = this.credentials.email;
|
|
34
|
+
const login = this.credentials.id;
|
|
35
|
+
const password = this.credentials.password;
|
|
36
|
+
const token = this.credentials.token;
|
|
37
|
+
|
|
38
|
+
//вызов для удаления всех устройств
|
|
39
|
+
const suburl = Buffer.from(email).toString('base64');
|
|
40
|
+
RED.httpAdmin.get("/noderedhome/"+suburl+"/clearalldevice",(req,res)=>{
|
|
41
|
+
const option = {
|
|
42
|
+
method: 'POST',
|
|
43
|
+
url: 'https://api.nodered-home.ru/gtw/device/clearallconfigs',
|
|
44
|
+
headers: {
|
|
45
|
+
'content-type': 'application/json',
|
|
46
|
+
'Authorization': "Bearer "+this.getToken()
|
|
47
|
+
},
|
|
48
|
+
data: {}
|
|
49
|
+
};
|
|
50
|
+
axios.request(option)
|
|
51
|
+
.then(result=>{
|
|
52
|
+
this.trace("All devices configs deleted on gateway successfully");
|
|
53
|
+
// console.log(result)
|
|
54
|
+
res.sendStatus(200);
|
|
55
|
+
})
|
|
56
|
+
.catch(error=>{
|
|
57
|
+
this.debug("Error when delete All devices configs deleted on gateway: "+error.message);
|
|
58
|
+
res.sendStatus(500);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
RED.httpAdmin.get("/noderedhome/"+this.id+"/getfullconfig",(req,res)=>{
|
|
63
|
+
const option = {
|
|
64
|
+
method: 'GET',
|
|
65
|
+
url: 'https://api.iot.yandex.net/v1.0/user/info',
|
|
66
|
+
headers: {
|
|
67
|
+
'content-type': 'application/json',
|
|
68
|
+
'Authorization': "Bearer "+this.getToken()
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
axios.request(option)
|
|
72
|
+
.then(result=>{
|
|
73
|
+
this.trace("Full Alice SmartHome config successfully retrieved");
|
|
74
|
+
// console.log(result)
|
|
75
|
+
res.json(result.data);
|
|
76
|
+
})
|
|
77
|
+
.catch(error=>{
|
|
78
|
+
this.debug("Error when retrieve Alice SmartHome config: "+error.message);
|
|
79
|
+
res.sendStatus(500);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
this.isOnline = false;
|
|
84
|
+
//// проверяем а есть ли токен
|
|
85
|
+
if (!token){
|
|
86
|
+
this.error("Authentication is required!!!");
|
|
87
|
+
return;
|
|
88
|
+
};
|
|
89
|
+
const mqttClient = mqtt.connect("mqtts://mqtt.cloud.yandex.net",{
|
|
90
|
+
port: 8883,
|
|
91
|
+
clientId: login,
|
|
92
|
+
rejectUnauthorized: false,
|
|
93
|
+
username: login,
|
|
94
|
+
password: password,
|
|
95
|
+
reconnectPeriod: 10000
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
mqttClient.on("message",(topic:string, payload:string)=>{
|
|
99
|
+
const arrTopic = topic.split('/');
|
|
100
|
+
const data = JSON.parse(payload);
|
|
101
|
+
this.trace("Incoming:" + topic +" timestamp:"+new Date().getTime());
|
|
102
|
+
if (payload.length && typeof data === 'object'){
|
|
103
|
+
if (arrTopic[3]=='message'){
|
|
104
|
+
this.warn(data.text);
|
|
105
|
+
}else{
|
|
106
|
+
this.emit(arrTopic[3],data);
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
mqttClient.on("connect",()=>{
|
|
111
|
+
this.debug("Yandex IOT client connected. ");
|
|
112
|
+
this.emit('online');
|
|
113
|
+
// Подписываемся на получение комманд
|
|
114
|
+
mqttClient.subscribe("$me/device/commands/+",_=>{
|
|
115
|
+
this.debug("Yandex IOT client subscribed to the command");
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
mqttClient.on("offline",()=>{
|
|
119
|
+
this.debug("Yandex IOT client offline. ");
|
|
120
|
+
this.emit('offline');
|
|
121
|
+
});
|
|
122
|
+
mqttClient.on("disconnect",()=>{
|
|
123
|
+
this.debug("Yandex IOT client disconnect.");
|
|
124
|
+
this.emit('offline');
|
|
125
|
+
});
|
|
126
|
+
mqttClient.on("reconnect",()=>{
|
|
127
|
+
this.debug("Yandex IOT client reconnecting ...");
|
|
128
|
+
});
|
|
129
|
+
mqttClient.on("error",(err)=>{
|
|
130
|
+
this.error("Yandex IOT client Error: "+ err.message);
|
|
131
|
+
this.emit('offline');
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
this.on('offline', ()=>{
|
|
135
|
+
this.isOnline = false;
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
this.on('online', ()=>{
|
|
139
|
+
this.isOnline = true;
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
this.on('close',(done:Object)=>{
|
|
143
|
+
this.emit('offline');
|
|
144
|
+
setTimeout(()=>{
|
|
145
|
+
mqttClient.end(false,done);
|
|
146
|
+
},500)
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
this.send2gate = (path:string,data:any,retain:boolean)=>{
|
|
150
|
+
// this.debug(path);
|
|
151
|
+
// this.debug(data);
|
|
152
|
+
this.trace("Outgoing: "+path);
|
|
153
|
+
mqttClient.publish(path, data ,{ qos: 0, retain: retain });
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
this.getToken = ()=>{
|
|
158
|
+
return JSON.parse(token).access_token;
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
RED.nodes.registerType("alice-service",AliceService,{
|
|
163
|
+
credentials: {
|
|
164
|
+
email: {type: "text"},
|
|
165
|
+
password: {type: "password"},
|
|
166
|
+
token: {type: "password"},
|
|
167
|
+
id:{type:"text"}
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// const mqtt = require('mqtt');
|
|
173
|
+
// const axios = require('axios');
|
|
174
|
+
|
|
175
|
+
// module.exports = function(RED) {
|
|
176
|
+
// //Sevice node, Alice-Service (credential)
|
|
177
|
+
// function AliceService(config) {
|
|
178
|
+
// RED.nodes.createNode(this,config);
|
|
179
|
+
// this.debug("Starting Alice service...");
|
|
180
|
+
|
|
181
|
+
// const email = this.credentials.email;
|
|
182
|
+
// const login = this.credentials.id;
|
|
183
|
+
// const password = this.credentials.password;
|
|
184
|
+
// const token = this.credentials.token;
|
|
185
|
+
|
|
186
|
+
// const suburl = Buffer.from(email).toString('base64');
|
|
187
|
+
// RED.httpAdmin.get("/noderedhome/"+suburl+"/clearalldevice",(req,res)=>{
|
|
188
|
+
// const option = {
|
|
189
|
+
// method: 'POST',
|
|
190
|
+
// url: 'https://api.nodered-home.ru/gtw/device/clearallconfigs',
|
|
191
|
+
// headers: {
|
|
192
|
+
// 'content-type': 'application/json',
|
|
193
|
+
// 'Authorization': "Bearer "+this.getToken()
|
|
194
|
+
// },
|
|
195
|
+
// data: {}
|
|
196
|
+
// };
|
|
197
|
+
// axios.request(option)
|
|
198
|
+
// .then(result=>{
|
|
199
|
+
// this.trace("All devices configs deleted on gateway successfully");
|
|
200
|
+
// // console.log(result)
|
|
201
|
+
// res.sendStatus(200);
|
|
202
|
+
// })
|
|
203
|
+
// .catch(error=>{
|
|
204
|
+
// this.debug("Error when delete All devices configs deleted on gateway: "+error.message);
|
|
205
|
+
// res.sendStatus(500);
|
|
206
|
+
// });
|
|
207
|
+
// });
|
|
208
|
+
|
|
209
|
+
// this.isOnline = false;
|
|
210
|
+
// if (!token){
|
|
211
|
+
// this.error("Authentication is required!!!");
|
|
212
|
+
// return;
|
|
213
|
+
// };
|
|
214
|
+
// const mqttClient = mqtt.connect("mqtts://mqtt.cloud.yandex.net",{
|
|
215
|
+
// port: 8883,
|
|
216
|
+
// clientId: login,
|
|
217
|
+
// rejectUnauthorized: false,
|
|
218
|
+
// username: login,
|
|
219
|
+
// password: password,
|
|
220
|
+
// reconnectPeriod: 10000
|
|
221
|
+
// });
|
|
222
|
+
// mqttClient.on("message",(topic, payload)=>{
|
|
223
|
+
// const arrTopic = topic.split('/');
|
|
224
|
+
// const data = JSON.parse(payload);
|
|
225
|
+
// this.trace("Incoming:" + topic +" timestamp:"+new Date().getTime());
|
|
226
|
+
// if (payload.length && typeof data === 'object'){
|
|
227
|
+
// if (arrTopic[3]=='message'){
|
|
228
|
+
// this.warn(data.text);
|
|
229
|
+
// }else{
|
|
230
|
+
// this.emit(arrTopic[3],data);
|
|
231
|
+
// };
|
|
232
|
+
// }
|
|
233
|
+
// });
|
|
234
|
+
// mqttClient.on("connect",()=>{
|
|
235
|
+
// this.debug("Yandex IOT client connected. ");
|
|
236
|
+
// this.emit('online');
|
|
237
|
+
// // Подписываемся на получение комманд
|
|
238
|
+
// mqttClient.subscribe("$me/device/commands/+",_=>{
|
|
239
|
+
// this.debug("Yandex IOT client subscribed to the command");
|
|
240
|
+
// });
|
|
241
|
+
// });
|
|
242
|
+
// mqttClient.on("offline",()=>{
|
|
243
|
+
// this.debug("Yandex IOT client offline. ");
|
|
244
|
+
// this.emit('offline');
|
|
245
|
+
// });
|
|
246
|
+
// mqttClient.on("disconnect",()=>{
|
|
247
|
+
// this.debug("Yandex IOT client disconnect.");
|
|
248
|
+
// this.emit('offline');
|
|
249
|
+
// });
|
|
250
|
+
// mqttClient.on("reconnect",(err)=>{
|
|
251
|
+
// this.debug("Yandex IOT client reconnecting ...");
|
|
252
|
+
// });
|
|
253
|
+
// mqttClient.on("error",(err)=>{
|
|
254
|
+
// this.error("Yandex IOT client Error: "+ err.message);
|
|
255
|
+
// this.emit('offline');
|
|
256
|
+
// });
|
|
257
|
+
|
|
258
|
+
// this.on('offline', ()=>{
|
|
259
|
+
// this.isOnline = false;
|
|
260
|
+
// })
|
|
261
|
+
|
|
262
|
+
// this.on('online', ()=>{
|
|
263
|
+
// this.isOnline = true;
|
|
264
|
+
// })
|
|
265
|
+
|
|
266
|
+
// this.on('close',(done)=>{
|
|
267
|
+
// this.emit('offline');
|
|
268
|
+
// setTimeout(()=>{
|
|
269
|
+
// mqttClient.end(false,done);
|
|
270
|
+
// },500)
|
|
271
|
+
// });
|
|
272
|
+
|
|
273
|
+
// this.send2gate= (path,data,retain)=>{
|
|
274
|
+
// // this.debug(path);
|
|
275
|
+
// // this.debug(data);
|
|
276
|
+
// this.trace("Outgoing: "+path);
|
|
277
|
+
// mqttClient.publish(path, data ,{ qos: 0, retain: retain });
|
|
278
|
+
// }
|
|
279
|
+
|
|
280
|
+
// this.getToken = ()=>{
|
|
281
|
+
// return JSON.parse(token).access_token;
|
|
282
|
+
// }
|
|
283
|
+
|
|
284
|
+
// };
|
|
285
|
+
// RED.nodes.registerType("alice-service",AliceService,{
|
|
286
|
+
// credentials: {
|
|
287
|
+
// email: {type: "text"},
|
|
288
|
+
// password: {type: "password"},
|
|
289
|
+
// token: {type: "password"},
|
|
290
|
+
// id:{type:"text"}
|
|
291
|
+
// }
|
|
292
|
+
// });
|
|
293
|
+
// };
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
|
package/tsconfig.json
CHANGED
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
|
|
57
57
|
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
|
|
58
58
|
"outDir": "./nodes", /* Specify an output folder for all emitted files. */
|
|
59
|
-
|
|
59
|
+
"removeComments": true, /* Disable emitting comments. */
|
|
60
60
|
// "noEmit": true, /* Disable emitting files from a compilation. */
|
|
61
61
|
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
|
|
62
62
|
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
|