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
17 from Components.TuneTest import Tuner
18 from Tools.Transponder import ConvertToHumanReadable
20 from time import sleep
22 class PositionerSetup(Screen):
24 <screen position="100,100" size="560,400" title="Positioner setup..." >
25 <widget name="list" position="100,0" size="350,155" />
27 <widget name="red" position="0,155" size="140,80" backgroundColor="red" halign="center" valign="center" font="Regular;21" />
28 <widget name="green" position="140,155" size="140,80" backgroundColor="green" halign="center" valign="center" font="Regular;21" />
29 <widget name="yellow" position="280,155" size="140,80" backgroundColor="yellow" halign="center" valign="center" font="Regular;21" />
30 <widget name="blue" position="420,155" size="140,80" backgroundColor="blue" halign="center" valign="center" font="Regular;21" />
32 <widget name="snr_db" position="60,245" size="150,22" halign="center" valign="center" font="Regular;21" />
33 <eLabel text="SNR:" position="0,270" size="60,22" font="Regular;21" />
34 <eLabel text="BER:" position="0,295" size="60,22" font="Regular;21" />
35 <eLabel text="Lock:" position="0,320" size="60,22" font="Regular;21" />
36 <widget name="snr_percentage" position="220,270" size="60,22" font="Regular;21" />
37 <widget name="ber_value" position="220,295" size="60,22" font="Regular;21" />
38 <widget name="lock_state" position="60,320" size="150,22" font="Regular;21" />
39 <widget name="snr_bar" position="60,270" size="150,22" />
40 <widget name="ber_bar" position="60,295" size="150,22" />
42 <eLabel text="Frequency:" position="300,245" size="120,22" font="Regular;21" />
43 <eLabel text="Symbolrate:" position="300,270" size="120,22" font="Regular;21" />
44 <eLabel 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)
56 if not self.openFrontend():
57 self.oldref = session.nav.getCurrentlyPlayingServiceReference()
58 service = session.nav.getCurrentService()
59 feInfo = service and service.frontendInfo()
61 cur = feInfo.getTransponderData(True)
64 session.nav.stopService() # try to disable foreground service
65 if not self.openFrontend():
66 if session.pipshown: # try to disable pip
67 service = self.session.pip.pipservice
68 feInfo = service and service.frontendInfo()
70 cur = feInfo.getTransponderData()
73 session.pipshown = False
75 if not self.openFrontend():
76 self.frontend = None # in normal case this should not happen
78 self.frontendStatus = { }
79 self.diseqc = Diseqc(self.frontend)
80 self.tuner = Tuner(self.frontend)
82 tp = ( cur.get("frequency", 0) / 1000,
83 cur.get("symbol_rate", 0) / 1000,
84 cur.get("polarization", eDVBFrontendParametersSatellite.Polarisation_Horizontal),
85 cur.get("fec_inner", eDVBFrontendParametersSatellite.FEC_Auto),
86 cur.get("inversion", eDVBFrontendParametersSatellite.Inversion_Unknown),
87 cur.get("orbital_position", 0),
88 cur.get("system", eDVBFrontendParametersSatellite.System_DVB_S),
89 cur.get("modulation", eDVBFrontendParametersSatellite.Modulation_QPSK),
90 cur.get("rolloff", eDVBFrontendParametersSatellite.RollOff_alpha_0_35),
91 cur.get("pilot", eDVBFrontendParametersSatellite.Pilot_Unknown))
97 self.stopOnLock = False
100 self["red"] = self.red
101 self.green = Label("")
102 self["green"] = self.green
103 self.yellow = Label("")
104 self["yellow"] = self.yellow
105 self.blue = Label("")
106 self["blue"] = self.blue
109 self["list"] = ConfigList(self.list)
112 self["snr_db"] = TunerInfo(TunerInfo.SNR_DB, statusDict = self.frontendStatus)
113 self["snr_percentage"] = TunerInfo(TunerInfo.SNR_PERCENTAGE, statusDict = self.frontendStatus)
114 self["ber_value"] = TunerInfo(TunerInfo.BER_VALUE, statusDict = self.frontendStatus)
115 self["snr_bar"] = TunerInfo(TunerInfo.SNR_BAR, statusDict = self.frontendStatus)
116 self["ber_bar"] = TunerInfo(TunerInfo.BER_BAR, statusDict = self.frontendStatus)
117 self["lock_state"] = TunerInfo(TunerInfo.LOCK_STATE, statusDict = self.frontendStatus)
119 self["frequency_value"] = Label("")
120 self["symbolrate_value"] = Label("")
121 self["fec_value"] = Label("")
123 self["actions"] = ActionMap(["DirectionActions", "OkCancelActions", "ColorActions"],
126 "cancel": self.keyCancel,
132 "green": self.greenKey,
133 "yellow": self.yellowKey,
134 "blue": self.blueKey,
137 self.updateColors("tune")
139 self.statusTimer = eTimer()
140 self.statusTimer.callback.append(self.updateStatus)
141 self.statusTimer.start(50, True)
142 self.onClose.append(self.__onClose)
145 self.session.nav.playService(self.oldref)
147 def restartPrevService(self, yesno):
158 self.session.openWithCallback(self.restartPrevService, MessageBox, _("Zap back to service before positioner setup?"), MessageBox.TYPE_YESNO)
160 self.restartPrevService(False)
162 def openFrontend(self):
163 res_mgr = eDVBResourceManager.getInstance()
165 self.raw_channel = res_mgr.allocateRawChannel(self.feid)
167 self.frontend = self.raw_channel.getFrontend()
171 print "getFrontend failed"
173 print "getRawChannel failed"
175 print "getResourceManager instance failed"
178 def createConfig(self):
179 self.positioner_tune = ConfigNothing()
180 self.positioner_move = ConfigNothing()
181 self.positioner_finemove = ConfigNothing()
182 self.positioner_limits = ConfigNothing()
183 self.positioner_goto0 = ConfigNothing()
185 for x in range(1,255):
186 storepos.append(str(x))
187 self.positioner_storage = ConfigSelection(choices = storepos)
189 def createSetup(self):
190 self.list.append((_("Tune"), self.positioner_tune, "tune"))
191 self.list.append((_("Positioner movement"), self.positioner_move, "move"))
192 self.list.append((_("Positioner fine movement"), self.positioner_finemove, "finemove"))
193 self.list.append((_("Set limits"), self.positioner_limits, "limits"))
194 self.list.append((_("Positioner storage"), self.positioner_storage, "storage"))
195 self.list.append((_("Goto 0"), self.positioner_goto0, "goto0"))
196 self["list"].l.setList(self.list)
201 def getCurrentConfigPath(self):
202 return self["list"].getCurrent()[2]
205 if not self.isMoving:
206 self["list"].instance.moveSelection(self["list"].instance.moveUp)
207 self.updateColors(self.getCurrentConfigPath())
210 if not self.isMoving:
211 self["list"].instance.moveSelection(self["list"].instance.moveDown)
212 self.updateColors(self.getCurrentConfigPath())
215 self["list"].handleKey(KEY_LEFT)
218 self["list"].handleKey(KEY_RIGHT)
220 def updateColors(self, entry):
222 self.red.setText(_("Tune"))
223 self.green.setText("")
224 self.yellow.setText("")
225 self.blue.setText("")
226 elif entry == "move":
228 self.red.setText(_("Stop"))
229 self.green.setText(_("Stop"))
230 self.yellow.setText(_("Stop"))
231 self.blue.setText(_("Stop"))
233 self.red.setText(_("Move west"))
234 self.green.setText(_("Search west"))
235 self.yellow.setText(_("Search east"))
236 self.blue.setText(_("Move east"))
237 elif entry == "finemove":
239 self.green.setText(_("Step west"))
240 self.yellow.setText(_("Step east"))
241 self.blue.setText("")
242 elif entry == "limits":
243 self.red.setText(_("Limits off"))
244 self.green.setText(_("Limit west"))
245 self.yellow.setText(_("Limit east"))
246 self.blue.setText(_("Limits on"))
247 elif entry == "storage":
249 self.green.setText(_("Store position"))
250 self.yellow.setText(_("Goto position"))
251 self.blue.setText("")
252 elif entry == "goto0":
253 self.red.setText(_("Goto 0"))
254 self.green.setText("")
255 self.yellow.setText("")
256 self.blue.setText("")
259 self.green.setText("")
260 self.yellow.setText("")
261 self.blue.setText("")
264 entry = self.getCurrentConfigPath()
267 self.diseqccommand("stop")
268 self.isMoving = False
269 self.stopOnLock = False
271 self.diseqccommand("moveWest", 0)
273 self.updateColors("move")
274 elif entry == "limits":
275 self.diseqccommand("limitOff")
276 elif entry == "tune":
278 self.frontend.getFrontendData(fe_data)
279 self.frontend.getTransponderData(fe_data, True)
280 feparm = self.tuner.lastparm.getDVBS()
281 fe_data["orbital_position"] = feparm.orbital_position
282 self.session.openWithCallback(self.tune, TunerScreen, self.feid, fe_data)
283 elif entry == "goto0":
284 print "move to position 0"
285 self.diseqccommand("moveTo", 0)
288 entry = self.getCurrentConfigPath()
291 self.diseqccommand("stop")
292 self.isMoving = False
293 self.stopOnLock = False
296 self.stopOnLock = True
297 self.diseqccommand("moveWest", 0)
298 self.updateColors("move")
299 elif entry == "finemove":
300 print "stepping west"
301 self.diseqccommand("moveWest", 0xFF) # one step
302 elif entry == "storage":
303 print "store at position", int(self.positioner_storage.value)
304 self.diseqccommand("store", int(self.positioner_storage.value))
306 elif entry == "limits":
307 self.diseqccommand("limitWest")
310 entry = self.getCurrentConfigPath()
313 self.diseqccommand("stop")
314 self.isMoving = False
315 self.stopOnLock = False
318 self.stopOnLock = True
319 self.diseqccommand("moveEast", 0)
320 self.updateColors("move")
321 elif entry == "finemove":
322 print "stepping east"
323 self.diseqccommand("moveEast", 0xFF) # one step
324 elif entry == "storage":
325 print "move to position", int(self.positioner_storage.value)
326 self.diseqccommand("moveTo", int(self.positioner_storage.value))
327 elif entry == "limits":
328 self.diseqccommand("limitEast")
331 entry = self.getCurrentConfigPath()
334 self.diseqccommand("stop")
335 self.isMoving = False
336 self.stopOnLock = False
338 self.diseqccommand("moveEast", 0)
340 self.updateColors("move")
342 elif entry == "limits":
343 self.diseqccommand("limitOn")
345 def diseqccommand(self, cmd, param = 0):
346 self.diseqc.command(cmd, param)
349 def updateStatus(self):
351 self.frontend.getFrontendStatus(self.frontendStatus)
352 self["snr_db"].update()
353 self["snr_percentage"].update()
354 self["ber_value"].update()
355 self["snr_bar"].update()
356 self["ber_bar"].update()
357 self["lock_state"].update()
358 transponderdata = ConvertToHumanReadable(self.tuner.getTransponderData(), "DVB-S")
359 self["frequency_value"].setText(str(transponderdata.get("frequency")))
360 self["symbolrate_value"].setText(str(transponderdata.get("symbol_rate")))
361 self["fec_value"].setText(str(transponderdata.get("fec_inner")))
362 if self.frontendStatus.get("tuner_locked", 0) == 1 and self.isMoving and self.stopOnLock:
363 self.diseqccommand("stop")
364 self.isMoving = False
365 self.stopOnLock = False
366 self.updateColors(self.getCurrentConfigPath())
367 self.statusTimer.start(50, True)
369 def tune(self, transponder):
370 if transponder is not None:
371 self.tuner.tune(transponder)
374 def __init__(self, frontend):
375 self.frontend = frontend
377 def command(self, what, param = 0):
379 cmd = eDVBDiseqcCommand()
380 if what == "moveWest":
381 string = 'e03169' + ("%02x" % param)
382 elif what == "moveEast":
383 string = 'e03168' + ("%02x" % param)
384 elif what == "moveTo":
385 string = 'e0316b' + ("%02x" % param)
386 elif what == "store":
387 string = 'e0316a' + ("%02x" % param)
388 elif what == "limitOn":
390 elif what == "limitOff":
392 elif what == "limitEast":
394 elif what == "limitWest":
397 string = 'e03160' #positioner stop
399 print "diseqc command:",
401 cmd.setCommandString(string)
402 self.frontend.setTone(iDVBFrontend.toneOff)
403 sleep(0.015) # wait 15msec after disable tone
404 self.frontend.sendDiseqc(cmd)
405 if string == 'e03160': #positioner stop
407 self.frontend.sendDiseqc(cmd) # send 2nd time
411 class TunerScreen(ScanSetup):
413 <screen position="90,100" size="520,400" title="Tune">
414 <widget name="config" position="20,10" size="460,350" scrollbarMode="showOnDemand" />
415 <widget name="introduction" position="20,360" size="350,30" font="Regular;23" />
418 def __init__(self, session, feid, fe_data):
420 self.fe_data = fe_data
421 ScanSetup.__init__(self, session)
422 self["introduction"].setText("")
424 def createSetup(self):
425 self.typeOfTuningEntry = None
428 self.typeOfTuningEntry = getConfigListEntry(_('Tune'), tuning.type)
429 self.list.append(self.typeOfTuningEntry)
430 self.satEntry = getConfigListEntry(_('Satellite'), tuning.sat)
431 self.list.append(self.satEntry)
432 nim = nimmanager.nim_slots[self.feid]
433 self.systemEntry = None
435 if tuning.type.value == "manual_transponder":
436 if nim.isCompatible("DVB-S2"):
437 self.systemEntry = getConfigListEntry(_('System'), self.scan_sat.system)
438 self.list.append(self.systemEntry)
440 # downgrade to dvb-s, in case a -s2 config was active
441 self.scan_sat.system.value = eDVBFrontendParametersSatellite.System_DVB_S
442 self.list.append(getConfigListEntry(_('Frequency'), self.scan_sat.frequency))
443 self.list.append(getConfigListEntry(_('Inversion'), self.scan_sat.inversion))
444 self.list.append(getConfigListEntry(_('Symbol Rate'), self.scan_sat.symbolrate))
445 self.list.append(getConfigListEntry(_("Polarity"), self.scan_sat.polarization))
446 if self.scan_sat.system.value == eDVBFrontendParametersSatellite.System_DVB_S:
447 self.list.append(getConfigListEntry(_("FEC"), self.scan_sat.fec))
448 elif self.scan_sat.system.value == eDVBFrontendParametersSatellite.System_DVB_S2:
449 self.list.append(getConfigListEntry(_("FEC"), self.scan_sat.fec_s2))
450 self.modulationEntry = getConfigListEntry(_('Modulation'), self.scan_sat.modulation)
451 self.list.append(self.modulationEntry)
452 self.list.append(getConfigListEntry(_('Rolloff'), self.scan_sat.rolloff))
453 self.list.append(getConfigListEntry(_('Pilot'), self.scan_sat.pilot))
454 elif tuning.type.value == "predefined_transponder":
455 self.list.append(getConfigListEntry(_("Transponder"), tuning.transponder))
456 self["config"].list = self.list
457 self["config"].l.setList(self.list)
460 if self["config"].getCurrent() in (self.typeOfTuningEntry, self.satEntry, self.systemEntry):
463 def createConfig(self, foo):
466 tuning = ConfigSubsection()
467 tuning.type = ConfigSelection(
468 default = "manual_transponder",
469 choices = { "manual_transponder" : _("Manual transponder"),
470 "predefined_transponder" : _("Predefined transponder") } )
471 tuning.sat = ConfigSatlist(list=nimmanager.getRotorSatListForNim(self.feid))
472 tuning.sat.addNotifier(self.tuningSatChanged)
473 self.updateTransponders()
474 orb_pos = self.fe_data.get("orbital_position", None)
475 if orb_pos is not None:
476 for x in nimmanager.getRotorSatListForNim(self.feid):
478 if x[0] == orb_pos and tuning.sat.value != opos:
479 tuning.sat.value = opos
480 del self.fe_data["orbital_position"]
481 ScanSetup.createConfig(self, self.fe_data)
483 def tuningSatChanged(self, *parm):
484 self.updateTransponders()
486 def updateTransponders(self):
487 if len(tuning.sat.choices):
488 transponderlist = nimmanager.getTransponders(int(tuning.sat.value))
491 for x in transponderlist:
526 tps.append(str(x[1]) + "," + str(x[2]) + "," + pol + "," + fec)
527 tuning.transponder = ConfigSelection(choices=tps)
530 returnvalue = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
531 satpos = int(tuning.sat.value)
532 if tuning.type.value == "manual_transponder":
533 if self.scan_sat.system.value == eDVBFrontendParametersSatellite.System_DVB_S2:
534 fec = self.scan_sat.fec_s2.value
536 fec = self.scan_sat.fec.value
538 self.scan_sat.frequency.value,
539 self.scan_sat.symbolrate.value,
540 self.scan_sat.polarization.value,
542 self.scan_sat.inversion.value,
544 self.scan_sat.system.value,
545 self.scan_sat.modulation.value,
546 self.scan_sat.rolloff.value,
547 self.scan_sat.pilot.value)
548 elif tuning.type.value == "predefined_transponder":
549 transponder = nimmanager.getTransponders(satpos)[tuning.transponder.index]
550 returnvalue = (transponder[1] / 1000, transponder[2] / 1000,
551 transponder[3], transponder[4], 2, satpos, transponder[5], transponder[6], transponder[8], transponder[9])
552 self.close(returnvalue)
557 class RotorNimSelection(Screen):
559 <screen position="140,165" size="400,130" title="select Slot">
560 <widget name="nimlist" position="20,10" size="360,100" />
563 def __init__(self, session):
564 Screen.__init__(self, session)
566 nimlist = nimmanager.getNimListOfType("DVB-S")
569 nimMenuList.append((nimmanager.nim_slots[x].friendly_full_description, x))
571 self["nimlist"] = MenuList(nimMenuList)
573 self["actions"] = ActionMap(["OkCancelActions"],
575 "ok": self.okbuttonClick ,
579 def okbuttonClick(self):
580 selection = self["nimlist"].getCurrent()
581 self.session.open(PositionerSetup, selection[1])
583 def PositionerMain(session, **kwargs):
584 nimList = nimmanager.getNimListOfType("DVB-S")
585 if len(nimList) == 0:
586 session.open(MessageBox, _("No positioner capable frontend found."), MessageBox.TYPE_ERROR)
588 if session.nav.RecordTimer.isRecording():
589 session.open(MessageBox, _("A recording is currently running. Please stop the recording before trying to configure the positioner."), MessageBox.TYPE_ERROR)
593 configured_rotor_sats = nimmanager.getRotorSatListForNim(x)
594 if len(configured_rotor_sats) != 0:
596 if len(usableNims) == 1:
597 session.open(PositionerSetup, usableNims[0])
598 elif len(usableNims) > 1:
599 session.open(RotorNimSelection)
601 session.open(MessageBox, _("No tuner is configured for use with a diseqc positioner!"), MessageBox.TYPE_ERROR)
603 def PositionerSetupStart(menuid, **kwargs):
605 return [(_("Positioner setup"), PositionerMain, "positioner_setup", None)]
609 def Plugins(**kwargs):
610 if (nimmanager.hasNimType("DVB-S")):
611 return PluginDescriptor(name=_("Positioner setup"), description="Setup your positioner", where = PluginDescriptor.WHERE_MENU, fnc=PositionerSetupStart)