trainman419 / python-cec

Other
171 stars 42 forks source link

Samsung source select: cec-client works, but python-cec doesn't #39

Closed jdtsmith closed 4 years ago

jdtsmith commented 4 years ago

I can change the source on my RPI2 connected SAMSUNG TV like:

echo "tx 4F:82:30:00" | cec-client -s

But running what I think is equivalent code using python-cec does nothing:

import cec
destination = cec.CECDEVICE_BROADCAST
opcode = cec.CEC_OPCODE_ACTIVE_SOURCE
cec.init()
cec.transmit(destination, opcode, bytes([0x30,0x00])) # Returns True, but does nothing

Both are compiled against libcec4.0.2. Using set_active_source does change to the RPI2 HDMI input if it's not active, so I know they're communicating. Is there something I'm missing? Thanks for this package.

nforro commented 4 years ago

Set up a log handler to see what is actually being sent, you can compare the logs with output from cec-client, it should be fairly similar.

Your command has initiator set to 0x04, which is cec.CECDEVICE_PLAYBACKDEVICE1, while python-cec configures libcec to act as a recording device, so the initiator is usually cec.CECDEVICE_RECORDINGDEVICE1. I don't know why it should matter, but maybe your TV is really that picky. Try sending tx 1F:82:30:00 using cec-client to see if it really matters.

jdtsmith commented 4 years ago

cec-client works fine with 1F. I added an event log that prints the argument ala:

def evlog(ev): print(ev)
cec.add_callback(evlog, cec.EVENT_LOG)

but see no events on transmit. Maybe I'm not doing that right.

nforro commented 4 years ago

There are multiple arguments passed to the handler, use def evlog(*args): print(args). You should see something like (1, 8, 184335, '<< 1f:82:30:00').

jdtsmith commented 4 years ago

OK thanks, here's what's being sent: (1, 8, 69375, '<< 1f:82:5b:31:36:2c:20:30:5d'). Looks like bytes is returning a string that is being sent...

nforro commented 4 years ago

Ok, that certainly explains why it doesn't work. Is this with python 2? Could you share your exact environment? OS, python version etc.?

nforro commented 4 years ago

Ok, I think I see the issue. In python 2, bytes([0x30,0x00]) returns '[48, 0]'. Try passing b'\x30\x00' instead.

nforro commented 4 years ago

I've updated the README, bytes literal works as expected in both python 2 and python 3.

jdtsmith commented 4 years ago

Switching to, e.g., b'\x10\x00' worked for me. Thanks!