homebridge-sharp-aquos-tv 3.0.2 → 3.0.3
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/index.js +67 -96
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -23,10 +23,7 @@ var cachedAccessories = [];
|
|
|
23
23
|
var didFinishLaunching = false;
|
|
24
24
|
|
|
25
25
|
/* Variables for telnet polling system */
|
|
26
|
-
var g_powerState =
|
|
27
|
-
var g_volLevel = [0,0,0];
|
|
28
|
-
var g_muteState = [false,false,false];
|
|
29
|
-
var g_inputID = [null,null,null];
|
|
26
|
+
var g_powerState = false;
|
|
30
27
|
|
|
31
28
|
module.exports = (homebridge) => {
|
|
32
29
|
Service = homebridge.hap.Service;
|
|
@@ -43,6 +40,7 @@ exports.logDebug = function(string) {
|
|
|
43
40
|
else
|
|
44
41
|
g_log.warn(string);
|
|
45
42
|
}
|
|
43
|
+
|
|
46
44
|
function logDebug(string) {
|
|
47
45
|
if (!debugToInfo)
|
|
48
46
|
g_log.debug(string);
|
|
@@ -50,6 +48,7 @@ function logDebug(string) {
|
|
|
50
48
|
g_log.warn(string);
|
|
51
49
|
}
|
|
52
50
|
|
|
51
|
+
|
|
53
52
|
class sharpClient {
|
|
54
53
|
constructor(log, config, api) {
|
|
55
54
|
g_log = log;
|
|
@@ -151,11 +150,8 @@ class tv {
|
|
|
151
150
|
this.disabletv = false;
|
|
152
151
|
this.pollingTimeout = false;
|
|
153
152
|
|
|
154
|
-
this.poweredOn =
|
|
155
|
-
this.currentInputID =
|
|
156
|
-
this.volDisp = [null,null,null];
|
|
157
|
-
this.volumeLevel = [30,30,30];
|
|
158
|
-
this.muteState = [false,false,false];
|
|
153
|
+
this.poweredOn = false;
|
|
154
|
+
this.currentInputID = null;
|
|
159
155
|
|
|
160
156
|
this.startConfiguration();
|
|
161
157
|
//start polling
|
|
@@ -206,43 +202,39 @@ class tv {
|
|
|
206
202
|
* This will start a polling loop that goes on forever and updates
|
|
207
203
|
* the on characteristic periodically.
|
|
208
204
|
*/
|
|
209
|
-
pollForUpdates(
|
|
210
|
-
// if (traceOn)
|
|
211
|
-
// logDebug('DEBUG: pollForUpdates zone: ' + zone + ': ' + this.ip);
|
|
205
|
+
pollForUpdates() {
|
|
212
206
|
|
|
213
|
-
/* Make sure
|
|
207
|
+
/* Make sure no poll is happening just after switch in input/power */
|
|
214
208
|
if (this.pollingTimeout) {
|
|
215
209
|
this.pollingTimeout = false;
|
|
216
210
|
return;
|
|
217
211
|
}
|
|
218
212
|
|
|
219
|
-
|
|
220
|
-
this.send('POWR? ');
|
|
221
|
-
|
|
222
|
-
this.send('RSPW2 '); //ensure TV can be turned on from IP control
|
|
223
|
-
|
|
213
|
+
// send all poll commands at once, as responses will be batched
|
|
214
|
+
this.send(['RSPW2 ','POWR? ','IAVD? ']); //ensure TV can be turned on from IP control, query power, query input
|
|
215
|
+
// response will be OK\rpowerstate\rinputID
|
|
224
216
|
}
|
|
225
217
|
|
|
226
218
|
|
|
227
219
|
/*
|
|
228
220
|
* Used to update the state of all. Disable polling for one poll.
|
|
229
221
|
*/
|
|
230
|
-
updateStates(
|
|
222
|
+
updateStates(stateInfo, curName) {
|
|
231
223
|
if (curName)
|
|
232
|
-
|
|
224
|
+
this.pollingTimeout = true;
|
|
233
225
|
|
|
234
226
|
if (traceOn)
|
|
235
227
|
logDebug(stateInfo);
|
|
236
228
|
|
|
237
229
|
if (stateInfo.power === true || stateInfo.power === false)
|
|
238
|
-
|
|
230
|
+
this.poweredOn = stateInfo.power;
|
|
239
231
|
|
|
240
232
|
if (stateInfo.inputID)
|
|
241
|
-
|
|
233
|
+
this.currentInputID = stateInfo.inputID;
|
|
242
234
|
|
|
243
|
-
for (let i in
|
|
244
|
-
if (
|
|
245
|
-
|
|
235
|
+
for (let i in this.tvAccessories) {
|
|
236
|
+
if (this.tvAccessories[i].getName() != curName) {
|
|
237
|
+
this.tvAccessories[i].settvState(stateInfo);
|
|
246
238
|
}
|
|
247
239
|
}
|
|
248
240
|
}
|
|
@@ -268,10 +260,12 @@ class tv {
|
|
|
268
260
|
}
|
|
269
261
|
|
|
270
262
|
send(cmd) {
|
|
271
|
-
if
|
|
272
|
-
this.connect();
|
|
273
|
-
|
|
274
|
-
|
|
263
|
+
// connect if we are not connected
|
|
264
|
+
if (this.telnet == null) this.connect();
|
|
265
|
+
// send command and await response if one is expected
|
|
266
|
+
logDebug('sendng ' + cmd);
|
|
267
|
+
this.telnet.send(cmd.join('\r')).then(
|
|
268
|
+
res => { this.responseHandler(res.slice(0, -1)) }).catch(
|
|
275
269
|
error => {
|
|
276
270
|
logDebug(error);
|
|
277
271
|
this.telnet=null;
|
|
@@ -279,28 +273,23 @@ class tv {
|
|
|
279
273
|
);
|
|
280
274
|
}
|
|
281
275
|
|
|
282
|
-
responseHandler(
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
if (!this.pollingTimeout)
|
|
300
|
-
this.updateStates(this, stateInfo, null);
|
|
301
|
-
this.telnet.end().then( () => { this.telnet = null; } )
|
|
302
|
-
|
|
303
|
-
break;
|
|
276
|
+
responseHandler(res) {
|
|
277
|
+
res=res.split('\r')
|
|
278
|
+
logDebug('response ' + res);
|
|
279
|
+
if (res.length == 3) { //response to poll will be ['OK',power,input]
|
|
280
|
+
// so get power and input now
|
|
281
|
+
if (res[1] === '1')
|
|
282
|
+
g_powerState = true;
|
|
283
|
+
else if (res[1] === '0')
|
|
284
|
+
g_powerState = false;
|
|
285
|
+
let stateInfo = {
|
|
286
|
+
power: g_powerState,
|
|
287
|
+
inputID: res[2],
|
|
288
|
+
}
|
|
289
|
+
logDebug(stateInfo);
|
|
290
|
+
if (!this.pollingTimeout) this.updateStates(stateInfo, null);
|
|
291
|
+
// if connection closed, dispose of client
|
|
292
|
+
this.telnet.end().then( () => { this.telnet = null; } )
|
|
304
293
|
}
|
|
305
294
|
}
|
|
306
295
|
}
|
|
@@ -319,10 +308,7 @@ class tvClient {
|
|
|
319
308
|
this.name = device.name || 'Sharp TV';
|
|
320
309
|
this.ip = device.ip;
|
|
321
310
|
this.inputs = device.inputs;
|
|
322
|
-
this.zone = device.zone || 1;
|
|
323
|
-
this.zone = 1;
|
|
324
311
|
|
|
325
|
-
this.iterator = this.zone - 1;
|
|
326
312
|
this.defaultInputID = device.defaultInputID;
|
|
327
313
|
|
|
328
314
|
/* setup variables */
|
|
@@ -342,8 +328,8 @@ class tvClient {
|
|
|
342
328
|
setupTvService() {
|
|
343
329
|
logDebug('setupTvService: ' + this.name);
|
|
344
330
|
|
|
345
|
-
this.
|
|
346
|
-
this.
|
|
331
|
+
this.tvAccessory = new Accessory(this.name, UUIDGen.generate(this.ip+this.name+"tvService"));
|
|
332
|
+
this.tvAccessory.category = this.api.hap.Categories.TELEVISION;
|
|
347
333
|
|
|
348
334
|
this.tvService = new Service.Television(this.name, 'tvService');
|
|
349
335
|
this.tvService
|
|
@@ -360,7 +346,7 @@ class tvClient {
|
|
|
360
346
|
this.setAppSwitchState(true, callback, this.inputIDs[inputIdentifier]);
|
|
361
347
|
})
|
|
362
348
|
.on('get', this.getAppSwitchState.bind(this));
|
|
363
|
-
this.
|
|
349
|
+
this.tvAccessory
|
|
364
350
|
.getService(Service.AccessoryInformation)
|
|
365
351
|
.setCharacteristic(Characteristic.Manufacturer, this.manufacturer)
|
|
366
352
|
.setCharacteristic(Characteristic.Model, this.modelName)
|
|
@@ -370,13 +356,13 @@ class tvClient {
|
|
|
370
356
|
.getCharacteristic(Characteristic.RemoteKey)
|
|
371
357
|
.on('set', this.remoteKeyPress.bind(this));
|
|
372
358
|
|
|
373
|
-
this.
|
|
359
|
+
this.tvAccessory.addService(this.tvService);
|
|
374
360
|
|
|
375
361
|
this.setupTvSpeakerService();
|
|
376
362
|
this.setupInputSourcesService();
|
|
377
363
|
|
|
378
364
|
logDebug('PublishExternalAccessories: '+ this.name);
|
|
379
|
-
this.api.publishExternalAccessories(pluginName, [this.
|
|
365
|
+
this.api.publishExternalAccessories(pluginName, [this.tvAccessory]);
|
|
380
366
|
}
|
|
381
367
|
|
|
382
368
|
setupTvSpeakerService() {
|
|
@@ -393,7 +379,7 @@ class tvClient {
|
|
|
393
379
|
this.tvSpeakerService
|
|
394
380
|
.getCharacteristic(Characteristic.Mute)
|
|
395
381
|
.on('set', this.setMute.bind(this));
|
|
396
|
-
this.
|
|
382
|
+
this.tvAccessory.addService(this.tvSpeakerService);
|
|
397
383
|
this.tvService.addLinkedService(this.tvSpeakerService);
|
|
398
384
|
}
|
|
399
385
|
|
|
@@ -438,7 +424,7 @@ class tvClient {
|
|
|
438
424
|
.setCharacteristic(Characteristic.Identifier, i)
|
|
439
425
|
.setCharacteristic(Characteristic.ConfiguredName, inputName)
|
|
440
426
|
.setCharacteristic(Characteristic.IsConfigured, Characteristic.IsConfigured.CONFIGURED)
|
|
441
|
-
|
|
427
|
+
//setCharacteristic(Characteristic.InputSourceType, Characteristic.InputSourceType.APPLICATION)
|
|
442
428
|
.setCharacteristic(Characteristic.CurrentVisibilityState,
|
|
443
429
|
Characteristic.CurrentVisibilityState.SHOWN);
|
|
444
430
|
|
|
@@ -449,7 +435,7 @@ class tvClient {
|
|
|
449
435
|
callback()
|
|
450
436
|
});
|
|
451
437
|
|
|
452
|
-
this.
|
|
438
|
+
this.tvAccessory.addService(tempInput);
|
|
453
439
|
if (!tempInput.linked)
|
|
454
440
|
this.tvService.addLinkedService(tempInput);
|
|
455
441
|
this.inputIDs.push(inputID);
|
|
@@ -480,14 +466,11 @@ class tvClient {
|
|
|
480
466
|
}
|
|
481
467
|
|
|
482
468
|
settvState(stateInfo) {
|
|
483
|
-
if (this.zone != stateInfo.zone)
|
|
484
|
-
return;
|
|
485
|
-
|
|
486
469
|
if (stateInfo.power === true || stateInfo.power === false)
|
|
487
|
-
this.updatetvState(this.tv.poweredOn
|
|
470
|
+
this.updatetvState(this.tv.poweredOn);
|
|
488
471
|
|
|
489
472
|
if (stateInfo.inputID) {
|
|
490
|
-
if (this.tv.poweredOn
|
|
473
|
+
if (this.tv.poweredOn) {
|
|
491
474
|
let inputName = stateInfo.inputID;
|
|
492
475
|
for (let i = 0; i < this.inputIDs.length; i++) {
|
|
493
476
|
if (inputName === this.inputIDs[i]) {
|
|
@@ -513,7 +496,7 @@ class tvClient {
|
|
|
513
496
|
if (traceOn)
|
|
514
497
|
logDebug('DEBUG: getPowerState: '+ this.name);
|
|
515
498
|
|
|
516
|
-
callback(null, this.tv.poweredOn
|
|
499
|
+
callback(null, this.tv.poweredOn ? 1 : 0);
|
|
517
500
|
}
|
|
518
501
|
|
|
519
502
|
setPowerState(state, callback) {
|
|
@@ -525,12 +508,10 @@ class tvClient {
|
|
|
525
508
|
else if (state === 1)
|
|
526
509
|
state = true;
|
|
527
510
|
var stateString;
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
this.tv.send(stateString);
|
|
511
|
+
stateString = 'POWR' + (state ? '1 ' : '0 ');
|
|
512
|
+
this.tv.send([stateString]);
|
|
531
513
|
/* Update possible other switches and accessories too */
|
|
532
514
|
let stateInfo = {
|
|
533
|
-
zone: this.zone,
|
|
534
515
|
power: state,
|
|
535
516
|
inputID: null,
|
|
536
517
|
masterVol: null,
|
|
@@ -541,13 +522,12 @@ class tvClient {
|
|
|
541
522
|
callback();
|
|
542
523
|
}
|
|
543
524
|
|
|
544
|
-
|
|
545
525
|
getAppSwitchState(callback) {
|
|
546
526
|
if (traceOn)
|
|
547
527
|
logDebug('DEBUG: getAppSwitchState: ' + this.name);
|
|
548
528
|
|
|
549
|
-
if (this.tv.poweredOn
|
|
550
|
-
let inputName = this.tv.currentInputID
|
|
529
|
+
if (this.tv.poweredOn) {
|
|
530
|
+
let inputName = this.tv.currentInputID;
|
|
551
531
|
for (let i = 0; i < this.inputIDs.length; i++) {
|
|
552
532
|
if (inputName === this.inputIDs[i]) {
|
|
553
533
|
this.tvService
|
|
@@ -563,29 +543,22 @@ class tvClient {
|
|
|
563
543
|
|
|
564
544
|
setAppSwitchState(state, callback, inputName) {
|
|
565
545
|
if (traceOn)
|
|
566
|
-
logDebug('DEBUG: setAppSwitchState
|
|
546
|
+
logDebug('DEBUG: setAppSwitchState: ' + this.name);
|
|
567
547
|
|
|
568
548
|
this.inputIDSet = true;
|
|
569
549
|
|
|
570
550
|
var inputString;
|
|
571
551
|
let inputNameN = inputName.replace('/', '%2F');
|
|
572
|
-
|
|
573
|
-
inputString = 'IAVD' + inputNameN+' ';
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
var that = this;
|
|
577
|
-
|
|
578
|
-
|
|
552
|
+
inputString = 'IAVD' + inputNameN+' ';
|
|
579
553
|
|
|
580
|
-
|
|
554
|
+
this.tv.send([inputString]);
|
|
581
555
|
|
|
582
556
|
/* Update possible other switches and accessories too */
|
|
583
557
|
let stateInfo = {
|
|
584
|
-
|
|
585
|
-
power: that.tv.poweredOn[that.iterator],
|
|
558
|
+
power: this.tv.poweredOn,
|
|
586
559
|
inputID: inputName
|
|
587
560
|
}
|
|
588
|
-
|
|
561
|
+
this.tv.updateStates(this.tv, stateInfo, this.name);
|
|
589
562
|
|
|
590
563
|
callback();
|
|
591
564
|
}
|
|
@@ -593,20 +566,18 @@ class tvClient {
|
|
|
593
566
|
setVolume(state, callback) {
|
|
594
567
|
logDebug('DEBUG: setVolume ' + state + ': ' + this.name);
|
|
595
568
|
|
|
596
|
-
|
|
597
|
-
if (this.tv.poweredOn[this.iterator]) {
|
|
569
|
+
if (this.tv.poweredOn) {
|
|
598
570
|
var stateString = state ? 'RCKY32 ' : 'RCKY33 '; // UP : DOWN
|
|
599
|
-
|
|
571
|
+
this.tv.send([stateString]);
|
|
600
572
|
}
|
|
601
573
|
callback();
|
|
602
574
|
}
|
|
603
575
|
|
|
604
|
-
setMute(callback) {
|
|
576
|
+
setMute(state, callback) {
|
|
605
577
|
logDebug('DEBUG: setMute: ' + this.name);
|
|
606
578
|
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
that.tv.send('RCKY31 ');
|
|
579
|
+
if (this.tv.poweredOn)
|
|
580
|
+
this.tv.send(['RCKY31 ']);
|
|
610
581
|
callback();
|
|
611
582
|
}
|
|
612
583
|
|
|
@@ -642,8 +613,8 @@ class tvClient {
|
|
|
642
613
|
break;
|
|
643
614
|
}
|
|
644
615
|
|
|
645
|
-
if (ctrlString != '' && this.tv.poweredOn
|
|
646
|
-
this.tv.send(ctrlString+' ');
|
|
616
|
+
if (ctrlString != '' && this.tv.poweredOn) {
|
|
617
|
+
this.tv.send([ctrlString+' ']);
|
|
647
618
|
}
|
|
648
619
|
callback();
|
|
649
620
|
}
|