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.sendDiseqc(cmd)
377 if string == 'e03160': #positioner stop
379 self.frontend.sendDiseqc(cmd) # send 2nd time
382 def __init__(self, frontend):
383 self.frontend = frontend
385 def tune(self, transponder):
386 print "tuning to transponder with data", transponder
387 parm = eDVBFrontendParametersSatellite()
388 parm.frequency = transponder[0] * 1000
389 parm.symbol_rate = transponder[1] * 1000
390 parm.polarisation = transponder[2]
391 parm.fec = transponder[3]
392 parm.inversion = transponder[4]
393 parm.orbital_position = transponder[5]
394 parm.system = 0 # FIXMEE !! HARDCODED DVB-S (add support for DVB-S2)
395 parm.modulation = 1 # FIXMEE !! HARDCODED QPSK
396 feparm = eDVBFrontendParameters()
397 feparm.setDVBS(parm, True)
398 self.lastparm = feparm
400 self.frontend.tune(feparm)
404 self.frontend.tune(self.lastparm)
406 def getTransponderData(self):
408 return self.frontend.readTransponderData(True)
413 class TunerScreen(ScanSetup):
415 <screen position="90,100" size="520,400" title="Tune">
416 <widget name="config" position="20,10" size="460,350" scrollbarMode="showOnDemand" />
417 <widget name="introduction" position="20,360" size="350,30" font="Regular;23" />
420 def __init__(self, session, feid):
422 ScanSetup.__init__(self, session)
423 self["introduction"].setText("")
425 def createSetup(self):
426 self.typeOfTuningEntry = None
429 self.typeOfTuningEntry = getConfigListEntry(_('Tune'), tuning.type)
430 self.list.append(self.typeOfTuningEntry)
431 self.satEntry = getConfigListEntry(_('Satellite'), tuning.sat)
432 self.list.append(self.satEntry)
433 if tuning.type.value == "manual_transponder":
434 self.list.append(getConfigListEntry(_('Frequency'), self.scan_sat.frequency))
435 self.list.append(getConfigListEntry(_('Inversion'), self.scan_sat.inversion))
436 self.list.append(getConfigListEntry(_('Symbol Rate'), self.scan_sat.symbolrate))
437 self.list.append(getConfigListEntry(_("Polarity"), self.scan_sat.polarization))
438 self.list.append(getConfigListEntry(_("FEC"), self.scan_sat.fec))
439 elif tuning.type.value == "predefined_transponder":
440 self.list.append(getConfigListEntry(_("Transponder"), tuning.transponder))
441 self["config"].list = self.list
442 self["config"].l.setList(self.list)
445 if self["config"].getCurrent() == self.typeOfTuningEntry:
447 elif self["config"].getCurrent() == self.satEntry:
450 def createConfig(self, foo):
453 tuning = ConfigSubsection()
454 tuning.type = ConfigSelection(
455 default = "manual_transponder",
456 choices = { "manual_transponder" : _("Manual transponder"),
457 "predefined_transponder" : _("Predefined transponder") } )
458 tuning.sat = ConfigSatlist(list=nimmanager.getRotorSatListForNim(self.feid))
459 tuning.sat.addNotifier(self.tuningSatChanged)
460 self.updateTransponders()
461 TunerScreenConfigCreated = True
462 ScanSetup.createConfig(self, None)
464 def tuningSatChanged(self, *parm):
465 self.updateTransponders()
467 def updateTransponders(self):
468 if len(tuning.sat.choices):
469 transponderlist = nimmanager.getTransponders(int(tuning.sat.value))
472 for x in transponderlist:
497 tps.append(str(x[1]) + "," + str(x[2]) + "," + pol + "," + fec)
498 tuning.transponder = ConfigSelection(choices=tps)
501 returnvalue = (0, 0, 0, 0, 0, 0)
502 satpos = int(tuning.sat.value)
503 if tuning.type.value == "manual_transponder":
505 self.scan_sat.frequency.value,
506 self.scan_sat.symbolrate.value,
507 self.scan_sat.polarization.index,
508 self.scan_sat.fec.index,
509 self.scan_sat.inversion.index,
511 elif tuning.type.value == "predefined_transponder":
512 transponder = nimmanager.getTransponders(satpos)[tuning.transponder.index]
513 returnvalue = (int(transponder[1] / 1000), int(transponder[2] / 1000), transponder[3], transponder[4], 2, satpos)
514 self.close(returnvalue)
519 class NimSelection(Screen):
521 <screen position="140,165" size="400,100" title="select Slot">
522 <widget name="nimlist" position="20,10" size="360,75" />
525 def __init__(self, session):
526 Screen.__init__(self, session)
528 nimlist = nimmanager.getNimListOfType(nimmanager.nimType["DVB-S"])
531 nimMenuList.append((_("NIM ") + (["A", "B", "C", "D"][x]) + ": " + nimmanager.getNimName(x) + " (" + nimmanager.getNimTypeName(x) + ")", x))
533 self["nimlist"] = MenuList(nimMenuList)
535 self["actions"] = ActionMap(["OkCancelActions"],
537 "ok": self.okbuttonClick ,
541 def okbuttonClick(self):
542 selection = self["nimlist"].getCurrent()
543 self.session.open(PositionerSetup, selection[1])
545 def PositionerMain(session, **kwargs):
546 nimList = nimmanager.getNimListOfType(nimmanager.nimType["DVB-S"])
547 if len(nimList) == 0:
548 session.open(MessageBox, _("No positioner capable frontend found."), MessageBox.TYPE_ERROR)
550 if session.nav.RecordTimer.isRecording():
551 session.open(MessageBox, _("A recording is currently running. Please stop the recording before trying to configure the positioner."), MessageBox.TYPE_ERROR)
555 configured_rotor_sats = nimmanager.getRotorSatListForNim(x)
556 if len(configured_rotor_sats) != 0:
558 if len(usableNims) == 1:
559 session.open(PositionerSetup, usableNims[0])
560 elif len(usableNims) > 1:
561 session.open(NimSelection)
563 session.open(MessageBox, _("No tuner is configured for use with a diseqc positioner!"), MessageBox.TYPE_ERROR)
565 def PositionerSetupStart(menuid):
567 return [(_("Positioner setup"), PositionerMain)]
571 def Plugins(**kwargs):
572 return PluginDescriptor(name=_("Positioner setup"), description="Setup your positioner", where = PluginDescriptor.WHERE_SETUP, fnc=PositionerSetupStart)