1 from enigma import eTimer, eDVBSatelliteEquipmentControl, eDVBResourceManager, eDVBDiseqcCommand, eDVBResourceManagerPtr, iDVBChannelPtr, iDVBFrontendPtr, iDVBFrontend, eDVBFrontendParametersSatellite, eDVBFrontendParameters
2 from Screens.Screen import Screen
3 from Screens.ScanSetup import ScanSetup
4 from Screens.MessageBox import MessageBox
5 from Plugins.Plugin import PluginDescriptor
7 from Components.Label import Label
8 from Components.ConfigList import ConfigList
9 from Components.TunerInfo import TunerInfo
10 from Components.ActionMap import ActionMap
11 from Components.NimManager import nimmanager
12 from Components.MenuList import MenuList
13 from Components.config import ConfigSatlist, ConfigNothing, ConfigSelection, ConfigSubsection, KEY_LEFT, KEY_RIGHT, getConfigListEntry
15 from time import sleep
17 class PositionerSetup(Screen):
19 <screen position="100,100" size="560,400" title="Positioner setup..." >
20 <widget name="list" position="100,0" size="350,155" />
22 <widget name="red" position="0,155" size="140,80" backgroundColor="red" halign="center" valign="center" font="Regular;21" />
23 <widget name="green" position="140,155" size="140,80" backgroundColor="green" halign="center" valign="center" font="Regular;21" />
24 <widget name="yellow" position="280,155" size="140,80" backgroundColor="yellow" halign="center" valign="center" font="Regular;21" />
25 <widget name="blue" position="420,155" size="140,80" backgroundColor="blue" halign="center" valign="center" font="Regular;21" />
27 <widget name="snr" text="SNR:" position="0,245" size="60,22" font="Regular;21" />
28 <widget name="agc" text="AGC:" position="0,270" size="60,22" font="Regular;21" />
29 <widget name="ber" text="BER:" position="0,295" size="60,22" font="Regular;21" />
30 <widget name="lock" text="Lock:" position="0,320" size="60,22" font="Regular;21" />
31 <widget name="snr_percentage" position="220,245" size="60,22" font="Regular;21" />
32 <widget name="agc_percentage" position="220,270" size="60,22" font="Regular;21" />
33 <widget name="ber_value" position="220,295" size="60,22" font="Regular;21" />
34 <widget name="lock_state" position="60,320" size="150,22" font="Regular;21" />
35 <widget name="snr_bar" position="60,245" size="150,22" />
36 <widget name="agc_bar" position="60,270" size="150,22" />
37 <widget name="ber_bar" position="60,295" size="150,22" />
39 <widget name="frequency" text="Frequency:" position="300,245" size="120,22" font="Regular;21" />
40 <widget name="symbolrate" text="Symbolrate:" position="300,270" size="120,22" font="Regular;21" />
41 <widget name="fec" text="FEC:" position="300,295" size="120,22" font="Regular;21" />
42 <widget name="frequency_value" position="420,245" size="120,22" font="Regular;21" />
43 <widget name="symbolrate_value" position="420,270" size="120,22" font="Regular;21" />
44 <widget name="fec_value" position="420,295" size="120,22" font="Regular;21" />
46 def __init__(self, session, feid):
47 self.skin = PositionerSetup.skin
48 Screen.__init__(self, session)
52 if not self.openFrontend():
53 self.oldref = session.nav.getCurrentlyPlayingServiceReference()
54 session.nav.stopService() # try to disable foreground service
55 if not self.openFrontend():
56 if session.pipshown: # try to disable pip
57 session.pipshown = False
59 if not self.openFrontend():
60 self.frontend = None # in normal case this should not happen
61 self.getFrontend = None
63 self.diseqc = Diseqc(self.frontend)
64 self.tuner = Tuner(self.frontend)
65 self.tuner.tune((0,0,0,0,0,0))
70 self.stopOnLock = False
73 self["red"] = self.red
74 self.green = Label("")
75 self["green"] = self.green
76 self.yellow = Label("")
77 self["yellow"] = self.yellow
79 self["blue"] = self.blue
82 self["list"] = ConfigList(self.list)
88 self["lock"] = Label()
89 self["snr_percentage"] = TunerInfo(TunerInfo.SNR_PERCENTAGE, frontendfkt = self.getFrontend)
90 self["agc_percentage"] = TunerInfo(TunerInfo.AGC_PERCENTAGE, frontendfkt = self.getFrontend)
91 self["ber_value"] = TunerInfo(TunerInfo.BER_VALUE, frontendfkt = self.getFrontend)
92 self["snr_bar"] = TunerInfo(TunerInfo.SNR_BAR, frontendfkt = self.getFrontend)
93 self["agc_bar"] = TunerInfo(TunerInfo.AGC_BAR, frontendfkt = self.getFrontend)
94 self["ber_bar"] = TunerInfo(TunerInfo.BER_BAR, frontendfkt = self.getFrontend)
95 self["lock_state"] = TunerInfo(TunerInfo.LOCK_STATE, frontendfkt = self.getFrontend)
97 self["frequency"] = Label()
98 self["symbolrate"] = Label()
101 self["frequency_value"] = Label("")
102 self["symbolrate_value"] = Label("")
103 self["fec_value"] = Label("")
105 self["actions"] = ActionMap(["DirectionActions", "OkCancelActions", "ColorActions"],
108 "cancel": self.keyCancel,
114 "green": self.greenKey,
115 "yellow": self.yellowKey,
116 "blue": self.blueKey,
119 self.updateColors("tune")
121 self.statusTimer = eTimer()
122 self.statusTimer.timeout.get().append(self.updateStatus)
123 self.statusTimer.start(50, False)
125 def restartPrevService(self, yesno):
130 self.session.nav.playService(self.oldref)
135 self.session.openWithCallback(self.restartPrevService, MessageBox, _("Zap back to service before positioner setup?"), MessageBox.TYPE_YESNO)
137 self.restartPrevService(False)
139 def getFrontend(self):
142 def openFrontend(self):
143 res_mgr = eDVBResourceManagerPtr()
144 if eDVBResourceManager.getInstance(res_mgr) == 0:
145 self.raw_channel = iDVBChannelPtr()
146 if res_mgr.allocateRawChannel(self.raw_channel, self.feid) == 0:
147 self.frontend = iDVBFrontendPtr()
148 if self.raw_channel.getFrontend(self.frontend) == 0:
151 print "getFrontend failed"
153 print "getRawChannel failed"
155 print "getResourceManager instance failed"
158 def createConfig(self):
159 self.positioner_tune = ConfigNothing()
160 self.positioner_move = ConfigNothing()
161 self.positioner_finemove = ConfigNothing()
162 self.positioner_limits = ConfigNothing()
163 self.positioner_goto0 = ConfigNothing()
165 for x in range(1,255):
166 storepos.append(str(x))
167 self.positioner_storage = ConfigSelection(choices = storepos)
169 def createSetup(self):
170 self.list.append((_("Tune"), self.positioner_tune, "tune"))
171 self.list.append((_("Positioner movement"), self.positioner_move, "move"))
172 self.list.append((_("Positioner fine movement"), self.positioner_finemove, "finemove"))
173 self.list.append((_("Set limits"), self.positioner_limits, "limits"))
174 self.list.append((_("Positioner storage"), self.positioner_storage, "storage"))
175 self.list.append((_("Goto 0"), self.positioner_goto0, "goto0"))
176 self["list"].l.setList(self.list)
181 def getCurrentConfigPath(self):
182 return self["list"].getCurrent()[2]
185 if not self.isMoving:
186 self["list"].instance.moveSelection(self["list"].instance.moveUp)
187 self.updateColors(self.getCurrentConfigPath())
190 if not self.isMoving:
191 self["list"].instance.moveSelection(self["list"].instance.moveDown)
192 self.updateColors(self.getCurrentConfigPath())
195 self["list"].handleKey(KEY_LEFT)
198 self["list"].handleKey(KEY_RIGHT)
200 def updateColors(self, entry):
202 self.red.setText(_("Tune"))
203 self.green.setText("")
204 self.yellow.setText("")
205 self.blue.setText("")
206 elif entry == "move":
208 self.red.setText(_("Stop"))
209 self.green.setText(_("Stop"))
210 self.yellow.setText(_("Stop"))
211 self.blue.setText(_("Stop"))
213 self.red.setText(_("Move west"))
214 self.green.setText(_("Search west"))
215 self.yellow.setText(_("Search east"))
216 self.blue.setText(_("Move east"))
217 elif entry == "finemove":
219 self.green.setText(_("Step west"))
220 self.yellow.setText(_("Step east"))
221 self.blue.setText("")
222 elif entry == "limits":
223 self.red.setText(_("Limits off"))
224 self.green.setText(_("Limit west"))
225 self.yellow.setText(_("Limit east"))
226 self.blue.setText(_("Limits on"))
227 elif entry == "storage":
229 self.green.setText(_("Store position"))
230 self.yellow.setText(_("Goto position"))
231 self.blue.setText("")
232 elif entry == "goto0":
233 self.red.setText(_("Goto 0"))
234 self.green.setText("")
235 self.yellow.setText("")
236 self.blue.setText("")
239 self.green.setText("")
240 self.yellow.setText("")
241 self.blue.setText("")
244 entry = self.getCurrentConfigPath()
247 self.diseqccommand("stop")
248 self.isMoving = False
249 self.stopOnLock = False
251 self.diseqccommand("moveWest", 0)
253 self.updateColors("move")
254 elif entry == "limits":
255 self.diseqccommand("limitOff")
256 elif entry == "tune":
257 self.session.openWithCallback(self.tune, TunerScreen, self.feid)
258 elif entry == "goto0":
259 print "move to position 0"
260 self.diseqccommand("moveTo", 0)
263 entry = self.getCurrentConfigPath()
266 self.diseqccommand("stop")
267 self.isMoving = False
268 self.stopOnLock = False
271 self.stopOnLock = True
272 self.diseqccommand("moveWest", 0)
273 self.updateColors("move")
274 elif entry == "finemove":
275 print "stepping west"
276 self.diseqccommand("moveWest", 0xFF) # one step
277 elif entry == "storage":
278 print "store at position", int(self.positioner_storage.value)
279 self.diseqccommand("store", int(self.positioner_storage.value))
280 elif entry == "limits":
281 self.diseqccommand("limitWest")
284 entry = self.getCurrentConfigPath()
287 self.diseqccommand("stop")
288 self.isMoving = False
289 self.stopOnLock = False
292 self.stopOnLock = True
293 self.diseqccommand("moveEast", 0)
294 self.updateColors("move")
295 elif entry == "finemove":
296 print "stepping east"
297 self.diseqccommand("moveEast", 0xFF) # one step
298 elif entry == "storage":
299 print "move to position", int(self.positioner_storage.value)
300 self.diseqccommand("moveTo", int(self.positioner_storage.value))
301 elif entry == "limits":
302 self.diseqccommand("limitEast")
305 entry = self.getCurrentConfigPath()
308 self.diseqccommand("stop")
309 self.isMoving = False
310 self.stopOnLock = False
312 self.diseqccommand("moveEast", 0)
314 self.updateColors("move")
316 elif entry == "limits":
317 self.diseqccommand("limitOn")
319 def diseqccommand(self, cmd, param = 0):
320 self.diseqc.command(cmd, param)
323 def updateStatus(self):
324 self["snr_percentage"].update()
325 self["agc_percentage"].update()
326 self["ber_value"].update()
327 self["snr_bar"].update()
328 self["agc_bar"].update()
329 self["ber_bar"].update()
330 self["lock_state"].update()
331 transponderdata = self.tuner.getTransponderData()
332 self["frequency_value"].setText(str(transponderdata["frequency"]))
333 self["symbolrate_value"].setText(str(transponderdata["symbol_rate"]))
334 self["fec_value"].setText(str(transponderdata["fec_inner"]))
335 if transponderdata["tuner_locked"] == 1 and self.isMoving and self.stopOnLock:
336 self.diseqccommand("stop")
337 self.isMoving = False
338 self.stopOnLock = False
339 self.updateColors(self.getCurrentConfigPath())
341 def tune(self, transponder):
342 if transponder is not None:
343 self.tuner.tune(transponder)
346 def __init__(self, frontend):
347 self.frontend = frontend
349 def command(self, what, param = 0):
351 cmd = eDVBDiseqcCommand()
352 if what == "moveWest":
353 string = 'e03169' + ("%02x" % param)
354 elif what == "moveEast":
355 string = 'e03168' + ("%02x" % param)
356 elif what == "moveTo":
357 string = 'e0316b' + ("%02x" % param)
358 elif what == "store":
359 string = 'e0316a' + ("%02x" % param)
360 elif what == "limitOn":
362 elif what == "limitOff":
364 elif what == "limitEast":
366 elif what == "limitWest":
369 string = 'e03160' #positioner stop
371 print "diseqc command:",
373 cmd.setCommandString(string)
374 self.frontend.sendDiseqc(cmd)
375 if string == 'e03160': #positioner stop
377 self.frontend.sendDiseqc(cmd) # send 2nd time
380 def __init__(self, frontend):
381 self.frontend = frontend
383 def tune(self, transponder):
384 print "tuning to transponder with data", transponder
385 parm = eDVBFrontendParametersSatellite()
386 parm.frequency = transponder[0] * 1000
387 parm.symbol_rate = transponder[1] * 1000
388 parm.polarisation = transponder[2]
389 parm.fec = transponder[3]
390 parm.inversion = transponder[4]
391 parm.orbital_position = transponder[5]
392 parm.system = 0 # FIXMEE !! HARDCODED DVB-S (add support for DVB-S2)
393 parm.modulation = 1 # FIXMEE !! HARDCODED QPSK
394 feparm = eDVBFrontendParameters()
395 feparm.setDVBS(parm, True)
396 self.lastparm = feparm
398 self.frontend.tune(feparm)
402 self.frontend.tune(self.lastparm)
404 def getTransponderData(self):
406 return self.frontend.readTransponderData(True)
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):
420 ScanSetup.__init__(self, session)
421 self["introduction"].setText("")
423 def createSetup(self):
424 self.typeOfTuningEntry = None
427 self.typeOfTuningEntry = getConfigListEntry(_('Tune'), tuning.type)
428 self.list.append(self.typeOfTuningEntry)
429 self.satEntry = getConfigListEntry(_('Satellite'), tuning.sat)
430 self.list.append(self.satEntry)
431 if tuning.type.value == "manual_transponder":
432 self.list.append(getConfigListEntry(_('Frequency'), self.scan_sat.frequency))
433 self.list.append(getConfigListEntry(_('Inversion'), self.scan_sat.inversion))
434 self.list.append(getConfigListEntry(_('Symbol Rate'), self.scan_sat.symbolrate))
435 self.list.append(getConfigListEntry(_("Polarity"), self.scan_sat.polarization))
436 self.list.append(getConfigListEntry(_("FEC"), self.scan_sat.fec))
437 elif tuning.type.value == "predefined_transponder":
438 self.list.append(getConfigListEntry(_("Transponder"), tuning.transponder))
439 self["config"].list = self.list
440 self["config"].l.setList(self.list)
443 if self["config"].getCurrent() == self.typeOfTuningEntry:
445 elif self["config"].getCurrent() == self.satEntry:
448 def createConfig(self, foo):
451 tuning = ConfigSubsection()
452 tuning.type = ConfigSelection(
453 default = "manual_transponder",
454 choices = { "manual_transponder" : _("Manual transponder"),
455 "predefined_transponder" : _("Predefined transponder") } )
456 tuning.sat = ConfigSatlist(list=nimmanager.getRotorSatListForNim(self.feid))
457 tuning.sat.addNotifier(self.tuningSatChanged)
458 self.updateTransponders()
459 TunerScreenConfigCreated = True
460 ScanSetup.createConfig(self, None)
462 def tuningSatChanged(self, *parm):
463 self.updateTransponders()
465 def updateTransponders(self):
466 if len(tuning.sat.choices):
467 transponderlist = nimmanager.getTransponders(int(tuning.sat.value))
470 for x in transponderlist:
495 tps.append(str(x[1]) + "," + str(x[2]) + "," + pol + "," + fec)
496 tuning.transponder = ConfigSelection(choices=tps)
499 returnvalue = (0, 0, 0, 0, 0, 0)
500 satpos = int(tuning.sat.value)
501 if tuning.type.value == "manual_transponder":
503 self.scan_sat.frequency.value,
504 self.scan_sat.symbolrate.value,
505 self.scan_sat.polarization.index,
506 self.scan_sat.fec.index,
507 self.scan_sat.inversion.index,
509 elif tuning.type.value == "predefined_transponder":
510 transponder = nimmanager.getTransponders(satpos)[tuning.transponder.index]
511 returnvalue = (int(transponder[1] / 1000), int(transponder[2] / 1000), transponder[3], transponder[4], 2, satpos)
512 self.close(returnvalue)
517 class NimSelection(Screen):
519 <screen position="140,165" size="400,100" title="select Slot">
520 <widget name="nimlist" position="20,10" size="360,75" />
523 def __init__(self, session):
524 Screen.__init__(self, session)
526 nimlist = nimmanager.getNimListOfType(nimmanager.nimType["DVB-S"])
529 nimMenuList.append((_("NIM ") + (["A", "B", "C", "D"][x]) + ": " + nimmanager.getNimName(x) + " (" + nimmanager.getNimTypeName(x) + ")", x))
531 self["nimlist"] = MenuList(nimMenuList)
533 self["actions"] = ActionMap(["OkCancelActions"],
535 "ok": self.okbuttonClick ,
539 def okbuttonClick(self):
540 selection = self["nimlist"].getCurrent()
541 self.session.open(PositionerSetup, selection[1])
543 def PositionerMain(session, **kwargs):
544 nimList = nimmanager.getNimListOfType(nimmanager.nimType["DVB-S"])
545 if len(nimList) == 0:
546 session.open(MessageBox, _("No positioner capable frontend found."), MessageBox.TYPE_ERROR)
548 if session.nav.RecordTimer.isRecording():
549 session.open(MessageBox, _("A recording is currently running. Please stop the recording before trying to configure the positioner."), MessageBox.TYPE_ERROR)
553 configured_rotor_sats = nimmanager.getRotorSatListForNim(x)
554 if len(configured_rotor_sats) != 0:
556 if len(usableNims) == 1:
557 session.open(PositionerSetup, usableNims[0])
558 elif len(usableNims) > 1:
559 session.open(NimSelection)
561 session.open(MessageBox, _("No tuner is configured for use with a diseqc positioner!"), MessageBox.TYPE_ERROR)
563 def PositionerSetupStart(menuid):
565 return [(_("Positioner setup"), PositionerMain)]
569 def Plugins(**kwargs):
570 return PluginDescriptor(name=_("Positioner setup"), description="Setup your positioner", where = PluginDescriptor.WHERE_SETUP, fnc=PositionerSetupStart)