Skip to content

Instantly share code, notes, and snippets.

@arpruss
Last active January 17, 2020 22:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arpruss/0496fb90480115e510856b9e162bac09 to your computer and use it in GitHub Desktop.
Save arpruss/0496fb90480115e510856b9e162bac09 to your computer and use it in GitHub Desktop.
cec to keyboard map
#!/usr/bin/python3
import cec
from time import sleep, time
from evdev import UInput, ecodes
import os
import sys
from threading import Thread
DEBUG = False
logfile = sys.stdout
ALLOW_MULTI_PRESS = False # not supported on my device
tvState = False
lastReboot = 0
rebootTime = 2*60*60
inReboot = False
def rebootWork():
global tvState,lastReboot
log("wait for reboot")
t = time() + 20
while time() < t:
if tvState:
return
sleep(1)
log("reboot")
os.system("adb kill-server")
sleep(2)
if tvState:
return
os.system("adb connect 192.168.1.210")
sleep(2)
if tvState:
return
if 0 == os.system("adb reboot"):
lastReboot = time()
os.system("adb disconnect")
def rebootThread():
global inReboot
if inReboot:
return
inReboot = True
rebootWork()
inReboot = False
def log(*args):
global logfile
if DEBUG:
if not logfile:
logfile = open("/tmp/cec-to-keyboard.log", "w+")
print(*args,file=logfile)
logfile.flush()
def running():
pids = (pid for pid in os.listdir('/proc') if pid.isdigit())
for pid in pids:
try:
cmdline = open(os.path.join('/proc', pid, 'cmdline'), 'rb').read().decode("utf-8","replace").split("\0")
name = os.path.basename(cmdline[0])
yield name
except GeneratorExit:
raise
except:
pass
def isRunning(names):
for name in running():
if name in names:
return name
return None
specialPrograms = set(("numptyphysics", "retroarch"))
emulationstation = ("emulationstation",)
keys_kodi = { 3:ecodes.KEY_LEFT, 4:ecodes.KEY_RIGHT, 1:ecodes.KEY_UP, 2:ecodes.KEY_DOWN,
13:ecodes.KEY_ESC, 0:ecodes.KEY_ENTER, 11:ecodes.KEY_COMPOSE, 72:ecodes.KEY_REWIND,
73:ecodes.KEY_FASTFORWARD, 70:ecodes.KEY_PLAY }
keys_np = { 3:ecodes.KEY_LEFT, 4:ecodes.KEY_RIGHT, 1:ecodes.KEY_UP, 2:ecodes.KEY_DOWN,
13:ecodes.KEY_ESC, 0:ecodes.KEY_ENTER, 11:ecodes.KEY_E, 72:ecodes.KEY_R,
73:ecodes.KEY_FASTFORWARD, 70:ecodes.KEY_SPACE }
keys = { 3:ecodes.KEY_LEFT, 4:ecodes.KEY_RIGHT, 1:ecodes.KEY_UP, 2:ecodes.KEY_DOWN,
13:ecodes.KEY_ESC, 0:ecodes.KEY_ENTER, 11:ecodes.KEY_LEFTMETA, 72:ecodes.KEY_REWIND,
73:ecodes.KEY_FASTFORWARD, 70:ecodes.KEY_PLAY }
keys_ra = { 3:ecodes.KEY_Z, 4:ecodes.KEY_RIGHT, 1:ecodes.KEY_UP, 2:ecodes.KEY_DOWN,
13:ecodes.KEY_ESC, 0:ecodes.KEY_X, 11:ecodes.KEY_LEFTMETA, 72:ecodes.KEY_H,
73:ecodes.KEY_FASTFORWARD, 70:ecodes.KEY_PLAY }
keys_es = { 13:((ecodes.KEY_LEFTALT,1),(ecodes.KEY_F4,1),(ecodes.KEY_F4,0),(ecodes.KEY_RIGHTALT,0)) }
mustRelease = {}
ui = UInput()
def keyPress(key, duration):
global mustRelease
press = duration == 0
if not press:
if ALLOW_MULTI_PRESS:
if key in mustRelease:
ui.write(ecodes.EV_KEY, mustRelease[key], 0)
ui.syn()
del mustRelease[key]
else:
for k in mustRelease:
ui.write(ecodes.EV_KEY, mustRelease[k], 0)
ui.syn()
mustRelease = {}
return
#kodi = isRunning("kodi-rbpi_v7")
#ckeys = keys_kodi if kodi else keys
found = isRunning(specialPrograms)
if found == "numptyphysics":
ckeys = keys_np
elif found == "retroarch":
ckeys = keys_ra
elif key in keys_es and isRunning(emulationstation):
ckeys = keys_es
else:
ckeys = keys
if key in ckeys:
mapped = ckeys[key]
try:
mapped[0]
for k,s in mapped:
ui.write(ecodes.EV_KEY, k, s)
except:
log("output", mapped)
ui.write(ecodes.EV_KEY, mapped, 1)
mustRelease[key] = mapped
ui.syn()
else:
log("pressed",key,duration)
def cecLog(message):
global tvState
if message.startswith(">> TV (0)"):
if ": give device power status" in message:
log("tv on")
tvState = True
elif ": standby" in message:
log("tv off")
if tvState and lastReboot + rebootTime <= time():
tvState = False
Thread(target=rebootThread).start()
cecConfig = cec.libcec_configuration()
cecConfig.strDeviceName = "pyLibCec"
cecConfig.bActivateSource = 0
cecConfig.deviceTypes.Add(cec.CEC_DEVICE_TYPE_RECORDING_DEVICE)
cecConfig.clientVersion = cec.LIBCEC_VERSION_CURRENT
cecConfig.SetLogCallback(lambda level, time, message: cecLog(message))
cecConfig.SetCommandCallback(lambda cmd: log("cmd",cmd))
cecConfig.SetKeyPressCallback(keyPress)
lib = cec.ICECAdapter.Create(cecConfig)
adapters = lib.DetectAdapters()
if not adapters:
log("No adapter: exiting")
sleep(1)
raise Exception("No CEC adapters found")
lib.Open(adapters[0].strComName)
log("Opening", adapters[0].strComName)
#lib = pyCecClient.pyCecClient()
#lib.SetKeyPressCallback(keyPress)
#lib.SetLogCallback(lambda level, time, message: log("log",level,time,message))
#lib.SetCommandCallback(lambda cmd: log("cmd",cmd))
#lib.InitLibCec()
while True:
sleep(10)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment