-
Notifications
You must be signed in to change notification settings - Fork 0
/
HdmiCec.py
301 lines (284 loc) · 12.6 KB
/
HdmiCec.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
# -*- coding: utf-8 -*-
# maintainer: <info@vuplus-support.org>
#This plugin is free software, you are allowed to
#modify it (if you keep the license),
#but you are not allowed to distribute/publish
#it without source code (this version and your modifications).
#This means you also have to distribute
#source code of your modifications.
import struct
from enigma import eHdmiCEC, eTimer
from Components.config import config, ConfigSelection, ConfigYesNo, ConfigSubsection, ConfigText
from Tools.HardwareInfo import HardwareInfo
from Screens.Standby import inStandby
import Screens.Standby
from Tools import Notifications
from Tools.DreamboxHardware import getFPWasTimerWakeup
from Tools.Directories import fileExists
import time
from os import system
import inspect
def lineno():
"""Returns current line number in plugin.py"""
return "H%03d " % inspect.currentframe().f_back.f_lineno
class HdmiCec:
def __init__(self):
config.hdmicec = ConfigSubsection()
config.hdmicec.enabled = ConfigYesNo(default = False)
config.hdmicec.logenabledserial = ConfigYesNo(default = False)
config.hdmicec.logenabledfile = ConfigYesNo(default = False)
config.hdmicec.tvstandby = ConfigYesNo(default = False)
config.hdmicec.tvwakeup = ConfigYesNo(default = False)
config.hdmicec.boxstandby = ConfigYesNo(default = False)
config.hdmicec.enabletvrc = ConfigYesNo(default = True)
config.hdmicec.active_source_reply = ConfigYesNo(default = True)
config.hdmicec.avvolumecontrol = ConfigYesNo(default = False)
config.hdmicec.disabletimerwakeup = ConfigYesNo(default = True)
config.hdmicec.device_name = ConfigText(default = self.getDeviceName(), visible_width = 50, fixed_size = False)
config.hdmicec.standby_message = ConfigSelection(default = "standby,inactive",
choices = [
("standby,inactive", _("TV standby")),
("standby,avpwroff,inactive,", _("TV + A/V standby")),
("inactive", _("Source inactive")),
("nothing", _("Nothing"))])
config.hdmicec.deepstandby_message = ConfigSelection(default = "standby,inactive",
choices = [
("standby,inactive", _("TV standby")),
("standby,avdeeppwroff,inactive", _("TV + A/V standby")),
("inactive", _("Source inactive")),
("nothing", _("Nothing"))])
config.hdmicec.wakeupstandby_message = ConfigSelection(default = "wakeup,active,activevu",
choices = [
("wakeup,active,activevu", _("TV wakeup")),
("wakeup,active,activevu,avpwron", _("TV + A/V wakeup")),
("avpwron,wakeup,active,activevu", _("A/V + TV wakeup")),
("active", _("Source active")),
("nothing", _("Nothing"))])
config.hdmicec.wakeupdeepstandby_message = ConfigSelection(default = "wakeup,active,activevu",
choices = [
("wakeup,active,activevu", _("TV wakeup")),
("wakeup,active,activevu,avpwron", _("TV + A/V wakeup")),
("avpwron,wakeup,active,activevu", _("A/V + TV wakeup")),
("active", _("Source active")),
("nothing", _("Nothing"))])
config.hdmicec.vustandby_message = ConfigSelection(default = "vustandby",
choices = [
("vustandby", _("VU+ standby")),
("vudeepstandby", _("VU+ DeepStandby")),
("vunothing", _("Nothing"))])
config.hdmicec.vuwakeup_message = ConfigSelection(default = "vuwakeup",
choices = [
("vuwakeup", _("VU+ wakeup")),
("vunothing", _("Nothing"))])
config.hdmicec.tvinput = ConfigSelection(default = "1",
choices = [
("1", "HDMI 1"),
("2", "HDMI 2"),
("3", "HDMI 3"),
("4", "HDMI 4"),
("5", "HDMI 5"),
("6", "HDMI 6"),
("7", "HDMI 7")])
config.hdmicec.avinput = ConfigSelection(default ="0",
choices = [
("0", _("no A/V Receiver")),
("1", "HDMI 1"),
("2", "HDMI 2"),
("3", "HDMI 3"),
("4", "HDMI 4"),
("5", "HDMI 5"),
("6", "HDMI 6"),
("7", "HDMI 7")])
config.hdmicec.message_delay = ConfigSelection(default = "10",
choices = [
("1", "0.1 sec"),
("5", "0.5 sec"),
("10", "1 sec"),
("20", "2 sec"),
("30", "3 sec"),
("50", "5 sec")])
self.cecmessage_queue = []
self.delayTimer = eTimer()
self.delayTimer.callback.append(self.sendCECMessage)
self.delayTimer_intervall = int(config.hdmicec.message_delay.value) * 100
config.misc.standbyCounter.addNotifier(self.enterStandby, initial_call = False)
config.misc.DeepStandbyOn.addNotifier(self.enterDeepStandby, initial_call = False)
self.activateSourceTimer()
self.leaveDeepStandby()
def getDeviceName(self):
return "Vu+ " + HardwareInfo().get_friendly_name()
def sendMessages(self, messages, delay = True):
messagedelay = float(config.hdmicec.message_delay.value)/10.0
for message in messages.split(','):
cmd = None
logcmd = None
addressvaluebroadcast = int("0F",16)
addressvalue = int("0",16)
addressvalueav = int("5",16)
wakeupmessage = int("04",16)
standbymessage=int("36",16)
activesourcemessage=int("82",16)
inactivesourcemessage=int("9D",16)
sendkeymessage = int("44",16)
sendkeypwronmessage = int("6D",16)
sendkeypwroffmessage = int("6C",16)
activevumessage=int("85",16)
physaddressmessage = int('0x84',16)
devicetypmessage = int('0x01',16)
physaddress1 = int("0x" + str(config.hdmicec.tvinput.value) + "0",16)
physaddress2 = int("0x00",16)
setnamemessage = int('0x47',16)
if message == "wakeup":
cmd = struct.pack('B', wakeupmessage)
logcmd = lineno()+"** WakeUpMessage ** : %x -> %x" % (wakeupmessage, addressvalue)
elif message == "active":
addressvalue = addressvaluebroadcast
cmd = struct.pack('BBB', activesourcemessage,physaddress1,physaddress2)
logcmd = lineno()+"** ActiveSourceMessage ** : %x:%x:%x -> %x" % (activesourcemessage,physaddress1,physaddress2,addressvalue)
# self.delayed_Message_Timer = eTimer()
# self.delayed_Message_Timer.start(20000, True)
# self.delayed_Message_Timer.callback.append(self.delayedActiveSourceMessage)
elif message == "standby":
cmd = struct.pack('B', standbymessage)
logcmd = lineno()+"** StandByMessage ** : %x -> %x" % (standbymessage, addressvalue)
elif message == "inactive":
addressvalue = addressvaluebroadcast
cmd = struct.pack('BBB', inactivesourcemessage,physaddress1,physaddress2)
logcmd = lineno()+"** InActiveSourceMessage ** : %x:%x:%x -> %x" % (inactivesourcemessage,physaddress1,physaddress2,addressvalue)
elif message == "avpwron":
cmd = struct.pack('BB', sendkeymessage,sendkeypwronmessage)
addressvalue = addressvalueav
logcmd = lineno()+"** Power on A/V ** : %x:%x -> %x" % (sendkeymessage, sendkeypwronmessage, addressvalue)
elif message == "avdeeppwroff":
cmd = struct.pack('BB',sendkeymessage,sendkeypwroffmessage)
addressvalue = addressvalueav
logcmd = lineno()+"** Standby A/V (Deepstandby)** : %x:%x -> %x" % (sendkeymessage,sendkeypwroffmessage, addressvalue)
elif message == "avpwroff":
addressvalue = addressvalueav
cmd = struct.pack('BB',sendkeymessage,sendkeypwroffmessage)
logcmd = lineno()+"** Standby A/V ** : %x:%x -> %x" % (sendkeymessage,sendkeypwroffmessage, addressvalue)
elif message == "activevu":
addressvalue = addressvaluebroadcast
cmd = struct.pack('B', activevumessage)
logcmd = lineno()+"** Active VU Message ** : %x -> %x" % (activevumessage,addressvalue)
elif message == "physaddress":
addressvalue = addressvaluebroadcast
cmd = struct.pack('BBBB',physaddressmessage,physaddress1,physaddress2,devicetypmessage)
logcmd = lineno()+"** Report phys address %x:%x:%x:%x -> %x" % (physaddressmessage,physaddress1,physaddress2,devicetypmessage,addressvalue)
elif message == "setdevicename":
cecmessage = setnamemessage
name_len = len(config.hdmicec.device_name.value)
if name_len == 0:
cecmessagetwo ="VU+"
cmd = struct.pack('B4s',cecmessage,cecmessagetwo)
else:
cecmessagetwo = config.hdmicec.device_name.value
cmd = struct.pack('B'+str(name_len+1)+'s',cecmessage,cecmessagetwo)
logcmd = lineno()+"** Send device name %x:%s -> %x" % (cecmessage,cecmessagetwo,addressvalue)
if cmd and logcmd:
if self.log:
self.log.info( lineno() + "Queue :" + logcmd )
self.cecmessage_queue.append((cmd, addressvalue, logcmd))
if not delay:
self.sendCECMessage(delay = False)
else:
self.delayTimer.start(self.delayTimer_intervall, True)
def sendCECMessage(self, delay = True):
self.delayTimer.stop()
if len(self.cecmessage_queue):
cmd, addressvalue, logcmd = self.cecmessage_queue.pop(0)
eHdmiCEC.getInstance().sendMessage(addressvalue, len(cmd), str(cmd))
if config.hdmicec.logenabledserial.value:
vtilog("[HDMICEC] "+logcmd)
#if config.hdmicec.logenabledfile.value:
# filelog = "echo %s >> /tmp/hdmicec.log" % (logcmd)
# system(filelog)
if self.log:
self.log.info( lineno() + logcmd )
if len(self.cecmessage_queue):
if not delay:
messagedelay = float(config.hdmicec.message_delay.value)/10.0
time.sleep(messagedelay)
self.sendCECMessage(delay = False)
else:
self.delayTimer.start(self.delayTimer_intervall, True)
def delayedActiveSourceMessage(self):
messagedelay = float(config.hdmicec.message_delay.value)/10.0
addressvaluebroadcast = int("0F",16)
activesourcemessage=int("82",16)
activevumessage=int("85",16)
addressvalue = int("0",16)
physaddress1 = int("0x" + str(config.hdmicec.tvinput.value) + "0",16)
physaddress2 = int("0x00",16)
setnamemessage = int('0x47',16)
addressvalue = addressvaluebroadcast
physaddressmessage = int('0x84',16)
devicetypmessage = int('0x01',16)
from Screens.Standby import inStandby
if not inStandby:
cmd_active = struct.pack('BBB', activesourcemessage,physaddress1,physaddress2)
logcmd_active = lineno()+"** ActiveSourceMessage ** : %x:%x:%x -> %x" % (activesourcemessage,physaddress1,physaddress2,addressvalue)
self.cecmessage_queue.append((cmd_active, addressvalue, logcmd_active))
if self.log:
self.log.info( lineno() + "Queue :" + logcmd_active )
cmd_vu_is_active = struct.pack('B', activevumessage)
logcmd_vu_is_active = lineno()+"** Active VU Message ** : %x -> %x" % (activevumessage,addressvalue)
self.cecmessage_queue.append((cmd_vu_is_active, addressvalue, logcmd_vu_is_active))
if self.log:
self.log.info( lineno() + "Queue :" + logcmd_vu_is_active )
cmd = struct.pack('BBBB',physaddressmessage,physaddress1,physaddress2,devicetypmessage)
logcmd = lineno()+"** Report phys address %x:%x:%x:%x -> %x" % (physaddressmessage,physaddress1,physaddress2,devicetypmessage,addressvaluebroadcast)
self.cecmessage_queue.append((cmd, addressvaluebroadcast, logcmd))
if self.log:
self.log.info( lineno() + "Queue :" + logcmd )
name_len = len(config.hdmicec.device_name.value)
if name_len > 0:
cecmessagetwo = config.hdmicec.device_name.value
cmd = struct.pack('B'+str(name_len+1)+'s',setnamemessage,config.hdmicec.device_name.value)
logcmd = lineno()+"** Send device name %x:%s -> %x" % (setnamemessage,config.hdmicec.device_name.value,addressvalue)
self.cecmessage_queue.append((cmd, addressvalue, logcmd))
if self.log:
self.log.info( lineno() + "Queue :" + logcmd )
if not self.delayTimer.isActive():
self.delayTimer.start(self.delayTimer_intervall, True)
def leaveStandby(self):
if config.hdmicec.enabled.value:
self.activateSourceTimer()
msg = str(config.hdmicec.wakeupstandby_message.value)
if not msg.find('nothing') != -1:
msg += ",physaddress,setdevicename"
self.sendMessages(config.hdmicec.wakeupstandby_message.value)
def enterStandby(self, configElement):
if hasattr(self, "activeSourceTimer"):
self.activeSourceTimer.stop()
from Screens.Standby import inStandby
inStandby.onClose.append(self.leaveStandby)
if config.hdmicec.enabled.value:
self.sendMessages(config.hdmicec.standby_message.value)
if inStandby != None:
self.sendMessages("inactive")
def enterDeepStandby(self,configElement):
if config.hdmicec.enabled.value:
self.sendMessages(config.hdmicec.deepstandby_message.value, delay = False)
def leaveDeepStandby(self):
if config.hdmicec.enabled.value:
msg = str(config.hdmicec.wakeupdeepstandby_message.value)
if not msg.find('nothing') != -1:
msg += ",physaddress,setdevicename"
if not getFPWasTimerWakeup():
self.sendMessages(msg)
else:
if config.hdmicec.disabletimerwakeup.value:
vtilog("[HDMICEC] "+lineno()+"timer wakeup => do not power on TV / A/V receiver")
if self.log:
self.log.info(lineno()+"timer wakeup => do not power on TV / A/V receiver")
else:
self.sendMessages(msg)
def activateSourceTimer(self):
self.initial_active_source_call = True
self.activeSourceTimer = eTimer()
self.activeSourceTimer.callback.append(self.setActiveSourceCall)
if config.hdmicec.active_source_reply.value == False:
self.activeSourceTimer.start(60000, True)
def setActiveSourceCall(self):
self.initial_active_source_call = False