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="ber" text="BER:" position="0,270" 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="ber_value" position="220,270" size="60,22" font="Regular;21" />
35 <widget name="lock_state" position="60,320" size="150,22" font="Regular;21" />
36 <widget name="snr_bar" position="60,245" size="150,22" />
37 <widget name="ber_bar" position="60,270" 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
62 self.frontendStatus = { }
64 self.diseqc = Diseqc(self.frontend)
65 self.tuner = Tuner(self.frontend)
66 self.tuner.tune((0,0,0,0,0,0))
71 self.stopOnLock = False
74 self["red"] = self.red
75 self.green = Label("")
76 self["green"] = self.green
77 self.yellow = Label("")
78 self["yellow"] = self.yellow
80 self["blue"] = self.blue
83 self["list"] = ConfigList(self.list)
88 self["lock"] = Label()
89 self["snr_percentage"] = TunerInfo(TunerInfo.SNR_PERCENTAGE, statusDict = self.frontendStatus)
90 self["ber_value"] = TunerInfo(TunerInfo.BER_VALUE, statusDict = self.frontendStatus)
91 self["snr_bar"] = TunerInfo(TunerInfo.SNR_BAR, statusDict = self.frontendStatus)
92 self["ber_bar"] = TunerInfo(TunerInfo.BER_BAR, statusDict = self.frontendStatus)
93 self["lock_state"] = TunerInfo(TunerInfo.LOCK_STATE, statusDict = self.frontendStatus)
95 self["frequency"] = Label()
96 self["symbolrate"] = Label()
99 self["frequency_value"] = Label("")
100 self["symbolrate_value"] = Label("")
101 self["fec_value"] = Label("")
103 self["actions"] = ActionMap(["DirectionActions", "OkCancelActions", "ColorActions"],
106 "cancel": self.keyCancel,
112 "green": self.greenKey,
113 "yellow": self.yellowKey,
114 "blue": self.blueKey,
117 self.updateColors("tune")
119 self.statusTimer = eTimer()
120 self.statusTimer.callback.append(self.updateStatus)
121 self.statusTimer.start(50, True)
122 self.onClose.append(self.__onClose)
125 self.session.nav.playService(self.oldref)
127 def restartPrevService(self, yesno):
138 self.session.openWithCallback(self.restartPrevService, MessageBox, _("Zap back to service before positioner setup?"), MessageBox.TYPE_YESNO)
140 self.restartPrevService(False)
142 def openFrontend(self):
143 res_mgr = eDVBResourceManager.getInstance()
145 self.raw_channel = res_mgr.allocateRawChannel(self.feid)
147 self.frontend = self.raw_channel.getFrontend()
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):
325 self.frontend.getFrontendStatus(self.frontendStatus)
326 self["snr_percentage"].update()
327 self["ber_value"].update()
328 self["snr_bar"].update()
329 self["ber_bar"].update()
330 self["lock_state"].update()
331 transponderdata = self.tuner.getTransponderData()
332 self["frequency_value"].setText(str(transponderdata.get("frequency")))
333 self["symbolrate_value"].setText(str(transponderdata.get("symbol_rate")))
334 self["fec_value"].setText(str(transponderdata.get("fec_inner")))
335 if self.frontendStatus.get("tuner_locked", 0) == 1 and self.isMoving and self.stopOnLock:
336 self.diseqccommand("stop")
337 self.isMoving = False
338 self.stopOnLock = False
339 self.updateColors(self.getCurrentConfigPath())
340 self.statusTimer.start(50, True)
342 def tune(self, transponder):
343 if transponder is not None:
344 self.tuner.tune(transponder)
347 def __init__(self, frontend):
348 self.frontend = frontend
350 def command(self, what, param = 0):
352 cmd = eDVBDiseqcCommand()
353 if what == "moveWest":
354 string = 'e03169' + ("%02x" % param)
355 elif what == "moveEast":
356 string = 'e03168' + ("%02x" % param)
357 elif what == "moveTo":
358 string = 'e0316b' + ("%02x" % param)
359 elif what == "store":
360 string = 'e0316a' + ("%02x" % param)
361 elif what == "limitOn":
363 elif what == "limitOff":
365 elif what == "limitEast":
367 elif what == "limitWest":
370 string = 'e03160' #positioner stop
372 print "diseqc command:",
374 cmd.setCommandString(string)
375 self.frontend.setTone(iDVBFrontend.toneOff)
376 sleep(0.015) # wait 15msec after disable tone
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):
410 self.frontend.getTransponderData(ret, 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:
509 tps.append(str(x[1]) + "," + str(x[2]) + "," + pol + "," + fec)
510 tuning.transponder = ConfigSelection(choices=tps)
513 returnvalue = (0, 0, 0, 0, 0, 0)
514 satpos = int(tuning.sat.value)
515 if tuning.type.value == "manual_transponder":
517 self.scan_sat.frequency.value,
518 self.scan_sat.symbolrate.value,
519 self.scan_sat.polarization.index,
520 self.scan_sat.fec.index,
521 self.scan_sat.inversion.index,
523 elif tuning.type.value == "predefined_transponder":
524 transponder = nimmanager.getTransponders(satpos)[tuning.transponder.index]
525 returnvalue = (int(transponder[1] / 1000), int(transponder[2] / 1000), transponder[3], transponder[4], 2, satpos)
526 self.close(returnvalue)
531 class RotorNimSelection(Screen):
533 <screen position="140,165" size="400,100" title="select Slot">
534 <widget name="nimlist" position="20,10" size="360,75" />
537 def __init__(self, session):
538 Screen.__init__(self, session)
540 nimlist = nimmanager.getNimListOfType("DVB-S")
543 nimMenuList.append((nimmanager.nim_slots[x].friendly_full_description, x))
545 self["nimlist"] = MenuList(nimMenuList)
547 self["actions"] = ActionMap(["OkCancelActions"],
549 "ok": self.okbuttonClick ,
553 def okbuttonClick(self):
554 selection = self["nimlist"].getCurrent()
555 self.session.open(PositionerSetup, selection[1])
557 def PositionerMain(session, **kwargs):
558 nimList = nimmanager.getNimListOfType("DVB-S")
559 if len(nimList) == 0:
560 session.open(MessageBox, _("No positioner capable frontend found."), MessageBox.TYPE_ERROR)
562 if session.nav.RecordTimer.isRecording():
563 session.open(MessageBox, _("A recording is currently running. Please stop the recording before trying to configure the positioner."), MessageBox.TYPE_ERROR)
567 configured_rotor_sats = nimmanager.getRotorSatListForNim(x)
568 if len(configured_rotor_sats) != 0:
570 if len(usableNims) == 1:
571 session.open(PositionerSetup, usableNims[0])
572 elif len(usableNims) > 1:
573 session.open(RotorNimSelection)
575 session.open(MessageBox, _("No tuner is configured for use with a diseqc positioner!"), MessageBox.TYPE_ERROR)
577 def PositionerSetupStart(menuid, **kwargs):
579 return [(_("Positioner setup"), PositionerMain, "positioner_setup", None)]
583 def Plugins(**kwargs):
584 if (nimmanager.hasNimType("DVB-S")):
585 return PluginDescriptor(name=_("Positioner setup"), description="Setup your positioner", where = PluginDescriptor.WHERE_MENU, fnc=PositionerSetupStart)