Open Samfox2 opened 5 years ago
This repo got renamed to homebridge-tv-cec
and yes it definitely is using the TV service :)
Just published new version on NPM (v0.5.0), let me know if it works great for you :) There might be bugs depends on your TV's implementation of CEC, please feedback and we can work upon them
Sounds great. I installed it but got the following error message:
[2019-03-26 20:24:18] [TV] Initializing TV-CEC accessory...
/usr/local/lib/node_modules/homebridge-tv-cec/index.js:23
this.inputs = Object.entries(this.config.devices).map(([port, name]) => {
^
TypeError: Object.entries is not a function
at new TV (/usr/local/lib/node_modules/homebridge-tv-cec/index.js:23:25)
at Server._loadAccessories (/usr/local/lib/node_modules/homebridge/lib/server.js:297:29)
at Server.run (/usr/local/lib/node_modules/homebridge/lib/server.js:87:38)
at module.exports (/usr/local/lib/node_modules/homebridge/lib/cli.js:45:10)
at Object.<anonymous> (/usr/local/lib/node_modules/homebridge/bin/homebridge:17:22)
at Module._compile (module.js:570:32)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)
This ist the accessory part of my config:
"accessories": [
{
"accessory": "PiTemperature",
"name": "Raspberry PI Temperature"
},
{
"accessory": "Hyperion",
"name": "Test-TV Backlight",
"ambilight_name": "Ambilight",
"description": "Control the Hyperion TV backlight server. https://github.com/tvdzwan/hyperion",
"host": "192.168.2.xxx",
"port": "xxxx"
},
{
"accessory": "TV-CEC",
"name": "TV",
"devices": {
"1": "Sat Receiver",
"2": "Raspberry Pi",
"3": "Apple TV"
}
}
]
Object.entries() requires at least node 7, which version are you running? https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries#Browser_compatibility
I was on node 6.x. Upgraded to 11 and the plugin starts now, however, TV does not react and after a few seconds I get the following error message:
[TV]Checking TV power status
events.js:173
throw er; // Unhandled 'error' event
^
Error [ERR_STREAM_DESTROYED]: Cannot call write after a stream was destroyed
at doWrite (_stream_writable.js:411:19)
at writeOrBuffer (_stream_writable.js:399:5)
at Socket.Writable.write (_stream_writable.js:299:11)
at TV.getPowerStatus (/usr/local/lib/node_modules/homebridge-tv-cec/index.js:89:20)
at Characteristic.Active.emit (events.js:197:13)
at Characteristic.Active.Characteristic.getValue (/usr/local/lib/node_modules/homebridge/node_modules/hap-nodejs/lib/Characteristic.js:164:10)
at Bridge.<anonymous> (/usr/local/lib/node_modules/homebridge/node_modules/hap-nodejs/lib/Accessory.js:762:20)
at Array.forEach (<anonymous>)
at Bridge.Accessory._handleGetCharacteristics (/usr/local/lib/node_modules/homebridge/node_modules/hap-nodejs/lib/Accessory.js:726:8)
at HAPServer.emit (events.js:197:13)
Emitted 'error' event at:
at errorOrDestroy (internal/streams/destroy.js:107:12)
at onwriteError (_stream_writable.js:430:5)
at onwrite (_stream_writable.js:461:5)
at doWrite (_stream_writable.js:411:11)
at writeOrBuffer (_stream_writable.js:399:5)
[... lines matching original stack trace ...]
at Bridge.<anonymous> (/usr/local/lib/node_modules/homebridge/node_modules/hap-nodejs/lib/Accessory.js:762:20)
Ok, I re-installed the cec client and did a restart and I can now switch the TV on - cool. However - the small rotating wheel at the home app tv icon indicates that the action is not finished. So nothing can be changed after the first signal. Could this mean that there is a callback missing?
Send me the exact model of your TV, and if you can do this so I can see your CEC streams:
cec-client -d 8
tx 10:04
then entercec-client -d 8
until TV turns onThen I can debug what's going on with your specific TV :)
I think it is a Toshiba 42X3000PG
This is what the console output looks like:
cec-client -s -d 1
requesting CEC bus information ...
CEC bus information
===================
device #0: TV
address: 0.0.0.0
active source: yes
vendor: Toshiba
osd string: TV
CEC version: 1.3a
power status: on
language: eng
cec-client -d 8
log level set to 8
No device type given. Using 'recording device'
CEC Parser created - libCEC version 4.0.2
no serial port given. trying autodetect:
path: Raspberry Pi
com port: RPI
opening a connection to the CEC adapter...
TRAFFIC: [ 37] << e0
TRAFFIC: [ 97] << e0:8c
TRAFFIC: [ 268] >> 0e:00:8c:01
TRAFFIC: [ 1158] << e0:8c
TRAFFIC: [ 1328] >> 0e:00:8c:01
TRAFFIC: [ 2218] << 11
TRAFFIC: [ 2489] << 11
TRAFFIC: [ 2760] << 1f:84:20:00:01
TRAFFIC: [ 2911] << 10:47:43:45:43:54:65:73:74:65:72
TRAFFIC: [ 3211] << 10:8f
TRAFFIC: [ 3392] >> 01:00:47:01
TRAFFIC: [ 3461] >> 01:90:01
waiting for input
tx 10:04
TRAFFIC: [ 90249] << 10:04
waiting for input
TRAFFIC: [ 93761] >> 0f:87:00:00:39
TRAFFIC: [ 93762] << 1f:87:00:15:82
TRAFFIC: [ 93912] << 1f:87:00:00:39
TRAFFIC: [ 95134] >> 01:a0:00:00:39:02
TRAFFIC: [ 95135] << 10:00:a0:03
TRAFFIC: [ 98389] >> 01:46
TRAFFIC: [ 98390] << 10:47:43:45:43:54:65:73:74:65:72
Can you wait a little longer after sending in tx 10:04
? For about 30-40 seconds until there are no additional outputs on console
(I'm not seeing any traffic regarding power status from the TV)
Sure, this is the complete traffic:
cec-client -d 8
log level set to 8
No device type given. Using 'recording device'
CEC Parser created - libCEC version 4.0.2
no serial port given. trying autodetect:
path: Raspberry Pi
com port: RPI
opening a connection to the CEC adapter...
TRAFFIC: [ 55] << e0
TRAFFIC: [ 116] << e0:8c
TRAFFIC: [ 288] >> 0e:00:8c:01
TRAFFIC: [ 1176] << e0:8c
TRAFFIC: [ 1348] >> 0e:00:8c:01
TRAFFIC: [ 2237] << 11
TRAFFIC: [ 2507] << 11
TRAFFIC: [ 2779] << 1f:84:20:00:01
TRAFFIC: [ 2929] << 10:47:43:45:43:54:65:73:74:65:72
TRAFFIC: [ 3230] << 10:8f
TRAFFIC: [ 3410] >> 01:00:47:01
TRAFFIC: [ 3479] >> 01:90:01
waiting for input
tx 10:04
TRAFFIC: [ 16413] << 10:04
waiting for input
TRAFFIC: [ 19921] >> 0f:87:00:00:39
TRAFFIC: [ 19921] << 1f:87:00:15:82
TRAFFIC: [ 20071] << 1f:87:00:00:39
TRAFFIC: [ 21254] >> 4f:a6:06:10:56:10
TRAFFIC: [ 21422] >> 01:a0:00:00:39:02
TRAFFIC: [ 21423] << 10:00:a0:03
TRAFFIC: [ 21813] >> 4f:84:30:00:04
TRAFFIC: [ 21850] >> 4f:85
TRAFFIC: [ 21943] >> 4f:90:00
TRAFFIC: [ 22341] >> 0f:84:00:00:00
TRAFFIC: [ 22342] << 1f:84:20:00:01
TRAFFIC: [ 22963] >> 0f:82:00:00
TRAFFIC: [ 24595] >> 0f:87:00:00:39
TRAFFIC: [ 24597] << 1f:87:00:00:39
TRAFFIC: [ 25046] >> 01:a0:00:00:39:02
TRAFFIC: [ 25048] << 10:00:a0:03
TRAFFIC: [ 25850] >> 01:46
TRAFFIC: [ 25851] << 10:47:43:45:43:54:65:73:74:65:72
This is the traffic with a higher debug level:
cec-client -d 31
log level set to 31
No device type given. Using 'recording device'
CEC Parser created - libCEC version 4.0.2
no serial port given. trying autodetect:
path: Raspberry Pi
com port: RPI
opening a connection to the CEC adapter...
DEBUG: [ 57] Broadcast (F): osd name set to 'Broadcast'
DEBUG: [ 58] Open - vc_cec initialised
DEBUG: [ 58] logical address changed to Free use (e)
NOTICE: [ 58] connection opened
DEBUG: [ 59] processor thread started
DEBUG: [ 59] << Broadcast (F) -> TV (0): POLL
DEBUG: [ 59] initiator 'Broadcast' is not supported by the CEC adapter. using 'Free use' instead
TRAFFIC: [ 59] << e0
DEBUG: [ 119] >> POLL sent
DEBUG: [ 120] TV (0): device status changed into 'present'
DEBUG: [ 120] << requesting vendor ID of 'TV' (0)
TRAFFIC: [ 120] << e0:8c
TRAFFIC: [ 292] >> 0e:00:8c:01
DEBUG: [ 1180] expected response not received (87: device vendor id)
TRAFFIC: [ 1180] << e0:8c
TRAFFIC: [ 1352] >> 0e:00:8c:01
DEBUG: [ 2241] expected response not received (87: device vendor id)
NOTICE: [ 2241] registering new CEC client - v4.0.2
DEBUG: [ 2241] detecting logical address for type 'recording device'
DEBUG: [ 2241] trying logical address 'Recorder 1'
DEBUG: [ 2242] << Recorder 1 (1) -> Recorder 1 (1): POLL
TRAFFIC: [ 2242] << 11
TRAFFIC: [ 2512] << 11
DEBUG: [ 2783] >> POLL not sent
DEBUG: [ 2783] using logical address 'Recorder 1'
DEBUG: [ 2783] Recorder 1 (1): device status changed into 'handled by libCEC'
DEBUG: [ 2783] Recorder 1 (1): power status changed from 'unknown' to 'on'
DEBUG: [ 2784] Recorder 1 (1): vendor = Pulse Eight (001582)
DEBUG: [ 2784] Recorder 1 (1): CEC version 1.4
DEBUG: [ 2784] AllocateLogicalAddresses - device '0', type 'recording device', LA '1'
DEBUG: [ 2784] logical address changed to Recorder 1 (1)
DEBUG: [ 2784] Recorder 1 (1): osd name set to 'CECTester'
DEBUG: [ 2784] Recorder 1 (1): menu language set to 'eng'
DEBUG: [ 2784] GetPhysicalAddress - physical address = 2000
DEBUG: [ 2785] AutodetectPhysicalAddress - autodetected physical address '2000'
DEBUG: [ 2785] Recorder 1 (1): physical address changed from ffff to 2000
DEBUG: [ 2785] << Recorder 1 (1) -> broadcast (F): physical address 2000
TRAFFIC: [ 2785] << 1f:84:20:00:01
NOTICE: [ 2935] CEC client registered: libCEC version = 4.0.2, client version = 4.0.2, firmware version = 1, logical address(es) = Recorder 1 (1) , physical address: 2.0.0.0, git revision: libcec-4.0.2+30-8adc786~dirty, compiled on Mon Aug 21 09:41:41 UTC 2017 by root@hostname: Name or service not known on Linux 4.4.0-92-generic (armv7l), features: P8_USB, DRM, P8_detect, randr, RPi
DEBUG: [ 2935] << Recorder 1 (1) -> TV (0): OSD name 'CECTester'
TRAFFIC: [ 2935] << 10:47:43:45:43:54:65:73:74:65:72
DEBUG: [ 3235] << requesting power status of 'TV' (0)
TRAFFIC: [ 3236] << 10:8f
TRAFFIC: [ 3416] >> 01:00:47:01
DEBUG: [ 3417] >> TV (0) -> Recorder 1 (1): feature abort ( 0)
TRAFFIC: [ 3483] >> 01:90:01
DEBUG: [ 3483] >> TV (0) -> Recorder 1 (1): report power status (90)
DEBUG: [ 3484] TV (0): power status changed from 'unknown' to 'standby'
DEBUG: [ 3484] expected response received (90: report power status)
waiting for input
tx 10:04
TRAFFIC: [ 37861] << 10:04
waiting for input
DEBUG: [ 41059] GetPhysicalAddress - physical address = 2000
DEBUG: [ 41060] physical address unchanged (2000)
TRAFFIC: [ 41370] >> 0f:87:00:00:39
DEBUG: [ 41371] >> TV (0) -> Broadcast (F): device vendor id (87)
DEBUG: [ 41371] TV (0): vendor = Toshiba (000039)
DEBUG: [ 41371] << Recorder 1 (1) -> Broadcast (F): vendor id Pulse Eight (1582)
TRAFFIC: [ 41372] << 1f:87:00:15:82
DEBUG: [ 41520] replacing the command handler for device 'TV' (0)
DEBUG: [ 41521] Recorder 1 (1): vendor = Toshiba (000039)
DEBUG: [ 41521] replacing the command handler for device 'Recorder 1' (1)
DEBUG: [ 41522] << Recorder 1 (1) -> Broadcast (F): vendor id Toshiba (39)
TRAFFIC: [ 41522] << 1f:87:00:00:39
WARNING: [ 41820] unhandled response received: opcode=87 initiator=1 destination=f response=0
TRAFFIC: [ 42761] >> 01:a0:00:00:39:02
DEBUG: [ 42762] >> TV (0) -> Recorder 1 (1): vendor command with id (A0)
DEBUG: [ 42762] sending abort with opcode a0 and reason 'invalid operand' to TV
DEBUG: [ 42762] << transmitting abort message
TRAFFIC: [ 42762] << 10:00:a0:03
NOTICE: [ 42882] Unmapped code detected. Please send an email to support@pulse-eight.com with the following details, and if you pressed a key, tell us which one you pressed, and we'll add support for this it.
CEC command: >> 01:a0:00:00:39:02
Vendor ID: Toshiba (000039)
WARNING: [ 43002] unhandled response received: opcode=0 initiator=1 destination=0 response=0
TRAFFIC: [ 46267] >> 01:46
DEBUG: [ 46267] >> TV (0) -> Recorder 1 (1): give osd name (46)
DEBUG: [ 46268] << Recorder 1 (1) -> TV (0): OSD name 'CECTester'
TRAFFIC: [ 46268] << 10:47:43:45:43:54:65:73:74:65:72
WARNING: [ 46868] unhandled response received: opcode=47 initiator=1 destination=0 response=0
Ok, I got it 2 work by deactivating the handler stuff in the setPowerStatus routine (not nice but ok for now):
setPowerStatus(value, callback) {
this.log.info(`Turning TV ${value ? 'on' : 'off'}`);
if (value === this.tvService.getCharacteristic(Characteristic.Active).value) {
callback();
this.log.info(`TV is already ${value ? 'on' : 'off'}`);
return;
}
// const handler = () => {
// handler.activated = true;
// callback();
// this.log.info(`TV is turned ${value ? 'on' : 'off'}`);
// };
// tvEvent.once(value ? 'POWER_ON' : 'POWER_OFF', handler);
// setTimeout(() => {
// tvEvent.removeListener(value ? 'POWER_ON' : 'POWER_OFF', handler);
// if (!handler.activated) {
// callback(`TV is not turning ${value ? 'on' : 'off'}`);
// this.log.info(`TV is not turning ${value ? 'on' : 'off'}`);
// }
// }, 30000);
// Send on or off signal
cecClient.stdin.write(value ? 'tx 10:04\n' : 'tx 10:36\n');
callback();
}
Just to mention it, thanks for your help and for the nice plugin :-)
The issue is that your TV never sent traffic on the CEC bus to declare that it had turned on I used my TV as a reference to implement, and it might be different especially in older TVs I'll probably add an option in the next release to disable these callbacks (The spinner while turning on/off)
If some TV‘s don‘t report the state back, maybe a delayed check would be possible like: user changes state -> wait 2 sec -> check state?
Volume control would also be nice (up/down) :-)
What happened with this issue? Is the project dead?
I also think volume control would be nice, but I am not sure if it is better to open a new issue or leave it, as the project has not been changed for more than a year.
I forked it and added basic volume control up/down here: https://github.com/Samfox2/homebridge-tv-cec
As IOS 12.2 is finally released, would it be possible to implement the new television service into this plugin instead of switch service? Volume and source selection could also be implemented over cec protocol.