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.callback.append(self.updateStatus)
127 self.statusTimer.start(50, False)
128 self.onClose.append(self.__onClose)
131 self.session.nav.playService(self.oldref)
133 def restartPrevService(self, yesno):
144 self.session.openWithCallback(self.restartPrevService, MessageBox, _("Zap back to service before positioner setup?"), MessageBox.TYPE_YESNO)
146 self.restartPrevService(False)
148 def openFrontend(self):
149 res_mgr = eDVBResourceManager.getInstance()
151 self.raw_channel = res_mgr.allocateRawChannel(self.feid)
153 self.frontend = self.raw_channel.getFrontend()
157 print "getFrontend failed"
159 print "getRawChannel failed"
161 print "getResourceManager instance failed"
164 def createConfig(self):
165 self.positioner_tune = ConfigNothing()
166 self.positioner_move = ConfigNothing()
167 self.positioner_finemove = ConfigNothing()
168 self.positioner_limits = ConfigNothing()
169 self.positioner_goto0 = ConfigNothing()
171 for x in range(1,255):
172 storepos.append(str(x))
173 self.positioner_storage = ConfigSelection(choices = storepos)
175 def createSetup(self):
176 self.list.append((_("Tune"), self.positioner_tune, "tune"))
177 self.list.append((_("Positioner movement"), self.positioner_move, "move"))
178 self.list.append((_("Positioner fine movement"), self.positioner_finemove, "finemove"))
179 self.list.append((_("Set limits"), self.positioner_limits, "limits"))
180 self.list.append((_("Positioner storage"), self.positioner_storage, "storage"))
181 self.list.append((_("Goto 0"), self.positioner_goto0, "goto0"))
182 self["list"].l.setList(self.list)
187 def getCurrentConfigPath(self):
188 return self["list"].getCurrent()[2]
191 if not self.isMoving:
192 self["list"].instance.moveSelection(self["list"].instance.moveUp)
193 self.updateColors(self.getCurrentConfigPath())
196 if not self.isMoving:
197 self["list"].instance.moveSelection(self["list"].instance.moveDown)
198 self.updateColors(self.getCurrentConfigPath())
201 self["list"].handleKey(KEY_LEFT)
204 self["list"].handleKey(KEY_RIGHT)
206 def updateColors(self, entry):
208 self.red.setText(_("Tune"))
209 self.green.setText("")
210 self.yellow.setText("")
211 self.blue.setText("")
212 elif entry == "move":
214 self.red.setText(_("Stop"))
215 self.green.setText(_("Stop"))
216 self.yellow.setText(_("Stop"))
217 self.blue.setText(_("Stop"))
219 self.red.setText(_("Move west"))
220 self.green.setText(_("Search west"))
221 self.yellow.setText(_("Search east"))
222 self.blue.setText(_("Move east"))
223 elif entry == "finemove":
225 self.green.setText(_("Step west"))
226 self.yellow.setText(_("Step east"))
227 self.blue.setText("")
228 elif entry == "limits":
229 self.red.setText(_("Limits off"))
230 self.green.setText(_("Limit west"))
231 self.yellow.setText(_("Limit east"))
232 self.blue.setText(_("Limits on"))
233 elif entry == "storage":
235 self.green.setText(_("Store position"))
236 self.yellow.setText(_("Goto position"))
237 self.blue.setText("")
238 elif entry == "goto0":
239 self.red.setText(_("Goto 0"))
240 self.green.setText("")
241 self.yellow.setText("")
242 self.blue.setText("")
245 self.green.setText("")
246 self.yellow.setText("")
247 self.blue.setText("")
250 entry = self.getCurrentConfigPath()
253 self.diseqccommand("stop")
254 self.isMoving = False
255 self.stopOnLock = False
257 self.diseqccommand("moveWest", 0)
259 self.updateColors("move")
260 elif entry == "limits":
261 self.diseqccommand("limitOff")
262 elif entry == "tune":
263 self.session.openWithCallback(self.tune, TunerScreen, self.feid)
264 elif entry == "goto0":
265 print "move to position 0"
266 self.diseqccommand("moveTo", 0)
269 entry = self.getCurrentConfigPath()
272 self.diseqccommand("stop")
273 self.isMoving = False
274 self.stopOnLock = False
277 self.stopOnLock = True
278 self.diseqccommand("moveWest", 0)
279 self.updateColors("move")
280 elif entry == "finemove":
281 print "stepping west"
282 self.diseqccommand("moveWest", 0xFF) # one step
283 elif entry == "storage":
284 print "store at position", int(self.positioner_storage.value)
285 self.diseqccommand("store", int(self.positioner_storage.value))
286 elif entry == "limits":
287 self.diseqccommand("limitWest")
290 entry = self.getCurrentConfigPath()
293 self.diseqccommand("stop")
294 self.isMoving = False
295 self.stopOnLock = False
298 self.stopOnLock = True
299 self.diseqccommand("moveEast", 0)
300 self.updateColors("move")
301 elif entry == "finemove":
302 print "stepping east"
303 self.diseqccommand("moveEast", 0xFF) # one step
304 elif entry == "storage":
305 print "move to position", int(self.positioner_storage.value)
306 self.diseqccommand("moveTo", int(self.positioner_storage.value))
307 elif entry == "limits":
308 self.diseqccommand("limitEast")
311 entry = self.getCurrentConfigPath()
314 self.diseqccommand("stop")
315 self.isMoving = False
316 self.stopOnLock = False
318 self.diseqccommand("moveEast", 0)
320 self.updateColors("move")
322 elif entry == "limits":
323 self.diseqccommand("limitOn")
325 def diseqccommand(self, cmd, param = 0):
326 self.diseqc.command(cmd, param)
329 def updateStatus(self):
331 self.frontend.getFrontendStatus(self.frontendStatus)
332 self["snr_percentage"].update()
333 self["agc_percentage"].update()
334 self["ber_value"].update()
335 self["snr_bar"].update()
336 self["agc_bar"].update()
337 self["ber_bar"].update()
338 self["lock_state"].update()
339 transponderdata = self.tuner.getTransponderData()
340 self["frequency_value"].setText(str(transponderdata.get("frequency")))
341 self["symbolrate_value"].setText(str(transponderdata.get("symbol_rate")))
342 self["fec_value"].setText(str(transponderdata.get("fec_inner")))
343 if self.frontendStatus.get("tuner_locked", 0) == 1 and self.isMoving and self.stopOnLock:
344 self.diseqccommand("stop")
345 self.isMoving = False
346 self.stopOnLock = False
347 self.updateColors(self.getCurrentConfigPath())
349 def tune(self, transponder):
350 if transponder is not None:
351 self.tuner.tune(transponder)
354 def __init__(self, frontend):
355 self.frontend = frontend
357 def command(self, what, param = 0):
359 cmd = eDVBDiseqcCommand()
360 if what == "moveWest":
361 string = 'e03169' + ("%02x" % param)
362 elif what == "moveEast":
363 string = 'e03168' + ("%02x" % param)
364 elif what == "moveTo":
365 string = 'e0316b' + ("%02x" % param)
366 elif what == "store":
367 string = 'e0316a' + ("%02x" % param)
368 elif what == "limitOn":
370 elif what == "limitOff":
372 elif what == "limitEast":
374 elif what == "limitWest":
377 string = 'e03160' #positioner stop
379 print "diseqc command:",
381 cmd.setCommandString(string)
382 self.frontend.setTone(iDVBFrontend.toneOff)
383 sleep(0.015) # wait 15msec after disable tone
384 self.frontend.sendDiseqc(cmd)
385 if string == 'e03160': #positioner stop
387 self.frontend.sendDiseqc(cmd) # send 2nd time
390 def __init__(self, frontend):
391 self.frontend = frontend
393 def tune(self, transponder):
394 print "tuning to transponder with data", transponder
395 parm = eDVBFrontendParametersSatellite()
396 parm.frequency = transponder[0] * 1000
397 parm.symbol_rate = transponder[1] * 1000
398 parm.polarisation = transponder[2]
399 parm.fec = transponder[3]
400 parm.inversion = transponder[4]
401 parm.orbital_position = transponder[5]
402 parm.system = 0 # FIXMEE !! HARDCODED DVB-S (add support for DVB-S2)
403 parm.modulation = 1 # FIXMEE !! HARDCODED QPSK
404 feparm = eDVBFrontendParameters()
405 feparm.setDVBS(parm, True)
406 self.lastparm = feparm
408 self.frontend.tune(feparm)
412 self.frontend.tune(self.lastparm)
414 def getTransponderData(self):
417 self.frontend.getTransponderData(ret, True)
422 class TunerScreen(ScanSetup):
424 <screen position="90,100" size="520,400" title="Tune">
425 <widget name="config" position="20,10" size="460,350" scrollbarMode="showOnDemand" />
426 <widget name="introduction" position="20,360" size="350,30" font="Regular;23" />
429 def __init__(self, session, feid):
431 ScanSetup.__init__(self, session)
432 self["introduction"].setText("")
434 def createSetup(self):
435 self.typeOfTuningEntry = None
438 self.typeOfTuningEntry = getConfigListEntry(_('Tune'), tuning.type)
439 self.list.append(self.typeOfTuningEntry)
440 self.satEntry = getConfigListEntry(_('Satellite'), tuning.sat)
441 self.list.append(self.satEntry)
442 if tuning.type.value == "manual_transponder":
443 self.list.append(getConfigListEntry(_('Frequency'), self.scan_sat.frequency))
444 self.list.append(getConfigListEntry(_('Inversion'), self.scan_sat.inversion))
445 self.list.append(getConfigListEntry(_('Symbol Rate'), self.scan_sat.symbolrate))
446 self.list.append(getConfigListEntry(_("Polarity"), self.scan_sat.polarization))
447 self.list.append(getConfigListEntry(_("FEC"), self.scan_sat.fec))
448 elif tuning.type.value == "predefined_transponder":
449 self.list.append(getConfigListEntry(_("Transponder"), tuning.transponder))
450 self["config"].list = self.list
451 self["config"].l.setList(self.list)
454 if self["config"].getCurrent() == self.typeOfTuningEntry:
456 elif self["config"].getCurrent() == self.satEntry:
459 def createConfig(self, foo):
462 tuning = ConfigSubsection()
463 tuning.type = ConfigSelection(
464 default = "manual_transponder",
465 choices = { "manual_transponder" : _("Manual transponder"),
466 "predefined_transponder" : _("Predefined transponder") } )
467 tuning.sat = ConfigSatlist(list=nimmanager.getRotorSatListForNim(self.feid))
468 tuning.sat.addNotifier(self.tuningSatChanged)
469 self.updateTransponders()
470 TunerScreenConfigCreated = True
471 ScanSetup.createConfig(self, None)
473 def tuningSatChanged(self, *parm):
474 self.updateTransponders()
476 def updateTransponders(self):
477 if len(tuning.sat.choices):
478 transponderlist = nimmanager.getTransponders(int(tuning.sat.value))
481 for x in transponderlist:
516 tps.append(str(x[1]) + "," + str(x[2]) + "," + pol + "," + fec)
517 tuning.transponder = ConfigSelection(choices=tps)
520 returnvalue = (0, 0, 0, 0, 0, 0)
521 satpos = int(tuning.sat.value)
522 if tuning.type.value == "manual_transponder":
524 self.scan_sat.frequency.value,
525 self.scan_sat.symbolrate.value,
526 self.scan_sat.polarization.index,
527 self.scan_sat.fec.index,
528 self.scan_sat.inversion.index,
530 elif tuning.type.value == "predefined_transponder":
531 transponder = nimmanager.getTransponders(satpos)[tuning.transponder.index]
532 returnvalue = (int(transponder[1] / 1000), int(transponder[2] / 1000), transponder[3], transponder[4], 2, satpos)
533 self.close(returnvalue)
538 class NimSelection(Screen):
540 <screen position="140,165" size="400,100" title="select Slot">
541 <widget name="nimlist" position="20,10" size="360,75" />
544 def __init__(self, session):
545 Screen.__init__(self, session)
547 nimlist = nimmanager.getNimListOfType("DVB-S")
550 nimMenuList.append((nimmanager.nim_slots[x].friendly_full_description, x))
552 self["nimlist"] = MenuList(nimMenuList)
554 self["actions"] = ActionMap(["OkCancelActions"],
556 "ok": self.okbuttonClick ,
560 def okbuttonClick(self):
561 selection = self["nimlist"].getCurrent()
562 self.session.open(PositionerSetup, selection[1])
564 def PositionerMain(session, **kwargs):
565 nimList = nimmanager.getNimListOfType("DVB-S")
566 if len(nimList) == 0:
567 session.open(MessageBox, _("No positioner capable frontend found."), MessageBox.TYPE_ERROR)
569 if session.nav.RecordTimer.isRecording():
570 session.open(MessageBox, _("A recording is currently running. Please stop the recording before trying to configure the positioner."), MessageBox.TYPE_ERROR)
574 configured_rotor_sats = nimmanager.getRotorSatListForNim(x)
575 if len(configured_rotor_sats) != 0:
577 if len(usableNims) == 1:
578 session.open(PositionerSetup, usableNims[0])
579 elif len(usableNims) > 1:
580 session.open(NimSelection)
582 session.open(MessageBox, _("No tuner is configured for use with a diseqc positioner!"), MessageBox.TYPE_ERROR)
584 def PositionerSetupStart(menuid, **kwargs):
586 return [(_("Positioner setup"), PositionerMain, "positioner_setup", None)]
590 def Plugins(**kwargs):
591 if (nimmanager.hasNimType("DVB-S")):
592 return PluginDescriptor(name=_("Positioner setup"), description="Setup your positioner", where = PluginDescriptor.WHERE_MENU, fnc=PositionerSetupStart)