node-red-contrib-alice 2.2.4 → 2.3.1

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.

Potentially problematic release.


This version of node-red-contrib-alice might be problematic. Click here for more details.

Files changed (43) hide show
  1. package/.claude/settings.local.json +11 -0
  2. package/CLAUDE.md +54 -0
  3. package/nodes/alice-color.js +208 -231
  4. package/nodes/alice-device.html +6 -1
  5. package/nodes/alice-device.js +252 -286
  6. package/nodes/alice-event.js +110 -114
  7. package/nodes/alice-get.html +91 -0
  8. package/nodes/alice-get.js +9 -0
  9. package/nodes/alice-mode.js +136 -145
  10. package/nodes/alice-onoff.js +126 -130
  11. package/nodes/alice-range.js +144 -150
  12. package/nodes/alice-sensor.html +0 -2
  13. package/nodes/alice-sensor.js +101 -106
  14. package/nodes/alice-togle.js +118 -125
  15. package/nodes/alice-video.js +88 -132
  16. package/nodes/alice.js +127 -122
  17. package/nodes/types.js +3 -0
  18. package/package.json +22 -8
  19. package/src/alice-color.html +255 -0
  20. package/src/alice-color.ts +227 -0
  21. package/src/alice-device.html +94 -0
  22. package/src/alice-device.ts +301 -0
  23. package/src/alice-event.html +148 -0
  24. package/src/alice-event.ts +112 -0
  25. package/src/alice-get.html +67 -6
  26. package/src/alice-get.ts +12 -15
  27. package/src/alice-mode.html +296 -0
  28. package/src/alice-mode.ts +139 -0
  29. package/src/alice-onoff.html +93 -0
  30. package/src/alice-onoff.ts +132 -0
  31. package/src/alice-range.html +293 -0
  32. package/src/alice-range.ts +144 -0
  33. package/src/alice-sensor.html +307 -0
  34. package/src/alice-sensor.ts +103 -0
  35. package/src/alice-togle.html +96 -0
  36. package/src/alice-togle.ts +122 -0
  37. package/src/alice-video.html +90 -0
  38. package/src/alice-video.ts +99 -0
  39. package/src/alice.html +242 -0
  40. package/src/alice.ts +146 -0
  41. package/src/types.ts +157 -0
  42. package/tsconfig.json +13 -106
  43. package/.eslintrc.json +0 -20
@@ -1,132 +1,88 @@
1
- module.exports = function(RED) {
2
- // ************** VIDEO *******************
3
- function AliceVideo(config){
4
- RED.nodes.createNode(this,config);
5
- const device = RED.nodes.getNode(config.device);
6
- device.setMaxListeners(device.getMaxListeners() + 1); // увеличиваем лимит для event
7
- const id =this.id;
8
- const name = config.name;
9
- const ctype = 'devices.capabilities.video_stream';
10
- const instance = 'get_stream';
11
- const stream_url = config.stream_url;
12
- const protocol = config.protocol;
13
- const response = true;
14
- const retrievable = false;
15
- const reportable = false;
16
- let initState = false;
17
- let curentState = {
18
- type:ctype,
19
- state:{
20
- instance: instance,
21
- value: {
22
- stream_url: stream_url,
23
- protocol: protocol
24
- }
25
- }
26
- };
27
-
28
- this.status({fill:"red",shape:"dot",text:"offline"});
29
-
30
- this.init = ()=>{
31
- this.debug("Starting capability initilization ...");
32
- let capab = {
33
- type: ctype,
34
- retrievable: retrievable,
35
- reportable: reportable,
36
- parameters: {
37
- instance: instance,
38
- protocols: [protocol]
39
- }
40
- };
41
-
42
- device.setCapability(id,capab)
43
- .then(res=>{
44
- this.debug("Capability initilization - success!");
45
- initState = true;
46
- this.status({fill:"green",shape:"dot",text:"online"});
47
- })
48
- .catch(err=>{
49
- this.error("Error on create capability: " + err.message);
50
- this.status({fill:"red",shape:"dot",text:"Error"});
51
- });
52
- device.updateCapabState(id,curentState)
53
- .then (res=>{
54
- this.status({fill:"green",shape:"dot",text:"online"});
55
- })
56
- .catch(err=>{
57
- this.error("Error on update capability state: " + err.message);
58
- this.status({fill:"red",shape:"dot",text:"Error"});
59
- });
60
- };
61
-
62
- // Проверяем сам девайс уже инициирован
63
- if (device.initState) this.init();
64
-
65
- device.on("online",()=>{
66
- this.init();
67
- });
68
-
69
- device.on("offline",()=>{
70
- this.status({fill:"red",shape:"dot",text:"offline"});
71
- });
72
-
73
- device.on(id,(val)=>{
74
- // this.send({
75
- // payload: val
76
- // });
77
- if (response){
78
- // curentState.state.value = val;
79
- device.updateCapabState(id,curentState)
80
- .then (res=>{
81
- str_url = stream_url.slice(0,25) + "...";
82
- this.status({fill:"green",shape:"dot",text:str_url});
83
- })
84
- .catch(err=>{
85
- this.error("Error on update capability state: " + err.message);
86
- this.status({fill:"red",shape:"dot",text:"Error"});
87
- })
88
- };
89
- })
90
-
91
- // this.on('input', (msg, send, done)=>{
92
- // if (typeof msg.payload != 'boolean'){
93
- // this.error("Wrong type! msg.payload must be boolean.");
94
- // if (done) {done();}
95
- // return;
96
- // };
97
- // if (msg.payload === curentState.state.value){
98
- // this.debug("Value not changed. Cancel update");
99
- // if (done) {done();}
100
- // return;
101
- // };
102
- // curentState.state.value = msg.payload;
103
- // device.updateCapabState(id,curentState)
104
- // .then(ref=>{
105
- // this.status({fill:"green",shape:"dot",text:msg.payload.toString()});
106
- // if (done) {done();}
107
- // })
108
- // .catch(err=>{
109
- // this.error("Error on update capability state: " + err.message);
110
- // this.status({fill:"red",shape:"dot",text:"Error"});
111
- // if (done) {done();}
112
- // })
113
- // });
114
-
115
- this.on('close', (removed, done)=>{
116
- device.setMaxListeners(device.getMaxListeners() - 1);
117
- if (removed) {
118
- device.delCapability(id)
119
- .then(res=>{
120
- done()
121
- })
122
- .catch(err=>{
123
- this.error("Error on delete capability: " + err.message);
124
- done();
125
- })
126
- };
127
- done();
128
- return;
129
- });
130
- }
131
- RED.nodes.registerType("Video",AliceVideo);
132
- };
1
+ "use strict";
2
+ module.exports = (RED) => {
3
+ function AliceVideo(config) {
4
+ RED.nodes.createNode(this, config);
5
+ const device = RED.nodes.getNode(config.device);
6
+ device.setMaxListeners(device.getMaxListeners() + 1);
7
+ const id = this.id;
8
+ const ctype = 'devices.capabilities.video_stream';
9
+ const instance = 'get_stream';
10
+ const stream_url = config.stream_url;
11
+ const protocol = config.protocol;
12
+ const curentState = {
13
+ type: ctype,
14
+ state: {
15
+ instance: instance,
16
+ value: {
17
+ stream_url: stream_url,
18
+ protocol: protocol
19
+ }
20
+ }
21
+ };
22
+ this.status({ fill: "red", shape: "dot", text: "offline" });
23
+ const init = () => {
24
+ this.debug("Starting capability initilization ...");
25
+ const capab = {
26
+ type: ctype,
27
+ retrievable: false,
28
+ reportable: false,
29
+ parameters: {
30
+ instance: instance,
31
+ protocols: [protocol]
32
+ }
33
+ };
34
+ device.setCapability(id, capab)
35
+ .then(() => {
36
+ this.debug("Capability initilization - success!");
37
+ this.status({ fill: "green", shape: "dot", text: "online" });
38
+ })
39
+ .catch(err => {
40
+ this.error("Error on create capability: " + err.message);
41
+ this.status({ fill: "red", shape: "dot", text: "Error" });
42
+ });
43
+ device.updateCapabState(id, curentState)
44
+ .then(() => {
45
+ this.status({ fill: "green", shape: "dot", text: "online" });
46
+ })
47
+ .catch(err => {
48
+ this.error("Error on update capability state: " + err.message);
49
+ this.status({ fill: "red", shape: "dot", text: "Error" });
50
+ });
51
+ };
52
+ if (device.initState)
53
+ init();
54
+ device.on("online", () => {
55
+ init();
56
+ });
57
+ device.on("offline", () => {
58
+ this.status({ fill: "red", shape: "dot", text: "offline" });
59
+ });
60
+ device.on(id, () => {
61
+ device.updateCapabState(id, curentState)
62
+ .then(() => {
63
+ const str_url = stream_url.slice(0, 25) + "...";
64
+ this.status({ fill: "green", shape: "dot", text: str_url });
65
+ })
66
+ .catch(err => {
67
+ this.error("Error on update capability state: " + err.message);
68
+ this.status({ fill: "red", shape: "dot", text: "Error" });
69
+ });
70
+ });
71
+ this.on('close', (removed, done) => {
72
+ device.setMaxListeners(device.getMaxListeners() - 1);
73
+ if (removed) {
74
+ device.delCapability(id)
75
+ .then(() => { done(); })
76
+ .catch(err => {
77
+ this.error("Error on delete capability: " + err.message);
78
+ done();
79
+ });
80
+ }
81
+ else {
82
+ done();
83
+ }
84
+ });
85
+ }
86
+ RED.nodes.registerType("Video", AliceVideo);
87
+ };
88
+ //# sourceMappingURL=alice-video.js.map
package/nodes/alice.js CHANGED
@@ -1,125 +1,130 @@
1
- const mqtt = require('mqtt');
2
- const axios = require('axios');
3
-
4
- module.exports = function(RED) {
5
- //Sevice node, Alice-Service (credential)
6
- function AliceService(config) {
7
- RED.nodes.createNode(this,config);
8
- this.debug("Starting Alice service...");
9
-
10
- const email = this.credentials.email;
11
- const login = this.credentials.id;
12
- const password = this.credentials.password;
13
- const token = this.credentials.token;
14
-
15
- const suburl = Buffer.from(email).toString('base64');
16
- RED.httpAdmin.get("/noderedhome/"+suburl+"/clearalldevice",(req,res)=>{
17
- const option = {
18
- method: 'POST',
19
- url: 'https://api.nodered-home.ru/gtw/device/clearallconfigs',
20
- headers: {
21
- 'content-type': 'application/json',
22
- 'Authorization': "Bearer "+this.getToken()
23
- },
24
- data: {}
25
- };
26
- axios.request(option)
27
- .then(result=>{
28
- this.trace("All devices configs deleted on gateway successfully");
29
- // console.log(result)
30
- res.sendStatus(200);
31
- })
32
- .catch(error=>{
33
- this.debug("Error when delete All devices configs deleted on gateway: "+error.message);
34
- res.sendStatus(500);
35
- });
36
- });
37
-
38
- this.isOnline = false;
39
- if (!token){
40
- this.error("Authentication is required!!!");
41
- return;
42
- };
43
- const mqttClient = mqtt.connect("mqtts://mqtt.cloud.yandex.net",{
44
- port: 8883,
45
- clientId: login,
46
- rejectUnauthorized: false,
47
- username: login,
48
- password: password,
49
- reconnectPeriod: 10000
50
- });
51
- mqttClient.on("message",(topic, payload)=>{
52
- const arrTopic = topic.split('/');
53
- const data = JSON.parse(payload);
54
- this.trace("Incoming:" + topic +" timestamp:"+new Date().getTime());
55
- if (payload.length && typeof data === 'object'){
56
- if (arrTopic[3]=='message'){
57
- this.warn(data.text);
58
- }else{
59
- this.emit(arrTopic[3],data);
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
+ module.exports = (RED) => {
8
+ function AliceService(config) {
9
+ RED.nodes.createNode(this, config);
10
+ this.debug("Starting Alice service... ID: " + this.id);
11
+ const email = this.credentials.email;
12
+ const login = this.credentials.id;
13
+ const password = this.credentials.password;
14
+ const token = this.credentials.token;
15
+ const suburl = Buffer.from(email).toString('base64');
16
+ RED.httpAdmin.get("/noderedhome/" + suburl + "/clearalldevice", (_req, res) => {
17
+ axios_1.default.request({
18
+ method: 'POST',
19
+ url: 'https://api.nodered-home.ru/gtw/device/clearallconfigs',
20
+ headers: {
21
+ 'content-type': 'application/json',
22
+ 'Authorization': "Bearer " + this.getToken()
23
+ },
24
+ data: {}
25
+ })
26
+ .then(() => {
27
+ this.trace("All devices configs deleted on gateway successfully");
28
+ res.sendStatus(200);
29
+ })
30
+ .catch(error => {
31
+ this.debug("Error when delete All devices configs deleted on gateway: " + error.message);
32
+ res.sendStatus(500);
33
+ });
34
+ });
35
+ RED.httpAdmin.get("/noderedhome/" + this.id + "/getfullconfig", (_req, res) => {
36
+ axios_1.default.request({
37
+ method: 'GET',
38
+ url: 'https://api.iot.yandex.net/v1.0/user/info',
39
+ headers: {
40
+ 'content-type': 'application/json',
41
+ 'Authorization': "Bearer " + this.getToken()
42
+ }
43
+ })
44
+ .then(result => {
45
+ this.trace("Full Alice SmartHome config successfully retrieved");
46
+ res.json(result.data);
47
+ })
48
+ .catch(error => {
49
+ this.debug("Error when retrieve Alice SmartHome config: " + error.message);
50
+ res.sendStatus(500);
51
+ });
52
+ });
53
+ this.isOnline = false;
54
+ if (!token) {
55
+ this.error("Authentication is required!!!");
56
+ return;
57
+ }
58
+ const mqttClient = mqtt_1.default.connect("mqtts://mqtt.cloud.yandex.net", {
59
+ port: 8883,
60
+ clientId: login,
61
+ rejectUnauthorized: false,
62
+ username: login,
63
+ password: password,
64
+ reconnectPeriod: 10000
65
+ });
66
+ mqttClient.on("message", (topic, payload) => {
67
+ const arrTopic = topic.split('/');
68
+ const data = JSON.parse(payload.toString());
69
+ this.trace("Incoming:" + topic + " timestamp:" + new Date().getTime());
70
+ if (payload.length && typeof data === 'object') {
71
+ if (arrTopic[3] == 'message') {
72
+ this.warn(data.text);
73
+ }
74
+ else {
75
+ this.emit(arrTopic[3], data);
76
+ }
77
+ }
78
+ });
79
+ mqttClient.on("connect", () => {
80
+ this.debug("Yandex IOT client connected. ");
81
+ this.emit('online');
82
+ mqttClient.subscribe("$me/device/commands/+", () => {
83
+ this.debug("Yandex IOT client subscribed to the command");
84
+ });
85
+ });
86
+ mqttClient.on("offline", () => {
87
+ this.debug("Yandex IOT client offline. ");
88
+ this.emit('offline');
89
+ });
90
+ mqttClient.on("disconnect", () => {
91
+ this.debug("Yandex IOT client disconnect.");
92
+ this.emit('offline');
93
+ });
94
+ mqttClient.on("reconnect", () => {
95
+ this.debug("Yandex IOT client reconnecting ...");
96
+ });
97
+ mqttClient.on("error", (err) => {
98
+ this.error("Yandex IOT client Error: " + err.message);
99
+ this.emit('offline');
100
+ });
101
+ this.on('offline', () => {
102
+ this.isOnline = false;
103
+ });
104
+ this.on('online', () => {
105
+ this.isOnline = true;
106
+ });
107
+ this.on('close', (done) => {
108
+ this.emit('offline');
109
+ setTimeout(() => {
110
+ mqttClient.end(false, {}, done);
111
+ }, 500);
112
+ });
113
+ this.send2gate = (path, data, retain) => {
114
+ this.trace("Outgoing: " + path);
115
+ mqttClient.publish(path, data, { qos: 0, retain: retain });
116
+ };
117
+ this.getToken = () => {
118
+ return JSON.parse(token).access_token;
60
119
  };
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
120
  }
121
- });
121
+ RED.nodes.registerType("alice-service", AliceService, {
122
+ credentials: {
123
+ email: { type: "text" },
124
+ password: { type: "password" },
125
+ token: { type: "password" },
126
+ id: { type: "text" }
127
+ }
128
+ });
122
129
  };
123
-
124
-
125
-
130
+ //# sourceMappingURL=alice.js.map
package/nodes/types.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
package/package.json CHANGED
@@ -1,13 +1,11 @@
1
1
  {
2
2
  "name": "node-red-contrib-alice",
3
- "version": "2.2.4",
3
+ "version": "2.3.1",
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",
@@ -49,12 +47,28 @@
49
47
  "mqtt": "^4.3.8"
50
48
  },
51
49
  "devDependencies": {
52
- "@types/axios": "^0.14.0",
53
50
  "@types/node": "^20.11.16",
54
51
  "@types/node-red": "^1.3.4",
55
- "@typescript-eslint/eslint-plugin": "^6.20.0",
56
- "@typescript-eslint/parser": "^6.20.0",
57
- "eslint": "^8.56.0",
52
+ "nodemon": "^3.0.3",
58
53
  "typescript": "^5.3.3"
54
+ },
55
+ "nodemonConfig": {
56
+ "ignoreRoot": [".git", "test"],
57
+ "restartable": "rs",
58
+ "ignore": [
59
+ "node_modules/**/node_modules",
60
+ "node_modules/**/test",
61
+ "*.log"
62
+ ],
63
+ "verbose": true,
64
+ "delay": "1000",
65
+ "events": {
66
+ "restart": "echo ------ restarted due to: $FILENAME ------"
67
+ },
68
+ "watch": [
69
+ "src/",
70
+ "node_modules/node-red-*"
71
+ ],
72
+ "ext": "js json htm html css"
59
73
  }
60
74
  }