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 sleep(0.015) # wait 15msec after disable tone
378 self.frontend.sendDiseqc(cmd)
379 if string == 'e03160': #positioner stop
381 self.frontend.sendDiseqc(cmd) # send 2nd time
384 def __init__(self, frontend):
385 self.frontend = frontend
387 def tune(self, transponder):
388 print "tuning to transponder with data", transponder
389 parm = eDVBFrontendParametersSatellite()
390 parm.frequency = transponder[0] * 1000
391 parm.symbol_rate = transponder[1] * 1000
392 parm.polarisation = transponder[2]
393 parm.fec = transponder[3]
394 parm.inversion = transponder[4]
395 parm.orbital_position = transponder[5]
396 parm.system = 0 # FIXMEE !! HARDCODED DVB-S (add support for DVB-S2)
397 parm.modulation = 1 # FIXMEE !! HARDCODED QPSK
398 feparm = eDVBFrontendParameters()
399 feparm.setDVBS(parm, True)
400 self.lastparm = feparm
402 self.frontend.tune(feparm)
406 self.frontend.tune(self.lastparm)
408 def getTransponderData(self):
410 return self.frontend.readTransponderData(True)
415 class TunerScreen(ScanSetup):
417 <screen position="90,100" size="520,400" title="Tune">
418 <widget name="config" position="20,10" size="460,350" scrollbarMode="showOnDemand" />
419 <widget name="introduction" position="20,360" size="350,30" font="Regular;23" />
422 def __init__(self, session, feid):
424 ScanSetup.__init__(self, session)
425 self["introduction"].setText("")
427 def createSetup(self):
428 self.typeOfTuningEntry = None
431 self.typeOfTuningEntry = getConfigListEntry(_('Tune'), tuning.type)
432 self.list.append(self.typeOfTuningEntry)
433 self.satEntry = getConfigListEntry(_('Satellite'), tuning.sat)
434 self.list.append(self.satEntry)
435 if tuning.type.value == "manual_transponder":
436 self.list.append(getConfigListEntry(_('Frequency'), self.scan_sat.frequency))
437 self.list.append(getConfigListEntry(_('Inversion'), self.scan_sat.inversion))
438 self.list.append(getConfigListEntry(_('Symbol Rate'), self.scan_sat.symbolrate))
439 self.list.append(getConfigListEntry(_("Polarity"), self.scan_sat.polarization))
440 self.list.append(getConfigListEntry(_("FEC"), self.scan_sat.fec))
441 elif tuning.type.value == "predefined_transponder":
442 self.list.append(getConfigListEntry(_("Transponder"), tuning.transponder))
443 self["config"].list = self.list
444 self["config"].l.setList(self.list)
447 if self["config"].getCurrent() == self.typeOfTuningEntry:
449 elif self["config"].getCurrent() == self.satEntry:
452 def createConfig(self, foo):
455 tuning = ConfigSubsection()
456 tuning.type = ConfigSelection(
457 default = "manual_transponder",
458 choices = { "manual_transponder" : _("Manual transponder"),
459 "predefined_transponder" : _("Predefined transponder") } )
460 tuning.sat = ConfigSatlist(list=nimmanager.getRotorSatListForNim(self.feid))
461 tuning.sat.addNotifier(self.tuningSatChanged)
462 self.updateTransponders()
463 TunerScreenConfigCreated = True
464 ScanSetup.createConfig(self, None)
466 def tuningSatChanged(self, *parm):
467 self.updateTransponders()
469 def updateTransponders(self):
470 if len(tuning.sat.choices):
471 transponderlist = nimmanager.getTransponders(int(tuning.sat.value))
474 for x in transponderlist:
499 tps.append(str(x[1]) + "," + str(x[2]) + "," + pol + "," + fec)
500 tuning.transponder = ConfigSelection(choices=tps)
503 returnvalue = (0, 0, 0, 0, 0, 0)
504 satpos = int(tuning.sat.value)
505 if tuning.type.value == "manual_transponder":
507 self.scan_sat.frequency.value,
508 self.scan_sat.symbolrate.value,
509 self.scan_sat.polarization.index,
510 self.scan_sat.fec.index,
511 self.scan_sat.inversion.index,
513 elif tuning.type.value == "predefined_transponder":
514 transponder = nimmanager.getTransponders(satpos)[tuning.transponder.index]
515 returnvalue = (int(transponder[1] / 1000), int(transponder[2] / 1000), transponder[3], transponder[4], 2, satpos)
516 self.close(returnvalue)
521 class NimSelection(Screen):
523 <screen position="140,165" size="400,100" title="select Slot">
524 <widget name="nimlist" position="20,10" size="360,75" />
527 def __init__(self, session):
528 Screen.__init__(self, session)
530 nimlist = nimmanager.getNimListOfType(nimmanager.nimType["DVB-S"])
533 nimMenuList.append((_("NIM ") + (["A", "B", "C", "D"][x]) + ": " + nimmanager.getNimName(x) + " (" + nimmanager.getNimTypeName(x) + ")", x))
535 self["nimlist"] = MenuList(nimMenuList)
537 self["actions"] = ActionMap(["OkCancelActions"],
539 "ok": self.okbuttonClick ,
543 def okbuttonClick(self):
544 selection = self["nimlist"].getCurrent()
545 self.session.open(PositionerSetup, selection[1])
547 def PositionerMain(session, **kwargs):
548 nimList = nimmanager.getNimListOfType(nimmanager.nimType["DVB-S"])
549 if len(nimList) == 0:
550 session.open(MessageBox, _("No positioner capable frontend found."), MessageBox.TYPE_ERROR)
552 if session.nav.RecordTimer.isRecording():
553 session.open(MessageBox, _("A recording is currently running. Please stop the recording before trying to configure the positioner."), MessageBox.TYPE_ERROR)
557 configured_rotor_sats = nimmanager.getRotorSatListForNim(x)
558 if len(configured_rotor_sats) != 0:
560 if len(usableNims) == 1:
561 session.open(PositionerSetup, usableNims[0])
562 elif len(usableNims) > 1:
563 session.open(NimSelection)
565 session.open(MessageBox, _("No tuner is configured for use with a diseqc positioner!"), MessageBox.TYPE_ERROR)
567 def PositionerSetupStart(menuid):
569 return [(_("Positioner setup"), PositionerMain)]
573 def Plugins(**kwargs):
574 return PluginDescriptor(name=_("Positioner setup"), description="Setup your positioner", where = PluginDescriptor.WHERE_SETUP, fnc=PositionerSetupStart)