node-red-contrib-loewe-tv 0.3.0 → 0.4.0

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/lib/loewe.js CHANGED
@@ -1,1289 +1,1337 @@
1
- module.exports = function(RED) {
2
- "use strict";
3
-
4
- const dgram = require('dgram');
5
- console.debug = function (){};
6
- console.debug('[LoeweTV]************************************************************');
7
- console.debug('[LoeweTV]************************************************************');
8
-
9
- var TVs = {};
10
-
11
- const socket = dgram.createSocket('udp4');
12
-
13
- socket.bind(1900, () => {
14
- socket.addMembership('239.255.255.250');
15
- console.log('[LoeweTV] SDDP Client lauscht an Port 1900');
16
- });
17
-
18
- socket.on('message', (msg, rinfo) => {
19
- var sddpMsg = msg.toString();
20
- // console.log('[LoeweTV SDDP:1900] ' + rinfo.address);
21
- // console.log(sddpMsg);
22
- if ( TVs.hasOwnProperty(rinfo.address) ) {
23
- var lines = sddpMsg.split('\r');
24
- var objSddpMsg = {};
25
- // console.log('[LoeweTV SDDP:1900] ' + rinfo.address);
26
- // console.log(sddpMsg);
27
- lines.forEach((line) => {
28
- // console.debug('[LoeweTV SDDP:1900]' + line);
29
- var del = line.indexOf(':');
30
- if(del>1) {
31
- var key = line.substring(0,del).trim().toLowerCase();
32
- var value = line.substring(del+1).trim();
33
- // console.debug('[LoeweTV SDDP:1900] Key: ' + key + ' Value: ' + value);
34
- objSddpMsg[key]=value;
35
- }
36
- });
37
- TVs[rinfo.address].onSDDP(objSddpMsg);
38
- }
39
- });
40
-
41
- const socket1902 = dgram.createSocket('udp4');
42
-
43
- socket1902.bind(1902, () => {
44
- socket1902.addMembership('239.255.255.250');
45
- console.log('[LoeweTV] SDDP Client lauscht an Port 1902');
46
- });
47
-
48
- socket1902.on('message', (msg, rinfo) => {
49
- var sddpMsg = msg.toString();
50
- // console.log('[LoeweTV SDDP:1902] ' + rinfo.address);
51
- // console.log(sddpMsg);
52
- if ( TVs.hasOwnProperty(rinfo.address) ) {
53
- var lines = sddpMsg.split('\r');
54
- var objSddpMsg = {};
55
- console.log('[LoeweTV SDDP:1902] ' + rinfo.address);
56
- console.log(sddpMsg);
57
- lines.forEach((line) => {
58
- // console.debug('[LoeweTV SDDP:1902]' + line);
59
- var del = line.indexOf(':');
60
- if(del>1) {
61
- var key = line.substring(0,del).trim().toLowerCase();
62
- var value = line.substring(del+1).trim();
63
- // console.debug('[LoeweTV SDDP:1902] Key: ' + key + ' Value: ' + value);
64
- objSddpMsg[key]=value;
65
- }
66
- });
67
-
68
- TVs[rinfo.address].onSDDP(objSddpMsg);
69
- }
70
- });
71
-
72
- function LoeweTvNode(config) {
73
- const http = require('http');
74
- const os = require('os');
75
- const xml2js = require('xml2js');
76
- const wol = require('wol');
77
- var parseString = xml2js.parseString;
78
- var node = this;
79
- node.ClientId = '';
80
- node.sddpUuid = '';
81
- node.Volume = '';
82
- node.Mute = '';
83
- node.data = {CurrentStatus:{Power:''}};
84
-
85
- RED.nodes.createNode(node, config);
86
-
87
- this.tv = RED.nodes.getNode(config.tv);
88
-
89
- node.name = this.tv.name;
90
-
91
- var interfaces = os.networkInterfaces();
92
-
93
- for ( var i in interfaces) {
94
- interfaces[i].forEach(function(details) {
95
- details.interface = i;
96
- if (!details.internal) {
97
- delete details.netmask;
98
- delete details.mac;
99
- delete details.internal;
100
- this.HostIP = details.address;
101
- }
102
- });
103
- break;
104
- }
105
-
106
- // Check if ipAddress is valid IP address
107
- var ipRegExp = /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/;
108
-
109
- if(ipRegExp.test(this.tv.ip)) {
110
- this.ipAddress = this.tv.ip;
111
- node.log('neuer LOEWE TV \"' + this.name + '\" angemeldet IP: ' + this.ipAddress);
112
- }
113
- else {
114
- throw new TypeError('IP address not valid!');
115
- }
116
-
117
- var ipRegExp = /^([0-9])*/;
118
-
119
- if(ipRegExp.test(this.tv.fcid)) {
120
- this.fcid = this.tv.fcid;
121
- console.debug('FCID: ' + this.fcid);
122
- }
123
- else {
124
- throw new TypeError('fcid not valid!');
125
- }
126
-
127
- TVs[this.ipAddress] = this;
128
-
129
- node.onActionTemplate = function(action, actionData) {
130
- var self = this;
131
- var newmsg = { payload:{
132
- Name:node.name,
133
- ClientId:node.ClientId,
134
- Status:node.data.CurrentStatus.Power
135
- },
136
- action:action,
137
- actionData:actionData,
138
- topic:'LoeweTV'
139
- };
140
- node.send(newmsg);
141
- }
142
-
143
- node.onAction = function(action, actionData) {
144
- var self = this;
145
- node.log(action);
146
- switch ( action ) {
147
- case "GetDeviceData":
148
- if (self.tv.mac === undefined | self.tv.mac === '') {
149
- if ( this.data.hasOwnProperty("DeviceData") ) {
150
- if ( this.data.DeviceData.hasOwnProperty("MAC-Address-LAN") ) {
151
- self.tv.mac = this.data.DeviceData['MAC-Address-LAN'];
152
- }
153
- }
154
- }
155
- node.onActionTemplate(action, actionData);
156
- break;
157
- case "GetVolume":
158
- node.log('Volume: ', node.Volume);
159
- var newmsg = { payload:{Name:node.name, ClientId:node.ClientId, Status:node.data.CurrentStatus.Power}, action:action, actionData:{Volume:node.Volume}, topic:action };
160
- node.send(newmsg);
161
- break;
162
-
163
- case "GetMute":
164
- node.log('Mute: ', node.Mute);
165
- var newmsg = { payload:{Name:node.name, ClientId:node.ClientId, Status:node.data.CurrentStatus.Power}, action:action, actionData:{Volume:node.Mute}, topic:action };
166
- node.send(newmsg);
167
- break;
168
-
169
- case "SetVolume":
170
- node.log('Set Volume to: ', node.Volume);
171
- var newmsg = { payload:{Name:node.name, ClientId:node.ClientId, Status:node.data.CurrentStatus.Power}, action:action, actionData:{Volume:node.Volume}, topic:action };
172
- node.send(newmsg);
173
- break;
174
-
175
- case "SetMute":
176
- node.log('Set Mute to: ', node.Mute);
177
- var newmsg = { payload:{Name:node.name, ClientId:node.ClientId, Status:node.data.CurrentStatus.Power}, action:action, actionData:{Volume:node.Mute}, topic:action };
178
- node.send(newmsg);
179
- break;
180
-
181
- default:
182
- node.log(actionData);
183
- break;
184
- }
185
-
186
- };
187
-
188
- node.on('input', function(msg) {
189
- var action = msg.topic;
190
- switch ( action ) {
191
- case "SwitchOn":
192
- node.switchOn();
193
- break;
194
- case "WakeUp":
195
- node.wakeUp(msg.payload);
196
- break;
197
- case "InjectSoapRequest":
198
- node.injectSoapRequest(msg.payload, node.onAction);
199
- break;
200
- case "RequestAccess":
201
- node.onEvent('alive');
202
- break;
203
- case "GetChannelList":
204
- node.getChannelList(msg.payload, node.onActionTemplate);
205
- break;
206
- case "GetCurrentEvent":
207
- node.getEvent('CurrentEvent', msg.payload, node.onActionTemplate);
208
- break;
209
- case "GetNextEvent":
210
- node.getEvent('NextEvent', msg.payload, node.onActionTemplate);
211
- break;
212
- case "GetMediaItem":
213
- node.getMediaItem(msg.payload, node.onActionTemplate);
214
- break;
215
- case "GetMediaEvent":
216
- node.getMediaEvent(msg.payload, node.onActionTemplate);
217
- // node.getMediaEvent(function(){});
218
- break;
219
- case "PlayerPrepare":
220
- node.playerPrepare(msg.payload, node.onActionTemplate);
221
- break;
222
- case "PlayerReleasePrepared":
223
- node.execAction(action, '', node.onAction);
224
- break;
225
- case "PlayerPlay":
226
- node.execAction(action, '', node.onAction);
227
- break;
228
- case "PlayerPause":
229
- node.execAction(action, '', node.onAction);
230
- break;
231
- case "PlayerResume":
232
- node.execAction(action, '', node.onAction);
233
- break;
234
- case "PlayerStop":
235
- node.execAction(action, '', node.onAction);
236
- break;
237
- case "PlayerSetSpeed":
238
- node.execAction(action, '', node.onAction);
239
- break;
240
- case "PlayerSeekTo":
241
- node.execAction(action, '', node.onAction);
242
- break;
243
- case "GetVolume":
244
- node.getValue('Volume', node.onAction);
245
- break;
246
- case "SetVolume":
247
- let volume = msg.payload.toString() + '0000';
248
- node.setValue('Volume', volume, node.onAction);
249
- break;
250
- case "GetMute":
251
- node.getValue('Mute', node.onAction);
252
- break;
253
- case "SetMute":
254
- node.setValue('Mute', msg.payload, node.onAction);
255
- break;
256
- case "Standby":
257
- node.standby(msg.payload, node.onAction);
258
- // node.standby(msg.payload, node.onAction);
259
- // node.execAction(action, '', node.onAction);
260
- break;
261
- case "ProgramTimer":
262
- node.execAction(action, '', node.onAction);
263
- break;
264
- case "GetDeviceData":
265
- node.execAction(action, '', node.onAction);
266
- break;
267
- case "GetValueFromBrowserJS":
268
- node.execAction(action, '', node.onAction);
269
- break;
270
- case "GetBrowserJSChangeList":
271
- node.execAction(action, '', node.onAction);
272
- break;
273
- case "SetValueToBrowserJS":
274
- node.execAction(action, '', node.onAction);
275
- break;
276
- case "GetCurrentPlayback":
277
- node.execAction(action, '', node.onActionTemplate);
278
- break;
279
- case "GetCurrentStatus":
280
- node.execAction(action, '', node.onActionTemplate);
281
- break;
282
- case "ZapToApplication":
283
- node.execAction(action, '', node.onAction);
284
- break;
285
- case "ZapToMedia":
286
- node.execAction(action, '', node.onAction);
287
- break;
288
- case "InjectRCKey":
289
- node.injectRCKey(msg.payload, node.onAction);
290
- break;
291
- case "InjectKeyboardKey":
292
- node.execAction(action, '', node.onAction);
293
- break;
294
- case "SetActionField":
295
- node.setActionField(msg.payload, node.onAction);
296
- break;
297
- case "GetActionField":
298
- node.getActionField(msg.payload, node.onAction);
299
- break;
300
- case "GetFeature":
301
- node.getFeature(msg.payload, node.onActionTemplate);
302
- break;
303
- case "ActivateFeaturePackage":
304
- node.activateFeaturePackage(msg.payload, node.onAction);
305
- break;
306
- case "DectivateFeaturePackage":
307
- node.execAction(action, '', node.onAction);
308
- break;
309
- case "GetUpgradeInfo":
310
- node.execAction(action, '', node.onAction);
311
- break;
312
- case "GetListOfChannelLists":
313
- node.getListOfChannelLists(msg.payload, node.onActionTemplate);
314
- break;
315
- case "AddFavoriteList":
316
- node.execAction(action, '', node.onAction);
317
- break;
318
- case "RemoveFavoriteList":
319
- node.execAction(action, '', node.onAction);
320
- break;
321
- case "RenameFavoriteList":
322
- node.execAction(action, '', node.onAction);
323
- break;
324
- case "AddServicesFavoriteList":
325
- node.execAction(action, '', node.onAction);
326
- break;
327
- case "RemoveServicesFavoriteList":
328
- node.execAction(action, '', node.onAction);
329
- break;
330
- case "MoveServicesFavoriteList":
331
- node.execAction(action, '', node.onAction);
332
- break;
333
- case "AddFavoriteListFromVirtual":
334
- node.execAction(action, '', node.onAction);
335
- break;
336
- case "GetListOfVirtualLists":
337
- node.getListOfVirtualLists(msg.payload, node.onActionTemplate);
338
- break;
339
- case "ImportServiceLists":
340
- node.execAction(action, '', node.onAction);
341
- break;
342
- case "ExportServiceLists":
343
- node.execAction(action, '', node.onAction);
344
- break;
345
- case "GetDRPlusArchive":
346
- node.getDRPlusArchive(msg.payload, node.onActionTemplate);
347
- break;
348
- case "GetVolumes":
349
- node.getVolumes(msg.payload, node.onActionTemplate);
350
- break;
351
- case "PlayMultiroom":
352
- node.execAction(action, '', node.onAction);
353
- break;
354
- case "GetSettings":
355
- node.execAction(action, '',node.onActionTemplate);
356
- break;
357
- case "SetSetting":
358
- node.execAction(action, '', node.onAction);
359
- break;
360
- case "ParentalLock":
361
- node.execAction(action, '', node.onAction);
362
- break;
363
- case "GetParentalLock":
364
- node.execAction(action, '', node.onActionTemplate);
365
- break;
366
- case "GetTimerList":
367
- node.execAction(action, '', node.onActionTemplate);
368
- break;
369
- case "CreateIterator":
370
- node.createIterator(node.onAction);
371
- break;
372
- case "CloseIterator":
373
- node.execAction(action, '', node.onAction);
374
- break;
375
- default:
376
- break;
377
- }
378
- });
379
-
380
- node.updateNodeStatus = function() {
381
- var statusFill ='';
382
- var power = node.data.CurrentStatus.Power;
383
- node.debug('updateNodeStatus');
384
- switch (power) {
385
- case "idle":
386
- statusFill = "blue";
387
- node.log('TV ist im \"Leerlauf\"');
388
- break;
389
- case "standby":
390
- statusFill = "yellow";
391
- node.log('TV ist im Standby');
392
- break;
393
- case "switch_on":
394
- case "tv":
395
- statusFill = "green";
396
- node.log('TV ist Eingeschaltet');
397
- break;
398
- default:
399
- statusFill = "grey";
400
- node.log('TV status unknown');
401
- break;
402
- }
403
- node.status({fill:statusFill,shape:"ring",text:"ClientId: " + node.ClientId});
404
- var newmsg = {
405
- payload:{
406
- Name:node.name,
407
- ClientId:node.ClientId,
408
- Status:node.data.CurrentStatus.Power
409
- },
410
- data:node.data,
411
- topic:'Status' };
412
- node.send(newmsg);
413
- };
414
-
415
- node.onEvent = function(event) {
416
- var self = this;
417
- node.log('received Event: ' + event);
418
- node.log('TV Status: ' + node.data.CurrentStatus.Power);
419
-
420
- if (event === 'alive') {
421
- node.debug('[' + node.name + '] handle Event:' + event);
422
- if (node.ClientId === '' | node.data.CurrentStatus.Power === 'switchon') {
423
- node.requestAccess(function() {
424
- node.log('Registriere ClientId: ' + node.ClientId);
425
- if (node.sddpUuid !== '') {
426
- node.log('SDDP uuid: ' + node.sddpUuid);
427
- }
428
- if (node.data.CurrentStatus.Power === 'switchon') {
429
- node.log('schalte ein');
430
- node.injectRCKey('12', function () {});
431
- var timerId = setTimeout(node.onEvent('alive'), 500);
432
- } else {
433
- node.execAction('GetSettings', '', function () {
434
- node.activateFeaturePackage({"Package":"72413U80"}, function(){
435
- node.execAction('GetDeviceData', '', function () {
436
- node.createIterator(function(){
437
- node.getValue('Volume', function(){
438
- node.getValue('Mute', function(){
439
- node.execAction('GetCurrentStatus', '', function () {
440
- node.updateNodeStatus();
441
- });
442
- });
443
- });
444
- });
445
- });
446
- });
447
- });
448
- }
449
- });
450
- }
451
- node.debug('[' + node.name + '] handle Event:' + event + 'ok');
452
- }
453
- else if (event === 'byebye') {
454
- node.debug('[' + node.name + '] handle Event:' + event);
455
- if (node.data.CurrentStatus.Power === 'tv') {
456
- node.log('schaltet ab');
457
- node.execAction('GetCurrentStatus', '', function() {});
458
- node.ClientId = '';
459
- }
460
- node.debug('[' + node.name + '] handle Event:' + event + 'ok');
461
- }
462
- else {
463
- node.warn('[' + node.name + '] received unhandeld Event');
464
- }
465
- node.debug('[' + node.name + '] received Event OK');
466
- };
467
-
468
- node.onSDDP = function() {
469
- var self = this;
470
- return function(objSddpMsg){
471
- console.debug('[LoeweTV SDDP]', objSddpMsg);
472
- if (objSddpMsg['nts'] === 'ssdp:alive') {
473
- try {
474
- var sddpUuid = objSddpMsg['usn'].split(':')[1].trim();
475
- if (self.sddpUuid === '') {
476
- self.sddpUuid = sddpUuid;
477
- node.log('SDDP uuid: ' + self.sddpUuid);
478
- self.onEvent('alive');
479
- }
480
- }
481
- catch {
482
- node.log('*********************** ERROR ***********************');
483
- node.error(objSddpMsg);
484
- node.error('********************* END ERROR *********************');
485
- }
486
-
487
- } else {
488
- if ( objSddpMsg['nts'] === 'ssdp:byebye' ) {
489
- self.sddpUuid = '';
490
- self.ClientId = '';
491
- self.onEvent('byebye');
492
- }
493
- else if ( objSddpMsg['nts'] === 'ssdp:discover' | objSddpMsg['man'] === '\"ssdp:discover\"') {
494
- }
495
- else {
496
- node.error('[LoeweTV ERROR] ', objSddpMsg);
497
- }
498
- }
499
- };
500
- };
501
-
502
- node.getTimeString = function(time) {
503
- var seconds = Math.floor(time/1000)%60;
504
- var minutes = Math.floor(time/60000)%60;
505
- var hours = Math.floor(time/3600000)%24;
506
- var timeString;
507
-
508
- if (seconds < 10) { seconds = "0" + seconds; }
509
- if (minutes < 10) { minutes = "0" + minutes; }
510
- if (hours < 10) { hours = " " + hours; }
511
- timeString = hours + ":" + minutes + ":" + seconds;
512
- return timeString;
513
- };
514
-
515
- node.wakeUp = function(mac) {
516
- var self = this;
517
- if (mac === undefined | mac === '') {
518
- node.log('mac undefined');
519
-
520
- if ( this.data.hasOwnProperty("DeviceData") ) {
521
- if ( this.data.DeviceData.hasOwnProperty("MAC-Address-LAN") ) {
522
- mac = this.data.DeviceData['MAC-Address-LAN'];
523
- }
524
- }
525
- }
526
- if (mac !== undefined & mac !== '') {
527
- node.log('wakeUp: ' + mac);
528
- wol.wake(mac, function(err, res){
529
- // node.log('', err);
530
- node.log('', res);
531
- });
532
- } else {
533
- node.error('*********************** ERROR ***********************');
534
- node.error('wakeUp: no MAC');
535
- node.log('********************* END ERROR *********************');
536
- }
537
- }
538
-
539
- node.switchOn = function() {
540
- var self = this;
541
- node.log('switchOn');
542
- node.log('Status: ' + self.data.CurrentStatus.Power);
543
-
544
- if (self.data.CurrentStatus.Power !== 'idle' & self.data.CurrentStatus.Power !== 'tv') {
545
- self.wakeUp();
546
- self.data.CurrentStatus.Power = 'switchon';
547
- }else if (self.data.CurrentStatus.Power === 'idle' | self.data.CurrentStatus.Power === 'standby') {
548
- self.injectRCKey('12', function () {});
549
- } else {
550
- node.log('[LoeweTV ' + self.name + '] ist bereits an');
551
- }
552
- }
553
-
554
- /**
555
- * Create and send request to the TV
556
- *
557
- * @param {String} ClientId The ClientId from RequestAccess
558
- * @param {String} action The action to perform
559
- * @param {Array} data like RC-Key number
560
- * @param {Array} options Options array (mostly for callback)
561
- */
562
- node.sendSOAPRequest = function(action, actionData, options) {
563
- var url, urn;
564
- var responseData = '';
565
- var self = this;
566
-
567
- url = '/loewe_tablet_0001';
568
- urn = 'loewe.de:RemoteTV:Tablet';
569
-
570
-
571
- // var body = '<?xml version="1.0" encoding="utf-8"?>' +
572
- var body = '<SOAP-ENV:Envelope ' +
573
- 'xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" ' +
574
- 'xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" ' +
575
- 'xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing/" ' +
576
- 'xmlns:wse="http://www.w3.org/2009/02/ws-evt" ' +
577
- 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ' +
578
- 'xmlns:xsd="http://www.w3.org/2001/XMLSchema" ' +
579
- 'xmlns:m="urn:loewe.de:RemoteTV:Tablet">' +
580
- '<SOAP-ENV:Body>' +
581
- '<m:' + action + '>' +
582
- '<fcid>' + this.fcid + '</fcid>' +
583
- '<ClientId>' + this.ClientId + '</ClientId>' +
584
- actionData +
585
- '</m:' + action + '>' +
586
- '</SOAP-ENV:Body>' +
587
- '</SOAP-ENV:Envelope>';
588
-
589
- var postRequest = {
590
- host: this.ipAddress,
591
- path: url,
592
- port: 905,
593
- method: "POST",
594
- headers: {
595
- 'SOAPAction': action,
596
- 'Accept': '*/*',
597
- 'Accept-Encoding': 'gzip, deflate',
598
- 'Accept-Language': 'de-de',
599
- 'Content-Type': 'application/soap+xml; charset=utf-8',
600
- 'Connection': 'keep-alive',
601
- 'User-Agent': 'Assist Media/23 CFNetwork/808 Darwin/16.0.0'
602
- }
603
- };
604
-
605
- if(options !== undefined) {
606
- self.callback = options.callback;
607
- } else {
608
- self.callback = function (soapRequest, soapResponse) {
609
- node.log('SOAP Request: ');
610
- node.log(soapRequest);
611
- node.log('SOAP Response: ');
612
- node.log(soapResponse);
613
- };
614
- }
615
-
616
- var req = http.request(postRequest, function(res) {
617
- res.setEncoding('utf8');
618
- res.on('data', (chunk) => {
619
- responseData += chunk.toString();
620
- });
621
-
622
- res.on('end', function() {
623
- var match = /<SOAP-ENV:Fault>/gm.exec(responseData);
624
- if(match !== null) {
625
- node.error('*********************** ERROR ***********************');
626
- node.error('SOAP body: ');
627
- node.error(body);
628
- node.error('---------------------------------------------------------------');
629
- node.error('SOAP Response: ');
630
- node.error(responseData);
631
- node.error('********************* END ERROR *********************');
632
- }
633
- self.callback(body, responseData);
634
- });
635
-
636
-
637
- });
638
-
639
- req.on('error', function(e) {
640
- node.log('' + e.address + ' ist nicht erreichbar!');
641
- self.sddpUuid = '';
642
- self.ClientId = '';
643
- });
644
-
645
- req.write(body);
646
- node.debug('sendSOAPRequest: ');
647
- node.debug(body);
648
- req.end();
649
-
650
- return this;
651
- };
652
-
653
- node.getObjectFromResponse = function(action, soapRequest, soapResponse, callback) {
654
- var self = this;
655
- node.debug('------------------ %s ----------------', action);
656
-
657
- var regex = new RegExp("<SOAP-ENV:Body>((.|\n)*)<\/SOAP-ENV:Body>", "gm");
658
- var dataFromAction = ((regex.exec(soapResponse))[1].replace(/m:|:m/gm, "")).replace(/xmlns="urn:loewe.de:RemoteTV:Tablet"/,"" );
659
- node.debug(soapResponse);
660
- /*
661
- var responseData = (regex.exec(soapResponse))[1];
662
- node.debug(responseData);
663
- responseData = responseData.replace(/m:|:m/gm, "");
664
- node.debug('--------------------------------------');
665
- console.debug(responseData);
666
- responseData = responseData.replace(/xmlns="urn:loewe.de:RemoteTV:Tablet"/,"");
667
- node.debug('--------------------------------------');
668
- console.debug(responseData);
669
- node.debug('--------------------------------------');
670
- */
671
- var options = {};
672
- var objResponse;
673
-
674
- node.debug(dataFromAction)
675
-
676
- options.async = false;
677
- options.trim = true;
678
- options.explicitArray = false;
679
- options.attrkey = options.attrkey || '$';
680
- options.charkey = options.charkey || '_';
681
-
682
- parseString(dataFromAction, options, function (err, result) {
683
- if (err) {
684
- node.error('*********************** ERROR ***********************');
685
- node.error(action);
686
- node.error(err)
687
- node.error('********************* END ERROR *********************');
688
- }
689
- else {
690
- for (var key in result) {
691
- for (var reponseKey in result[key]) {
692
- break
693
- }
694
- break
695
- }
696
- if (result[key] === undefined | result[key] === '' | result[key] === ' ' | reponseKey == 0) {
697
- node.error('*********************** ERROR ***********************');
698
- node.error('SoapRequest');
699
- node.error(soapRequest);
700
- node.error('---------------------------------------------------------------');
701
- node.error('SoapResponse');
702
- node.error(soapResponse);
703
- node.error('---------------------------------------------------------------');
704
- node.error(result);
705
- node.error('********************* END ERROR *********************');
706
- } else {
707
- objResponse = result;
708
- }
709
- }
710
- });
711
-
712
- var objName = action.replace('Get', '');
713
- if (objResponse !== undefined) {
714
- this.data[objName] = objResponse[action+'Response'];
715
- node.debug('result obj: ', objName);
716
- node.debug(this.data[objName]);
717
- } else {
718
- this.data[objName] = {};
719
- }
720
- callback(action, this.data[objName]);
721
- };
722
-
723
- node.injectSoapRequest = function(soapRequest, callback) {
724
- var self = this;
725
- self.actionCallback = callback;
726
-
727
- node.log('', soapRequest);
728
-
729
- var action = (/<m:(\w*)>/gm.exec(soapRequest))[1];
730
- node.log('****************************************************');
731
- node.log('****************************************************');
732
- node.log('-------------------- %s ------------------', action);
733
-
734
- var regex = new RegExp("<m:" + action + ">((.)*)<\/m:" + action + ">", "gm");
735
- var actionData = (regex.exec(soapRequest))[1];
736
-
737
- node.log('', actionData);
738
-
739
- /*
740
- this.sendSOAPRequest(action, actionData, {
741
- callback: function(soapRequest, soapResponse){
742
- node.debug('soapResponse:');
743
- console.debug(soapResponse);
744
- self.actionCallback(action, soapResponse);
745
- }
746
- });
747
- */
748
-
749
- this.sendSOAPRequest(action, actionData, {
750
- callback: function(soapRequest, soapResponse){
751
- node.log('soapResponse:');
752
- node.log(soapResponse);
753
- self.getObjectFromResponse(action, soapRequest, soapResponse, function (action, responseData) {
754
- self.actionCallback(action, responseData)
755
- node.log('****************************************************');
756
- node.log('****************************************************');
757
- });
758
- }
759
- });
760
- };
761
-
762
- node.getEvent = function(event, player, callback) {
763
- var self = this;
764
- var action = 'Get'+event;
765
- var actionData = '<Player>' + player + '</Player>';
766
- node.debug('------------------ %s ----------------', action);
767
-
768
- self.actionCallback = callback;
769
-
770
- this.sendSOAPRequest(action, actionData, {
771
- callback: function(soapRequest, soapResponse){
772
- node.debug('soapResponse:');
773
- console.debug(soapResponse);
774
- self.getObjectFromResponse(action, soapRequest, soapResponse, self.actionCallback);
775
- }
776
- });
777
- };
778
-
779
- node.getMediaItem = function(mediaItemUuid, callback) {
780
- var self = this;
781
- var action = 'GetMediaItem';
782
- var actionData = '<MediaItemReference mediaItemUuid=\"' + mediaItemUuid + '\"/>';
783
-
784
- self.actionCallback = callback;
785
-
786
- self.sendSOAPRequest(action, actionData, {
787
- callback: function(soapRequest, soapResponse){
788
- self.getObjectFromResponse(action, soapRequest, soapResponse, self.actionCallback);
789
- }
790
- });
791
- };
792
-
793
- node.getMediaEvent = function(mediaEventUuid, callback) {
794
- var self = this;
795
- var action = 'GetMediaEvent';
796
- var actionData = '<MediaEventReference mediaEventUuid=\"' + mediaEventUuid + '\"/>';
797
-
798
- self.actionCallback = callback;
799
-
800
- self.sendSOAPRequest(action, actionData, {
801
- callback: function(soapRequest, soapResponse){
802
- self.getObjectFromResponse(action, soapRequest, soapResponse, self.actionCallback);
803
- }
804
- });
805
- };
806
-
807
- node.playerPrepare = function(data, callback) {
808
- var self = this;
809
- var action = 'PlayerPrepare';
810
- var actionData = '<Player>' + data.Player + '</Player><Locator>' + data.Locator + '</Locator>';
811
-
812
- self.actionCallback = callback;
813
-
814
- self.sendSOAPRequest(action, actionData, {
815
- callback: function(soapRequest, soapResponse){
816
- self.getObjectFromResponse(action, soapRequest, soapResponse, self.actionCallback);
817
- }
818
- });
819
- };
820
-
821
- node.execAction = function(action, actionData, callback) {
822
- var self = this;
823
-
824
- self.actionCallback = callback;
825
-
826
- self.sendSOAPRequest(action, actionData, {
827
- callback: function(soapRequest, soapResponse){
828
- self.getObjectFromResponse(action, soapRequest, soapResponse, self.actionCallback);
829
- }
830
- });
831
- };
832
-
833
- node.standby = function(value, callback) {
834
- var self = this;
835
- var action = 'Standby';
836
- var actionData = '<Value>' + value + '</Value>';
837
- self.actionCallback = callback;
838
-
839
- self.sendSOAPRequest(action, actionData, {
840
- callback: function(soapRequest, soapResponse){
841
- var regex = new RegExp("<m:Value>(\\d*)<\/m:Value>", "gm");
842
- var responseValue = regex.exec(soapResponse);
843
- node.debug('----------------- ' + action + ' -----------------------');
844
- node.debug(soapResponse);
845
- node.debug('----------------- ' + action + ' -----------------------');
846
- if(responseValue !== null) {
847
- node.log('' + action + ' value: ' + responseValue[1])
848
- self[value] = responseValue[1];
849
- self.actionCallback(action, responseValue[1]);
850
- } else {
851
- regex = new RegExp("<m:" + action + "Response [A-Za-z:=\".]*>(.*)<\/m:" + action + "Response>", "gm");
852
- console.debug(soapResponse);
853
- var responseData = (regex.exec(soapResponse))[1];
854
- if (responseData !== null) {
855
- node.debug('' + action + ' data: ' + responseData);
856
- self.actionCallback(action, responseData);
857
- } else {
858
- node.error('*********************** ERROR ***********************');
859
- node.error('SoapRequest');
860
- node.error(soapRequest);
861
- node.error('---------------------------------------------------------------');
862
- node.error('error: ', action);
863
- node.error('data: ', soapResponse);
864
- node.error('********************* END ERROR *********************');
865
- }
866
- }
867
- }
868
- });
869
- };
870
-
871
- node.setValue = function(valueName, value, callback) {
872
- var self = this;
873
- var action = 'Set'+valueName;
874
- var actionData = '<Value>' + value + '</Value>';
875
- self.actionCallback = callback;
876
-
877
- self.sendSOAPRequest(action, actionData, {
878
- callback: function(soapRequest, soapResponse){
879
- var regex = new RegExp("<m:Value>(\\d*)<\/m:Value>", "gm");
880
- var responseValue = regex.exec(soapResponse);
881
- node.debug('----------------- ' + action + ' -----------------------');
882
- node.debug(soapResponse);
883
- node.debug('----------------- ' + action + ' -----------------------');
884
- if(responseValue !== null) {
885
- node.log('' + action + ' value: ' + responseValue[1])
886
- self[value] = responseValue[1];
887
- self.actionCallback(action, responseValue[1]);
888
- } else {
889
- regex = new RegExp("<m:" + action + "Response [A-Za-z:=\".]*>(.*)<\/m:" + action + "Response>", "gm");
890
- console.debug(soapResponse);
891
- var responseData = (regex.exec(soapResponse))[1];
892
- if (responseData !== null) {
893
- node.debug('' + action + ' data: ' + responseData);
894
- self.actionCallback(action, responseData);
895
- } else {
896
- node.error('*********************** ERROR ***********************');
897
- node.error('SoapRequest');
898
- node.error(soapRequest);
899
- node.error('---------------------------------------------------------------');
900
- node.error('error: ', action);
901
- node.error('data: ', soapResponse);
902
- node.error('********************* END ERROR *********************');
903
- }
904
- }
905
- }
906
- });
907
- };
908
-
909
- node.getValue = function(valueName, callback) {
910
- var self = this;
911
- var action = 'Get'+valueName;
912
- var actionData = '';
913
- self.actionCallback = callback;
914
-
915
- self.sendSOAPRequest(action, actionData, {
916
- callback: function(soapRequest, soapResponse){
917
- var regex = new RegExp("<m:Value>(\\d*)<\/m:Value>", "gm");
918
- var responseValue = regex.exec(soapResponse);
919
- node.debug('----------------- ' + action + ' -----------------------');
920
- node.debug(soapResponse);
921
- node.debug('----------------- ' + action + ' -----------------------');
922
- if(responseValue !== null) {
923
- node.debug('' + action + ' ' + valueName + ': ' + responseValue[1])
924
- self[valueName] = responseValue[1];
925
- self.actionCallback(action, self[valueName]);
926
- } else {
927
- regex = new RegExp("<m:" + action + "Response [A-Za-z:=\".]*>(.*)<\/m:" + action + "Response>", "gm");
928
- var responseData = (regex.exec(soapResponse))[1];
929
- if (responseData !== null) {
930
- node.debug('' + action + ' data: ' + responseData);
931
- self.actionCallback(action, responseData);
932
- } else {
933
- node.error('*********************** ERROR ***********************');
934
- node.error('SoapRequest');
935
- node.error(soapRequest);
936
- node.error('---------------------------------------------------------------');
937
- node.error('error: ', action);
938
- node.error('data: ', soapResponse);
939
- node.error('********************* END ERROR *********************');
940
- }
941
- }
942
- }
943
- });
944
- };
945
-
946
- node.getDRPlusArchive = function(startindex, callback) {
947
- var self = this;
948
- var action = 'GetDRPlusArchive';
949
- var actionData = '<m:QueryParameters>' +
950
- '<m:Range startIndex="' + startindex + '" maxItems="5"/>' +
951
- '</m:QueryParameters>';
952
-
953
- self.actionCallback = callback;
954
-
955
- self.sendSOAPRequest(action, actionData, {
956
- callback: function(soapRequest, soapResponse){
957
- self.getObjectFromResponse(action, soapRequest, soapResponse, self.actionCallback);
958
- }
959
- });
960
- };
961
-
962
- node.getListOfVirtualLists = function(startindex, callback) {
963
- var self = this;
964
- var action = 'GetListOfVirtualLists';
965
- var actionData = '<m:QueryParameters>' +
966
- '<m:Range startIndex="' + startindex + '" maxItems="5"/>' +
967
- '</m:QueryParameters>';
968
-
969
- self.actionCallback = callback;
970
-
971
- self.sendSOAPRequest(action, actionData, {
972
- callback: function(soapRequest, soapResponse){
973
- self.getObjectFromResponse(action, soapRequest, soapResponse, self.actionCallback);
974
- }
975
- });
976
- };
977
-
978
- node.getVolumes = function(startindex, callback) {
979
- var self = this;
980
- var action = 'GetVolumes';
981
- var actionData = '<m:QueryParameters>' +
982
- '<m:Range startIndex="' + startindex + '" maxItems="5"/>' +
983
- '</m:QueryParameters>';
984
-
985
- self.actionCallback = callback;
986
-
987
- self.sendSOAPRequest(action, actionData, {
988
- callback: function(soapRequest, soapResponse){
989
- self.getObjectFromResponse(action, soapRequest, soapResponse, self.actionCallback);
990
- }
991
- });
992
- };
993
-
994
- node.getListOfChannelLists = function(startindex, callback) {
995
- var self = this;
996
- var action = 'GetListOfChannelLists';
997
- var actionData = '<m:QueryParameters>' +
998
- '<m:Range startIndex="' + startindex + '" maxItems="5"/>' +
999
- '</m:QueryParameters>' +
1000
- '<m:AdditionalParameters>' +
1001
- '<m:Properties isActiveList="0"/>' +
1002
- '</m:AdditionalParameters>';
1003
-
1004
- self.actionCallback = callback;
1005
-
1006
- self.sendSOAPRequest(action, actionData, {
1007
- callback: function(soapRequest, soapResponse){
1008
- self.getObjectFromResponse(action, soapRequest, soapResponse, self.actionCallback);
1009
- }
1010
- });
1011
- };
1012
-
1013
- node.getChannelList = function(startindex, callback) {
1014
- var self = this;
1015
- var action = 'GetChannelList';
1016
- var actionData = '<ChannelListView>fastscansl7f33a470-7d6e-4b60-a103-f7739be9484d</ChannelListView>' +
1017
- '<QueryParameters>' +
1018
- '<Range startIndex="' + startindex + '" maxItems="1"/>' +
1019
- '<OrderField field="userChannelNumber" type="ascending"/>' +
1020
- '</QueryParameters>';
1021
-
1022
- self.actionCallback = callback;
1023
-
1024
- self.sendSOAPRequest(action, actionData, {
1025
- callback: function(soapRequest, soapResponse){
1026
- self.getObjectFromResponse(action, soapRequest, soapResponse, self.actionCallback);
1027
- }
1028
- });
1029
- };
1030
-
1031
- node.createIterator = function(callback) {
1032
- var self = this;
1033
- var action = 'CreateIterator';
1034
- var actionData = '<TableName>de.loewe.sl2.volume.table.main</TableName>' +
1035
- '<Type>0</Type>' +
1036
- '<Selections>' +
1037
- '<Selection>' +
1038
- '<Field>4</Field>' +
1039
- '<Condition>7</Condition>' +
1040
- '<Value>1052708</Value>' +
1041
- '</Selection>' +
1042
- '</Selections>' +
1043
- '<Fields>' +
1044
- '<Field>0</Field>' +
1045
- '<Field>1</Field>' +
1046
- '</Fields>' +
1047
- '<Orders>' +
1048
- '<Order>' +
1049
- '<Field>1</Field>' +
1050
- '<Direction>1</Direction>' +
1051
- '</Order>' +
1052
- '</Orders>' +
1053
- '<NotifyUpdate>yes</NotifyUpdate>';
1054
-
1055
-
1056
- self.actionCallback = callback;
1057
-
1058
- self.sendSOAPRequest(action, actionData, {
1059
- callback: function(soapRequest, soapResponse){
1060
- node.debug('' + action);
1061
- var regex = new RegExp("<SOAP-ENV:Body>((.|\n)*)<\/SOAP-ENV:Body>", "gm");
1062
- var responseData = ((regex.exec(soapResponse))[1].replace(/m:|:m/gm, "")).replace(/xmlns="urn:loewe.de:RemoteTV:Tablet"/,"" );
1063
- if (responseData !== null) {
1064
- var options = {};
1065
- options.async = false;
1066
- options.trim = true;
1067
- options.explicitArray = false;
1068
- options.attrkey = options.attrkey || '$';
1069
- options.charkey = options.charkey || '_';
1070
- console.debug(responseData);
1071
-
1072
- parseString(responseData, options, function (err, result) {
1073
- if (err) {
1074
- node.error('*********************** ERROR ***********************');
1075
- node.error('error: ', action);
1076
- node.error('err: ', err)
1077
- node.error(responseData);
1078
- node.error('********************* END ERROR *********************');
1079
- }
1080
- else {
1081
- console.debug(result['CreateIteratorResponse']);
1082
- self.data['Iterator'] = result['CreateIteratorResponse'];
1083
- node.debug('' + action + ' Id: ' + self.data.Iterator.Id);
1084
- }
1085
- });
1086
- }
1087
- else {
1088
- node.error('*********************** ERROR ***********************');
1089
- node.error('SoapRequest');
1090
- node.error(soapRequest);
1091
- node.error('---------------------------------------------------------------');
1092
- node.error('error: ', action);
1093
- node.error('data: ', responseData)
1094
- node.error('********************* END ERROR *********************');
1095
- }
1096
- self.actionCallback(action, responseData);
1097
- }
1098
- });
1099
- };
1100
-
1101
- node.setActionField = function(actionText, callback) {
1102
- var self = this;
1103
- var action = 'SetActionField';
1104
- var actionData = '<m:InputText>' + actionText + '</m:InputText>';
1105
- self.actionCallback = callback;
1106
-
1107
- self.sendSOAPRequest(action, actionData, {
1108
- callback: function(soapRequest, soapResponse){
1109
- node.debug('' + action);
1110
- node.debug(soapResponse);
1111
-
1112
- var regex = new RegExp("<m:" + action + "Response [A-Za-z:=\".]*>(.*)<\/m:" + action + "Response>", "gm");
1113
- var responseData = (regex.exec(soapResponse))[1];
1114
-
1115
- if (responseData !== null) {
1116
- node.debug(' result: ', responseData)
1117
- }
1118
- else {
1119
- node.error('*********************** ERROR ***********************');
1120
- node.error('error: ', action);
1121
- node.error('---------------------------------------------------------------');
1122
- node.error('SoapRequest');
1123
- node.error(soapRequest);
1124
- node.error('---------------------------------------------------------------');
1125
- node.error('soapResponse');
1126
- node.error(soapResponse);
1127
- node.error('********************* END ERROR *********************');
1128
- }
1129
- self.actionCallback(action, responseData);
1130
- }
1131
- });
1132
- }
1133
-
1134
- node.getActionField = function(RequestId, callback) {
1135
- var self = this;
1136
- var action = 'GetActionField';
1137
- var actionData = '<m:RequestId>' + RequestId + '</m:RequestId>';
1138
- self.actionCallback = callback;
1139
-
1140
- self.sendSOAPRequest(action, actionData, {
1141
- callback: function(soapRequest, soapResponse){
1142
- node.debug('' + action);
1143
- node.debug(soapResponse);
1144
-
1145
- var regex = new RegExp("<m:" + action + "Response [A-Za-z:=\".]*>(.*)<\/m:" + action + "Response>", "gm");
1146
- var responseData = (regex.exec(soapResponse))[1];
1147
-
1148
- if (responseData !== null) {
1149
- node.debug(' result: ', responseData)
1150
- }
1151
- else {
1152
- node.error('*********************** ERROR ***********************');
1153
- node.error('error: ', action);
1154
- node.error('---------------------------------------------------------------');
1155
- node.error('SoapRequest');
1156
- node.error(soapRequest);
1157
- node.error('---------------------------------------------------------------');
1158
- node.error('soapResponse');
1159
- node.error(soapResponse);
1160
- node.error('********************* END ERROR *********************');
1161
- }
1162
- self.actionCallback(action, responseData);
1163
- }
1164
- });
1165
- }
1166
-
1167
- node.injectRCKey = function(key, callback) {
1168
- var self = this;
1169
- var action = 'InjectRCKey';
1170
- var actionData = '<InputEventSequence>' +
1171
- '<RCKeyEvent alphabet="l2700" value="' + key + '" mode="press"/>' +
1172
- '<RCKeyEvent alphabet="l2700" value="' + key + '" mode="release"/>' +
1173
- '</InputEventSequence>';
1174
- self.actionCallback = callback;
1175
-
1176
- self.sendSOAPRequest(action, actionData, {
1177
- callback: function(soapRequest, soapResponse){
1178
- node.debug(soapResponse);
1179
- node.debug('' + action);
1180
- var regex = new RegExp("<m:" + action + "Response [A-Za-z:=\".]*>(.*)<\/m:" + action + "Response>", "gm");
1181
- var responseData = (regex.exec(soapResponse))[1];
1182
- if (responseData !== null) {
1183
- node.debug(' result: ', responseData)
1184
- }
1185
- else {
1186
- node.error('*********************** ERROR ***********************');
1187
- node.error('error: ', action);
1188
- node.error('---------------------------------------------------------------');
1189
- node.error('SoapRequest');
1190
- node.error(soapRequest);
1191
- node.error('---------------------------------------------------------------');
1192
- node.error('soapResponse');
1193
- node.error(soapResponse);
1194
- node.error('********************* END ERROR *********************');
1195
- }
1196
- self.actionCallback(action, soapResponse);
1197
- }
1198
- });
1199
- }
1200
-
1201
- node.activateFeaturePackage = function(featurePackageData, callback) {
1202
- var self = this;
1203
- var action = 'ActivateFeaturePackage';
1204
- var actionData = '<m:Package>' + featurePackageData.Package + '</m:Package>';
1205
- if ( featurePackageData.ActivationCode !== undefined & featurePackageData.ActivationCode !== '') {
1206
- actionData += '<m:ActivationCode>' + featurePackageData.ActivationCode + '</m:ActivationCode>';
1207
- }
1208
-
1209
- self.actionCallback = callback;
1210
-
1211
- self.sendSOAPRequest(action, actionData, {
1212
- callback: function(soapRequest, soapResponse){
1213
- var match = /<m:ActivateFeaturePackageResponse [A-Za-z:=\".]*>((.|\n)*)<\/m:ActivateFeaturePackageResponse>/gm.exec(soapResponse);
1214
- if(match !== null) {
1215
- var result = (/<m:Result>(.*)<\/m:Result>/gm.exec(soapResponse))[1];
1216
- node.debug('FeaturePackage' + featurePackageData.Package + ' ' + result + 'activated');
1217
- }
1218
- else {
1219
- node.error('*********************** ERROR ***********************');
1220
- node.error('activating Feature ' + featurePackageData);
1221
- node.error('---------------------------------------------------------------');
1222
- node.error('SoapRequest');
1223
- node.error(soapRequest);
1224
- node.error('---------------------------------------------------------------');
1225
- node.error('soapResponse');
1226
- node.error(soapResponse);
1227
- node.error('********************* END ERROR *********************');
1228
- }
1229
- self.actionCallback(action, soapResponse);
1230
- }
1231
- });
1232
- };
1233
-
1234
- /**
1235
- * Get ClientId from TV
1236
- *
1237
- * @param {Function} callback
1238
- */
1239
- node.requestAccess = function(callback) {
1240
- var self = this;
1241
- var action = 'RequestAccess';
1242
- var actionData = '<DeviceType>----------------</DeviceType>';
1243
-
1244
- this.actionCallback = callback;
1245
-
1246
- this.sendSOAPRequest(action, actionData, {
1247
- callback: function(soapRequest, soapResponse){
1248
- var clientId = (/<m:ClientId>(.*)<\/m:ClientId>/gm.exec(soapResponse))[1];
1249
- if(clientId !== null) {
1250
- self.ClientId = clientId;
1251
- node.debug('Access ClientId: ' + self.ClientId)
1252
- }
1253
- else {
1254
- node.error('*********************** ERROR ***********************');
1255
- node.error('error: ', actionData);
1256
- node.error('---------------------------------------------------------------');
1257
- node.error('SoapRequest');
1258
- node.error(soapRequest);
1259
- node.error('---------------------------------------------------------------');
1260
- node.error('soapResponse');
1261
- node.error(soapResponse);
1262
- node.error('********************* END ERROR *********************');
1263
- }
1264
- self.actionCallback(action, soapResponse);
1265
- }
1266
- });
1267
- };
1268
-
1269
- node.getFeature = function(featureName, callback) {
1270
- var self = this;
1271
- var action = 'GetFeature';
1272
- var actionData = '<m:Name>' + featureName + '</m:Name>';
1273
-
1274
- self.actionCallback = callback;
1275
-
1276
- self.sendSOAPRequest(action, actionData, {
1277
- callback: function(soapRequest, soapResponse){
1278
- self.getObjectFromResponse(action, soapRequest, soapResponse, self.actionCallback);
1279
- }
1280
- });
1281
- };
1282
-
1283
- this.onSDDP = node.onSDDP();
1284
-
1285
- node.status({fill:"red",shape:"ring",text:"disconnected"});
1286
- node.onEvent('alive');
1287
- }
1288
- RED.nodes.registerType("LOEWE-TV", LoeweTvNode);
1289
- };
1
+ module.exports = function(RED) {
2
+ "use strict";
3
+
4
+ const dgram = require('dgram');
5
+ console.debug = function (){};
6
+ console.debug('[LoeweTV]************************************************************');
7
+ console.debug('[LoeweTV]************************************************************');
8
+
9
+ var TVs = {};
10
+
11
+ const socket = dgram.createSocket('udp4');
12
+
13
+ socket.bind(1900, () => {
14
+ socket.addMembership('239.255.255.250');
15
+ console.log('[LoeweTV] SDDP Client lauscht an Port 1900');
16
+ });
17
+
18
+ socket.on('message', (msg, rinfo) => {
19
+ var sddpMsg = msg.toString();
20
+ // console.log('[LoeweTV SDDP:1900] ' + rinfo.address);
21
+ // console.log(sddpMsg);
22
+ if ( TVs.hasOwnProperty(rinfo.address) ) {
23
+ var lines = sddpMsg.split('\r');
24
+ var objSddpMsg = {};
25
+ // console.log('[LoeweTV SDDP:1900] ' + rinfo.address);
26
+ // console.log(sddpMsg);
27
+ lines.forEach((line) => {
28
+ // console.debug('[LoeweTV SDDP:1900]' + line);
29
+ var del = line.indexOf(':');
30
+ if(del>1) {
31
+ var key = line.substring(0,del).trim().toLowerCase();
32
+ var value = line.substring(del+1).trim();
33
+ // console.debug('[LoeweTV SDDP:1900] Key: ' + key + ' Value: ' + value);
34
+ objSddpMsg[key]=value;
35
+ }
36
+ });
37
+ TVs[rinfo.address].onSDDP(objSddpMsg);
38
+ }
39
+ });
40
+
41
+ const socket1902 = dgram.createSocket('udp4');
42
+
43
+ socket1902.bind(1902, () => {
44
+ socket1902.addMembership('239.255.255.250');
45
+ console.log('[LoeweTV] SDDP Client lauscht an Port 1902');
46
+ });
47
+
48
+ socket1902.on('message', (msg, rinfo) => {
49
+ var sddpMsg = msg.toString();
50
+ // console.log('[LoeweTV SDDP:1902] ' + rinfo.address);
51
+ // console.log(sddpMsg);
52
+ if ( TVs.hasOwnProperty(rinfo.address) ) {
53
+ var lines = sddpMsg.split('\r');
54
+ var objSddpMsg = {};
55
+ console.log('[LoeweTV SDDP:1902] ' + rinfo.address);
56
+ console.log(sddpMsg);
57
+ lines.forEach((line) => {
58
+ // console.debug('[LoeweTV SDDP:1902]' + line);
59
+ var del = line.indexOf(':');
60
+ if(del>1) {
61
+ var key = line.substring(0,del).trim().toLowerCase();
62
+ var value = line.substring(del+1).trim();
63
+ // console.debug('[LoeweTV SDDP:1902] Key: ' + key + ' Value: ' + value);
64
+ objSddpMsg[key]=value;
65
+ }
66
+ });
67
+
68
+ TVs[rinfo.address].onSDDP(objSddpMsg);
69
+ }
70
+ });
71
+
72
+ function LoeweTvNode(config) {
73
+ const http = require('http');
74
+ const os = require('os');
75
+ const xml2js = require('xml2js');
76
+ const wol = require('wol');
77
+ var parseString = xml2js.parseString;
78
+ var node = this;
79
+ node.ClientId = '';
80
+ node.sddpUuid = '';
81
+ node.Volume = '';
82
+ node.Mute = '';
83
+ node.data = {CurrentStatus:{Power:'disconnected'}};
84
+
85
+ RED.nodes.createNode(node, config);
86
+
87
+ this.tv = RED.nodes.getNode(config.tv);
88
+
89
+ node.name = this.tv.name;
90
+
91
+ var interfaces = os.networkInterfaces();
92
+
93
+ for ( var i in interfaces) {
94
+ interfaces[i].forEach(function(details) {
95
+ details.interface = i;
96
+ if (!details.internal) {
97
+ delete details.netmask;
98
+ delete details.mac;
99
+ delete details.internal;
100
+ this.HostIP = details.address;
101
+ }
102
+ });
103
+ break;
104
+ }
105
+
106
+ // Check if ipAddress is valid IP address
107
+ var ipRegExp = /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/;
108
+
109
+ if(ipRegExp.test(this.tv.ip)) {
110
+ this.ipAddress = this.tv.ip;
111
+ node.log('neuer LOEWE TV \"' + this.name + '\" angemeldet IP: ' + this.ipAddress);
112
+ }
113
+ else {
114
+ throw new TypeError('IP address not valid!');
115
+ }
116
+
117
+ var ipRegExp = /^([0-9])*/;
118
+
119
+ if(ipRegExp.test(this.tv.fcid)) {
120
+ this.fcid = this.tv.fcid;
121
+ console.debug('FCID: ' + this.fcid);
122
+ }
123
+ else {
124
+ throw new TypeError('fcid not valid!');
125
+ }
126
+
127
+ TVs[this.ipAddress] = this;
128
+
129
+ node.onActionTemplate = function(action, actionData) {
130
+ var self = this;
131
+ var newmsg = { payload:{
132
+ Name:node.name,
133
+ ClientId:node.ClientId,
134
+ Status:node.data.CurrentStatus.Power
135
+ },
136
+ action:action,
137
+ actionData:actionData,
138
+ topic:'LoeweTV'
139
+ };
140
+ node.updateNodeStatus();
141
+ node.send(newmsg);
142
+ };
143
+
144
+ node.onAction = function(action, actionData) {
145
+ var self = this;
146
+ node.log(action);
147
+ switch ( action ) {
148
+ case "GetVolume":
149
+ node.log('Volume: ', node.Volume);
150
+ var newmsg = { payload:{Name:node.name, ClientId:node.ClientId, Status:node.data.CurrentStatus.Power}, action:action, actionData:{Volume:node.Volume}, topic:action };
151
+ node.send(newmsg);
152
+ break;
153
+
154
+ case "GetMute":
155
+ node.log('Mute: ', node.Mute);
156
+ var newmsg = { payload:{Name:node.name, ClientId:node.ClientId, Status:node.data.CurrentStatus.Power}, action:action, actionData:{Volume:node.Mute}, topic:action };
157
+ node.send(newmsg);
158
+ break;
159
+
160
+ case "SetVolume":
161
+ node.log('Set Volume to: ', node.Volume);
162
+ var newmsg = { payload:{Name:node.name, ClientId:node.ClientId, Status:node.data.CurrentStatus.Power}, action:action, actionData:{Volume:node.Volume}, topic:action };
163
+ node.send(newmsg);
164
+ break;
165
+
166
+ case "SetMute":
167
+ node.log('Set Mute to: ', node.Mute);
168
+ var newmsg = { payload:{Name:node.name, ClientId:node.ClientId, Status:node.data.CurrentStatus.Power}, action:action, actionData:{Volume:node.Mute}, topic:action };
169
+ node.send(newmsg);
170
+ break;
171
+
172
+ default:
173
+ node.log(actionData);
174
+ break;
175
+ }
176
+ };
177
+
178
+ node.on('input', function(msg) {
179
+ var action = msg.topic;
180
+ switch ( action ) {
181
+ case "SDDPDiscover":
182
+ node.sddpDiscover();
183
+ break;
184
+ case "SwitchOn":
185
+ node.switchOn();
186
+ break;
187
+ case "WakeUp":
188
+ node.wakeUp(msg.payload);
189
+ break;
190
+ case "InjectSoapRequest":
191
+ node.injectSoapRequest(msg.payload, node.onAction);
192
+ break;
193
+ case "RequestAccess":
194
+ node.onEvent('alive');
195
+ break;
196
+ case "GetChannelList":
197
+ node.getChannelList(msg.payload, node.onActionTemplate);
198
+ break;
199
+ case "GetCurrentEvent":
200
+ node.getEvent('CurrentEvent', msg.payload, node.onActionTemplate);
201
+ break;
202
+ case "GetNextEvent":
203
+ node.getEvent('NextEvent', msg.payload, node.onActionTemplate);
204
+ break;
205
+ case "GetMediaItem":
206
+ node.getMediaItem(msg.payload, node.onActionTemplate);
207
+ break;
208
+ case "GetMediaEvent":
209
+ node.getMediaEvent(msg.payload, node.onActionTemplate);
210
+ // node.getMediaEvent(function(){});
211
+ break;
212
+ case "PlayerPrepare":
213
+ node.playerPrepare(msg.payload, node.onActionTemplate);
214
+ break;
215
+ case "PlayerReleasePrepared":
216
+ node.execAction(action, '', node.onAction);
217
+ break;
218
+ case "PlayerPlay":
219
+ node.execAction(action, '', node.onAction);
220
+ break;
221
+ case "PlayerPause":
222
+ node.execAction(action, '', node.onAction);
223
+ break;
224
+ case "PlayerResume":
225
+ node.execAction(action, '', node.onAction);
226
+ break;
227
+ case "PlayerStop":
228
+ node.execAction(action, '', node.onAction);
229
+ break;
230
+ case "PlayerSetSpeed":
231
+ node.execAction(action, '', node.onAction);
232
+ break;
233
+ case "PlayerSeekTo":
234
+ node.execAction(action, '', node.onAction);
235
+ break;
236
+ case "GetVolume":
237
+ node.getValue('Volume', node.onAction);
238
+ break;
239
+ case "SetVolume":
240
+ let volume = msg.payload.toString() + '0000';
241
+ node.setValue('Volume', volume, node.onAction);
242
+ break;
243
+ case "GetMute":
244
+ node.getValue('Mute', node.onAction);
245
+ break;
246
+ case "SetMute":
247
+ node.setValue('Mute', msg.payload, node.onAction);
248
+ break;
249
+ case "Standby":
250
+ node.standby(msg.payload, node.onAction);
251
+ // node.standby(msg.payload, node.onAction);
252
+ // node.execAction(action, '', node.onAction);
253
+ break;
254
+ case "ProgramTimer":
255
+ node.execAction(action, '', node.onAction);
256
+ break;
257
+ case "GetDeviceData":
258
+ node.execAction(action, '', node.onActionTemplate);
259
+ break;
260
+ case "GetValueFromBrowserJS":
261
+ node.execAction(action, '', node.onAction);
262
+ break;
263
+ case "GetBrowserJSChangeList":
264
+ node.execAction(action, '', node.onAction);
265
+ break;
266
+ case "SetValueToBrowserJS":
267
+ node.execAction(action, '', node.onAction);
268
+ break;
269
+ case "GetCurrentPlayback":
270
+ node.execAction(action, '', node.onActionTemplate);
271
+ break;
272
+ case "GetCurrentStatus":
273
+ node.execAction(action, '', node.onActionTemplate);
274
+ break;
275
+ case "ZapToApplication":
276
+ node.execAction(action, '', node.onAction);
277
+ break;
278
+ case "ZapToMedia":
279
+ node.execAction(action, '', node.onAction);
280
+ break;
281
+ case "InjectRCKey":
282
+ node.injectRCKey(msg.payload, node.onAction);
283
+ // node.injectRCKey(msg.payload, function(){});
284
+ // setTimeout( node.execAction, 3000, ['GetCurrentStatus', '', ]
285
+ break;
286
+ case "InjectKeyboardKey":
287
+ node.execAction(action, '', node.onAction);
288
+ break;
289
+ case "SetActionField":
290
+ node.setActionField(msg.payload, node.onAction);
291
+ break;
292
+ case "GetActionField":
293
+ node.getActionField(msg.payload, node.onAction);
294
+ break;
295
+ case "GetFeature":
296
+ node.getFeature(msg.payload, node.onActionTemplate);
297
+ break;
298
+ case "ActivateFeaturePackage":
299
+ node.activateFeaturePackage(msg.payload, node.onAction);
300
+ break;
301
+ case "DectivateFeaturePackage":
302
+ node.execAction(action, '', node.onAction);
303
+ break;
304
+ case "GetUpgradeInfo":
305
+ node.execAction(action, '', node.onAction);
306
+ break;
307
+ case "GetListOfChannelLists":
308
+ node.getListOfChannelLists(msg.payload, node.onActionTemplate);
309
+ break;
310
+ case "AddFavoriteList":
311
+ node.execAction(action, '', node.onAction);
312
+ break;
313
+ case "RemoveFavoriteList":
314
+ node.execAction(action, '', node.onAction);
315
+ break;
316
+ case "RenameFavoriteList":
317
+ node.execAction(action, '', node.onAction);
318
+ break;
319
+ case "AddServicesFavoriteList":
320
+ node.execAction(action, '', node.onAction);
321
+ break;
322
+ case "RemoveServicesFavoriteList":
323
+ node.execAction(action, '', node.onAction);
324
+ break;
325
+ case "MoveServicesFavoriteList":
326
+ node.execAction(action, '', node.onAction);
327
+ break;
328
+ case "AddFavoriteListFromVirtual":
329
+ node.execAction(action, '', node.onAction);
330
+ break;
331
+ case "GetListOfVirtualLists":
332
+ node.getListOfVirtualLists(msg.payload, node.onActionTemplate);
333
+ break;
334
+ case "ImportServiceLists":
335
+ node.execAction(action, '', node.onAction);
336
+ break;
337
+ case "ExportServiceLists":
338
+ node.execAction(action, '', node.onAction);
339
+ break;
340
+ case "GetDRPlusArchive":
341
+ node.getDRPlusArchive(msg.payload, node.onActionTemplate);
342
+ break;
343
+ case "GetVolumes":
344
+ node.getVolumes(msg.payload, node.onActionTemplate);
345
+ break;
346
+ case "PlayMultiroom":
347
+ node.execAction(action, '', node.onAction);
348
+ break;
349
+ case "GetSettings":
350
+ node.execAction(action, '',node.onActionTemplate);
351
+ break;
352
+ case "SetSetting":
353
+ node.execAction(action, '', node.onAction);
354
+ break;
355
+ case "ParentalLock":
356
+ node.execAction(action, '', node.onAction);
357
+ break;
358
+ case "GetParentalLock":
359
+ node.execAction(action, '', node.onActionTemplate);
360
+ break;
361
+ case "GetTimerList":
362
+ node.execAction(action, '', node.onActionTemplate);
363
+ break;
364
+ case "CreateIterator":
365
+ node.createIterator(node.onAction);
366
+ break;
367
+ case "CloseIterator":
368
+ node.execAction(action, '', node.onAction);
369
+ break;
370
+ default:
371
+ break;
372
+ }
373
+ });
374
+
375
+ node.updateNodeStatus = function() {
376
+ var statusFill = "";
377
+ var statusShape = "ring";
378
+ var power = node.data.CurrentStatus.Power;
379
+ node.debug('updateNodeStatus');
380
+ switch (power) {
381
+ case "idle":
382
+ statusFill = "blue";
383
+ node.log('TV ist im \"Leerlauf\"');
384
+ break;
385
+ case "standby":
386
+ statusFill = "grey";
387
+ node.log('TV ist im Standby');
388
+ break;
389
+ case "switch_on":
390
+ case "tv":
391
+ statusFill = "green";
392
+ statusShape = "dot";
393
+ node.log('TV ist Eingeschaltet');
394
+ break;
395
+ default:
396
+ statusFill = "grey";
397
+ node.log('TV status unknown');
398
+ break;
399
+ }
400
+ node.status({fill:statusFill,shape:statusShape,text:node.data.CurrentStatus.Power});
401
+ var newmsg = { payload:{
402
+ Name:node.name,
403
+ ClientId:node.ClientId,
404
+ Status:node.data.CurrentStatus.Power
405
+ },
406
+ data:node.data,
407
+ topic:'Status'
408
+ };
409
+ node.send(newmsg);
410
+ };
411
+
412
+ node.onEvent = function(event) {
413
+ var self = this;
414
+ node.debug('received SDDP Event: ' + event);
415
+ node.debug('TV Status: ' + node.data.CurrentStatus.Power);
416
+
417
+ if (event === 'alive') {
418
+ node.debug('handle SDDP Event: ' + event);
419
+ if (node.ClientId === '' |
420
+ node.data.CurrentStatus.Power === 'switchon' |
421
+ node.data.CurrentStatus.Power === 'disconnected' |
422
+ node.data.CurrentStatus.Power === 'standby' ) {
423
+ node.requestAccess(function() {
424
+ node.execAction('GetCurrentStatus', '', function () {
425
+ node.log('Registriere ClientId: ' + node.ClientId);
426
+ if (node.sddpUuid !== '') {
427
+ node.log('SDDP uuid: ' + node.sddpUuid);
428
+ }
429
+ if (node.data.CurrentStatus.Power === 'switchon') {
430
+ node.log('schalte ein');
431
+ node.injectRCKey('12', function () {});
432
+ setTimeout(node.onEvent, 500, 'alive');
433
+ } else {
434
+ node.execAction('GetSettings', '', function () {
435
+ node.activateFeaturePackage({"Package":"72413U80"}, function(){
436
+ node.execAction('GetDeviceData', '', function () {
437
+ if (self.tv.mac === undefined | self.tv.mac === '') {
438
+ if ( self.data.hasOwnProperty("DeviceData") ) {
439
+ if ( self.data.DeviceData.hasOwnProperty("MAC-Address-LAN") ) {
440
+ self.tv.mac = self.data.DeviceData['MAC-Address-LAN'];
441
+ }
442
+ }
443
+ }
444
+
445
+ node.createIterator(function(){
446
+ node.getValue('Volume', function(){
447
+ node.getValue('Mute', function(){
448
+ // node.execAction('GetCurrentStatus', '', function () {
449
+ node.updateNodeStatus();
450
+ // });
451
+ });
452
+ });
453
+ });
454
+ });
455
+ });
456
+ });
457
+ }
458
+ });
459
+ });
460
+ }
461
+ node.debug('handle SDDP Event: ' + event + ' ok');
462
+ }
463
+ else if (event === 'byebye') {
464
+ node.debug('handle SDDP Event: ' + event);
465
+ if (node.data.CurrentStatus.Power === 'tv' | node.data.CurrentStatus.Power === 'idle' | node.data.CurrentStatus.Power === 'disconnected') {
466
+ node.debug('schaltet ab');
467
+ // node.execAction('GetCurrentStatus', '', function() {});
468
+ node.data.CurrentStatus.Power = "standby";
469
+ node.ClientId = '';
470
+ }
471
+ node.debug('handle SDDP Event: ' + event + ' ok');
472
+ }
473
+ else {
474
+ node.warn('SDDP: received unhandeld Event');
475
+ }
476
+ node.updateNodeStatus();
477
+ node.debug('TV Status: ' + node.data.CurrentStatus.Power);
478
+ node.debug('received SDDP Event END');
479
+ };
480
+
481
+ node.onSDDP = function() {
482
+ var self = this;
483
+ return function(objSddpMsg){
484
+ if (objSddpMsg.hasOwnProperty("nt")) {
485
+ if (objSddpMsg.nt === 'upnp:rootdevice') {
486
+ if (objSddpMsg.nts === 'ssdp:alive') {
487
+ try {
488
+ var sddpUuid = (objSddpMsg.usn).split(':')[1].trim();
489
+ if (self.sddpUuid === '') {
490
+ self.sddpUuid = sddpUuid;
491
+ node.log('SDDP uuid: ' + self.sddpUuid);
492
+ self.onEvent('alive');
493
+ }
494
+ }
495
+ catch {
496
+ node.error('*********************** ERROR ***********************');
497
+ node.error(objSddpMsg);
498
+ node.error('********************* END ERROR *********************');
499
+ }
500
+
501
+ } else {
502
+ if ( objSddpMsg.nts === 'ssdp:byebye' ) {
503
+ self.sddpUuid = '';
504
+ self.ClientId = '';
505
+ self.onEvent('byebye');
506
+ }
507
+ else if ( objSddpMsg.nts === 'ssdp:discover' | objSddpMsg.man === '\"ssdp:discover\"') {
508
+ }
509
+ else {
510
+ node.error('[LoeweTV ERROR] ', objSddpMsg);
511
+ }
512
+ }
513
+ }
514
+ } else {
515
+ console.log("[" + node.name + "] SDDP:");
516
+ console.log(objSddpMsg);
517
+ }
518
+ };
519
+ };
520
+
521
+ node.sddpDiscover = function() {
522
+ const client = dgram.createSocket('udp4');
523
+ client.bind({
524
+ address: 'localhost',
525
+ port: 0
526
+ }, (err) => {
527
+ !!err && console.error(err);
528
+ });
529
+
530
+ let msg_txt = 'M-SEARCH * HTTP/1.1\r\n' +
531
+ 'HOST:239.255.255.250:1900\r\n' +
532
+ 'ST:upnp:rootdevice\r\n' +
533
+ 'MX:2\r\n' +
534
+ 'MAN:"ssdp:discover"\r\n\r\n';
535
+
536
+ const message = Buffer.from(msg_txt);
537
+
538
+ // client.bind(); // So that we get a port so we can listen before sending
539
+ // listen(client.address().port);
540
+ client.send(message, 0, message.length, 1900, "239.255.255.250", (err) => {
541
+ !!err && console.error(err); // err != null);
542
+ });
543
+ client.close();
544
+ };
545
+
546
+ node.getTimeString = function(time) {
547
+ var seconds = Math.floor(time/1000)%60;
548
+ var minutes = Math.floor(time/60000)%60;
549
+ var hours = Math.floor(time/3600000)%24;
550
+ var timeString;
551
+
552
+ if (seconds < 10) { seconds = "0" + seconds; }
553
+ if (minutes < 10) { minutes = "0" + minutes; }
554
+ if (hours < 10) { hours = " " + hours; }
555
+ timeString = hours + ":" + minutes + ":" + seconds;
556
+ return timeString;
557
+ };
558
+
559
+ node.wakeUp = function(mac) {
560
+ var self = this;
561
+ if (mac === undefined | mac === '') {
562
+ node.log('mac undefined');
563
+
564
+ if ( this.data.hasOwnProperty("DeviceData") ) {
565
+ if ( this.data.DeviceData.hasOwnProperty("MAC-Address-LAN") ) {
566
+ mac = this.data.DeviceData['MAC-Address-LAN'];
567
+ }
568
+ }
569
+ }
570
+ if (mac !== undefined & mac !== '') {
571
+ node.log('wakeUp: ' + mac);
572
+ wol.wake(mac, function(err, res){
573
+ // node.log('', err);
574
+ node.log('', res);
575
+ });
576
+ } else {
577
+ node.error('*********************** ERROR ***********************');
578
+ node.error('wakeUp: no MAC');
579
+ node.error('********************* END ERROR *********************');
580
+ }
581
+ }
582
+
583
+ node.switchOn = function() {
584
+ var self = this;
585
+ node.log('switchOn');
586
+ node.log('Status: ' + self.data.CurrentStatus.Power);
587
+
588
+ if (self.data.CurrentStatus.Power !== 'idle' & self.data.CurrentStatus.Power !== 'tv') {
589
+ self.wakeUp();
590
+ self.data.CurrentStatus.Power = 'switchon';
591
+ }else if (self.data.CurrentStatus.Power === 'idle' | self.data.CurrentStatus.Power === 'standby') {
592
+ self.injectRCKey('12', function () {});
593
+ } else {
594
+ node.log('[LoeweTV ' + self.name + '] ist bereits an');
595
+ }
596
+ }
597
+
598
+ /**
599
+ * Create and send request to the TV
600
+ *
601
+ * @param {String} ClientId The ClientId from RequestAccess
602
+ * @param {String} action The action to perform
603
+ * @param {Array} data like RC-Key number
604
+ * @param {Array} options Options array (mostly for callback)
605
+ */
606
+ node.sendSOAPRequest = function(action, actionData, options) {
607
+ var url, urn;
608
+ var responseData = '';
609
+ var self = this;
610
+
611
+ url = '/loewe_tablet_0001';
612
+ urn = 'loewe.de:RemoteTV:Tablet';
613
+
614
+
615
+ // var body = '<?xml version="1.0" encoding="utf-8"?>' +
616
+ var body = '<SOAP-ENV:Envelope ' +
617
+ 'xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" ' +
618
+ 'xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" ' +
619
+ 'xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing/" ' +
620
+ 'xmlns:wse="http://www.w3.org/2009/02/ws-evt" ' +
621
+ 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ' +
622
+ 'xmlns:xsd="http://www.w3.org/2001/XMLSchema" ' +
623
+ 'xmlns:m="urn:loewe.de:RemoteTV:Tablet">' +
624
+ '<SOAP-ENV:Body>' +
625
+ '<m:' + action + '>' +
626
+ '<fcid>' + this.fcid + '</fcid>' +
627
+ '<ClientId>' + this.ClientId + '</ClientId>' +
628
+ actionData +
629
+ '</m:' + action + '>' +
630
+ '</SOAP-ENV:Body>' +
631
+ '</SOAP-ENV:Envelope>';
632
+
633
+ var postRequest = {
634
+ host: this.ipAddress,
635
+ path: url,
636
+ port: 905,
637
+ method: "POST",
638
+ headers: {
639
+ 'SOAPAction': action,
640
+ 'Accept': '*/*',
641
+ 'Accept-Encoding': 'gzip, deflate',
642
+ 'Accept-Language': 'de-de',
643
+ 'Content-Type': 'application/soap+xml; charset=utf-8',
644
+ 'Connection': 'keep-alive',
645
+ 'User-Agent': 'Assist Media/23 CFNetwork/808 Darwin/16.0.0'
646
+ }
647
+ };
648
+
649
+ if(options !== undefined) {
650
+ self.callback = options.callback;
651
+ } else {
652
+ self.callback = function (soapRequest, soapResponse) {
653
+ node.log('SOAP Request: ');
654
+ node.log(soapRequest);
655
+ node.log('SOAP Response: ');
656
+ node.log(soapResponse);
657
+ };
658
+ }
659
+
660
+ var req = http.request(postRequest, function(res) {
661
+ res.setEncoding('utf8');
662
+ res.on('data', (chunk) => {
663
+ responseData += chunk.toString();
664
+ });
665
+
666
+ res.on('end', function() {
667
+ var match = /<SOAP-ENV:Fault>/gm.exec(responseData);
668
+ if(match !== null) {
669
+ node.error('*********************** ERROR ***********************');
670
+ node.error('SOAP body: ');
671
+ node.error(body);
672
+ node.error('---------------------------------------------------------------');
673
+ node.error('SOAP Response: ');
674
+ node.error(responseData);
675
+ node.error('********************* END ERROR *********************');
676
+ }
677
+ self.callback(body, responseData);
678
+ });
679
+
680
+
681
+ });
682
+
683
+ req.on('error', function(e) {
684
+ node.log('' + e.address + ' ist nicht erreichbar!');
685
+ self.sddpUuid = '';
686
+ self.ClientId = '';
687
+ });
688
+
689
+ req.write(body);
690
+ node.debug('sendSOAPRequest: ');
691
+ node.debug(body);
692
+ req.end();
693
+
694
+ return this;
695
+ };
696
+
697
+ node.getObjectFromResponse = function(action, soapRequest, soapResponse, callback) {
698
+ var self = this;
699
+ node.debug('-------------------- ' + action + ' ------------------');
700
+
701
+ var regex = new RegExp("<SOAP-ENV:Body>((.|\n)*)<\/SOAP-ENV:Body>", "gm");
702
+ var dataFromAction = ((regex.exec(soapResponse))[1].replace(/m:|:m/gm, "")).replace(/xmlns="urn:loewe.de:RemoteTV:Tablet"/,"" );
703
+ node.debug(soapResponse);
704
+ /*
705
+ var responseData = (regex.exec(soapResponse))[1];
706
+ node.debug(responseData);
707
+ responseData = responseData.replace(/m:|:m/gm, "");
708
+ node.debug('--------------------------------------');
709
+ console.debug(responseData);
710
+ responseData = responseData.replace(/xmlns="urn:loewe.de:RemoteTV:Tablet"/,"");
711
+ node.debug('--------------------------------------');
712
+ console.debug(responseData);
713
+ node.debug('--------------------------------------');
714
+ */
715
+ var options = {};
716
+ var objResponse;
717
+
718
+ node.debug(dataFromAction)
719
+
720
+ options.async = false;
721
+ options.trim = true;
722
+ options.explicitArray = false;
723
+ options.attrkey = options.attrkey || '$';
724
+ options.charkey = options.charkey || '_';
725
+
726
+ parseString(dataFromAction, options, function (err, result) {
727
+ if (err) {
728
+ node.error('*********************** ERROR ***********************');
729
+ node.error(action);
730
+ node.error(err)
731
+ node.error('********************* END ERROR *********************');
732
+ }
733
+ else {
734
+ for (var key in result) {
735
+ for (var reponseKey in result[key]) {
736
+ break
737
+ }
738
+ break
739
+ }
740
+ if (result[key] === undefined | result[key] === '' | result[key] === ' ' | reponseKey == 0) {
741
+ node.error('*********************** ERROR ***********************');
742
+ node.error('SoapRequest');
743
+ node.error(soapRequest);
744
+ node.error('---------------------------------------------------------------');
745
+ node.error('SoapResponse');
746
+ node.error(soapResponse);
747
+ node.error('---------------------------------------------------------------');
748
+ node.error(result);
749
+ node.error('********************* END ERROR *********************');
750
+ } else {
751
+ objResponse = result;
752
+ }
753
+ }
754
+ });
755
+
756
+ var objName = action.replace('Get', '');
757
+ if (objResponse !== undefined) {
758
+ this.data[objName] = objResponse[action+'Response'];
759
+ node.debug('result obj: ' + objName);
760
+ node.debug(this.data[objName]);
761
+ } else {
762
+ this.data[objName] = {};
763
+ }
764
+ callback(action, this.data[objName]);
765
+ };
766
+
767
+ node.injectSoapRequest = function(soapRequest, callback) {
768
+ var self = this;
769
+ self.actionCallback = callback;
770
+
771
+ node.log('', soapRequest);
772
+
773
+ var action = (/<m:(\w*)>/gm.exec(soapRequest))[1];
774
+ node.log('****************************************************');
775
+ node.log('****************************************************');
776
+ node.log('-------------------- ' + action + ' ------------------');
777
+
778
+ var regex = new RegExp("<m:" + action + ">((.)*)<\/m:" + action + ">", "gm");
779
+ var actionData = (regex.exec(soapRequest))[1];
780
+
781
+ node.log('', actionData);
782
+
783
+ /*
784
+ this.sendSOAPRequest(action, actionData, {
785
+ callback: function(soapRequest, soapResponse){
786
+ node.debug('soapResponse:');
787
+ console.debug(soapResponse);
788
+ self.actionCallback(action, soapResponse);
789
+ }
790
+ });
791
+ */
792
+
793
+ this.sendSOAPRequest(action, actionData, {
794
+ callback: function(soapRequest, soapResponse){
795
+ node.log('soapResponse:');
796
+ node.log(soapResponse);
797
+ self.getObjectFromResponse(action, soapRequest, soapResponse, function (action, responseData) {
798
+ self.actionCallback(action, responseData)
799
+ node.log('****************************************************');
800
+ node.log('****************************************************');
801
+ });
802
+ }
803
+ });
804
+ };
805
+
806
+ node.getEvent = function(event, player, callback) {
807
+ var self = this;
808
+ var action = 'Get'+event;
809
+ var actionData = '<Player>' + player + '</Player>';
810
+ node.debug('-------------------- ' + action + ' ------------------');
811
+
812
+ self.actionCallback = callback;
813
+
814
+ this.sendSOAPRequest(action, actionData, {
815
+ callback: function(soapRequest, soapResponse){
816
+ node.debug('soapResponse:');
817
+ console.debug(soapResponse);
818
+ self.getObjectFromResponse(action, soapRequest, soapResponse, self.actionCallback);
819
+ }
820
+ });
821
+ };
822
+
823
+ node.getMediaItem = function(mediaItemUuid, callback) {
824
+ var self = this;
825
+ var action = 'GetMediaItem';
826
+ var actionData = '<MediaItemReference mediaItemUuid=\"' + mediaItemUuid + '\"/>';
827
+
828
+ self.actionCallback = callback;
829
+
830
+ self.sendSOAPRequest(action, actionData, {
831
+ callback: function(soapRequest, soapResponse){
832
+ self.getObjectFromResponse(action, soapRequest, soapResponse, self.actionCallback);
833
+ }
834
+ });
835
+ };
836
+
837
+ node.getMediaEvent = function(mediaEventUuid, callback) {
838
+ var self = this;
839
+ var action = 'GetMediaEvent';
840
+ var actionData = '<MediaEventReference mediaEventUuid=\"' + mediaEventUuid + '\"/>';
841
+
842
+ self.actionCallback = callback;
843
+
844
+ self.sendSOAPRequest(action, actionData, {
845
+ callback: function(soapRequest, soapResponse){
846
+ self.getObjectFromResponse(action, soapRequest, soapResponse, self.actionCallback);
847
+ }
848
+ });
849
+ };
850
+
851
+ node.playerPrepare = function(data, callback) {
852
+ var self = this;
853
+ var action = 'PlayerPrepare';
854
+ var actionData = '<Player>' + data.Player + '</Player><Locator>' + data.Locator + '</Locator>';
855
+
856
+ self.actionCallback = callback;
857
+
858
+ self.sendSOAPRequest(action, actionData, {
859
+ callback: function(soapRequest, soapResponse){
860
+ self.getObjectFromResponse(action, soapRequest, soapResponse, self.actionCallback);
861
+ }
862
+ });
863
+ };
864
+
865
+ node.execAction = function(action, actionData, callback) {
866
+ var self = this;
867
+
868
+ self.actionCallback = callback;
869
+
870
+ self.sendSOAPRequest(action, actionData, {
871
+ callback: function(soapRequest, soapResponse){
872
+ self.getObjectFromResponse(action, soapRequest, soapResponse, self.actionCallback);
873
+ }
874
+ });
875
+ };
876
+
877
+ node.standby = function(value, callback) {
878
+ var self = this;
879
+ var action = 'Standby';
880
+ var actionData = '<Value>' + value + '</Value>';
881
+ self.actionCallback = callback;
882
+
883
+ self.sendSOAPRequest(action, actionData, {
884
+ callback: function(soapRequest, soapResponse){
885
+ var regex = new RegExp("<m:Value>(\\d*)<\/m:Value>", "gm");
886
+ var responseValue = regex.exec(soapResponse);
887
+ node.debug('----------------- ' + action + ' -----------------------');
888
+ node.debug(soapResponse);
889
+ node.debug('----------------- ' + action + ' -----------------------');
890
+ if(responseValue !== null) {
891
+ node.log('' + action + ' value: ' + responseValue[1])
892
+ self[value] = responseValue[1];
893
+ self.actionCallback(action, responseValue[1]);
894
+ } else {
895
+ regex = new RegExp("<m:" + action + "Response [A-Za-z:=\".]*>(.*)<\/m:" + action + "Response>", "gm");
896
+ console.debug(soapResponse);
897
+ var responseData = (regex.exec(soapResponse))[1];
898
+ if (responseData !== null) {
899
+ node.debug(action + ' data: ' + responseData);
900
+ self.actionCallback(action, responseData);
901
+ } else {
902
+ node.error('*********************** ERROR ***********************');
903
+ node.error('SoapRequest');
904
+ node.error(soapRequest);
905
+ node.error('---------------------------------------------------------------');
906
+ node.error('error: ', action);
907
+ node.error('data: ', soapResponse);
908
+ node.error('********************* END ERROR *********************');
909
+ }
910
+ }
911
+ }
912
+ });
913
+ };
914
+
915
+ node.setValue = function(valueName, value, callback) {
916
+ var self = this;
917
+ var action = 'Set'+valueName;
918
+ var actionData = '<Value>' + value + '</Value>';
919
+ self.actionCallback = callback;
920
+
921
+ self.sendSOAPRequest(action, actionData, {
922
+ callback: function(soapRequest, soapResponse){
923
+ var regex = new RegExp("<m:Value>(\\d*)<\/m:Value>", "gm");
924
+ var responseValue = regex.exec(soapResponse);
925
+ node.debug('----------------- ' + action + ' -----------------------');
926
+ node.debug(soapResponse);
927
+ node.debug('----------------- ' + action + ' -----------------------');
928
+ if(responseValue !== null) {
929
+ node.log('' + action + ' value: ' + responseValue[1])
930
+ self[value] = responseValue[1];
931
+ self.actionCallback(action, responseValue[1]);
932
+ } else {
933
+ regex = new RegExp("<m:" + action + "Response [A-Za-z:=\".]*>(.*)<\/m:" + action + "Response>", "gm");
934
+ console.debug(soapResponse);
935
+ var responseData = (regex.exec(soapResponse))[1];
936
+ if (responseData !== null) {
937
+ node.debug(action + ' data: ' + responseData);
938
+ self.actionCallback(action, responseData);
939
+ } else {
940
+ node.error('*********************** ERROR ***********************');
941
+ node.error('SoapRequest');
942
+ node.error(soapRequest);
943
+ node.error('---------------------------------------------------------------');
944
+ node.error('error: ', action);
945
+ node.error('data: ', soapResponse);
946
+ node.error('********************* END ERROR *********************');
947
+ }
948
+ }
949
+ }
950
+ });
951
+ };
952
+
953
+ node.getValue = function(valueName, callback) {
954
+ var self = this;
955
+ var action = 'Get'+valueName;
956
+ var actionData = '';
957
+ self.actionCallback = callback;
958
+
959
+ self.sendSOAPRequest(action, actionData, {
960
+ callback: function(soapRequest, soapResponse){
961
+ var regex = new RegExp("<m:Value>(\\d*)<\/m:Value>", "gm");
962
+ var responseValue = regex.exec(soapResponse);
963
+ node.debug('----------------- ' + action + ' -----------------------');
964
+ node.debug(soapResponse);
965
+ node.debug('----------------- ' + action + ' -----------------------');
966
+ if(responseValue !== null) {
967
+ node.debug(action + ' ' + valueName + ': ' + responseValue[1])
968
+ self[valueName] = responseValue[1];
969
+ self.actionCallback(action, self[valueName]);
970
+ } else {
971
+ regex = new RegExp("<m:" + action + "Response [A-Za-z:=\".]*>(.*)<\/m:" + action + "Response>", "gm");
972
+ var responseData = (regex.exec(soapResponse))[1];
973
+ if (responseData !== null) {
974
+ node.debug(action + ' data: ' + responseData);
975
+ self.actionCallback(action, responseData);
976
+ } else {
977
+ node.error('*********************** ERROR ***********************');
978
+ node.error('SoapRequest');
979
+ node.error(soapRequest);
980
+ node.error('---------------------------------------------------------------');
981
+ node.error('error: ', action);
982
+ node.error('data: ', soapResponse);
983
+ node.error('********************* END ERROR *********************');
984
+ }
985
+ }
986
+ }
987
+ });
988
+ };
989
+
990
+ node.getDRPlusArchive = function(startindex, callback) {
991
+ var self = this;
992
+ var action = 'GetDRPlusArchive';
993
+ var actionData = '<m:QueryParameters>' +
994
+ '<m:Range startIndex="' + startindex + '" maxItems="5"/>' +
995
+ '</m:QueryParameters>';
996
+
997
+ self.actionCallback = callback;
998
+
999
+ self.sendSOAPRequest(action, actionData, {
1000
+ callback: function(soapRequest, soapResponse){
1001
+ self.getObjectFromResponse(action, soapRequest, soapResponse, self.actionCallback);
1002
+ }
1003
+ });
1004
+ };
1005
+
1006
+ node.getListOfVirtualLists = function(startindex, callback) {
1007
+ var self = this;
1008
+ var action = 'GetListOfVirtualLists';
1009
+ var actionData = '<m:QueryParameters>' +
1010
+ '<m:Range startIndex="' + startindex + '" maxItems="5"/>' +
1011
+ '</m:QueryParameters>';
1012
+
1013
+ self.actionCallback = callback;
1014
+
1015
+ self.sendSOAPRequest(action, actionData, {
1016
+ callback: function(soapRequest, soapResponse){
1017
+ self.getObjectFromResponse(action, soapRequest, soapResponse, self.actionCallback);
1018
+ }
1019
+ });
1020
+ };
1021
+
1022
+ node.getVolumes = function(startindex, callback) {
1023
+ var self = this;
1024
+ var action = 'GetVolumes';
1025
+ var actionData = '<m:QueryParameters>' +
1026
+ '<m:Range startIndex="' + startindex + '" maxItems="5"/>' +
1027
+ '</m:QueryParameters>';
1028
+
1029
+ self.actionCallback = callback;
1030
+
1031
+ self.sendSOAPRequest(action, actionData, {
1032
+ callback: function(soapRequest, soapResponse){
1033
+ self.getObjectFromResponse(action, soapRequest, soapResponse, self.actionCallback);
1034
+ }
1035
+ });
1036
+ };
1037
+
1038
+ node.getListOfChannelLists = function(startindex, callback) {
1039
+ var self = this;
1040
+ var action = 'GetListOfChannelLists';
1041
+ var actionData = '<m:QueryParameters>' +
1042
+ '<m:Range startIndex="' + startindex + '" maxItems="5"/>' +
1043
+ '</m:QueryParameters>' +
1044
+ '<m:AdditionalParameters>' +
1045
+ '<m:Properties isActiveList="0"/>' +
1046
+ '</m:AdditionalParameters>';
1047
+
1048
+ self.actionCallback = callback;
1049
+
1050
+ self.sendSOAPRequest(action, actionData, {
1051
+ callback: function(soapRequest, soapResponse){
1052
+ self.getObjectFromResponse(action, soapRequest, soapResponse, self.actionCallback);
1053
+ }
1054
+ });
1055
+ };
1056
+
1057
+ node.getChannelList = function(startindex, callback) {
1058
+ var self = this;
1059
+ var action = 'GetChannelList';
1060
+ var actionData = '<ChannelListView>fastscansl7f33a470-7d6e-4b60-a103-f7739be9484d</ChannelListView>' +
1061
+ '<QueryParameters>' +
1062
+ '<Range startIndex="' + startindex + '" maxItems="1"/>' +
1063
+ '<OrderField field="userChannelNumber" type="ascending"/>' +
1064
+ '</QueryParameters>';
1065
+
1066
+ self.actionCallback = callback;
1067
+
1068
+ self.sendSOAPRequest(action, actionData, {
1069
+ callback: function(soapRequest, soapResponse){
1070
+ self.getObjectFromResponse(action, soapRequest, soapResponse, self.actionCallback);
1071
+ }
1072
+ });
1073
+ };
1074
+
1075
+ node.createIterator = function(callback) {
1076
+ var self = this;
1077
+ var action = 'CreateIterator';
1078
+ var actionData = '<TableName>de.loewe.sl2.volume.table.main</TableName>' +
1079
+ '<Type>0</Type>' +
1080
+ '<Selections>' +
1081
+ '<Selection>' +
1082
+ '<Field>4</Field>' +
1083
+ '<Condition>7</Condition>' +
1084
+ '<Value>1052708</Value>' +
1085
+ '</Selection>' +
1086
+ '</Selections>' +
1087
+ '<Fields>' +
1088
+ '<Field>0</Field>' +
1089
+ '<Field>1</Field>' +
1090
+ '</Fields>' +
1091
+ '<Orders>' +
1092
+ '<Order>' +
1093
+ '<Field>1</Field>' +
1094
+ '<Direction>1</Direction>' +
1095
+ '</Order>' +
1096
+ '</Orders>' +
1097
+ '<NotifyUpdate>yes</NotifyUpdate>';
1098
+
1099
+
1100
+ self.actionCallback = callback;
1101
+
1102
+ self.sendSOAPRequest(action, actionData, {
1103
+ callback: function(soapRequest, soapResponse){
1104
+ node.debug(action);
1105
+ var regex = new RegExp("<SOAP-ENV:Body>((.|\n)*)<\/SOAP-ENV:Body>", "gm");
1106
+ var responseData = ((regex.exec(soapResponse))[1].replace(/m:|:m/gm, "")).replace(/xmlns="urn:loewe.de:RemoteTV:Tablet"/,"" );
1107
+ if (responseData !== null) {
1108
+ var options = {};
1109
+ options.async = false;
1110
+ options.trim = true;
1111
+ options.explicitArray = false;
1112
+ options.attrkey = options.attrkey || '$';
1113
+ options.charkey = options.charkey || '_';
1114
+ console.debug(responseData);
1115
+
1116
+ parseString(responseData, options, function (err, result) {
1117
+ if (err) {
1118
+ node.error('*********************** ERROR ***********************');
1119
+ node.error('error: ', action);
1120
+ node.error('err: ', err)
1121
+ node.error(responseData);
1122
+ node.error('********************* END ERROR *********************');
1123
+ }
1124
+ else {
1125
+ console.debug(result['CreateIteratorResponse']);
1126
+ self.data['Iterator'] = result['CreateIteratorResponse'];
1127
+ node.debug(action + ' Id: ' + self.data.Iterator.Id);
1128
+ }
1129
+ });
1130
+ }
1131
+ else {
1132
+ node.error('*********************** ERROR ***********************');
1133
+ node.error('SoapRequest');
1134
+ node.error(soapRequest);
1135
+ node.error('---------------------------------------------------------------');
1136
+ node.error('error: ', action);
1137
+ node.error('data: ', responseData)
1138
+ node.error('********************* END ERROR *********************');
1139
+ }
1140
+ self.actionCallback(action, responseData);
1141
+ }
1142
+ });
1143
+ };
1144
+
1145
+ node.setActionField = function(actionText, callback) {
1146
+ var self = this;
1147
+ var action = 'SetActionField';
1148
+ var actionData = '<m:InputText>' + actionText + '</m:InputText>';
1149
+ self.actionCallback = callback;
1150
+
1151
+ self.sendSOAPRequest(action, actionData, {
1152
+ callback: function(soapRequest, soapResponse){
1153
+ node.debug(action);
1154
+ node.debug(soapResponse);
1155
+
1156
+ var regex = new RegExp("<m:" + action + "Response [A-Za-z:=\".]*>(.*)<\/m:" + action + "Response>", "gm");
1157
+ var responseData = (regex.exec(soapResponse))[1];
1158
+
1159
+ if (responseData !== null) {
1160
+ node.debug(' result: ', responseData)
1161
+ }
1162
+ else {
1163
+ node.error('*********************** ERROR ***********************');
1164
+ node.error('error: ', action);
1165
+ node.error('---------------------------------------------------------------');
1166
+ node.error('SoapRequest');
1167
+ node.error(soapRequest);
1168
+ node.error('---------------------------------------------------------------');
1169
+ node.error('soapResponse');
1170
+ node.error(soapResponse);
1171
+ node.error('********************* END ERROR *********************');
1172
+ }
1173
+ self.actionCallback(action, responseData);
1174
+ }
1175
+ });
1176
+ }
1177
+
1178
+ node.getActionField = function(RequestId, callback) {
1179
+ var self = this;
1180
+ var action = 'GetActionField';
1181
+ var actionData = '<m:RequestId>' + RequestId + '</m:RequestId>';
1182
+ self.actionCallback = callback;
1183
+
1184
+ self.sendSOAPRequest(action, actionData, {
1185
+ callback: function(soapRequest, soapResponse){
1186
+ node.debug(action);
1187
+ node.debug(soapResponse);
1188
+
1189
+ var regex = new RegExp("<m:" + action + "Response [A-Za-z:=\".]*>(.*)<\/m:" + action + "Response>", "gm");
1190
+ var responseData = (regex.exec(soapResponse))[1];
1191
+
1192
+ if (responseData !== null) {
1193
+ node.debug(' result: ', responseData)
1194
+ }
1195
+ else {
1196
+ node.error('*********************** ERROR ***********************');
1197
+ node.error('error: ', action);
1198
+ node.error('---------------------------------------------------------------');
1199
+ node.error('SoapRequest');
1200
+ node.error(soapRequest);
1201
+ node.error('---------------------------------------------------------------');
1202
+ node.error('soapResponse');
1203
+ node.error(soapResponse);
1204
+ node.error('********************* END ERROR *********************');
1205
+ }
1206
+ self.actionCallback(action, responseData);
1207
+ }
1208
+ });
1209
+ }
1210
+
1211
+ node.injectRCKey = function(key, callback) {
1212
+ var self = this;
1213
+ var action = 'InjectRCKey';
1214
+ var actionData = '<InputEventSequence>' +
1215
+ '<RCKeyEvent alphabet="l2700" value="' + key + '" mode="press"/>' +
1216
+ '<RCKeyEvent alphabet="l2700" value="' + key + '" mode="release"/>' +
1217
+ '</InputEventSequence>';
1218
+ self.actionCallback = callback;
1219
+
1220
+ self.sendSOAPRequest(action, actionData, {
1221
+ callback: function(soapRequest, soapResponse){
1222
+ node.debug(soapResponse);
1223
+ node.debug(action);
1224
+ var regex = new RegExp("<m:" + action + "Response [A-Za-z:=\".]*>(.*)<\/m:" + action + "Response>", "gm");
1225
+ var responseData = (regex.exec(soapResponse))[1];
1226
+ if (responseData !== null) {
1227
+ node.debug(' result: ', responseData)
1228
+ }
1229
+ else {
1230
+ node.error('*********************** ERROR ***********************');
1231
+ node.error('error: ', action);
1232
+ node.error('---------------------------------------------------------------');
1233
+ node.error('SoapRequest');
1234
+ node.error(soapRequest);
1235
+ node.error('---------------------------------------------------------------');
1236
+ node.error('soapResponse');
1237
+ node.error(soapResponse);
1238
+ node.error('********************* END ERROR *********************');
1239
+ }
1240
+ self.actionCallback(action, soapResponse);
1241
+ }
1242
+ });
1243
+ }
1244
+
1245
+ node.activateFeaturePackage = function(featurePackageData, callback) {
1246
+ var self = this;
1247
+ var action = 'ActivateFeaturePackage';
1248
+ var actionData = '<m:Package>' + featurePackageData.Package + '</m:Package>';
1249
+ if ( featurePackageData.ActivationCode !== undefined & featurePackageData.ActivationCode !== '') {
1250
+ actionData += '<m:ActivationCode>' + featurePackageData.ActivationCode + '</m:ActivationCode>';
1251
+ }
1252
+
1253
+ self.actionCallback = callback;
1254
+
1255
+ self.sendSOAPRequest(action, actionData, {
1256
+ callback: function(soapRequest, soapResponse){
1257
+ var match = /<m:ActivateFeaturePackageResponse [A-Za-z:=\".]*>((.|\n)*)<\/m:ActivateFeaturePackageResponse>/gm.exec(soapResponse);
1258
+ if(match !== null) {
1259
+ var result = (/<m:Result>(.*)<\/m:Result>/gm.exec(soapResponse))[1];
1260
+ node.debug('FeaturePackage ' + featurePackageData.Package + ' ' + result + ' activated');
1261
+ }
1262
+ else {
1263
+ node.error('*********************** ERROR ***********************');
1264
+ node.error('activating Feature ' + featurePackageData);
1265
+ node.error('---------------------------------------------------------------');
1266
+ node.error('SoapRequest');
1267
+ node.error(soapRequest);
1268
+ node.error('---------------------------------------------------------------');
1269
+ node.error('soapResponse');
1270
+ node.error(soapResponse);
1271
+ node.error('********************* END ERROR *********************');
1272
+ }
1273
+ self.actionCallback(action, soapResponse);
1274
+ }
1275
+ });
1276
+ };
1277
+
1278
+ /**
1279
+ * Get ClientId from TV
1280
+ *
1281
+ * @param {Function} callback
1282
+ */
1283
+ node.requestAccess = function(callback) {
1284
+ var self = this;
1285
+ var action = 'RequestAccess';
1286
+ var actionData = '<DeviceType>----------------</DeviceType>';
1287
+
1288
+ this.actionCallback = callback;
1289
+
1290
+ this.sendSOAPRequest(action, actionData, {
1291
+ callback: function(soapRequest, soapResponse){
1292
+ var clientId = (/<m:ClientId>(.*)<\/m:ClientId>/gm.exec(soapResponse))[1];
1293
+ var accessStatus = 'undefined';
1294
+ node.debug(soapResponse);
1295
+ if(clientId !== null) {
1296
+ accessStatus = (/<m:AccessStatus>(.*)<\/m:AccessStatus>/gm.exec(soapResponse))[1];
1297
+ self.ClientId = clientId;
1298
+ node.debug('Access ClientId: ' + clientId);
1299
+ node.debug('Access Status: ' + accessStatus);
1300
+ }
1301
+ else {
1302
+ node.error('*********************** ERROR ***********************');
1303
+ node.error('error: ', actionData);
1304
+ node.error('---------------------------------------------------------------');
1305
+ node.error('SoapRequest');
1306
+ node.error(soapRequest);
1307
+ node.error('---------------------------------------------------------------');
1308
+ node.error('soapResponse');
1309
+ node.error(soapResponse);
1310
+ node.error('********************* END ERROR *********************');
1311
+ }
1312
+ self.actionCallback(action, soapResponse);
1313
+ }
1314
+ });
1315
+ };
1316
+
1317
+ node.getFeature = function(featureName, callback) {
1318
+ var self = this;
1319
+ var action = 'GetFeature';
1320
+ var actionData = '<m:Name>' + featureName + '</m:Name>';
1321
+
1322
+ self.actionCallback = callback;
1323
+
1324
+ self.sendSOAPRequest(action, actionData, {
1325
+ callback: function(soapRequest, soapResponse){
1326
+ self.getObjectFromResponse(action, soapRequest, soapResponse, self.actionCallback);
1327
+ }
1328
+ });
1329
+ };
1330
+
1331
+ this.onSDDP = node.onSDDP();
1332
+
1333
+ node.status({fill:"red",shape:"ring",text:node.data.CurrentStatus.Power});
1334
+ node.onEvent('alive');
1335
+ }
1336
+ RED.nodes.registerType("LOEWE-TV", LoeweTvNode);
1337
+ };