1 from enigma import eTimer, eDVBSatelliteEquipmentControl, eDVBResourceManager, \
2 eDVBDiseqcCommand, eDVBFrontendParametersSatellite, eDVBFrontendParameters,\
5 from Screens.Screen import Screen
6 from Screens.ScanSetup import ScanSetup
7 from Screens.MessageBox import MessageBox
8 from Plugins.Plugin import PluginDescriptor
10 from Components.Label import Label
11 from Components.ConfigList import ConfigList
12 from Components.TunerInfo import TunerInfo
13 from Components.ActionMap import ActionMap
14 from Components.NimManager import nimmanager
15 from Components.MenuList import MenuList
16 from Components.config import ConfigSatlist, ConfigNothing, ConfigSelection, ConfigSubsection, KEY_LEFT, KEY_RIGHT, getConfigListEntry
18 from time import sleep
20 class PositionerSetup(Screen):
22 <screen position="100,100" size="560,400" title="Positioner setup..." >
23 <widget name="list" position="100,0" size="350,155" />
25 <widget name="red" position="0,155" size="140,80" backgroundColor="red" halign="center" valign="center" font="Regular;21" />
26 <widget name="green" position="140,155" size="140,80" backgroundColor="green" halign="center" valign="center" font="Regular;21" />
27 <widget name="yellow" position="280,155" size="140,80" backgroundColor="yellow" halign="center" valign="center" font="Regular;21" />
28 <widget name="blue" position="420,155" size="140,80" backgroundColor="blue" halign="center" valign="center" font="Regular;21" />
30 <widget name="snr" text="SNR:" position="0,245" size="60,22" font="Regular;21" />
31 <widget name="agc" text="AGC:" position="0,270" size="60,22" font="Regular;21" />
32 <widget name="ber" text="BER:" position="0,295" size="60,22" font="Regular;21" />
33 <widget name="lock" text="Lock:" position="0,320" size="60,22" font="Regular;21" />
34 <widget name="snr_percentage" position="220,245" size="60,22" font="Regular;21" />
35 <widget name="agc_percentage" position="220,270" size="60,22" font="Regular;21" />
36 <widget name="ber_value" position="220,295" size="60,22" font="Regular;21" />
37 <widget name="lock_state" position="60,320" size="150,22" font="Regular;21" />
38 <widget name="snr_bar" position="60,245" size="150,22" />
39 <widget name="agc_bar" position="60,270" size="150,22" />
40 <widget name="ber_bar" position="60,295" size="150,22" />
42 <widget name="frequency" text="Frequency:" position="300,245" size="120,22" font="Regular;21" />
43 <widget name="symbolrate" text="Symbolrate:" position="300,270" size="120,22" font="Regular;21" />
44 <widget name="fec" text="FEC:" position="300,295" size="120,22" font="Regular;21" />
45 <widget name="frequency_value" position="420,245" size="120,22" font="Regular;21" />
46 <widget name="symbolrate_value" position="420,270" size="120,22" font="Regular;21" />
47 <widget name="fec_value" position="420,295" size="120,22" font="Regular;21" />
49 def __init__(self, session, feid):
50 self.skin = PositionerSetup.skin
51 Screen.__init__(self, session)
55 if not self.openFrontend():
56 self.oldref = session.nav.getCurrentlyPlayingServiceReference()
57 session.nav.stopService() # try to disable foreground service
58 if not self.openFrontend():
59 if session.pipshown: # try to disable pip
60 session.pipshown = False
62 if not self.openFrontend():
63 self.frontend = None # in normal case this should not happen
65 self.frontendStatus = { }
67 self.diseqc = Diseqc(self.frontend)
68 self.tuner = Tuner(self.frontend)
69 self.tuner.tune((0,0,0,0,0,0))
74 self.stopOnLock = False
77 self["red"] = self.red
78 self.green = Label("")
79 self["green"] = self.green
80 self.yellow = Label("")
81 self["yellow"] = self.yellow
83 self["blue"] = self.blue
86 self["list"] = ConfigList(self.list)
92 self["lock"] = Label()
93 self["snr_percentage"] = TunerInfo(TunerInfo.SNR_PERCENTAGE, statusDict = self.frontendStatus)
94 self["agc_percentage"] = TunerInfo(TunerInfo.AGC_PERCENTAGE, statusDict = self.frontendStatus)
95 self["ber_value"] = TunerInfo(TunerInfo.BER_VALUE, statusDict = self.frontendStatus)
96 self["snr_bar"] = TunerInfo(TunerInfo.SNR_BAR, statusDict = self.frontendStatus)
97 self["agc_bar"] = TunerInfo(TunerInfo.AGC_BAR, statusDict = self.frontendStatus)
98 self["ber_bar"] = TunerInfo(TunerInfo.BER_BAR, statusDict = self.frontendStatus)
99 self["lock_state"] = TunerInfo(TunerInfo.LOCK_STATE, statusDict = self.frontendStatus)
101 self["frequency"] = Label()
102 self["symbolrate"] = Label()
103 self["fec"] = Label()
105 self["frequency_value"] = Label("")
106 self["symbolrate_value"] = Label("")
107 self["fec_value"] = Label("")
109 self["actions"] = ActionMap(["DirectionActions", "OkCancelActions", "ColorActions"],
112 "cancel": self.keyCancel,
118 "green": self.greenKey,
119 "yellow": self.yellowKey,
120 "blue": self.blueKey,
123 self.updateColors("tune")
125 self.statusTimer = eTimer()
126 self.statusTimer.timeout.get().append(self.updateStatus)
127 self.statusTimer.start(50, False)
129 def restartPrevService(self, yesno):
134 self.session.nav.playService(self.oldref)
139 self.session.openWithCallback(self.restartPrevService, MessageBox, _("Zap back to service before positioner setup?"), MessageBox.TYPE_YESNO)
141 self.restartPrevService(False)
143 def openFrontend(self):
144 res_mgr = eDVBResourceManager.getInstance()
146 self.raw_channel = res_mgr.allocateRawChannel(self.feid)
148 self.frontend = self.raw_channel.getFrontend()
152 print "getFrontend failed"
154 print "getRawChannel failed"
156 print "getResourceManager instance failed"
159 def createConfig(self):
160 self.positioner_tune = ConfigNothing()
161 self.positioner_move = ConfigNothing()
162 self.positioner_finemove = ConfigNothing()
163 self.positioner_limits = ConfigNothing()
164 self.positioner_goto0 = ConfigNothing()
166 for x in range(1,255):
167 storepos.append(str(x))
168 self.positioner_storage = ConfigSelection(choices = storepos)
170 def createSetup(self):
171 self.list.append((_("Tune"), self.positioner_tune, "tune"))
172 self.list.append((_("Positioner movement"), self.positioner_move, "move"))
173 self.list.append((_("Positioner fine movement"), self.positioner_finemove, "finemove"))
174 self.list.append((_("Set limits"), self.positioner_limits, "limits"))
175 self.list.append((_("Positioner storage"), self.positioner_storage, "storage"))
176 self.list.append((_("Goto 0"), self.positioner_goto0, "goto0"))
177 self["list"].l.setList(self.list)
182 def getCurrentConfigPath(self):
183 return self["list"].getCurrent()[2]
186 if not self.isMoving:
187 self["list"].instance.moveSelection(self["list"].instance.moveUp)
188 self.updateColors(self.getCurrentConfigPath())
191 if not self.isMoving:
192 self["list"].instance.moveSelection(self["list"].instance.moveDown)
193 self.updateColors(self.getCurrentConfigPath())
196 self["list"].handleKey(KEY_LEFT)
199 self["list"].handleKey(KEY_RIGHT)
201 def updateColors(self, entry):
203 self.red.setText(_("Tune"))
204 self.green.setText("")
205 self.yellow.setText("")
206 self.blue.setText("")
207 elif entry == "move":
209 self.red.setText(_("Stop"))
210 self.green.setText(_("Stop"))
211 self.yellow.setText(_("Stop"))
212 self.blue.setText(_("Stop"))
214 self.red.setText(_("Move west"))
215 self.green.setText(_("Search west"))
216 self.yellow.setText(_("Search east"))
217 self.blue.setText(_("Move east"))
218 elif entry == "finemove":
220 self.green.setText(_("Step west"))
221 self.yellow.setText(_("Step east"))
222 self.blue.setText("")
223 elif entry == "limits":
224 self.red.setText(_("Limits off"))
225 self.green.setText(_("Limit west"))
226 self.yellow.setText(_("Limit east"))
227 self.blue.setText(_("Limits on"))
228 elif entry == "storage":
230 self.green.setText(_("Store position"))
231 self.yellow.setText(_("Goto position"))
232 self.blue.setText("")
233 elif entry == "goto0":
234 self.red.setText(_("Goto 0"))
235 self.green.setText("")
236 self.yellow.setText("")
237 self.blue.setText("")
240 self.green.setText("")
241 self.yellow.setText("")
242 self.blue.setText("")
245 entry = self.getCurrentConfigPath()
248 self.diseqccommand("stop")
249 self.isMoving = False
250 self.stopOnLock = False
252 self.diseqccommand("moveWest", 0)
254 self.updateColors("move")
255 elif entry == "limits":
256 self.diseqccommand("limitOff")
257 elif entry == "tune":
258 self.session.openWithCallback(self.tune, TunerScreen, self.feid)
259 elif entry == "goto0":
260 print "move to position 0"
261 self.diseqccommand("moveTo", 0)
264 entry = self.getCurrentConfigPath()
267 self.diseqccommand("stop")
268 self.isMoving = False
269 self.stopOnLock = False
272 self.stopOnLock = True
273 self.diseqccommand("moveWest", 0)
274 self.updateColors("move")
275 elif entry == "finemove":
276 print "stepping west"
277 self.diseqccommand("moveWest", 0xFF) # one step
278 elif entry == "storage":
279 print "store at position", int(self.positioner_storage.value)
280 self.diseqccommand("store", int(self.positioner_storage.value))
281 elif entry == "limits":
282 self.diseqccommand("limitWest")
285 entry = self.getCurrentConfigPath()
288 self.diseqccommand("stop")
289 self.isMoving = False
290 self.stopOnLock = False
293 self.stopOnLock = True
294 self.diseqccommand("moveEast", 0)
295 self.updateColors("move")
296 elif entry == "finemove":
297 print "stepping east"
298 self.diseqccommand("moveEast", 0xFF) # one step
299 elif entry == "storage":
300 print "move to position", int(self.positioner_storage.value)
301 self.diseqccommand("moveTo", int(self.positioner_storage.value))
302 elif entry == "limits":
303 self.diseqccommand("limitEast")
306 entry = self.getCurrentConfigPath()
309 self.diseqccommand("stop")
310 self.isMoving = False
311 self.stopOnLock = False
313 self.diseqccommand("moveEast", 0)
315 self.updateColors("move")
317 elif entry == "limits":
318 self.diseqccommand("limitOn")
320 def diseqccommand(self, cmd, param = 0):
321 self.diseqc.command(cmd, param)
324 def updateStatus(self):
326 self.frontend.getFrontendStatus(self.frontendStatus)
327 self["snr_percentage"].update()
328 self["agc_percentage"].update()
329 self["ber_value"].update()
330 self["snr_bar"].update()
331 self["agc_bar"].update()
332 self["ber_bar"].update()
333 self["lock_state"].update()
334 transponderdata = self.tuner.getTransponderData()
335 self["frequency_value"].setText(str(transponderdata.get("frequency")))
336 self["symbolrate_value"].setText(str(transponderdata.get("symbol_rate")))
337 self["fec_value"].setText(str(transponderdata.get("fec_inner")))
338 if self.frontendStatus.get("tuner_locked", 0) == 1 and self.isMoving and self.stopOnLock:
339 self.diseqccommand("stop")
340 self.isMoving = False
341 self.stopOnLock = False
342 self.updateColors(self.getCurrentConfigPath())
344 def tune(self, transponder):
345 if transponder is not None:
346 self.tuner.tune(transponder)
349 def __init__(self, frontend):
350 self.frontend = frontend
352 def command(self, what, param = 0):
354 cmd = eDVBDiseqcCommand()
355 if what == "moveWest":
356 string = 'e03169' + ("%02x" % param)
357 elif what == "moveEast":
358 string = 'e03168' + ("%02x" % param)
359 elif what == "moveTo":
360 string = 'e0316b' + ("%02x" % param)
361 elif what == "store":
362 string = 'e0316a' + ("%02x" % param)
363 elif what == "limitOn":
365 elif what == "limitOff":
367 elif what == "limitEast":
369 elif what == "limitWest":
372 string = 'e03160' #positioner stop
374 print "diseqc command:",
376 cmd.setCommandString(string)
377 self.frontend.setTone(iDVBFrontend.toneOff)
378 sleep(0.015) # wait 15msec after disable tone
379 self.frontend.sendDiseqc(cmd)
380 if string == 'e03160': #positioner stop
382 self.frontend.sendDiseqc(cmd) # send 2nd time
385 def __init__(self, frontend):
386 self.frontend = frontend
388 def tune(self, transponder):
389 print "tuning to transponder with data", transponder
390 parm = eDVBFrontendParametersSatellite()
391 parm.frequency = transponder[0] * 1000
392 parm.symbol_rate = transponder[1] * 1000
393 parm.polarisation = transponder[2]
394 parm.fec = transponder[3]
395 parm.inversion = transponder[4]
396 parm.orbital_position = transponder[5]
397 parm.system = 0 # FIXMEE !! HARDCODED DVB-S (add support for DVB-S2)
398 parm.modulation = 1 # FIXMEE !! HARDCODED QPSK
399 feparm = eDVBFrontendParameters()
400 feparm.setDVBS(parm, True)
401 self.lastparm = feparm
403 self.frontend.tune(feparm)
407 self.frontend.tune(self.lastparm)
409 def getTransponderData(self):
412 self.frontend.getTransponderData(ret, True)
417 class TunerScreen(ScanSetup):
419 <screen position="90,100" size="520,400" title="Tune">
420 <widget name="config" position="20,10" size="460,350" scrollbarMode="showOnDemand" />
421 <widget name="introduction" position="20,360" size="350,30" font="Regular;23" />
424 def __init__(self, session, feid):
426 ScanSetup.__init__(self, session)
427 self["introduction"].setText("")
429 def createSetup(self):
430 self.typeOfTuningEntry = None
433 self.typeOfTuningEntry = getConfigListEntry(_('Tune'), tuning.type)
434 self.list.append(self.typeOfTuningEntry)
435 self.satEntry = getConfigListEntry(_('Satellite'), tuning.sat)
436 self.list.append(self.satEntry)
437 if tuning.type.value == "manual_transponder":
438 self.list.append(getConfigListEntry(_('Frequency'), self.scan_sat.frequency))
439 self.list.append(getConfigListEntry(_('Inversion'), self.scan_sat.inversion))
440 self.list.append(getConfigListEntry(_('Symbol Rate'), self.scan_sat.symbolrate))
441 self.list.append(getConfigListEntry(_("Polarity"), self.scan_sat.polarization))
442 self.list.append(getConfigListEntry(_("FEC"), self.scan_sat.fec))
443 elif tuning.type.value == "predefined_transponder":
444 self.list.append(getConfigListEntry(_("Transponder"), tuning.transponder))
445 self["config"].list = self.list
446 self["config"].l.setList(self.list)
449 if self["config"].getCurrent() == self.typeOfTuningEntry:
451 elif self["config"].getCurrent() == self.satEntry:
454 def createConfig(self, foo):
457 tuning = ConfigSubsection()
458 tuning.type = ConfigSelection(
459 default = "manual_transponder",
460 choices = { "manual_transponder" : _("Manual transponder"),
461 "predefined_transponder" : _("Predefined transponder") } )
462 tuning.sat = ConfigSatlist(list=nimmanager.getRotorSatListForNim(self.feid))
463 tuning.sat.addNotifier(self.tuningSatChanged)
464 self.updateTransponders()
465 TunerScreenConfigCreated = True
466 ScanSetup.createConfig(self, None)
468 def tuningSatChanged(self, *parm):
469 self.updateTransponders()
471 def updateTransponders(self):
472 if len(tuning.sat.choices):
473 transponderlist = nimmanager.getTransponders(int(tuning.sat.value))
476 for x in transponderlist:
501 tps.append(str(x[1]) + "," + str(x[2]) + "," + pol + "," + fec)
502 tuning.transponder = ConfigSelection(choices=tps)
505 returnvalue = (0, 0, 0, 0, 0, 0)
506 satpos = int(tuning.sat.value)
507 if tuning.type.value == "manual_transponder":
509 self.scan_sat.frequency.value,
510 self.scan_sat.symbolrate.value,
511 self.scan_sat.polarization.index,
512 self.scan_sat.fec.index,
513 self.scan_sat.inversion.index,
515 elif tuning.type.value == "predefined_transponder":
516 transponder = nimmanager.getTransponders(satpos)[tuning.transponder.index]
517 returnvalue = (int(transponder[1] / 1000), int(transponder[2] / 1000), transponder[3], transponder[4], 2, satpos)
518 self.close(returnvalue)
523 class NimSelection(Screen):
525 <screen position="140,165" size="400,100" title="select Slot">
526 <widget name="nimlist" position="20,10" size="360,75" />
529 def __init__(self, session):
530 Screen.__init__(self, session)
532 nimlist = nimmanager.getNimListOfType(nimmanager.nimType["DVB-S"])
535 n = nimmanager.nim_slots[x]
536 nimMenuList.append((n.friendly_full_name, x))
538 self["nimlist"] = MenuList(nimMenuList)
540 self["actions"] = ActionMap(["OkCancelActions"],
542 "ok": self.okbuttonClick ,
546 def okbuttonClick(self):
547 selection = self["nimlist"].getCurrent()
548 self.session.open(PositionerSetup, selection[1])
550 def PositionerMain(session, **kwargs):
551 nimList = nimmanager.getNimListOfType("DVB-S")
552 if len(nimList) == 0:
553 session.open(MessageBox, _("No positioner capable frontend found."), MessageBox.TYPE_ERROR)
555 if session.nav.RecordTimer.isRecording():
556 session.open(MessageBox, _("A recording is currently running. Please stop the recording before trying to configure the positioner."), MessageBox.TYPE_ERROR)
560 configured_rotor_sats = nimmanager.getRotorSatListForNim(x)
561 if len(configured_rotor_sats) != 0:
563 if len(usableNims) == 1:
564 session.open(PositionerSetup, usableNims[0])
565 elif len(usableNims) > 1:
566 session.open(NimSelection)
568 session.open(MessageBox, _("No tuner is configured for use with a diseqc positioner!"), MessageBox.TYPE_ERROR)
570 def PositionerSetupStart(menuid, **kwargs):
572 return [(_("Positioner setup"), PositionerMain, "positioner_setup", None)]
576 def Plugins(**kwargs):
577 if (nimmanager.hasNimType("DVB-S")):
578 return PluginDescriptor(name=_("Positioner setup"), description="Setup your positioner", where = PluginDescriptor.WHERE_MENU, fnc=PositionerSetupStart)