node-red-contrib-loewe-tv 0.2.3 → 0.3.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,107 +1,185 @@
1
1
  module.exports = function(RED) {
2
+ "use strict";
2
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
+
3
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;
4
78
  var node = this;
5
- const Loewe = require('loewetv');
79
+ node.ClientId = '';
80
+ node.sddpUuid = '';
81
+ node.Volume = '';
82
+ node.Mute = '';
83
+ node.data = {CurrentStatus:{Power:''}};
6
84
 
7
85
  RED.nodes.createNode(node, config);
8
86
 
9
- var LoeweTV = new Loewe(config.ip);
10
- LoeweTV.name = node.name;
87
+ this.tv = RED.nodes.getNode(config.tv);
11
88
 
12
- console.log('[', node.name, ']');
13
- console.log(LoeweTV);
14
-
15
- node.status({fill:"red",shape:"ring",text:"disconnected"});
89
+ node.name = this.tv.name;
16
90
 
17
- LoeweTV.onAction = function(action, data) {
18
-
19
- console.log('[' + node.name + '] ' + action);
20
- switch ( action ) {
21
- case "RequestAccess":
22
- break;
91
+ var interfaces = os.networkInterfaces();
23
92
 
24
- case "Subscribe":
25
- console.log(data);
26
- break;
27
-
28
- case "GetChannelList":
29
- console.log(data);
30
- break;
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
+ }
31
105
 
32
- case "GetListOfChannelLists":
33
- console.log(data);
34
- break;
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])$/;
35
108
 
36
- case "GetMediaItem":
37
- console.log(data);
38
- break;
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
+ }
39
116
 
40
- case "GetMediaEvent":
41
- console.log(data);
42
- break;
117
+ var ipRegExp = /^([0-9])*/;
43
118
 
44
- case "GetCurrentEvent":
45
- console.log(data);
46
- break;
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
+ }
47
126
 
48
- case "GetNextEvent":
49
- console.log(data);
50
- break;
127
+ TVs[this.ipAddress] = this;
51
128
 
52
- case "GetFeature":
53
- console.log(data);
54
- break;
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
+ }
55
142
 
143
+ node.onAction = function(action, actionData) {
144
+ var self = this;
145
+ node.log(action);
146
+ switch ( action ) {
56
147
  case "GetDeviceData":
57
- console.log(data);
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);
58
156
  break;
59
-
60
- case "GetChannelInfo":
61
- console.log(data);
62
- break;
63
-
64
- case "GetCurrentPlayback":
65
- console.log(data);
66
- break;
67
-
68
157
  case "GetVolume":
69
- console.log(data);
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);
70
161
  break;
71
162
 
72
163
  case "GetMute":
73
- console.log(data);
74
- break;
75
-
76
- case "SetActionField":
77
- console.log(data);
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);
78
167
  break;
79
168
 
80
169
  case "SetVolume":
81
- console.log(data);
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);
82
173
  break;
83
174
 
84
175
  case "SetMute":
85
- console.log(data);
86
- break;
87
-
88
- case "InjectRCKey":
89
- console.log(data);
90
- break;
91
-
92
- case "Standby":
93
- console.log(data);
94
- break;
95
-
96
- case "ActivateFeaturePackage":
97
- console.log(data);
98
- break;
99
-
100
- case "CreateIterator":
101
- console.log(data);
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);
102
179
  break;
103
180
 
104
181
  default:
182
+ node.log(actionData);
105
183
  break;
106
184
  }
107
185
 
@@ -110,295 +188,256 @@ module.exports = function(RED) {
110
188
  node.on('input', function(msg) {
111
189
  var action = msg.topic;
112
190
  switch ( action ) {
113
- case "RequestAccess":
114
- LoeweTV.onEvent('alive');
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);
115
199
  break;
116
- case "Subscribe":
117
- LoeweTV.subscribe(LoeweTV.onAction);
200
+ case "RequestAccess":
201
+ node.onEvent('alive');
118
202
  break;
119
203
  case "GetChannelList":
120
- LoeweTV.execAction(action, '', LoeweTV.onAction);
121
- // LoeweTV.getChannelList(msg.payload, function(){});
204
+ node.getChannelList(msg.payload, node.onActionTemplate);
122
205
  break;
123
-
124
206
  case "GetCurrentEvent":
125
- LoeweTV.execAction(action, '', LoeweTV.onAction);
126
- // LoeweTV.getCurrentEvent(function(){});
207
+ node.getEvent('CurrentEvent', msg.payload, node.onActionTemplate);
127
208
  break;
128
-
129
209
  case "GetNextEvent":
130
- LoeweTV.execAction(action, '', LoeweTV.onAction);
131
- // LoeweTV.getNextEvent(function(){});
210
+ node.getEvent('NextEvent', msg.payload, node.onActionTemplate);
132
211
  break;
133
-
134
212
  case "GetMediaItem":
135
- LoeweTV.execAction(action, '', LoeweTV.onAction);
136
- // LoeweTV.getMediaItem(msg.payload, function(){});
213
+ node.getMediaItem(msg.payload, node.onActionTemplate);
137
214
  break;
138
-
139
215
  case "GetMediaEvent":
140
- LoeweTV.execAction(action, '', LoeweTV.onAction);
141
- // LoeweTV.getMediaEvent(function(){});
216
+ node.getMediaEvent(msg.payload, node.onActionTemplate);
217
+ // node.getMediaEvent(function(){});
142
218
  break;
143
-
144
219
  case "PlayerPrepare":
145
- LoeweTV.execAction(action, '', LoeweTV.onAction);
220
+ node.playerPrepare(msg.payload, node.onActionTemplate);
146
221
  break;
147
-
148
222
  case "PlayerReleasePrepared":
149
- LoeweTV.execAction(action, '', LoeweTV.onAction);
223
+ node.execAction(action, '', node.onAction);
150
224
  break;
151
-
152
225
  case "PlayerPlay":
153
- LoeweTV.execAction(action, '', LoeweTV.onAction);
226
+ node.execAction(action, '', node.onAction);
154
227
  break;
155
-
156
228
  case "PlayerPause":
157
- LoeweTV.execAction(action, '', LoeweTV.onAction);
229
+ node.execAction(action, '', node.onAction);
158
230
  break;
159
-
160
231
  case "PlayerResume":
161
- LoeweTV.execAction(action, '', LoeweTV.onAction);
232
+ node.execAction(action, '', node.onAction);
162
233
  break;
163
-
164
234
  case "PlayerStop":
165
- LoeweTV.execAction(action, '', LoeweTV.onAction);
235
+ node.execAction(action, '', node.onAction);
166
236
  break;
167
-
168
237
  case "PlayerSetSpeed":
169
- LoeweTV.execAction(action, '', LoeweTV.onAction);
238
+ node.execAction(action, '', node.onAction);
170
239
  break;
171
-
172
240
  case "PlayerSeekTo":
173
- LoeweTV.execAction(action, '', LoeweTV.onAction);
241
+ node.execAction(action, '', node.onAction);
174
242
  break;
175
-
176
243
  case "GetVolume":
177
- LoeweTV.getVolume(LoeweTV.onAction);
244
+ node.getValue('Volume', node.onAction);
178
245
  break;
179
-
180
246
  case "SetVolume":
181
- LoeweTV.setVolume(msg.payload, LoeweTV.onAction);
247
+ let volume = msg.payload.toString() + '0000';
248
+ node.setValue('Volume', volume, node.onAction);
182
249
  break;
183
-
184
250
  case "GetMute":
185
- LoeweTV.getMute(LoeweTV.onAction);
251
+ node.getValue('Mute', node.onAction);
186
252
  break;
187
-
188
253
  case "SetMute":
189
- LoeweTV.setMute(msg.payload, LoeweTV.onAction);
254
+ node.setValue('Mute', msg.payload, node.onAction);
190
255
  break;
191
-
192
256
  case "Standby":
193
- // LoeweTV.standby(msg.payload, LoeweTV.onAction);
194
- LoeweTV.execAction(action, '', LoeweTV.onAction);
257
+ node.standby(msg.payload, node.onAction);
258
+ // node.standby(msg.payload, node.onAction);
259
+ // node.execAction(action, '', node.onAction);
195
260
  break;
196
-
197
261
  case "ProgramTimer":
198
- LoeweTV.execAction(action, '', LoeweTV.onAction);
262
+ node.execAction(action, '', node.onAction);
199
263
  break;
200
-
201
264
  case "GetDeviceData":
202
- LoeweTV.getDeviceData(LoeweTV.onAction);
265
+ node.execAction(action, '', node.onAction);
203
266
  break;
204
-
205
267
  case "GetValueFromBrowserJS":
206
- LoeweTV.execAction(action, '', LoeweTV.onAction);
268
+ node.execAction(action, '', node.onAction);
207
269
  break;
208
-
209
270
  case "GetBrowserJSChangeList":
210
- LoeweTV.execAction(action, '', LoeweTV.onAction);
271
+ node.execAction(action, '', node.onAction);
211
272
  break;
212
-
213
273
  case "SetValueToBrowserJS":
214
- LoeweTV.execAction(action, '', LoeweTV.onAction);
274
+ node.execAction(action, '', node.onAction);
215
275
  break;
216
-
217
276
  case "GetCurrentPlayback":
218
- LoeweTV.execAction(action, '', LoeweTV.onAction);
277
+ node.execAction(action, '', node.onActionTemplate);
219
278
  break;
220
-
221
279
  case "GetCurrentStatus":
222
- LoeweTV.getCurrentStatus(LoeweTV.onAction);
280
+ node.execAction(action, '', node.onActionTemplate);
223
281
  break;
224
-
225
282
  case "ZapToApplication":
226
- LoeweTV.execAction(action, '', LoeweTV.onAction);
283
+ node.execAction(action, '', node.onAction);
227
284
  break;
228
-
229
285
  case "ZapToMedia":
230
- LoeweTV.execAction(action, '', LoeweTV.onAction);
231
- break;
232
-
233
- case "InjectRCKey":
234
- LoeweTV.execAction(action, '', LoeweTV.onAction);
286
+ node.execAction(action, '', node.onAction);
235
287
  break;
236
-
237
288
  case "InjectRCKey":
238
- LoeweTV.injectRCKey(msg.payload, LoeweTV.onAction);
289
+ node.injectRCKey(msg.payload, node.onAction);
239
290
  break;
240
-
241
291
  case "InjectKeyboardKey":
242
- LoeweTV.execAction(action, '', LoeweTV.onAction);
292
+ node.execAction(action, '', node.onAction);
243
293
  break;
244
-
245
294
  case "SetActionField":
246
- LoeweTV.setActionField(msg.payload, LoeweTV.onAction);
295
+ node.setActionField(msg.payload, node.onAction);
247
296
  break;
248
-
249
297
  case "GetActionField":
250
- LoeweTV.execAction(action, '', LoeweTV.onAction);
298
+ node.getActionField(msg.payload, node.onAction);
251
299
  break;
252
-
253
300
  case "GetFeature":
254
- LoeweTV.execAction(action, '', LoeweTV.onAction);
255
- // LoeweTV.getFeature(function(){});
301
+ node.getFeature(msg.payload, node.onActionTemplate);
256
302
  break;
257
-
258
303
  case "ActivateFeaturePackage":
259
- LoeweTV.activateFeaturePackage(msg.payload, LoeweTV.onAction);
304
+ node.activateFeaturePackage(msg.payload, node.onAction);
260
305
  break;
261
-
262
306
  case "DectivateFeaturePackage":
263
- LoeweTV.execAction(action, '', LoeweTV.onAction);
307
+ node.execAction(action, '', node.onAction);
264
308
  break;
265
-
266
309
  case "GetUpgradeInfo":
267
- LoeweTV.execAction(action, '', LoeweTV.onAction);
310
+ node.execAction(action, '', node.onAction);
268
311
  break;
269
-
270
312
  case "GetListOfChannelLists":
271
- LoeweTV.execAction(action, '', LoeweTV.onAction);
272
- // LoeweTV.getListOfChannelLists(function(){});
313
+ node.getListOfChannelLists(msg.payload, node.onActionTemplate);
273
314
  break;
274
-
275
315
  case "AddFavoriteList":
276
- LoeweTV.execAction(action, '', LoeweTV.onAction);
316
+ node.execAction(action, '', node.onAction);
277
317
  break;
278
-
279
318
  case "RemoveFavoriteList":
280
- LoeweTV.execAction(action, '', LoeweTV.onAction);
319
+ node.execAction(action, '', node.onAction);
281
320
  break;
282
321
  case "RenameFavoriteList":
283
- LoeweTV.execAction(action, '', LoeweTV.onAction);
322
+ node.execAction(action, '', node.onAction);
284
323
  break;
285
-
286
324
  case "AddServicesFavoriteList":
287
- LoeweTV.execAction(action, '', LoeweTV.onAction);
325
+ node.execAction(action, '', node.onAction);
288
326
  break;
289
-
290
327
  case "RemoveServicesFavoriteList":
291
- LoeweTV.execAction(action, '', LoeweTV.onAction);
328
+ node.execAction(action, '', node.onAction);
292
329
  break;
293
-
294
330
  case "MoveServicesFavoriteList":
295
- LoeweTV.execAction(action, '', LoeweTV.onAction);
331
+ node.execAction(action, '', node.onAction);
296
332
  break;
297
-
298
333
  case "AddFavoriteListFromVirtual":
299
- LoeweTV.execAction(action, '', LoeweTV.onAction);
334
+ node.execAction(action, '', node.onAction);
300
335
  break;
301
-
302
336
  case "GetListOfVirtualLists":
303
- LoeweTV.execAction(action, '', LoeweTV.onAction);
337
+ node.getListOfVirtualLists(msg.payload, node.onActionTemplate);
304
338
  break;
305
-
306
339
  case "ImportServiceLists":
307
- LoeweTV.execAction(action, '', LoeweTV.onAction);
340
+ node.execAction(action, '', node.onAction);
308
341
  break;
309
-
310
342
  case "ExportServiceLists":
311
- LoeweTV.execAction(action, '', LoeweTV.onAction);
343
+ node.execAction(action, '', node.onAction);
312
344
  break;
313
-
314
345
  case "GetDRPlusArchive":
315
- LoeweTV.execAction(action, '', LoeweTV.onAction);
346
+ node.getDRPlusArchive(msg.payload, node.onActionTemplate);
316
347
  break;
317
-
318
348
  case "GetVolumes":
319
- LoeweTV.execAction(action, '', LoeweTV.onAction);
349
+ node.getVolumes(msg.payload, node.onActionTemplate);
320
350
  break;
321
-
322
351
  case "PlayMultiroom":
323
- LoeweTV.execAction(action, '', LoeweTV.onAction);
352
+ node.execAction(action, '', node.onAction);
324
353
  break;
325
-
326
354
  case "GetSettings":
327
- LoeweTV.execAction(action, '', LoeweTV.onAction);
355
+ node.execAction(action, '',node.onActionTemplate);
328
356
  break;
329
-
330
357
  case "SetSetting":
331
- LoeweTV.execAction(action, '', LoeweTV.onAction);
358
+ node.execAction(action, '', node.onAction);
332
359
  break;
333
-
334
360
  case "ParentalLock":
335
- LoeweTV.execAction(action, '', LoeweTV.onAction);
361
+ node.execAction(action, '', node.onAction);
336
362
  break;
337
-
338
363
  case "GetParentalLock":
339
- LoeweTV.execAction(action, '', LoeweTV.onAction);
364
+ node.execAction(action, '', node.onActionTemplate);
340
365
  break;
341
-
342
366
  case "GetTimerList":
343
- LoeweTV.execAction(action, '', LoeweTV.onAction);
367
+ node.execAction(action, '', node.onActionTemplate);
344
368
  break;
345
-
346
369
  case "CreateIterator":
347
- LoeweTV.createIterator(LoeweTV.onAction);
370
+ node.createIterator(node.onAction);
348
371
  break;
349
-
350
372
  case "CloseIterator":
351
- LoeweTV.execAction(action, '', LoeweTV.onAction);
373
+ node.execAction(action, '', node.onAction);
352
374
  break;
353
375
  default:
354
376
  break;
355
377
  }
356
378
  });
357
379
 
358
- LoeweTV.updateNodeStatus = function() {
380
+ node.updateNodeStatus = function() {
359
381
  var statusFill ='';
360
- console.log('[' + node.name + '] updateNodeStatus');
361
-
362
- switch (LoeweTV.Status.Power) {
382
+ var power = node.data.CurrentStatus.Power;
383
+ node.debug('updateNodeStatus');
384
+ switch (power) {
363
385
  case "idle":
364
386
  statusFill = "blue";
387
+ node.log('TV ist im \"Leerlauf\"');
365
388
  break;
366
389
  case "standby":
367
390
  statusFill = "yellow";
391
+ node.log('TV ist im Standby');
368
392
  break;
369
393
  case "switch_on":
370
394
  case "tv":
371
395
  statusFill = "green";
396
+ node.log('TV ist Eingeschaltet');
372
397
  break;
373
398
  default:
374
399
  statusFill = "grey";
400
+ node.log('TV status unknown');
375
401
  break;
376
402
  }
377
- node.status({fill:statusFill,shape:"ring",text:"ClientId: " + LoeweTV.ClientId});
378
- var newmsg = { payload:LoeweTV.name, ClientId:LoeweTV.ClientId, Status:LoeweTV.Status.Power, topic:'Status' };
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' };
379
412
  node.send(newmsg);
380
413
  };
381
414
 
382
- LoeweTV.onEvent = function(event) {
415
+ node.onEvent = function(event) {
383
416
  var self = this;
384
- node.debug('[' + node.name + '] received Event:' + event);
417
+ node.log('received Event: ' + event);
418
+ node.log('TV Status: ' + node.data.CurrentStatus.Power);
385
419
 
386
420
  if (event === 'alive') {
387
421
  node.debug('[' + node.name + '] handle Event:' + event);
388
- // if (LoeweTV.ClientId === '') {
389
- if (LoeweTV.Status.Power === 'idle' || LoeweTV.Status.Power !== 'idle') {
390
- LoeweTV.RequestAccess(function() {
391
- console.log('[', node.name, '] Registriere ClientId: ', LoeweTV.ClientId);
392
- console.log('[', node.name, '] SDDP uuid: ', LoeweTV.uuid);
393
- // LoeweTV.subscribe(function(){
394
- LoeweTV.getSettings(function(){
395
- LoeweTV.activateFeaturePackage('72413U80', function(){
396
- LoeweTV.getDeviceData(function(){
397
- LoeweTV.createIterator(function(){
398
- LoeweTV.getVolume(function(){
399
- LoeweTV.getMute(function(){
400
- LoeweTV.getCurrentStatus(function(){
401
- LoeweTV.updateNodeStatus();
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();
402
441
  });
403
442
  });
404
443
  });
@@ -406,18 +445,17 @@ module.exports = function(RED) {
406
445
  });
407
446
  });
408
447
  });
409
-
410
- // });
448
+ }
411
449
  });
412
450
  }
413
451
  node.debug('[' + node.name + '] handle Event:' + event + 'ok');
414
452
  }
415
453
  else if (event === 'byebye') {
416
454
  node.debug('[' + node.name + '] handle Event:' + event);
417
- if (LoeweTV.Status.Power === 'tv') {
418
- console.log('[', node.name, '] schaltet ab');
419
- LoeweTV.getCurrentStatus(LoeweTV.updateNodeStatus);
420
- // LoeweTV.ClientId = '';
455
+ if (node.data.CurrentStatus.Power === 'tv') {
456
+ node.log('schaltet ab');
457
+ node.execAction('GetCurrentStatus', '', function() {});
458
+ node.ClientId = '';
421
459
  }
422
460
  node.debug('[' + node.name + '] handle Event:' + event + 'ok');
423
461
  }
@@ -426,8 +464,826 @@ module.exports = function(RED) {
426
464
  }
427
465
  node.debug('[' + node.name + '] received Event OK');
428
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
+ };
429
1100
 
430
- LoeweTV.onEvent('alive');
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');
431
1287
  }
432
1288
  RED.nodes.registerType("LOEWE-TV", LoeweTvNode);
433
1289
  };