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
18 from time import sleep
20 class PositionerSetup(Screen):
22 <screen position="100,100" size="560,400" title="Positioner setup..." >
23 <widget name="list" position="100,0" size="350,155" />
25 <widget name="red" position="0,155" size="140,80" backgroundColor="red" halign="center" valign="center" font="Regular;21" />
26 <widget name="green" position="140,155" size="140,80" backgroundColor="green" halign="center" valign="center" font="Regular;21" />
27 <widget name="yellow" position="280,155" size="140,80" backgroundColor="yellow" halign="center" valign="center" font="Regular;21" />
28 <widget name="blue" position="420,155" size="140,80" backgroundColor="blue" halign="center" valign="center" font="Regular;21" />
30 <widget name="snr" text="SNR:" position="0,245" size="60,22" font="Regular;21" />
31 <widget name="agc" text="AGC:" position="0,270" size="60,22" font="Regular;21" />
32 <widget name="ber" text="BER:" position="0,295" size="60,22" font="Regular;21" />
33 <widget name="lock" text="Lock:" position="0,320" size="60,22" font="Regular;21" />
34 <widget name="snr_percentage" position="220,245" size="60,22" font="Regular;21" />
35 <widget name="agc_percentage" position="220,270" size="60,22" font="Regular;21" />
36 <widget name="ber_value" position="220,295" size="60,22" font="Regular;21" />
37 <widget name="lock_state" position="60,320" size="150,22" font="Regular;21" />
38 <widget name="snr_bar" position="60,245" size="150,22" />
39 <widget name="agc_bar" position="60,270" size="150,22" />
40 <widget name="ber_bar" position="60,295" size="150,22" />
42 <widget name="frequency" text="Frequency:" position="300,245" size="120,22" font="Regular;21" />
43 <widget name="symbolrate" text="Symbolrate:" position="300,270" size="120,22" font="Regular;21" />
44 <widget name="fec" 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)
55 if not self.openFrontend():
56 self.oldref = session.nav.getCurrentlyPlayingServiceReference()
57 session.nav.stopService() # try to disable foreground service
58 if not self.openFrontend():
59 if session.pipshown: # try to disable pip
60 session.pipshown = False
62 if not self.openFrontend():
63 self.frontend = None # in normal case this should not happen
64 self.getFrontend = None
66 self.diseqc = Diseqc(self.frontend)
67 self.tuner = Tuner(self.frontend)
68 self.tuner.tune((0,0,0,0,0,0))
73 self.stopOnLock = False
76 self["red"] = self.red
77 self.green = Label("")
78 self["green"] = self.green
79 self.yellow = Label("")
80 self["yellow"] = self.yellow
82 self["blue"] = self.blue
85 self["list"] = ConfigList(self.list)
91 self["lock"] = Label()
92 self["snr_percentage"] = TunerInfo(TunerInfo.SNR_PERCENTAGE, frontendfkt = self.getFrontend)
93 self["agc_percentage"] = TunerInfo(TunerInfo.AGC_PERCENTAGE, frontendfkt = self.getFrontend)
94 self["ber_value"] = TunerInfo(TunerInfo.BER_VALUE, frontendfkt = self.getFrontend)
95 self["snr_bar"] = TunerInfo(TunerInfo.SNR_BAR, frontendfkt = self.getFrontend)
96 self["agc_bar"] = TunerInfo(TunerInfo.AGC_BAR, frontendfkt = self.getFrontend)
97 self["ber_bar"] = TunerInfo(TunerInfo.BER_BAR, frontendfkt = self.getFrontend)
98 self["lock_state"] = TunerInfo(TunerInfo.LOCK_STATE, frontendfkt = self.getFrontend)
100 self["frequency"] = Label()
101 self["symbolrate"] = Label()
102 self["fec"] = Label()
104 self["frequency_value"] = Label("")
105 self["symbolrate_value"] = Label("")
106 self["fec_value"] = Label("")
108 self["actions"] = ActionMap(["DirectionActions", "OkCancelActions", "ColorActions"],
111 "cancel": self.keyCancel,
117 "green": self.greenKey,
118 "yellow": self.yellowKey,
119 "blue": self.blueKey,
122 self.updateColors("tune")
124 self.statusTimer = eTimer()
125 self.statusTimer.timeout.get().append(self.updateStatus)
126 self.statusTimer.start(50, False)
128 def restartPrevService(self, yesno):
133 self.session.nav.playService(self.oldref)
138 self.session.openWithCallback(self.restartPrevService, MessageBox, _("Zap back to service before positioner setup?"), MessageBox.TYPE_YESNO)
140 self.restartPrevService(False)
142 def getFrontend(self):
145 def openFrontend(self):
146 res_mgr = eDVBResourceManager.getInstance()
148 self.raw_channel = res_mgr.allocateRawChannel(self.feid)
150 self.frontend = self.raw_channel.getFrontend()
154 print "getFrontend failed"
156 print "getRawChannel failed"
158 print "getResourceManager instance failed"
161 def createConfig(self):
162 self.positioner_tune = ConfigNothing()
163 self.positioner_move = ConfigNothing()
164 self.positioner_finemove = ConfigNothing()
165 self.positioner_limits = ConfigNothing()
166 self.positioner_goto0 = ConfigNothing()
168 for x in range(1,255):
169 storepos.append(str(x))
170 self.positioner_storage = ConfigSelection(choices = storepos)
172 def createSetup(self):
173 self.list.append((_("Tune"), self.positioner_tune, "tune"))
174 self.list.append((_("Positioner movement"), self.positioner_move, "move"))
175 self.list.append((_("Positioner fine movement"), self.positioner_finemove, "finemove"))
176 self.list.append((_("Set limits"), self.positioner_limits, "limits"))
177 self.list.append((_("Positioner storage"), self.positioner_storage, "storage"))
178 self.list.append((_("Goto 0"), self.positioner_goto0, "goto0"))
179 self["list"].l.setList(self.list)
184 def getCurrentConfigPath(self):
185 return self["list"].getCurrent()[2]
188 if not self.isMoving:
189 self["list"].instance.moveSelection(self["list"].instance.moveUp)
190 self.updateColors(self.getCurrentConfigPath())
193 if not self.isMoving:
194 self["list"].instance.moveSelection(self["list"].instance.moveDown)
195 self.updateColors(self.getCurrentConfigPath())
198 self["list"].handleKey(KEY_LEFT)
201 self["list"].handleKey(KEY_RIGHT)
203 def updateColors(self, entry):
205 self.red.setText(_("Tune"))
206 self.green.setText("")
207 self.yellow.setText("")
208 self.blue.setText("")
209 elif entry == "move":
211 self.red.setText(_("Stop"))
212 self.green.setText(_("Stop"))
213 self.yellow.setText(_("Stop"))
214 self.blue.setText(_("Stop"))
216 self.red.setText(_("Move west"))
217 self.green.setText(_("Search west"))
218 self.yellow.setText(_("Search east"))
219 self.blue.setText(_("Move east"))
220 elif entry == "finemove":
222 self.green.setText(_("Step west"))
223 self.yellow.setText(_("Step east"))
224 self.blue.setText("")
225 elif entry == "limits":
226 self.red.setText(_("Limits off"))
227 self.green.setText(_("Limit west"))
228 self.yellow.setText(_("Limit east"))
229 self.blue.setText(_("Limits on"))
230 elif entry == "storage":
232 self.green.setText(_("Store position"))
233 self.yellow.setText(_("Goto position"))
234 self.blue.setText("")
235 elif entry == "goto0":
236 self.red.setText(_("Goto 0"))
237 self.green.setText("")
238 self.yellow.setText("")
239 self.blue.setText("")
242 self.green.setText("")
243 self.yellow.setText("")
244 self.blue.setText("")
247 entry = self.getCurrentConfigPath()
250 self.diseqccommand("stop")
251 self.isMoving = False
252 self.stopOnLock = False
254 self.diseqccommand("moveWest", 0)
256 self.updateColors("move")
257 elif entry == "limits":
258 self.diseqccommand("limitOff")
259 elif entry == "tune":
260 self.session.openWithCallback(self.tune, TunerScreen, self.feid)
261 elif entry == "goto0":
262 print "move to position 0"
263 self.diseqccommand("moveTo", 0)
266 entry = self.getCurrentConfigPath()
269 self.diseqccommand("stop")
270 self.isMoving = False
271 self.stopOnLock = False
274 self.stopOnLock = True
275 self.diseqccommand("moveWest", 0)
276 self.updateColors("move")
277 elif entry == "finemove":
278 print "stepping west"
279 self.diseqccommand("moveWest", 0xFF) # one step
280 elif entry == "storage":
281 print "store at position", int(self.positioner_storage.value)
282 self.diseqccommand("store", int(self.positioner_storage.value))
283 elif entry == "limits":
284 self.diseqccommand("limitWest")
287 entry = self.getCurrentConfigPath()
290 self.diseqccommand("stop")
291 self.isMoving = False
292 self.stopOnLock = False
295 self.stopOnLock = True
296 self.diseqccommand("moveEast", 0)
297 self.updateColors("move")
298 elif entry == "finemove":
299 print "stepping east"
300 self.diseqccommand("moveEast", 0xFF) # one step
301 elif entry == "storage":
302 print "move to position", int(self.positioner_storage.value)
303 self.diseqccommand("moveTo", int(self.positioner_storage.value))
304 elif entry == "limits":
305 self.diseqccommand("limitEast")
308 entry = self.getCurrentConfigPath()
311 self.diseqccommand("stop")
312 self.isMoving = False
313 self.stopOnLock = False
315 self.diseqccommand("moveEast", 0)
317 self.updateColors("move")
319 elif entry == "limits":
320 self.diseqccommand("limitOn")
322 def diseqccommand(self, cmd, param = 0):
323 self.diseqc.command(cmd, param)
326 def updateStatus(self):
327 self["snr_percentage"].update()
328 self["agc_percentage"].update()
329 self["ber_value"].update()
330 self["snr_bar"].update()
331 self["agc_bar"].update()
332 self["ber_bar"].update()
333 self["lock_state"].update()
334 transponderdata = self.tuner.getTransponderData()
335 self["frequency_value"].setText(str(transponderdata["frequency"]))
336 self["symbolrate_value"].setText(str(transponderdata["symbol_rate"]))
337 self["fec_value"].setText(str(transponderdata["fec_inner"]))
338 if transponderdata["tuner_locked"] == 1 and self.isMoving and self.stopOnLock:
339 self.diseqccommand("stop")
340 self.isMoving = False
341 self.stopOnLock = False
342 self.updateColors(self.getCurrentConfigPath())
344 def tune(self, transponder):
345 if transponder is not None:
346 self.tuner.tune(transponder)
349 def __init__(self, frontend):
350 self.frontend = frontend
352 def command(self, what, param = 0):
354 cmd = eDVBDiseqcCommand()
355 if what == "moveWest":
356 string = 'e03169' + ("%02x" % param)
357 elif what == "moveEast":
358 string = 'e03168' + ("%02x" % param)
359 elif what == "moveTo":
360 string = 'e0316b' + ("%02x" % param)
361 elif what == "store":
362 string = 'e0316a' + ("%02x" % param)
363 elif what == "limitOn":
365 elif what == "limitOff":
367 elif what == "limitEast":
369 elif what == "limitWest":
372 string = 'e03160' #positioner stop
374 print "diseqc command:",
376 cmd.setCommandString(string)
377 self.frontend.setTone(iDVBFrontend.toneOff)
378 sleep(0.015) # wait 15msec after disable tone
379 self.frontend.sendDiseqc(cmd)
380 if string == 'e03160': #positioner stop
382 self.frontend.sendDiseqc(cmd) # send 2nd time
385 def __init__(self, frontend):
386 self.frontend = frontend
388 def tune(self, transponder):
389 print "tuning to transponder with data", transponder
390 parm = eDVBFrontendParametersSatellite()
391 parm.frequency = transponder[0] * 1000
392 parm.symbol_rate = transponder[1] * 1000
393 parm.polarisation = transponder[2]
394 parm.fec = transponder[3]
395 parm.inversion = transponder[4]
396 parm.orbital_position = transponder[5]
397 parm.system = 0 # FIXMEE !! HARDCODED DVB-S (add support for DVB-S2)
398 parm.modulation = 1 # FIXMEE !! HARDCODED QPSK
399 feparm = eDVBFrontendParameters()
400 feparm.setDVBS(parm, True)
401 self.lastparm = feparm
403 self.frontend.tune(feparm)
407 self.frontend.tune(self.lastparm)
409 def getTransponderData(self):
411 return self.frontend.readTransponderData(True)
416 class TunerScreen(ScanSetup):
418 <screen position="90,100" size="520,400" title="Tune">
419 <widget name="config" position="20,10" size="460,350" scrollbarMode="showOnDemand" />
420 <widget name="introduction" position="20,360" size="350,30" font="Regular;23" />
423 def __init__(self, session, feid):
425 ScanSetup.__init__(self, session)
426 self["introduction"].setText("")
428 def createSetup(self):
429 self.typeOfTuningEntry = None
432 self.typeOfTuningEntry = getConfigListEntry(_('Tune'), tuning.type)
433 self.list.append(self.typeOfTuningEntry)
434 self.satEntry = getConfigListEntry(_('Satellite'), tuning.sat)
435 self.list.append(self.satEntry)
436 if tuning.type.value == "manual_transponder":
437 self.list.append(getConfigListEntry(_('Frequency'), self.scan_sat.frequency))
438 self.list.append(getConfigListEntry(_('Inversion'), self.scan_sat.inversion))
439 self.list.append(getConfigListEntry(_('Symbol Rate'), self.scan_sat.symbolrate))
440 self.list.append(getConfigListEntry(_("Polarity"), self.scan_sat.polarization))
441 self.list.append(getConfigListEntry(_("FEC"), self.scan_sat.fec))
442 elif tuning.type.value == "predefined_transponder":
443 self.list.append(getConfigListEntry(_("Transponder"), tuning.transponder))
444 self["config"].list = self.list
445 self["config"].l.setList(self.list)
448 if self["config"].getCurrent() == self.typeOfTuningEntry:
450 elif self["config"].getCurrent() == self.satEntry:
453 def createConfig(self, foo):
456 tuning = ConfigSubsection()
457 tuning.type = ConfigSelection(
458 default = "manual_transponder",
459 choices = { "manual_transponder" : _("Manual transponder"),
460 "predefined_transponder" : _("Predefined transponder") } )
461 tuning.sat = ConfigSatlist(list=nimmanager.getRotorSatListForNim(self.feid))
462 tuning.sat.addNotifier(self.tuningSatChanged)
463 self.updateTransponders()
464 TunerScreenConfigCreated = True
465 ScanSetup.createConfig(self, None)
467 def tuningSatChanged(self, *parm):
468 self.updateTransponders()
470 def updateTransponders(self):
471 if len(tuning.sat.choices):
472 transponderlist = nimmanager.getTransponders(int(tuning.sat.value))
475 for x in transponderlist:
500 tps.append(str(x[1]) + "," + str(x[2]) + "," + pol + "," + fec)
501 tuning.transponder = ConfigSelection(choices=tps)
504 returnvalue = (0, 0, 0, 0, 0, 0)
505 satpos = int(tuning.sat.value)
506 if tuning.type.value == "manual_transponder":
508 self.scan_sat.frequency.value,
509 self.scan_sat.symbolrate.value,
510 self.scan_sat.polarization.index,
511 self.scan_sat.fec.index,
512 self.scan_sat.inversion.index,
514 elif tuning.type.value == "predefined_transponder":
515 transponder = nimmanager.getTransponders(satpos)[tuning.transponder.index]
516 returnvalue = (int(transponder[1] / 1000), int(transponder[2] / 1000), transponder[3], transponder[4], 2, satpos)
517 self.close(returnvalue)
522 class NimSelection(Screen):
524 <screen position="140,165" size="400,100" title="select Slot">
525 <widget name="nimlist" position="20,10" size="360,75" />
528 def __init__(self, session):
529 Screen.__init__(self, session)
531 nimlist = nimmanager.getNimListOfType(nimmanager.nimType["DVB-S"])
534 nimMenuList.append((_("NIM ") + (["A", "B", "C", "D"][x]) + ": " + nimmanager.getNimName(x) + " (" + nimmanager.getNimTypeName(x) + ")", x))
536 self["nimlist"] = MenuList(nimMenuList)
538 self["actions"] = ActionMap(["OkCancelActions"],
540 "ok": self.okbuttonClick ,
544 def okbuttonClick(self):
545 selection = self["nimlist"].getCurrent()
546 self.session.open(PositionerSetup, selection[1])
548 def PositionerMain(session, **kwargs):
549 nimList = nimmanager.getNimListOfType(nimmanager.nimType["DVB-S"])
550 if len(nimList) == 0:
551 session.open(MessageBox, _("No positioner capable frontend found."), MessageBox.TYPE_ERROR)
553 if session.nav.RecordTimer.isRecording():
554 session.open(MessageBox, _("A recording is currently running. Please stop the recording before trying to configure the positioner."), MessageBox.TYPE_ERROR)
558 configured_rotor_sats = nimmanager.getRotorSatListForNim(x)
559 if len(configured_rotor_sats) != 0:
561 if len(usableNims) == 1:
562 session.open(PositionerSetup, usableNims[0])
563 elif len(usableNims) > 1:
564 session.open(NimSelection)
566 session.open(MessageBox, _("No tuner is configured for use with a diseqc positioner!"), MessageBox.TYPE_ERROR)
568 def PositionerSetupStart(menuid):
570 return [(_("Positioner setup"), PositionerMain)]
574 def Plugins(**kwargs):
575 return PluginDescriptor(name=_("Positioner setup"), description="Setup your positioner", where = PluginDescriptor.WHERE_SETUP, fnc=PositionerSetupStart)