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_db" position="60,245" size="150,22" halign="center" valign="center" font="Regular;21" />
31 <eLabel text="SNR:" position="0,270" size="60,22" font="Regular;21" />
32 <eLabel text="BER:" position="0,295" size="60,22" font="Regular;21" />
33 <eLabel text="Lock:" position="0,320" size="60,22" font="Regular;21" />
34 <widget name="snr_percentage" position="220,270" size="60,22" font="Regular;21" />
35 <widget name="ber_value" position="220,295" size="60,22" font="Regular;21" />
36 <widget name="lock_state" position="60,320" size="150,22" font="Regular;21" />
37 <widget name="snr_bar" position="60,270" size="150,22" />
38 <widget name="ber_bar" position="60,295" size="150,22" />
40 <eLabel text="Frequency:" position="300,245" size="120,22" font="Regular;21" />
41 <eLabel text="Symbolrate:" position="300,270" size="120,22" font="Regular;21" />
42 <eLabel text="FEC:" position="300,295" size="120,22" font="Regular;21" />
43 <widget name="frequency_value" position="420,245" size="120,22" font="Regular;21" />
44 <widget name="symbolrate_value" position="420,270" size="120,22" font="Regular;21" />
45 <widget name="fec_value" position="420,295" size="120,22" font="Regular;21" />
47 def __init__(self, session, feid):
48 self.skin = PositionerSetup.skin
49 Screen.__init__(self, session)
54 if not self.openFrontend():
55 self.oldref = session.nav.getCurrentlyPlayingServiceReference()
56 service = session.nav.getCurrentService()
57 feInfo = service and service.frontendInfo()
59 cur = feInfo.getTransponderData(True)
62 session.nav.stopService() # try to disable foreground service
63 if not self.openFrontend():
64 if session.pipshown: # try to disable pip
65 service = self.session.pip.pipservice
66 feInfo = service and service.frontendInfo()
68 cur = feInfo.getTransponderData()
71 session.pipshown = False
73 if not self.openFrontend():
74 self.frontend = None # in normal case this should not happen
76 self.frontendStatus = { }
77 self.diseqc = Diseqc(self.frontend)
78 self.tuner = Tuner(self.frontend)
80 tp = ( cur.get("frequency", 0) / 1000,
81 cur.get("symbol_rate", 0) / 1000,
82 cur.get("polarization", eDVBFrontendParametersSatellite.Polarisation_Horizontal),
83 cur.get("fec_inner", eDVBFrontendParametersSatellite.FEC_Auto),
84 cur.get("inversion", eDVBFrontendParametersSatellite.Inversion_Unknown)
85 cur.get("orbital_position", 0)
86 cur.get("system", eDVBFrontendParametersSatellite.System_DVB_S)
87 cur.get("modulation", eDVBFrontendParametersSatellite.Modulation_QPSK)
88 cur.get("rolloff", eDVBFrontendParametersSatellite.RollOff_alpha_0_35)
89 cur.get("pilot", eDVBFrontendParametersSatellite.Pilot_Unknown))
95 self.stopOnLock = False
98 self["red"] = self.red
99 self.green = Label("")
100 self["green"] = self.green
101 self.yellow = Label("")
102 self["yellow"] = self.yellow
103 self.blue = Label("")
104 self["blue"] = self.blue
107 self["list"] = ConfigList(self.list)
110 self["snr_db"] = TunerInfo(TunerInfo.SNR_DB, statusDict = self.frontendStatus)
111 self["snr_percentage"] = TunerInfo(TunerInfo.SNR_PERCENTAGE, statusDict = self.frontendStatus)
112 self["ber_value"] = TunerInfo(TunerInfo.BER_VALUE, statusDict = self.frontendStatus)
113 self["snr_bar"] = TunerInfo(TunerInfo.SNR_BAR, statusDict = self.frontendStatus)
114 self["ber_bar"] = TunerInfo(TunerInfo.BER_BAR, statusDict = self.frontendStatus)
115 self["lock_state"] = TunerInfo(TunerInfo.LOCK_STATE, statusDict = self.frontendStatus)
117 self["frequency_value"] = Label("")
118 self["symbolrate_value"] = Label("")
119 self["fec_value"] = Label("")
121 self["actions"] = ActionMap(["DirectionActions", "OkCancelActions", "ColorActions"],
124 "cancel": self.keyCancel,
130 "green": self.greenKey,
131 "yellow": self.yellowKey,
132 "blue": self.blueKey,
135 self.updateColors("tune")
137 self.statusTimer = eTimer()
138 self.statusTimer.callback.append(self.updateStatus)
139 self.statusTimer.start(50, True)
140 self.onClose.append(self.__onClose)
143 self.session.nav.playService(self.oldref)
145 def restartPrevService(self, yesno):
156 self.session.openWithCallback(self.restartPrevService, MessageBox, _("Zap back to service before positioner setup?"), MessageBox.TYPE_YESNO)
158 self.restartPrevService(False)
160 def openFrontend(self):
161 res_mgr = eDVBResourceManager.getInstance()
163 self.raw_channel = res_mgr.allocateRawChannel(self.feid)
165 self.frontend = self.raw_channel.getFrontend()
169 print "getFrontend failed"
171 print "getRawChannel failed"
173 print "getResourceManager instance failed"
176 def createConfig(self):
177 self.positioner_tune = ConfigNothing()
178 self.positioner_move = ConfigNothing()
179 self.positioner_finemove = ConfigNothing()
180 self.positioner_limits = ConfigNothing()
181 self.positioner_goto0 = ConfigNothing()
183 for x in range(1,255):
184 storepos.append(str(x))
185 self.positioner_storage = ConfigSelection(choices = storepos)
187 def createSetup(self):
188 self.list.append((_("Tune"), self.positioner_tune, "tune"))
189 self.list.append((_("Positioner movement"), self.positioner_move, "move"))
190 self.list.append((_("Positioner fine movement"), self.positioner_finemove, "finemove"))
191 self.list.append((_("Set limits"), self.positioner_limits, "limits"))
192 self.list.append((_("Positioner storage"), self.positioner_storage, "storage"))
193 self.list.append((_("Goto 0"), self.positioner_goto0, "goto0"))
194 self["list"].l.setList(self.list)
199 def getCurrentConfigPath(self):
200 return self["list"].getCurrent()[2]
203 if not self.isMoving:
204 self["list"].instance.moveSelection(self["list"].instance.moveUp)
205 self.updateColors(self.getCurrentConfigPath())
208 if not self.isMoving:
209 self["list"].instance.moveSelection(self["list"].instance.moveDown)
210 self.updateColors(self.getCurrentConfigPath())
213 self["list"].handleKey(KEY_LEFT)
216 self["list"].handleKey(KEY_RIGHT)
218 def updateColors(self, entry):
220 self.red.setText(_("Tune"))
221 self.green.setText("")
222 self.yellow.setText("")
223 self.blue.setText("")
224 elif entry == "move":
226 self.red.setText(_("Stop"))
227 self.green.setText(_("Stop"))
228 self.yellow.setText(_("Stop"))
229 self.blue.setText(_("Stop"))
231 self.red.setText(_("Move west"))
232 self.green.setText(_("Search west"))
233 self.yellow.setText(_("Search east"))
234 self.blue.setText(_("Move east"))
235 elif entry == "finemove":
237 self.green.setText(_("Step west"))
238 self.yellow.setText(_("Step east"))
239 self.blue.setText("")
240 elif entry == "limits":
241 self.red.setText(_("Limits off"))
242 self.green.setText(_("Limit west"))
243 self.yellow.setText(_("Limit east"))
244 self.blue.setText(_("Limits on"))
245 elif entry == "storage":
247 self.green.setText(_("Store position"))
248 self.yellow.setText(_("Goto position"))
249 self.blue.setText("")
250 elif entry == "goto0":
251 self.red.setText(_("Goto 0"))
252 self.green.setText("")
253 self.yellow.setText("")
254 self.blue.setText("")
257 self.green.setText("")
258 self.yellow.setText("")
259 self.blue.setText("")
262 entry = self.getCurrentConfigPath()
265 self.diseqccommand("stop")
266 self.isMoving = False
267 self.stopOnLock = False
269 self.diseqccommand("moveWest", 0)
271 self.updateColors("move")
272 elif entry == "limits":
273 self.diseqccommand("limitOff")
274 elif entry == "tune":
276 self.frontend.getFrontendData(fe_data)
277 self.frontend.getTransponderData(fe_data, True)
278 feparm = self.tuner.lastparm.getDVBS()
279 fe_data["orbital_position"] = feparm.orbital_position
280 self.session.openWithCallback(self.tune, TunerScreen, self.feid, fe_data)
281 elif entry == "goto0":
282 print "move to position 0"
283 self.diseqccommand("moveTo", 0)
286 entry = self.getCurrentConfigPath()
289 self.diseqccommand("stop")
290 self.isMoving = False
291 self.stopOnLock = False
294 self.stopOnLock = True
295 self.diseqccommand("moveWest", 0)
296 self.updateColors("move")
297 elif entry == "finemove":
298 print "stepping west"
299 self.diseqccommand("moveWest", 0xFF) # one step
300 elif entry == "storage":
301 print "store at position", int(self.positioner_storage.value)
302 self.diseqccommand("store", int(self.positioner_storage.value))
304 elif entry == "limits":
305 self.diseqccommand("limitWest")
308 entry = self.getCurrentConfigPath()
311 self.diseqccommand("stop")
312 self.isMoving = False
313 self.stopOnLock = False
316 self.stopOnLock = True
317 self.diseqccommand("moveEast", 0)
318 self.updateColors("move")
319 elif entry == "finemove":
320 print "stepping east"
321 self.diseqccommand("moveEast", 0xFF) # one step
322 elif entry == "storage":
323 print "move to position", int(self.positioner_storage.value)
324 self.diseqccommand("moveTo", int(self.positioner_storage.value))
325 elif entry == "limits":
326 self.diseqccommand("limitEast")
329 entry = self.getCurrentConfigPath()
332 self.diseqccommand("stop")
333 self.isMoving = False
334 self.stopOnLock = False
336 self.diseqccommand("moveEast", 0)
338 self.updateColors("move")
340 elif entry == "limits":
341 self.diseqccommand("limitOn")
343 def diseqccommand(self, cmd, param = 0):
344 self.diseqc.command(cmd, param)
347 def updateStatus(self):
349 self.frontend.getFrontendStatus(self.frontendStatus)
350 self["snr_db"].update()
351 self["snr_percentage"].update()
352 self["ber_value"].update()
353 self["snr_bar"].update()
354 self["ber_bar"].update()
355 self["lock_state"].update()
356 transponderdata = self.tuner.getTransponderData()
357 self["frequency_value"].setText(str(transponderdata.get("frequency")))
358 self["symbolrate_value"].setText(str(transponderdata.get("symbol_rate")))
359 self["fec_value"].setText(str(transponderdata.get("fec_inner")))
360 if self.frontendStatus.get("tuner_locked", 0) == 1 and self.isMoving and self.stopOnLock:
361 self.diseqccommand("stop")
362 self.isMoving = False
363 self.stopOnLock = False
364 self.updateColors(self.getCurrentConfigPath())
365 self.statusTimer.start(50, True)
367 def tune(self, transponder):
368 if transponder is not None:
369 self.tuner.tune(transponder)
372 def __init__(self, frontend):
373 self.frontend = frontend
375 def command(self, what, param = 0):
377 cmd = eDVBDiseqcCommand()
378 if what == "moveWest":
379 string = 'e03169' + ("%02x" % param)
380 elif what == "moveEast":
381 string = 'e03168' + ("%02x" % param)
382 elif what == "moveTo":
383 string = 'e0316b' + ("%02x" % param)
384 elif what == "store":
385 string = 'e0316a' + ("%02x" % param)
386 elif what == "limitOn":
388 elif what == "limitOff":
390 elif what == "limitEast":
392 elif what == "limitWest":
395 string = 'e03160' #positioner stop
397 print "diseqc command:",
399 cmd.setCommandString(string)
400 self.frontend.setTone(iDVBFrontend.toneOff)
401 sleep(0.015) # wait 15msec after disable tone
402 self.frontend.sendDiseqc(cmd)
403 if string == 'e03160': #positioner stop
405 self.frontend.sendDiseqc(cmd) # send 2nd time
408 def __init__(self, frontend):
409 self.frontend = frontend
411 def tune(self, transponder):
412 print "tuning to transponder with data", transponder
413 parm = eDVBFrontendParametersSatellite()
414 parm.frequency = transponder[0] * 1000
415 parm.symbol_rate = transponder[1] * 1000
416 parm.polarisation = transponder[2]
417 parm.fec = transponder[3]
418 parm.inversion = transponder[4]
419 parm.orbital_position = transponder[5]
420 parm.system = transponder[6]
421 parm.modulation = transponder[7]
422 parm.rolloff = transponder[8]
423 parm.pilot = transponder[9]
424 feparm = eDVBFrontendParameters()
425 feparm.setDVBS(parm, True)
426 self.lastparm = feparm
428 self.frontend.tune(feparm)
432 self.frontend.tune(self.lastparm)
434 def getTransponderData(self):
437 self.frontend.getTransponderData(ret, True)
442 class TunerScreen(ScanSetup):
444 <screen position="90,100" size="520,400" title="Tune">
445 <widget name="config" position="20,10" size="460,350" scrollbarMode="showOnDemand" />
446 <widget name="introduction" position="20,360" size="350,30" font="Regular;23" />
449 def __init__(self, session, feid, fe_data):
451 self.fe_data = fe_data
452 ScanSetup.__init__(self, session)
453 self["introduction"].setText("")
455 def createSetup(self):
456 self.typeOfTuningEntry = None
459 self.typeOfTuningEntry = getConfigListEntry(_('Tune'), tuning.type)
460 self.list.append(self.typeOfTuningEntry)
461 self.satEntry = getConfigListEntry(_('Satellite'), tuning.sat)
462 self.list.append(self.satEntry)
463 nim = nimmanager.nim_slots[self.feid]
464 self.systemEntry = None
466 if tuning.type.value == "manual_transponder":
467 if nim.isCompatible("DVB-S2"):
468 self.systemEntry = getConfigListEntry(_('System'), self.scan_sat.system)
469 self.list.append(self.systemEntry)
471 # downgrade to dvb-s, in case a -s2 config was active
472 self.scan_sat.system.value = eDVBFrontendParametersSatellite.System_DVB_S
473 self.list.append(getConfigListEntry(_('Frequency'), self.scan_sat.frequency))
474 self.list.append(getConfigListEntry(_('Inversion'), self.scan_sat.inversion))
475 self.list.append(getConfigListEntry(_('Symbol Rate'), self.scan_sat.symbolrate))
476 self.list.append(getConfigListEntry(_("Polarity"), self.scan_sat.polarization))
477 if self.scan_sat.system.value == eDVBFrontendParametersSatellite.System_DVB_S:
478 self.list.append(getConfigListEntry(_("FEC"), self.scan_sat.fec))
479 elif self.scan_sat.system.value == eDVBFrontendParametersSatellite.System_DVB_S2:
480 self.list.append(getConfigListEntry(_("FEC"), self.scan_sat.fec_s2))
481 self.modulationEntry = getConfigListEntry(_('Modulation'), self.scan_sat.modulation)
482 self.list.append(self.modulationEntry)
483 self.list.append(getConfigListEntry(_('Rolloff'), self.scan_sat.rolloff))
484 self.list.append(getConfigListEntry(_('Pilot'), self.scan_sat.pilot))
485 elif tuning.type.value == "predefined_transponder":
486 self.list.append(getConfigListEntry(_("Transponder"), tuning.transponder))
487 self["config"].list = self.list
488 self["config"].l.setList(self.list)
491 if self["config"].getCurrent() in (self.typeOfTuningEntry, self.satEntry, self.systemEntry):
494 def createConfig(self, foo):
497 tuning = ConfigSubsection()
498 tuning.type = ConfigSelection(
499 default = "manual_transponder",
500 choices = { "manual_transponder" : _("Manual transponder"),
501 "predefined_transponder" : _("Predefined transponder") } )
502 tuning.sat = ConfigSatlist(list=nimmanager.getRotorSatListForNim(self.feid))
503 tuning.sat.addNotifier(self.tuningSatChanged)
504 self.updateTransponders()
505 orb_pos = self.fe_data.get("orbital_position", None)
506 if orb_pos is not None:
507 for x in nimmanager.getRotorSatListForNim(self.feid):
509 if x[0] == orb_pos and tuning.sat.value != opos:
510 tuning.sat.value = opos
511 del self.fe_data["orbital_position"]
512 ScanSetup.createConfig(self, self.fe_data)
514 def tuningSatChanged(self, *parm):
515 self.updateTransponders()
517 def updateTransponders(self):
518 if len(tuning.sat.choices):
519 transponderlist = nimmanager.getTransponders(int(tuning.sat.value))
522 for x in transponderlist:
557 tps.append(str(x[1]) + "," + str(x[2]) + "," + pol + "," + fec)
558 tuning.transponder = ConfigSelection(choices=tps)
561 returnvalue = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
562 satpos = int(tuning.sat.value)
563 if tuning.type.value == "manual_transponder":
564 if self.scan_sat.system.value == eDVBFrontendParametersSatellite.System_DVB_S2:
565 fec = self.scan_sat.fec_s2.value
567 fec = self.scan_sat.fec.value
569 self.scan_sat.frequency.value,
570 self.scan_sat.symbolrate.value,
571 self.scan_sat.polarization.value,
573 self.scan_sat.inversion.value,
575 self.scan_sat.system.value,
576 self.scan_sat.modulation.value,
577 self.scan_sat.rolloff.value,
578 self.scan_sat.pilot.value)
579 elif tuning.type.value == "predefined_transponder":
580 transponder = nimmanager.getTransponders(satpos)[tuning.transponder.index]
581 returnvalue = (transponder[1] / 1000, transponder[2] / 1000,
582 transponder[3], transponder[4], 2, satpos, transponder[5], transponder[6], transponder[8], transponder[9])
583 self.close(returnvalue)
588 class RotorNimSelection(Screen):
590 <screen position="140,165" size="400,130" title="select Slot">
591 <widget name="nimlist" position="20,10" size="360,100" />
594 def __init__(self, session):
595 Screen.__init__(self, session)
597 nimlist = nimmanager.getNimListOfType("DVB-S")
600 nimMenuList.append((nimmanager.nim_slots[x].friendly_full_description, x))
602 self["nimlist"] = MenuList(nimMenuList)
604 self["actions"] = ActionMap(["OkCancelActions"],
606 "ok": self.okbuttonClick ,
610 def okbuttonClick(self):
611 selection = self["nimlist"].getCurrent()
612 self.session.open(PositionerSetup, selection[1])
614 def PositionerMain(session, **kwargs):
615 nimList = nimmanager.getNimListOfType("DVB-S")
616 if len(nimList) == 0:
617 session.open(MessageBox, _("No positioner capable frontend found."), MessageBox.TYPE_ERROR)
619 if session.nav.RecordTimer.isRecording():
620 session.open(MessageBox, _("A recording is currently running. Please stop the recording before trying to configure the positioner."), MessageBox.TYPE_ERROR)
624 configured_rotor_sats = nimmanager.getRotorSatListForNim(x)
625 if len(configured_rotor_sats) != 0:
627 if len(usableNims) == 1:
628 session.open(PositionerSetup, usableNims[0])
629 elif len(usableNims) > 1:
630 session.open(RotorNimSelection)
632 session.open(MessageBox, _("No tuner is configured for use with a diseqc positioner!"), MessageBox.TYPE_ERROR)
634 def PositionerSetupStart(menuid, **kwargs):
636 return [(_("Positioner setup"), PositionerMain, "positioner_setup", None)]
640 def Plugins(**kwargs):
641 if (nimmanager.hasNimType("DVB-S")):
642 return PluginDescriptor(name=_("Positioner setup"), description="Setup your positioner", where = PluginDescriptor.WHERE_MENU, fnc=PositionerSetupStart)