1 from enigma import eTimer, eDVBSatelliteEquipmentControl, eDVBResourceManager, \
2 eDVBDiseqcCommand, eDVBFrontendParametersSatellite, eDVBFrontendParameters
4 from Screens.Screen import Screen
5 from Screens.ScanSetup import ScanSetup
6 from Screens.MessageBox import MessageBox
7 from Plugins.Plugin import PluginDescriptor
9 from Components.Label import Label
10 from Components.ConfigList import ConfigList
11 from Components.TunerInfo import TunerInfo
12 from Components.ActionMap import ActionMap
13 from Components.NimManager import nimmanager
14 from Components.MenuList import MenuList
15 from Components.config import ConfigSatlist, ConfigNothing, ConfigSelection, ConfigSubsection, KEY_LEFT, KEY_RIGHT, getConfigListEntry
17 from time import sleep
19 class PositionerSetup(Screen):
21 <screen position="100,100" size="560,400" title="Positioner setup..." >
22 <widget name="list" position="100,0" size="350,155" />
24 <widget name="red" position="0,155" size="140,80" backgroundColor="red" halign="center" valign="center" font="Regular;21" />
25 <widget name="green" position="140,155" size="140,80" backgroundColor="green" halign="center" valign="center" font="Regular;21" />
26 <widget name="yellow" position="280,155" size="140,80" backgroundColor="yellow" halign="center" valign="center" font="Regular;21" />
27 <widget name="blue" position="420,155" size="140,80" backgroundColor="blue" halign="center" valign="center" font="Regular;21" />
29 <widget name="snr" text="SNR:" position="0,245" size="60,22" font="Regular;21" />
30 <widget name="agc" text="AGC:" position="0,270" size="60,22" font="Regular;21" />
31 <widget name="ber" text="BER:" position="0,295" size="60,22" font="Regular;21" />
32 <widget name="lock" text="Lock:" position="0,320" size="60,22" font="Regular;21" />
33 <widget name="snr_percentage" position="220,245" size="60,22" font="Regular;21" />
34 <widget name="agc_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,245" size="150,22" />
38 <widget name="agc_bar" position="60,270" size="150,22" />
39 <widget name="ber_bar" position="60,295" size="150,22" />
41 <widget name="frequency" text="Frequency:" position="300,245" size="120,22" font="Regular;21" />
42 <widget name="symbolrate" text="Symbolrate:" position="300,270" size="120,22" font="Regular;21" />
43 <widget name="fec" text="FEC:" position="300,295" size="120,22" font="Regular;21" />
44 <widget name="frequency_value" position="420,245" size="120,22" font="Regular;21" />
45 <widget name="symbolrate_value" position="420,270" size="120,22" font="Regular;21" />
46 <widget name="fec_value" position="420,295" size="120,22" font="Regular;21" />
48 def __init__(self, session, feid):
49 self.skin = PositionerSetup.skin
50 Screen.__init__(self, session)
54 if not self.openFrontend():
55 self.oldref = session.nav.getCurrentlyPlayingServiceReference()
56 session.nav.stopService() # try to disable foreground service
57 if not self.openFrontend():
58 if session.pipshown: # try to disable pip
59 session.pipshown = False
61 if not self.openFrontend():
62 self.frontend = None # in normal case this should not happen
63 self.getFrontend = None
65 self.diseqc = Diseqc(self.frontend)
66 self.tuner = Tuner(self.frontend)
67 self.tuner.tune((0,0,0,0,0,0))
72 self.stopOnLock = False
75 self["red"] = self.red
76 self.green = Label("")
77 self["green"] = self.green
78 self.yellow = Label("")
79 self["yellow"] = self.yellow
81 self["blue"] = self.blue
84 self["list"] = ConfigList(self.list)
90 self["lock"] = Label()
91 self["snr_percentage"] = TunerInfo(TunerInfo.SNR_PERCENTAGE, frontendfkt = self.getFrontend)
92 self["agc_percentage"] = TunerInfo(TunerInfo.AGC_PERCENTAGE, frontendfkt = self.getFrontend)
93 self["ber_value"] = TunerInfo(TunerInfo.BER_VALUE, frontendfkt = self.getFrontend)
94 self["snr_bar"] = TunerInfo(TunerInfo.SNR_BAR, frontendfkt = self.getFrontend)
95 self["agc_bar"] = TunerInfo(TunerInfo.AGC_BAR, frontendfkt = self.getFrontend)
96 self["ber_bar"] = TunerInfo(TunerInfo.BER_BAR, frontendfkt = self.getFrontend)
97 self["lock_state"] = TunerInfo(TunerInfo.LOCK_STATE, frontendfkt = self.getFrontend)
99 self["frequency"] = Label()
100 self["symbolrate"] = Label()
101 self["fec"] = Label()
103 self["frequency_value"] = Label("")
104 self["symbolrate_value"] = Label("")
105 self["fec_value"] = Label("")
107 self["actions"] = ActionMap(["DirectionActions", "OkCancelActions", "ColorActions"],
110 "cancel": self.keyCancel,
116 "green": self.greenKey,
117 "yellow": self.yellowKey,
118 "blue": self.blueKey,
121 self.updateColors("tune")
123 self.statusTimer = eTimer()
124 self.statusTimer.timeout.get().append(self.updateStatus)
125 self.statusTimer.start(50, False)
127 def restartPrevService(self, yesno):
132 self.session.nav.playService(self.oldref)
137 self.session.openWithCallback(self.restartPrevService, MessageBox, _("Zap back to service before positioner setup?"), MessageBox.TYPE_YESNO)
139 self.restartPrevService(False)
141 def getFrontend(self):
144 def openFrontend(self):
145 res_mgr = eDVBResourceManager.getInstance()
147 self.raw_channel = res_mgr.allocateRawChannel(self.feid)
149 self.frontend = self.raw_channel.getFrontend()
153 print "getFrontend failed"
155 print "getRawChannel failed"
157 print "getResourceManager instance failed"
160 def createConfig(self):
161 self.positioner_tune = ConfigNothing()
162 self.positioner_move = ConfigNothing()
163 self.positioner_finemove = ConfigNothing()
164 self.positioner_limits = ConfigNothing()
165 self.positioner_goto0 = ConfigNothing()
167 for x in range(1,255):
168 storepos.append(str(x))
169 self.positioner_storage = ConfigSelection(choices = storepos)
171 def createSetup(self):
172 self.list.append((_("Tune"), self.positioner_tune, "tune"))
173 self.list.append((_("Positioner movement"), self.positioner_move, "move"))
174 self.list.append((_("Positioner fine movement"), self.positioner_finemove, "finemove"))
175 self.list.append((_("Set limits"), self.positioner_limits, "limits"))
176 self.list.append((_("Positioner storage"), self.positioner_storage, "storage"))
177 self.list.append((_("Goto 0"), self.positioner_goto0, "goto0"))
178 self["list"].l.setList(self.list)
183 def getCurrentConfigPath(self):
184 return self["list"].getCurrent()[2]
187 if not self.isMoving:
188 self["list"].instance.moveSelection(self["list"].instance.moveUp)
189 self.updateColors(self.getCurrentConfigPath())
192 if not self.isMoving:
193 self["list"].instance.moveSelection(self["list"].instance.moveDown)
194 self.updateColors(self.getCurrentConfigPath())
197 self["list"].handleKey(KEY_LEFT)
200 self["list"].handleKey(KEY_RIGHT)
202 def updateColors(self, entry):
204 self.red.setText(_("Tune"))
205 self.green.setText("")
206 self.yellow.setText("")
207 self.blue.setText("")
208 elif entry == "move":
210 self.red.setText(_("Stop"))
211 self.green.setText(_("Stop"))
212 self.yellow.setText(_("Stop"))
213 self.blue.setText(_("Stop"))
215 self.red.setText(_("Move west"))
216 self.green.setText(_("Search west"))
217 self.yellow.setText(_("Search east"))
218 self.blue.setText(_("Move east"))
219 elif entry == "finemove":
221 self.green.setText(_("Step west"))
222 self.yellow.setText(_("Step east"))
223 self.blue.setText("")
224 elif entry == "limits":
225 self.red.setText(_("Limits off"))
226 self.green.setText(_("Limit west"))
227 self.yellow.setText(_("Limit east"))
228 self.blue.setText(_("Limits on"))
229 elif entry == "storage":
231 self.green.setText(_("Store position"))
232 self.yellow.setText(_("Goto position"))
233 self.blue.setText("")
234 elif entry == "goto0":
235 self.red.setText(_("Goto 0"))
236 self.green.setText("")
237 self.yellow.setText("")
238 self.blue.setText("")
241 self.green.setText("")
242 self.yellow.setText("")
243 self.blue.setText("")
246 entry = self.getCurrentConfigPath()
249 self.diseqccommand("stop")
250 self.isMoving = False
251 self.stopOnLock = False
253 self.diseqccommand("moveWest", 0)
255 self.updateColors("move")
256 elif entry == "limits":
257 self.diseqccommand("limitOff")
258 elif entry == "tune":
259 self.session.openWithCallback(self.tune, TunerScreen, self.feid)
260 elif entry == "goto0":
261 print "move to position 0"
262 self.diseqccommand("moveTo", 0)
265 entry = self.getCurrentConfigPath()
268 self.diseqccommand("stop")
269 self.isMoving = False
270 self.stopOnLock = False
273 self.stopOnLock = True
274 self.diseqccommand("moveWest", 0)
275 self.updateColors("move")
276 elif entry == "finemove":
277 print "stepping west"
278 self.diseqccommand("moveWest", 0xFF) # one step
279 elif entry == "storage":
280 print "store at position", int(self.positioner_storage.value)
281 self.diseqccommand("store", int(self.positioner_storage.value))
282 elif entry == "limits":
283 self.diseqccommand("limitWest")
286 entry = self.getCurrentConfigPath()
289 self.diseqccommand("stop")
290 self.isMoving = False
291 self.stopOnLock = False
294 self.stopOnLock = True
295 self.diseqccommand("moveEast", 0)
296 self.updateColors("move")
297 elif entry == "finemove":
298 print "stepping east"
299 self.diseqccommand("moveEast", 0xFF) # one step
300 elif entry == "storage":
301 print "move to position", int(self.positioner_storage.value)
302 self.diseqccommand("moveTo", int(self.positioner_storage.value))
303 elif entry == "limits":
304 self.diseqccommand("limitEast")
307 entry = self.getCurrentConfigPath()
310 self.diseqccommand("stop")
311 self.isMoving = False
312 self.stopOnLock = False
314 self.diseqccommand("moveEast", 0)
316 self.updateColors("move")
318 elif entry == "limits":
319 self.diseqccommand("limitOn")
321 def diseqccommand(self, cmd, param = 0):
322 self.diseqc.command(cmd, param)
325 def updateStatus(self):
326 self["snr_percentage"].update()
327 self["agc_percentage"].update()
328 self["ber_value"].update()
329 self["snr_bar"].update()
330 self["agc_bar"].update()
331 self["ber_bar"].update()
332 self["lock_state"].update()
333 transponderdata = self.tuner.getTransponderData()
334 self["frequency_value"].setText(str(transponderdata["frequency"]))
335 self["symbolrate_value"].setText(str(transponderdata["symbol_rate"]))
336 self["fec_value"].setText(str(transponderdata["fec_inner"]))
337 if transponderdata["tuner_locked"] == 1 and self.isMoving and self.stopOnLock:
338 self.diseqccommand("stop")
339 self.isMoving = False
340 self.stopOnLock = False
341 self.updateColors(self.getCurrentConfigPath())
343 def tune(self, transponder):
344 if transponder is not None:
345 self.tuner.tune(transponder)
348 def __init__(self, frontend):
349 self.frontend = frontend
351 def command(self, what, param = 0):
353 cmd = eDVBDiseqcCommand()
354 if what == "moveWest":
355 string = 'e03169' + ("%02x" % param)
356 elif what == "moveEast":
357 string = 'e03168' + ("%02x" % param)
358 elif what == "moveTo":
359 string = 'e0316b' + ("%02x" % param)
360 elif what == "store":
361 string = 'e0316a' + ("%02x" % param)
362 elif what == "limitOn":
364 elif what == "limitOff":
366 elif what == "limitEast":
368 elif what == "limitWest":
371 string = 'e03160' #positioner stop
373 print "diseqc command:",
375 cmd.setCommandString(string)
376 self.frontend.setTone(iDVBFrontend.toneOff)
377 self.frontend.sendDiseqc(cmd)
378 if string == 'e03160': #positioner stop
380 self.frontend.sendDiseqc(cmd) # send 2nd time
383 def __init__(self, frontend):
384 self.frontend = frontend
386 def tune(self, transponder):
387 print "tuning to transponder with data", transponder
388 parm = eDVBFrontendParametersSatellite()
389 parm.frequency = transponder[0] * 1000
390 parm.symbol_rate = transponder[1] * 1000
391 parm.polarisation = transponder[2]
392 parm.fec = transponder[3]
393 parm.inversion = transponder[4]
394 parm.orbital_position = transponder[5]
395 parm.system = 0 # FIXMEE !! HARDCODED DVB-S (add support for DVB-S2)
396 parm.modulation = 1 # FIXMEE !! HARDCODED QPSK
397 feparm = eDVBFrontendParameters()
398 feparm.setDVBS(parm, True)
399 self.lastparm = feparm
401 self.frontend.tune(feparm)
405 self.frontend.tune(self.lastparm)
407 def getTransponderData(self):
409 return self.frontend.readTransponderData(True)
414 class TunerScreen(ScanSetup):
416 <screen position="90,100" size="520,400" title="Tune">
417 <widget name="config" position="20,10" size="460,350" scrollbarMode="showOnDemand" />
418 <widget name="introduction" position="20,360" size="350,30" font="Regular;23" />
421 def __init__(self, session, feid):
423 ScanSetup.__init__(self, session)
424 self["introduction"].setText("")
426 def createSetup(self):
427 self.typeOfTuningEntry = None
430 self.typeOfTuningEntry = getConfigListEntry(_('Tune'), tuning.type)
431 self.list.append(self.typeOfTuningEntry)
432 self.satEntry = getConfigListEntry(_('Satellite'), tuning.sat)
433 self.list.append(self.satEntry)
434 if tuning.type.value == "manual_transponder":
435 self.list.append(getConfigListEntry(_('Frequency'), self.scan_sat.frequency))
436 self.list.append(getConfigListEntry(_('Inversion'), self.scan_sat.inversion))
437 self.list.append(getConfigListEntry(_('Symbol Rate'), self.scan_sat.symbolrate))
438 self.list.append(getConfigListEntry(_("Polarity"), self.scan_sat.polarization))
439 self.list.append(getConfigListEntry(_("FEC"), self.scan_sat.fec))
440 elif tuning.type.value == "predefined_transponder":
441 self.list.append(getConfigListEntry(_("Transponder"), tuning.transponder))
442 self["config"].list = self.list
443 self["config"].l.setList(self.list)
446 if self["config"].getCurrent() == self.typeOfTuningEntry:
448 elif self["config"].getCurrent() == self.satEntry:
451 def createConfig(self, foo):
454 tuning = ConfigSubsection()
455 tuning.type = ConfigSelection(
456 default = "manual_transponder",
457 choices = { "manual_transponder" : _("Manual transponder"),
458 "predefined_transponder" : _("Predefined transponder") } )
459 tuning.sat = ConfigSatlist(list=nimmanager.getRotorSatListForNim(self.feid))
460 tuning.sat.addNotifier(self.tuningSatChanged)
461 self.updateTransponders()
462 TunerScreenConfigCreated = True
463 ScanSetup.createConfig(self, None)
465 def tuningSatChanged(self, *parm):
466 self.updateTransponders()
468 def updateTransponders(self):
469 if len(tuning.sat.choices):
470 transponderlist = nimmanager.getTransponders(int(tuning.sat.value))
473 for x in transponderlist:
498 tps.append(str(x[1]) + "," + str(x[2]) + "," + pol + "," + fec)
499 tuning.transponder = ConfigSelection(choices=tps)
502 returnvalue = (0, 0, 0, 0, 0, 0)
503 satpos = int(tuning.sat.value)
504 if tuning.type.value == "manual_transponder":
506 self.scan_sat.frequency.value,
507 self.scan_sat.symbolrate.value,
508 self.scan_sat.polarization.index,
509 self.scan_sat.fec.index,
510 self.scan_sat.inversion.index,
512 elif tuning.type.value == "predefined_transponder":
513 transponder = nimmanager.getTransponders(satpos)[tuning.transponder.index]
514 returnvalue = (int(transponder[1] / 1000), int(transponder[2] / 1000), transponder[3], transponder[4], 2, satpos)
515 self.close(returnvalue)
520 class NimSelection(Screen):
522 <screen position="140,165" size="400,100" title="select Slot">
523 <widget name="nimlist" position="20,10" size="360,75" />
526 def __init__(self, session):
527 Screen.__init__(self, session)
529 nimlist = nimmanager.getNimListOfType(nimmanager.nimType["DVB-S"])
532 nimMenuList.append((_("NIM ") + (["A", "B", "C", "D"][x]) + ": " + nimmanager.getNimName(x) + " (" + nimmanager.getNimTypeName(x) + ")", x))
534 self["nimlist"] = MenuList(nimMenuList)
536 self["actions"] = ActionMap(["OkCancelActions"],
538 "ok": self.okbuttonClick ,
542 def okbuttonClick(self):
543 selection = self["nimlist"].getCurrent()
544 self.session.open(PositionerSetup, selection[1])
546 def PositionerMain(session, **kwargs):
547 nimList = nimmanager.getNimListOfType(nimmanager.nimType["DVB-S"])
548 if len(nimList) == 0:
549 session.open(MessageBox, _("No positioner capable frontend found."), MessageBox.TYPE_ERROR)
551 if session.nav.RecordTimer.isRecording():
552 session.open(MessageBox, _("A recording is currently running. Please stop the recording before trying to configure the positioner."), MessageBox.TYPE_ERROR)
556 configured_rotor_sats = nimmanager.getRotorSatListForNim(x)
557 if len(configured_rotor_sats) != 0:
559 if len(usableNims) == 1:
560 session.open(PositionerSetup, usableNims[0])
561 elif len(usableNims) > 1:
562 session.open(NimSelection)
564 session.open(MessageBox, _("No tuner is configured for use with a diseqc positioner!"), MessageBox.TYPE_ERROR)
566 def PositionerSetupStart(menuid):
568 return [(_("Positioner setup"), PositionerMain)]
572 def Plugins(**kwargs):
573 return PluginDescriptor(name=_("Positioner setup"), description="Setup your positioner", where = PluginDescriptor.WHERE_SETUP, fnc=PositionerSetupStart)