node-red-contrib-alice 2.2.4 → 2.3.2

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.
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,115 +1,111 @@
1
- module.exports = function(RED) {
2
- // ************** ON/OFF *******************
3
- function AliceEvent(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 =JSON.parse(JSON.stringify(this.id));
8
- const name = config.name;
9
- const stype = 'devices.properties.event';
10
- const instance = config.instance;
11
- const reportable = true;
12
- const retrievable = false;
13
- const events = config.events;
14
- let initState = false;
15
- let curentState = {
16
- type:stype,
17
- state:{
18
- instance: instance,
19
- value: ''
20
- }
21
- };
22
- this.status({fill:"red",shape:"dot",text:"offline"});
23
-
24
- const init = ()=>{
25
- this.debug("Starting sensor initilization ...");
26
- let objEvents=[]
27
- events.forEach(v => {
28
- objEvents.push({value:v})
29
- });
30
- let sensor = {
31
- type: stype,
32
- reportable: reportable,
33
- retrievable: retrievable,
34
- parameters: {
35
- instance: instance,
36
- events: objEvents
37
- }
38
- };
39
-
40
- device.setSensor(id,sensor)
41
- .then(res=>{
42
- this.debug("Sensor initilization - success!");
43
- this.status({fill:"green",shape:"dot",text:"online"});
44
- initState = true;
45
- })
46
- .catch(err=>{
47
- this.error("Error on create sensor: " +err.message);
48
- this.status({fill:"red",shape:"dot",text:"error"});
1
+ "use strict";
2
+ module.exports = (RED) => {
3
+ function AliceEvent(config) {
4
+ RED.nodes.createNode(this, config);
5
+ const device = RED.nodes.getNode(config.device);
6
+ device.setMaxListeners(device.getMaxListeners() + 1);
7
+ const id = JSON.parse(JSON.stringify(this.id));
8
+ const stype = 'devices.properties.event';
9
+ const instance = config.instance;
10
+ const events = config.events;
11
+ let initState = false;
12
+ const curentState = {
13
+ type: stype,
14
+ state: {
15
+ instance: instance,
16
+ value: ''
17
+ }
18
+ };
19
+ this.status({ fill: "red", shape: "dot", text: "offline" });
20
+ const init = () => {
21
+ this.debug("Starting sensor initilization ...");
22
+ const objEvents = events.map(v => ({ value: v }));
23
+ const sensor = {
24
+ type: stype,
25
+ reportable: true,
26
+ retrievable: false,
27
+ parameters: {
28
+ instance: instance,
29
+ events: objEvents
30
+ }
31
+ };
32
+ device.setSensor(id, sensor)
33
+ .then(() => {
34
+ this.debug("Sensor initilization - success!");
35
+ this.status({ fill: "green", shape: "dot", text: "online" });
36
+ initState = true;
37
+ })
38
+ .catch(err => {
39
+ this.error("Error on create sensor: " + err.message);
40
+ this.status({ fill: "red", shape: "dot", text: "error" });
41
+ });
42
+ };
43
+ if (device.initState)
44
+ init();
45
+ device.on("online", () => {
46
+ if (!initState) {
47
+ init();
48
+ }
49
+ else {
50
+ this.status({ fill: "green", shape: "dot", text: curentState.state.value });
51
+ }
49
52
  });
50
- };
51
-
52
- // Проверяем сам девайс уже инициирован
53
- if (device.initState) init();
54
-
55
- device.on("online",()=>{
56
- if (!initState){
57
- init();
58
- }else{
59
- this.status({fill:"green",shape:"dot",text: curentState.state.value});
60
- };
61
- });
62
-
63
- device.on("offline",()=>{
64
- this.status({fill:"red",shape:"dot",text:"offline"});
65
- });
66
-
67
- this.on('input', (msg, send, done)=>{
68
- if (!events.includes(msg.payload)){
69
- this.error("Wrong type! msg.payload must be from the list of allowed events.");
70
- if (done) {done();}
71
- return;
72
- };
73
- if (curentState.state.value==msg.payload){
74
- this.debug("Value not changed. Cancel update");
75
- if (done) {done();}
76
- return;
77
- }else{
78
- curentState.state.value = msg.payload;
79
- };
80
- // для кнопок обнуляем значение через 1 сек
81
- if (instance=='button'){
82
- setTimeout(() => {
83
- curentState.state.value = null;
84
- this.status({fill:"green",shape:"dot",text:""});
85
- }, 1000);
86
- };
87
- device.updateSensorState(id,curentState)
88
- .then(ref=>{
89
- this.status({fill:"green",shape:"dot",text: curentState.state.value});
90
- if (done) {done();}
91
- })
92
- .catch(err=>{
93
- this.error("Error on update sensor state: " +err.message);
94
- this.status({fill:"red",shape:"dot",text:"Error"});
95
- if (done) {done();}
96
- })
97
- });
98
-
99
- this.on('close', function(removed, done) {
100
- if (removed) {
101
- device.delSensor(id)
102
- .then(res=>{
103
- done()
104
- })
105
- .catch(err=>{
106
- this.error("Error on delete property: " +err.message);
107
- done();
108
- })
109
- }else{
110
- done();
111
- }
112
- });
113
- }
114
- RED.nodes.registerType("Event",AliceEvent);
115
- };
53
+ device.on("offline", () => {
54
+ this.status({ fill: "red", shape: "dot", text: "offline" });
55
+ });
56
+ this.on('input', (msg, _send, done) => {
57
+ if (!events.includes(msg.payload)) {
58
+ this.error("Wrong type! msg.payload must be from the list of allowed events.");
59
+ if (done) {
60
+ done();
61
+ }
62
+ return;
63
+ }
64
+ if (curentState.state.value == msg.payload) {
65
+ this.debug("Value not changed. Cancel update");
66
+ if (done) {
67
+ done();
68
+ }
69
+ return;
70
+ }
71
+ else {
72
+ curentState.state.value = msg.payload;
73
+ }
74
+ if (instance == 'button') {
75
+ setTimeout(() => {
76
+ curentState.state.value = null;
77
+ this.status({ fill: "green", shape: "dot", text: "" });
78
+ }, 1000);
79
+ }
80
+ device.updateSensorState(id, curentState)
81
+ .then(() => {
82
+ this.status({ fill: "green", shape: "dot", text: curentState.state.value });
83
+ if (done) {
84
+ done();
85
+ }
86
+ })
87
+ .catch(err => {
88
+ this.error("Error on update sensor state: " + err.message);
89
+ this.status({ fill: "red", shape: "dot", text: "Error" });
90
+ if (done) {
91
+ done();
92
+ }
93
+ });
94
+ });
95
+ this.on('close', (removed, done) => {
96
+ if (removed) {
97
+ device.delSensor(id)
98
+ .then(() => { done(); })
99
+ .catch(err => {
100
+ this.error("Error on delete property: " + err.message);
101
+ done();
102
+ });
103
+ }
104
+ else {
105
+ done();
106
+ }
107
+ });
108
+ }
109
+ RED.nodes.registerType("Event", AliceEvent);
110
+ };
111
+ //# sourceMappingURL=alice-event.js.map
@@ -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>
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ module.exports = (RED) => {
3
+ function AliceGet(config) {
4
+ RED.nodes.createNode(this, config);
5
+ const _service = RED.nodes.getNode(config.service);
6
+ }
7
+ RED.nodes.registerType("Alice-Get", AliceGet);
8
+ };
9
+ //# sourceMappingURL=alice-get.js.map
@@ -1,146 +1,137 @@
1
- module.exports = function(RED) {
2
- // ************** Modes *******************
3
- function AliceMode(config){
4
- RED.nodes.createNode(this,config);
5
- this.device = RED.nodes.getNode(config.device);
6
- this.name = config.name;
7
- this.ctype = 'devices.capabilities.mode';
8
- this.retrievable = true;
9
- this.random_access = true;
10
- this.response = config.response;
11
- this.instance = config.instance;
12
- this.modes = config.modes;
13
- this.initState = false;
14
- this.value;
15
-
16
- if (config.response === undefined){
17
- this.response = true;
18
- }
19
-
20
- this.init = _=>{
21
- if (this.modes.length<1){
22
- this.status({fill:"red",shape:"dot",text:"error"});
23
- this.error("In the list of supported commands, there must be at least one command");
24
- return;
25
- };
26
- if (!this.instance){
27
- this.status({fill:"red",shape:"dot",text:"error"});
28
- this.error("Mode type not selected");
29
- return;
30
- };
31
- var cfgModes = [];
32
- this.modes.forEach(v=>{
33
- cfgModes.push({value:v});
34
- });
35
- let capab = {
36
- type: this.ctype,
37
- retrievable: this.retrievable,
38
- reportable: true,
39
- parameters: {
40
- instance: this.instance,
41
- modes: cfgModes
42
- }
43
- };
44
- this.device.setCapability(this.id,capab)
45
- .then(res=>{
46
- this.initState = true;
47
- this.status({fill:"green",shape:"dot",text:"online"});
48
- })
49
- .catch(err=>{
50
- this.error("Error on create capability: " + err.message);
51
- this.status({fill:"red",shape:"dot",text:"error"});
52
- });
53
- };
54
-
55
- // Проверяем сам девайс уже инициирован
56
- if (this.device.initState) this.init();
57
-
58
- this.device.on("online",()=>{
59
- this.init();
60
- });
61
-
62
- this.device.on("offline",()=>{
63
- this.status({fill:"red",shape:"dot",text:"offline"});
64
- });
65
-
66
- this.device.on(this.id,(val,fullstate)=>{
67
- let value = val;
68
- this.send({
69
- payload: value
70
- });
71
- let state= {
72
- type:this.ctype,
73
- state:{
74
- instance: this.instance,
75
- value: value
1
+ "use strict";
2
+ module.exports = (RED) => {
3
+ function AliceMode(config) {
4
+ RED.nodes.createNode(this, config);
5
+ const device = RED.nodes.getNode(config.device);
6
+ const ctype = 'devices.capabilities.mode';
7
+ const instance = config.instance || '';
8
+ const modes = config.modes;
9
+ let response = config.response;
10
+ let value;
11
+ if (config.response === undefined) {
12
+ response = true;
76
13
  }
77
- };
78
- if (this.response){
79
- this.device.updateCapabState(this.id,state)
80
- .then (res=>{
81
- this.value = value;
82
- this.status({fill:"green",shape:"dot",text:"online"});
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
- const value = msg.payload;
93
- if (typeof value != 'string'){
94
- this.error("Wrong type! msg.payload must be String.");
95
- this.status({fill:"red",shape:"dot",text:"Error"});
96
- if (done) {done();}
97
- return;
98
- };
99
- if (this.modes.indexOf(value)<0){
100
- this.error("Error! Unsupported command.");
101
- this.status({fill:"red",shape:"dot",text:"Error"});
102
- if (done) {done();}
103
- return;
104
- };
105
- if (value === this.value){
106
- this.debug("Value not changed. Cancel update");
107
- if (done) {done();}
108
- return;
109
- };
110
- let state= {
111
- type:this.ctype,
112
- state:{
113
- instance: this.instance,
114
- value: value
115
- }
116
- };
117
- this.device.updateCapabState(this.id,state)
118
- .then(ref=>{
119
- this.value = value;
120
- this.status({fill:"green",shape:"dot",text:value});
121
- if (done) {done();}
122
- })
123
- .catch(err=>{
124
- this.error("Error on update capability state: " + err.message);
125
- this.status({fill:"red",shape:"dot",text:"Error"});
126
- if (done) {done();}
127
- });
128
- });
129
-
130
- this.on('close', function(removed, done) {
131
- if (removed) {
132
- this.device.delCapability(this.id)
133
- .then(res=>{
134
- done()
135
- })
136
- .catch(err=>{
137
- this.error("Error on delete capability: " + err.message);
138
- done();
139
- })
140
- }else{
141
- done();
142
- }
143
- });
144
- }
145
- RED.nodes.registerType("Mode",AliceMode);
146
- };
14
+ const init = () => {
15
+ if (modes.length < 1) {
16
+ this.status({ fill: "red", shape: "dot", text: "error" });
17
+ this.error("In the list of supported commands, there must be at least one command");
18
+ return;
19
+ }
20
+ if (!instance) {
21
+ this.status({ fill: "red", shape: "dot", text: "error" });
22
+ this.error("Mode type not selected");
23
+ return;
24
+ }
25
+ const cfgModes = modes.map(v => ({ value: v }));
26
+ const capab = {
27
+ type: ctype,
28
+ retrievable: true,
29
+ reportable: true,
30
+ parameters: {
31
+ instance: instance,
32
+ modes: cfgModes
33
+ }
34
+ };
35
+ device.setCapability(this.id, capab)
36
+ .then(() => {
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
+ };
44
+ if (device.initState)
45
+ init();
46
+ device.on("online", () => {
47
+ init();
48
+ });
49
+ device.on("offline", () => {
50
+ this.status({ fill: "red", shape: "dot", text: "offline" });
51
+ });
52
+ device.on(this.id, (val) => {
53
+ this.send({ payload: val });
54
+ const state = {
55
+ type: ctype,
56
+ state: {
57
+ instance: instance,
58
+ value: val
59
+ }
60
+ };
61
+ if (response) {
62
+ device.updateCapabState(this.id, state)
63
+ .then(() => {
64
+ value = val;
65
+ this.status({ fill: "green", shape: "dot", text: "online" });
66
+ })
67
+ .catch(err => {
68
+ this.error("Error on update capability state: " + err.message);
69
+ this.status({ fill: "red", shape: "dot", text: "Error" });
70
+ });
71
+ }
72
+ });
73
+ this.on('input', (msg, _send, done) => {
74
+ const newValue = msg.payload;
75
+ if (typeof newValue != 'string') {
76
+ this.error("Wrong type! msg.payload must be String.");
77
+ this.status({ fill: "red", shape: "dot", text: "Error" });
78
+ if (done) {
79
+ done();
80
+ }
81
+ return;
82
+ }
83
+ if (modes.indexOf(newValue) < 0) {
84
+ this.error("Error! Unsupported command.");
85
+ this.status({ fill: "red", shape: "dot", text: "Error" });
86
+ if (done) {
87
+ done();
88
+ }
89
+ return;
90
+ }
91
+ if (newValue === value) {
92
+ this.debug("Value not changed. Cancel update");
93
+ if (done) {
94
+ done();
95
+ }
96
+ return;
97
+ }
98
+ const state = {
99
+ type: ctype,
100
+ state: {
101
+ instance: instance,
102
+ value: newValue
103
+ }
104
+ };
105
+ device.updateCapabState(this.id, state)
106
+ .then(() => {
107
+ value = newValue;
108
+ this.status({ fill: "green", shape: "dot", text: newValue });
109
+ if (done) {
110
+ done();
111
+ }
112
+ })
113
+ .catch(err => {
114
+ this.error("Error on update capability state: " + err.message);
115
+ this.status({ fill: "red", shape: "dot", text: "Error" });
116
+ if (done) {
117
+ done();
118
+ }
119
+ });
120
+ });
121
+ this.on('close', (removed, done) => {
122
+ if (removed) {
123
+ device.delCapability(this.id)
124
+ .then(() => { done(); })
125
+ .catch(err => {
126
+ this.error("Error on delete capability: " + err.message);
127
+ done();
128
+ });
129
+ }
130
+ else {
131
+ done();
132
+ }
133
+ });
134
+ }
135
+ RED.nodes.registerType("Mode", AliceMode);
136
+ };
137
+ //# sourceMappingURL=alice-mode.js.map