node-red-contrib-yandex-station-management 0.3.3 → 0.3.4

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.
@@ -0,0 +1,52 @@
1
+ 'use strict';
2
+
3
+ class stationHelper {
4
+
5
+ static preparePayload(node, message) {
6
+ let payload = {};
7
+ if (node.output == 'status') {
8
+ payload = { 'payload': message }
9
+ } else if (node.output == 'homekit') {
10
+ let playing = false;
11
+ if (typeof(message.playing) !== 'undefined') {
12
+ playing = message.playing;
13
+ }
14
+ if (node.homekitFormat == 'speaker') {
15
+ let subtitle = 'No Artist';
16
+ let title = 'No Track Name';
17
+
18
+ if (typeof(message.playerState) !== 'undefined') {
19
+ let playerState = message.playerState;
20
+ if (typeof(playerState.subtitle) !== 'undefined') {
21
+ subtitle = playerState.subtitle;
22
+ }
23
+ if (typeof(playerState.title) !== 'undefined') {
24
+ title = playerState.title;
25
+ }
26
+ }
27
+
28
+ let ConfiguredName = `${subtitle} - ${title}`;
29
+ if (ConfiguredName.length > 64) {
30
+ ConfiguredName = title.length <= 64 ? title : title.substr(0, 61) + `...`;
31
+ }
32
+
33
+ payload = {
34
+ 'payload': {
35
+ 'CurrentMediaState': (playing) ? 0 : 1,
36
+ 'ConfiguredName': ConfiguredName
37
+ }
38
+ }
39
+ } else if (node.homekitFormat == 'tv') {
40
+ payload = {
41
+ 'payload': {
42
+ 'Active': (playing) ? 1 : 0
43
+ }
44
+ }
45
+ }
46
+ }
47
+ return payload;
48
+ }
49
+
50
+ }
51
+
52
+ module.exports = stationHelper;
package/nodes/get.js CHANGED
@@ -1,4 +1,6 @@
1
1
  module.exports = function(RED) {
2
+ const stationHelper = require('../lib/stationHelper.js');
3
+
2
4
  function AliceLocalGetNode(config) {
3
5
  RED.nodes.createNode(this,config);
4
6
  let node = this;
@@ -16,43 +18,15 @@ module.exports = function(RED) {
16
18
  node.log(text);
17
19
  }
18
20
  }
19
- function preparePayload(message,inputMsg){
20
- //let payload = {};
21
- if (node.output == 'status') {
22
- inputMsg.payload = message;
23
- } else if (node.output == 'homekit') {
24
- try {
25
- if (node.homekitFormat == 'speaker') {
26
- let ConfiguredName = `${(message.playerState.subtitle) ? message.playerState.subtitle : 'No Artist'} - ${(message.playerState.title) ? message.playerState.title : 'No Track Name'}`;
27
- let title = `${message.playerState.title}`;
28
- if (ConfiguredName.length > 64 && title.length > 0 && title.length <= 64) {
29
- ConfiguredName = title;
30
- } else {
31
- ConfiguredName = title.substr(0, 61) + `...`;
32
- }
33
- (message.playerState)? inputMsg.payload = {
34
- "CurrentMediaState": (message.playing) ? 0 : 1,
35
- "ConfiguredName": ConfiguredName
36
- } :inputMsg.payload = {
37
- "CurrentMediaState": (message.playing) ? 0 : 1,
38
- "ConfiguredName": `No Artist - No Track Name`
39
- }
40
- }else if (node.homekitFormat == 'tv') {
41
- inputMsg.payload = {
42
- "Active": (message.playing) ? 1 : 0
43
- }
44
-
45
- }
46
- } catch (error) {
47
- debugMessage(`Error while preparing payload: `+ e);
48
- }
49
21
 
22
+ function _preparePayload(message, inputMsg) {
23
+ let prepare = stationHelper.preparePayload(node, message);
24
+ if (typeof(prepare.payload) !== 'undefined') {
25
+ inputMsg.payload = prepare.payload;
50
26
  }
51
- return inputMsg;
52
-
27
+ return inputMsg;
53
28
  }
54
29
 
55
-
56
30
  node.onStatus = function(data) {
57
31
  if (data) {
58
32
  node.status({fill: `${data.color}`,shape:"dot",text: `${data.text}`});
@@ -61,7 +35,7 @@ module.exports = function(RED) {
61
35
  }
62
36
  node.onInput = function(msg, send, done){
63
37
  debugMessage('current state: ' + JSON.stringify(node.lastState));
64
- ( 'aliceState' in node.lastState )?node.send(preparePayload(node.lastState,msg)):node.send(msg)
38
+ ( 'aliceState' in node.lastState )?node.send(_preparePayload(node.lastState,msg)):node.send(msg)
65
39
  }
66
40
  node.onMessage = function(message){
67
41
  node.lastState = message;
package/nodes/in.js CHANGED
@@ -1,4 +1,6 @@
1
1
  module.exports = function(RED) {
2
+ const stationHelper = require('../lib/stationHelper.js');
3
+
2
4
  function AliceLocalInNode(config) {
3
5
  RED.nodes.createNode(this,config);
4
6
  let node = this;
@@ -20,42 +22,6 @@ module.exports = function(RED) {
20
22
  }
21
23
  }
22
24
 
23
-
24
- function preparePayload(message){
25
- let payload = {};
26
- if (node.output == 'status') {
27
- payload = {'payload': message}
28
- } else if (node.output == 'homekit') {
29
- try {
30
- if (node.homekitFormat == 'speaker') {
31
- let ConfiguredName = `${(message.playerState.subtitle) ? message.playerState.subtitle : 'No Artist'} - ${(message.playerState.title) ? message.playerState.title : 'No Track Name'}`;
32
- let title = `${message.playerState.title}`;
33
- if (ConfiguredName.length > 64 && title.length > 0 && title.length <= 64) {
34
- ConfiguredName = title;
35
- } else {
36
- ConfiguredName = title.substr(0, 61) + `...`;
37
- }
38
- (message.playerState)? payload = {'payload': {
39
- "CurrentMediaState": (message.playing) ? 0 : 1,
40
- "ConfiguredName": ConfiguredName
41
- } }:payload = {'payload': {
42
- "CurrentMediaState": (message.playing) ? 0 : 1,
43
- "ConfiguredName": `No Artists - No Track Name`
44
- } }
45
- }else if (node.homekitFormat == 'tv') {
46
- payload = {'payload': {
47
- "Active": (message.playing) ? 1 : 0
48
- }
49
- }
50
- }
51
- } catch(e) {
52
- debugMessage(`Error while preparing payload: `+ e)
53
- }
54
-
55
- }
56
- return payload;
57
-
58
- }
59
25
  function sendMessage(message){
60
26
  //debugMessage(JSON.stringify(message));
61
27
  if (node.uniqueFlag && node.output == 'homekit') {
@@ -71,7 +37,7 @@ module.exports = function(RED) {
71
37
  }
72
38
  node.onMessage = function(data){
73
39
  //debugMessage(JSON.stringify(data));
74
- sendMessage(preparePayload(data));
40
+ sendMessage(stationHelper.preparePayload(node, data));
75
41
  }
76
42
  node.onStatus = function(data) {
77
43
  if (data) {
@@ -18,27 +18,32 @@ module.exports = function(RED) {
18
18
  node.readyList = [];
19
19
  node.activeStationList = [];
20
20
  //node.skipCloudDevices = false;
21
-
22
-
21
+
22
+
23
23
  node.on('stopListening', onStopListening);
24
24
  node.on('startPlay', onStartPlay);
25
25
  node.on('stopPlay', onStopPlay);
26
26
  node.on('setVolume', onSetVolume);
27
27
  node.on('deviceReady', onDeviceReady);
28
28
  node.setMaxListeners(0)
29
-
29
+
30
30
  function debugMessage(text){
31
31
  if (node.debugFlag) {
32
- node.log(text);
32
+ try {
33
+ node.log(text);
34
+ } catch (error) {
35
+ node.log(error)
36
+ }
37
+
33
38
  }
34
39
  }
35
-
40
+
36
41
  let registrationBuffer = [];
37
-
42
+
38
43
  function deviceListProcessing(deviceList) {
39
44
  deviceList.forEach(device => {
40
45
  if (device.address && device.port ) {
41
-
46
+
42
47
  if (node.readyList.find(item => item.id == device.id)){
43
48
  //debugMessage('skipping');
44
49
  } else {
@@ -54,23 +59,23 @@ module.exports = function(RED) {
54
59
 
55
60
  async function getDevices(token)
56
61
  {
57
- let options =
58
- {
62
+ let options =
63
+ {
59
64
  method: 'GET',
60
65
  url: 'https://quasar.yandex.net/glagol/device_list',
61
- headers:
62
- {
66
+ headers:
67
+ {
63
68
  'Content-Type': 'application/json',
64
- 'Authorization': 'Oauth ' + token
65
- }
69
+ 'Authorization': 'Oauth ' + token
70
+ }
66
71
  };
67
- // вариант для снижения частоты запросов на серверы ЯНдекса для обновления списка устройств. Требует тестирования.
72
+ // вариант для снижения частоты запросов на серверы ЯНдекса для обновления списка устройств. Требует тестирования.
68
73
  /* if (node.skipCloudDevices) {
69
74
  discoverDevices(node.deviceList)
70
75
  .then(() => {
71
76
  //debugMessage(`calling processing for ${node.deviceList.length} devices`);
72
77
  deviceListProcessing(node.deviceList)
73
-
78
+
74
79
  });
75
80
  return node.deviceList;
76
81
  } */
@@ -91,7 +96,7 @@ module.exports = function(RED) {
91
96
  if (result != 2 && result != undefined) {
92
97
  registrationBuffer.splice(registrationBuffer.indexOf(bufferStation,1));
93
98
  }
94
-
99
+
95
100
  }
96
101
  node.activeStationList.push({ 'name': device.name, 'id': device.id, 'platform': device.platform, 'address': device.address, 'port': device.port});
97
102
  });
@@ -102,13 +107,13 @@ module.exports = function(RED) {
102
107
  .then(() => {
103
108
  //debugMessage(`calling processing for ${node.deviceList.length} devices`);
104
109
  deviceListProcessing(node.deviceList)
105
-
110
+
106
111
  });
107
112
  //debugMessage(node.id);
108
113
  return node.deviceList;
109
114
  } catch (error) {
110
115
  debugMessage(`Error while searching: ${error}`);
111
- }
116
+ }
112
117
 
113
118
  })
114
119
  .catch(function (err) {
@@ -126,7 +131,6 @@ module.exports = function(RED) {
126
131
  await mDnsSd.discover({
127
132
  name: '_yandexio._tcp.local'
128
133
  }).then((result) => {
129
- debugMessage(`MDNS. Found ${result.length} devices`);
130
134
  node.emit('refreshHttpDNS', result);
131
135
  if (result.length != 0){
132
136
  for (const device of deviceList) {
@@ -147,15 +151,15 @@ module.exports = function(RED) {
147
151
  } catch(e) {
148
152
  debugMessage(`Error searching hostname in mDNS answer`)
149
153
  }
150
-
154
+
151
155
  }
152
156
  }
153
- }
157
+ }
154
158
  })
155
-
159
+
156
160
  }
157
161
  }
158
-
162
+
159
163
  }).catch(function (err) {
160
164
  debugMessage(err);
161
165
  });
@@ -172,15 +176,15 @@ module.exports = function(RED) {
172
176
 
173
177
  async function getLocalToken(device) {
174
178
  let data;
175
- let options = {
179
+ let options = {
176
180
  method: 'GET',
177
181
  url: 'https://quasar.yandex.net/glagol/token',
178
182
  qs: { device_id: device.id, platform: device.platform },
179
- headers:
180
- {
183
+ headers:
184
+ {
181
185
  'Authorization': 'Oauth ' + node.token,
182
- 'Content-Type': 'application/json'
183
- }
186
+ 'Content-Type': 'application/json'
187
+ }
184
188
  };
185
189
  // debugMessage(JSON.stringify(options))
186
190
  statusUpdate({"color": "yellow", "text": "connecting..."}, device);
@@ -188,7 +192,8 @@ module.exports = function(RED) {
188
192
  .then(function(response)
189
193
  {
190
194
  data = JSON.parse(response);
191
- device.token = data.token
195
+ device.token = data.token;
196
+ debugMessage(`${device.id}: Recieved conversation new token`)
192
197
  })
193
198
  .catch(function (err) {
194
199
  removeDevice(node.readyList, device);
@@ -208,12 +213,12 @@ module.exports = function(RED) {
208
213
  connect(device)
209
214
  };
210
215
 
211
-
216
+
212
217
  function connect(device) {
213
218
  //connect only if !device.ws
214
219
  //debugMessage(`device.ws = ${JSON.stringify(device.ws)}`);
215
220
  if ( (device.connection == true || typeof(device.connection) == "undefined") && node.listenerCount(`statusUpdate_${device.id}`) > 0 ) {
216
- debugMessage(`Connecting to device ${device.id}. ws is ${JSON.stringify(device.ws)}. Listeners: ` + node.listenerCount(`statusUpdate_${device.id}`));
221
+ debugMessage(`Connecting to device ${device.id}. ws is ${device.ws}. Listeners: ` + node.listenerCount(`statusUpdate_${device.id}`));
217
222
  if (!device.ws) {
218
223
  debugMessage('recieving conversation token...');
219
224
  getLocalToken(device)
@@ -226,7 +231,7 @@ module.exports = function(RED) {
226
231
  })
227
232
  .catch(function (err) {
228
233
  debugMessage('Error while getting token: ' + err);
229
-
234
+
230
235
  });
231
236
  } else {
232
237
  if (device.ws.readyState == 3) {
@@ -258,16 +263,16 @@ module.exports = function(RED) {
258
263
  //}
259
264
  }
260
265
  } else {
261
- debugMessage(`${device.id} connection is disabled by settings in manager node ${device.manager} or you have not use any node for this station`)
262
- statusUpdate({"color": "red", "text": "disconnected"}, device);
266
+ //debugMessage(`${device.id} connection is disabled by settings in manager node ${device.manager} or you have not use any node for this station`)
267
+ //statusUpdate({"color": "red", "text": "disconnected"}, device);
263
268
  device.timer = setTimeout(connect, 60000, device);
264
269
 
265
270
  }
266
271
 
267
272
  }
268
-
273
+
269
274
  async function makeConn(device) {
270
-
275
+
271
276
  let options = {
272
277
  key: device.glagol.security.server_private_key,
273
278
  cert: device.glagol.security.server_certificate,
@@ -276,7 +281,9 @@ module.exports = function(RED) {
276
281
  device.lastState = {};
277
282
  debugMessage(`Connecting to wss://${device.address}:${device.port}`);
278
283
  device.ws = new WebSocket(`wss://${device.address}:${device.port}`, options);
279
- device.ws.on('open', function open(data) {
284
+ debugMessage(`${device.id}: Fire connection watchdog for 60 seconds`);
285
+ device.watchDogConn = setTimeout(() => {reconnect(device)}, 60000);
286
+ device.ws.on('open', function open(data) {
280
287
  debugMessage(`Connected to ${device.address}, data: ${data}`);
281
288
  sendMessage(device.id, 'command', {payload: 'ping'});
282
289
  statusUpdate({"color": "green", "text": "connected"}, device);
@@ -286,13 +293,15 @@ module.exports = function(RED) {
286
293
  device.waitForIdle = false;
287
294
  device.watchDog = setTimeout(() => device.ws.close(), 10000);
288
295
  device.pingInterval = setInterval(onPing,300,device);
296
+ debugMessage(`${device.id}: Kill connection watchdog`);
297
+ clearTimeout(device.watchDogConn);
289
298
  clearTimeout(device.timer);
290
299
  debugMessage(`readyState: ${device.ws.readyState}`)
291
300
  });
292
301
  device.ws.on('message', function incoming(data) {
293
302
  //debugMessage(`${device.id}: ${JSON.stringify(data)}`);
294
303
  let dataRecieved = JSON.parse(data);
295
- device.lastState = dataRecieved.state;
304
+ device.lastState = dataRecieved.state;
296
305
  device.fullMessage = JSON.stringify(dataRecieved);
297
306
  //debugMessage(checkSheduler(device, JSON.parse(data).sentTime));
298
307
  node.emit(`message_${device.id}`, device.lastState);
@@ -312,7 +321,7 @@ module.exports = function(RED) {
312
321
  if (device.lastState.playing && device.lastState.aliceState != 'LISTENING' && device.parameters.hasOwnProperty("sheduler")) {
313
322
  let res = checkSheduler(device, dataRecieved.sentTime)
314
323
  //debugMessage(`Result of cheking sheduler is ${res.toString}`);
315
- if (!res[0]) {
324
+ if (!res[0]) {
316
325
  if (device.shedulerFlag || device.shedulerFlag == undefined) {
317
326
  node.emit('stopPlay', device, res[1])
318
327
  device.shedulerFlag = false
@@ -324,7 +333,7 @@ module.exports = function(RED) {
324
333
  clearTimeout(device.watchDog);
325
334
  //debugMessage(`cleared timeout for ${device.id}`)
326
335
  device.watchDog = setTimeout(() => {device.ws.close()}, 10000);
327
- });
336
+ });
328
337
  //device.ws.on('ping', function);
329
338
  device.ws.on('close', function close(code, reason){
330
339
  statusUpdate({"color": "red", "text": "disconnected"}, device);
@@ -336,15 +345,15 @@ module.exports = function(RED) {
336
345
  debugMessage(`getting new token...`);
337
346
  connect(device);
338
347
  break;
339
- case 1000:
348
+ case 1000:
340
349
  debugMessage(`Closed connection code ${code} with reason ${reason}. Reconnecting...` );
341
350
  connect(device);
342
- break;
351
+ break;
343
352
  case 1006:
344
353
  debugMessage(`Lost server, reconnect in 60 seconds...${code} + ${reason}` );
345
354
  device.timer = setTimeout(connect, 60000, device);
346
355
  break;
347
-
356
+
348
357
  case 10000:
349
358
  debugMessage(`Reconnect device reason 10000 ${device.id}`);
350
359
  connect(device);
@@ -356,7 +365,7 @@ module.exports = function(RED) {
356
365
  }
357
366
 
358
367
 
359
- })
368
+ })
360
369
  device.ws.on('error', function error(data){
361
370
  //statusUpdate({"color": "red", "text": "disconnected"}, device);
362
371
  debugMessage(`error: ${data}`);
@@ -417,7 +426,7 @@ module.exports = function(RED) {
417
426
  return [{
418
427
  "command": "rewind",
419
428
  "position": 0
420
- }]
429
+ }]
421
430
  }
422
431
  } else if (message.payload == 'volumeup') {
423
432
  debugMessage(currentVolume);
@@ -425,7 +434,7 @@ module.exports = function(RED) {
425
434
  return [{
426
435
  "command": "setVolume",
427
436
  "volume": currentVolume + 0.1
428
- }]
437
+ }]
429
438
  }
430
439
  } else if (message.payload == 'volumedown') {
431
440
  debugMessage(currentVolume);
@@ -433,13 +442,13 @@ module.exports = function(RED) {
433
442
  return [{
434
443
  "command": "setVolume",
435
444
  "volume": currentVolume - 0.1
436
- }]
445
+ }]
437
446
  }
438
447
  } else if (message.payload == 'volume') {
439
448
  return [{
440
449
  "command": "setVolume",
441
450
  "volume": parseFloat(message.level)
442
- }]
451
+ }]
443
452
  }
444
453
 
445
454
  } else {
@@ -447,7 +456,7 @@ module.exports = function(RED) {
447
456
  //node.error(`You can send commands in msg.payload from list as String ${commands + extraCommands}`);
448
457
  return [{"command": "ping"}];
449
458
  }
450
- case 'voice':
459
+ case 'voice':
451
460
  debugMessage(`Message Voice command: ${message}`);
452
461
  return [{
453
462
  "command" : "sendText",
@@ -515,56 +524,84 @@ module.exports = function(RED) {
515
524
  return result;
516
525
  break;
517
526
  case 'homekit':
518
- debugMessage('HAP: ' + JSON.stringify(message) + ' PL: ' + JSON.stringify(message.payload) );
527
+ debugMessage('HAP: ' + JSON.stringify(message) + ' PL: ' + JSON.stringify(message.payload) );
519
528
  if ("session" in message.hap) {
520
- switch(JSON.stringify(message.payload)){
521
- case '{"TargetMediaState":1}':
522
- return messageConstructor('command', {'payload': 'stop'})
523
- case '{"Active":0}':
524
- return messageConstructor('command', {'payload': 'stop'})
525
- case '{"TargetMediaState":0}':
526
- case '{"Active":1}':
527
- if (!device.lastState.playerState && !device.playAfterTTS && message.noTrackPhrase) {
528
- return messageConstructor('voice', {'payload': message.noTrackPhrase})
529
- } else if (device.lastState.playerState.title != "" && !device.playAfterTTS){
530
- return messageConstructor('command', {'payload': 'play'})
531
- } else if (message.noTrackPhrase && !device.playAfterTTS) {
532
- return messageConstructor('voice', {'payload': message.noTrackPhrase})
533
- } else {
534
- return messageConstructor('command', {'payload': 'ping'})
529
+ let playing = false;
530
+ let id = null;
531
+ let noTrackPhrase = message.noTrackPhrase;
532
+
533
+ if (typeof (device.lastState) !== 'undefined') {
534
+ let lastState = device.lastState;
535
+ if (typeof (lastState.playing) !== 'undefined') {
536
+ playing = lastState.playing;
537
+ }
538
+ if (typeof (lastState.playerState) !== 'undefined') {
539
+ if (typeof (lastState.playerState.id) !== 'undefined') {
540
+ id = lastState.playerState.id;
535
541
  }
536
- case '{"RemoteKey":7}':
537
- return messageConstructor('command', {'payload': 'forward'}, device)
538
- case '{"RemoteKey":6}':
539
- return messageConstructor('command', {'payload': 'backward'}, device)
540
- case '{"RemoteKey":4}':
541
- return messageConstructor('command', {'payload': 'next'})
542
- case '{"RemoteKey":5}':
543
- return messageConstructor('command', {'payload': 'prev'})
544
- case '{"RemoteKey":11}':
545
- if (typeof device.lastState.playing !== "undefined") {
546
- if (device.lastState.playing){
547
- return messageConstructor('command', {'payload': 'stop'})
542
+ }
543
+ }
544
+
545
+ // speaker
546
+ if ("TargetMediaState" in message.payload) {
547
+ let TargetMediaState = message.payload.TargetMediaState;
548
+ if (id) {
549
+ return messageConstructor('command', { 'payload': (TargetMediaState ? 'stop' : 'play') })
550
+ } else if (!id && !TargetMediaState && noTrackPhrase) {
551
+ return messageConstructor('voice', { 'payload': noTrackPhrase })
552
+ }
553
+ }
554
+
555
+ // tv
556
+ if ("Active" in message.payload) {
557
+ let Active = message.payload.Active;
558
+ if (id) {
559
+ return messageConstructor('command', { 'payload': (Active ? 'play' : 'stop') })
560
+ } else if (!id && Active && noTrackPhrase) {
561
+ return messageConstructor('voice', { 'payload': noTrackPhrase })
562
+ }
563
+ }
564
+
565
+ // tv + RemoteKey
566
+ if ("RemoteKey" in message.payload) {
567
+ let RemoteKey = message.payload.RemoteKey;
568
+ switch (RemoteKey) {
569
+ case '7':
570
+ return messageConstructor('command', { 'payload': 'forward' }, device)
571
+ case '6':
572
+ return messageConstructor('command', { 'payload': 'backward' }, device)
573
+ case '4':
574
+ return messageConstructor('command', { 'payload': 'next' })
575
+ case '5':
576
+ return messageConstructor('command', { 'payload': 'prev' })
577
+ case '11':
578
+ if (playing) {
579
+ return messageConstructor('command', { 'payload': 'stop' })
548
580
  } else {
549
- return messageConstructor('command', {'payload': 'play'})
581
+ if (id) {
582
+ return messageConstructor('command', { 'payload': 'play' })
583
+ } else if (!id && noTrackPhrase) {
584
+ return messageConstructor('voice', { 'payload': noTrackPhrase })
585
+ }
550
586
  }
551
- }
552
- case '{"VolumeSelector":1}':
553
- return messageConstructor('command', {'payload': 'volumedown'}, device)
554
- case '{"VolumeSelector":0}':
555
- return messageConstructor('command', {'payload': 'volumeup'}, device)
556
- default:
557
- debugMessage('unknown command')
558
- return messageConstructor('command', {'payload': 'ping'})
587
+ }
559
588
  }
560
-
589
+
590
+ // tv + VolumeSelector
591
+ if ("VolumeSelector" in message.payload) {
592
+ let VolumeSelector = message.payload.VolumeSelector;
593
+ return messageConstructor('command', { 'payload': (VolumeSelector ? 'volumedown' : 'volumeup') }, device)
594
+ }
595
+
596
+ debugMessage('unknown command')
597
+ return messageConstructor('command', { 'payload': 'ping' })
561
598
  } else {
562
- return messageConstructor('command', {'payload': 'ping'})
599
+ return messageConstructor('command', { 'payload': 'ping' })
563
600
  }
564
- case 'raw':
601
+ case 'raw':
565
602
  if (Array.isArray(message.payload)) { return message.payload }
566
603
  return [message.payload];
567
- case 'stopListening':
604
+ case 'stopListening':
568
605
  return [{
569
606
  "command": "serverAction",
570
607
  "serverActionEventPayload": {
@@ -576,7 +613,7 @@ module.exports = function(RED) {
576
613
 
577
614
  }
578
615
  function sendMessage(deviceId, messageType, message) {
579
-
616
+
580
617
  try {
581
618
  let device = searchDeviceByID(deviceId);
582
619
  //debugMessage(`deviceId: ${searchDeviceByID(deviceId)}`);
@@ -617,19 +654,19 @@ module.exports = function(RED) {
617
654
  //debugMessage(`timeCur: ${timeCurrent} timeMin: ${timeMin} timeMax: ${timeMax}`);
618
655
  return [false, daySheduler.phrase];
619
656
  }
620
-
657
+
621
658
 
622
659
  }
623
-
660
+
624
661
  function searchDeviceByID(id) {
625
662
  if (node.deviceList) {
626
663
  return node.deviceList.find(device => device.id == id)
627
- }
664
+ }
628
665
  }
629
666
  function onPing(device) {
630
667
  if (device) {sendMessage(device.id, 'command', {payload: 'ping'});}
631
668
  }
632
-
669
+
633
670
  function onPing(device) {
634
671
  sendMessage(device.id, 'command', {payload: 'ping'});
635
672
  }
@@ -638,19 +675,19 @@ module.exports = function(RED) {
638
675
  if (device) {
639
676
  if (device.ws) {
640
677
  switch(device.ws.readyState){
641
- case 0:
678
+ case 0:
642
679
  return {"color": "yellow", "text": "connecting..."}
643
- case 1:
680
+ case 1:
644
681
  return {"color": "green", "text": "connected"}
645
- case 2:
682
+ case 2:
646
683
  return {"color": "red", "text": "disconnecting"}
647
- case 3:
684
+ case 3:
648
685
  return {"color": "red", "text": "disconnected"}
649
686
  default:
650
687
  return {"color": "red", "text": "disconnected"}
651
688
  }
652
-
653
- }
689
+
690
+ }
654
691
  } else {
655
692
  return {"color": "red", "text": "disconnected"}
656
693
  }
@@ -658,7 +695,7 @@ module.exports = function(RED) {
658
695
  }
659
696
 
660
697
 
661
-
698
+
662
699
  function registerDevice(deviceId, nodeId, parameters) {
663
700
  let device = searchDeviceByID(deviceId);
664
701
  debugMessage(`Recieved parameters ${JSON.stringify(parameters)} for station id ${deviceId}`);
@@ -670,7 +707,7 @@ module.exports = function(RED) {
670
707
  debugMessage(`Device ${device.id} already registered with manager id ${device.manager}. Updating parameters and restart...`);
671
708
  reconnect(device);
672
709
  return 1;
673
-
710
+
674
711
  }
675
712
  //новый и первый запрос на регистрацию для устройства
676
713
  if (typeof(device.manager) == 'undefined') {
@@ -699,7 +736,7 @@ module.exports = function(RED) {
699
736
  registrationBuffer.splice(registrationBuffer.indexOf(currentBuffer), 1)
700
737
  debugMessage(`Element from registration buffer was deleted. Current buffer size is ${registrationBuffer.length}`)
701
738
  }
702
- reconnect(device);
739
+ reconnect(device);
703
740
  return 0;
704
741
  }
705
742
  //новый запрос на регистрацию при наличии уже зарегистрированной ноды
@@ -717,9 +754,9 @@ module.exports = function(RED) {
717
754
  registrationBuffer.push({"id": deviceId, "manager": nodeId, "parameters": parameters});
718
755
  debugMessage(`New element in registration buffer. Current buffer size is ${registrationBuffer.length}`)
719
756
  }
720
-
757
+
721
758
  }
722
-
759
+
723
760
 
724
761
  }
725
762
  function unregisterDevice(deviceId, nodeId){
@@ -730,7 +767,7 @@ module.exports = function(RED) {
730
767
  device.parameters = {};
731
768
  debugMessage(`For device ${deviceId} was succesfully unregistred managment node whith id ${device.manager}`);
732
769
  debugMessage(`device is: ${device}`);
733
- return 0;
770
+ return 0;
734
771
  } else {
735
772
  return 2;
736
773
  }
@@ -751,7 +788,7 @@ module.exports = function(RED) {
751
788
  if (device.savedVolumeLevel) { sendMessage(device.id, 'raw',{payload: {
752
789
  "command": "setVolume",
753
790
  "volume": parseFloat(device.savedVolumeLevel)
754
- }
791
+ }
755
792
  });
756
793
  }
757
794
  device.waitForIdle = false;
@@ -760,13 +797,13 @@ module.exports = function(RED) {
760
797
  function onStopPlay(device, phrase) {
761
798
  sendMessage(device.id, 'command', {payload: 'stop'});
762
799
  if (phrase.length > 0 && device.lastState.aliceState != 'SPEAKING') {sendMessage(device.id, 'tts', {payload: phrase, stopListening: true});}
763
- }
800
+ }
764
801
  function onClose() {
765
802
  clearInterval(node.interval);
766
803
  node.deviceList = [];
767
804
  node.removeListener('deviceReady', onDeviceReady)
768
805
  }
769
-
806
+
770
807
  node.on('refreshHttp', function(activeList, readyList) {
771
808
  RED.httpAdmin.get("/yandexdevices_"+node.id, RED.auth.needsPermission('yandex-login.read'), function(req,res) {
772
809
  res.json({"devices": readyList});
@@ -775,8 +812,8 @@ module.exports = function(RED) {
775
812
  res.json({"devices": activeList});
776
813
  });
777
814
  });
778
-
779
- node.on('refreshHttpDNS', function(dnsList) {
815
+
816
+ node.on('refreshHttpDNS', function(dnsList) {
780
817
  RED.httpAdmin.get("/mdns/"+node.id, RED.auth.needsPermission('yandex-login.read'), function(req,res) {
781
818
  res.json({"SearchResult": dnsList});
782
819
  });
@@ -800,7 +837,7 @@ module.exports = function(RED) {
800
837
  res.json({"error": 'no device found'});
801
838
  }
802
839
  });
803
-
840
+
804
841
  // main init
805
842
  if (typeof(node.token) !== 'undefined') {
806
843
  debugMessage(`Starting server with id ${node.id}`)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-red-contrib-yandex-station-management",
3
- "version": "0.3.3",
3
+ "version": "0.3.4",
4
4
  "description": "Local management of YandexStation using API on websockets",
5
5
  "main": "index.js",
6
6
  "scripts": {