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_db" position="60,245" size="150,22" halign="center" valign="center" font="Regular;21" />
31 <eLabel text="SNR:" position="0,270" size="60,22" font="Regular;21" />
32 <eLabel text="BER:" position="0,295" size="60,22" font="Regular;21" />
33 <eLabel text="Lock:" position="0,320" size="60,22" font="Regular;21" />
34 <widget name="snr_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,270" size="150,22" />
38 <widget name="ber_bar" position="60,295" size="150,22" />
40 <eLabel text="Frequency:" position="300,245" size="120,22" font="Regular;21" />
41 <eLabel text="Symbolrate:" position="300,270" size="120,22" font="Regular;21" />
42 <eLabel text="FEC:" position="300,295" size="120,22" font="Regular;21" />
43 <widget name="frequency_value" position="420,245" size="120,22" font="Regular;21" />
44 <widget name="symbolrate_value" position="420,270" size="120,22" font="Regular;21" />
45 <widget name="fec_value" position="420,295" size="120,22" font="Regular;21" />
47 def __init__(self, session, feid):
48 self.skin = PositionerSetup.skin
49 Screen.__init__(self, session)
53 if not self.openFrontend():
54 self.oldref = session.nav.getCurrentlyPlayingServiceReference()
55 session.nav.stopService() # try to disable foreground service
56 if not self.openFrontend():
57 if session.pipshown: # try to disable pip
58 session.pipshown = False
60 if not self.openFrontend():
61 self.frontend = None # in normal case this should not happen
63 self.frontendStatus = { }
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)
87 self["snr_db"] = TunerInfo(TunerInfo.SNR_DB, statusDict = self.frontendStatus)
88 self["snr_percentage"] = TunerInfo(TunerInfo.SNR_PERCENTAGE, statusDict = self.frontendStatus)
89 self["ber_value"] = TunerInfo(TunerInfo.BER_VALUE, statusDict = self.frontendStatus)
90 self["snr_bar"] = TunerInfo(TunerInfo.SNR_BAR, statusDict = self.frontendStatus)
91 self["ber_bar"] = TunerInfo(TunerInfo.BER_BAR, statusDict = self.frontendStatus)
92 self["lock_state"] = TunerInfo(TunerInfo.LOCK_STATE, statusDict = self.frontendStatus)
94 self["frequency_value"] = Label("")
95 self["symbolrate_value"] = Label("")
96 self["fec_value"] = Label("")
98 self["actions"] = ActionMap(["DirectionActions", "OkCancelActions", "ColorActions"],
101 "cancel": self.keyCancel,
107 "green": self.greenKey,
108 "yellow": self.yellowKey,
109 "blue": self.blueKey,
112 self.updateColors("tune")
114 self.statusTimer = eTimer()
115 self.statusTimer.callback.append(self.updateStatus)
116 self.statusTimer.start(50, True)
117 self.onClose.append(self.__onClose)
120 self.session.nav.playService(self.oldref)
122 def restartPrevService(self, yesno):
133 self.session.openWithCallback(self.restartPrevService, MessageBox, _("Zap back to service before positioner setup?"), MessageBox.TYPE_YESNO)
135 self.restartPrevService(False)
137 def openFrontend(self):
138 res_mgr = eDVBResourceManager.getInstance()
140 self.raw_channel = res_mgr.allocateRawChannel(self.feid)
142 self.frontend = self.raw_channel.getFrontend()
146 print "getFrontend failed"
148 print "getRawChannel failed"
150 print "getResourceManager instance failed"
153 def createConfig(self):
154 self.positioner_tune = ConfigNothing()
155 self.positioner_move = ConfigNothing()
156 self.positioner_finemove = ConfigNothing()
157 self.positioner_limits = ConfigNothing()
158 self.positioner_goto0 = ConfigNothing()
160 for x in range(1,255):
161 storepos.append(str(x))
162 self.positioner_storage = ConfigSelection(choices = storepos)
164 def createSetup(self):
165 self.list.append((_("Tune"), self.positioner_tune, "tune"))
166 self.list.append((_("Positioner movement"), self.positioner_move, "move"))
167 self.list.append((_("Positioner fine movement"), self.positioner_finemove, "finemove"))
168 self.list.append((_("Set limits"), self.positioner_limits, "limits"))
169 self.list.append((_("Positioner storage"), self.positioner_storage, "storage"))
170 self.list.append((_("Goto 0"), self.positioner_goto0, "goto0"))
171 self["list"].l.setList(self.list)
176 def getCurrentConfigPath(self):
177 return self["list"].getCurrent()[2]
180 if not self.isMoving:
181 self["list"].instance.moveSelection(self["list"].instance.moveUp)
182 self.updateColors(self.getCurrentConfigPath())
185 if not self.isMoving:
186 self["list"].instance.moveSelection(self["list"].instance.moveDown)
187 self.updateColors(self.getCurrentConfigPath())
190 self["list"].handleKey(KEY_LEFT)
193 self["list"].handleKey(KEY_RIGHT)
195 def updateColors(self, entry):
197 self.red.setText(_("Tune"))
198 self.green.setText("")
199 self.yellow.setText("")
200 self.blue.setText("")
201 elif entry == "move":
203 self.red.setText(_("Stop"))
204 self.green.setText(_("Stop"))
205 self.yellow.setText(_("Stop"))
206 self.blue.setText(_("Stop"))
208 self.red.setText(_("Move west"))
209 self.green.setText(_("Search west"))
210 self.yellow.setText(_("Search east"))
211 self.blue.setText(_("Move east"))
212 elif entry == "finemove":
214 self.green.setText(_("Step west"))
215 self.yellow.setText(_("Step east"))
216 self.blue.setText("")
217 elif entry == "limits":
218 self.red.setText(_("Limits off"))
219 self.green.setText(_("Limit west"))
220 self.yellow.setText(_("Limit east"))
221 self.blue.setText(_("Limits on"))
222 elif entry == "storage":
224 self.green.setText(_("Store position"))
225 self.yellow.setText(_("Goto position"))
226 self.blue.setText("")
227 elif entry == "goto0":
228 self.red.setText(_("Goto 0"))
229 self.green.setText("")
230 self.yellow.setText("")
231 self.blue.setText("")
234 self.green.setText("")
235 self.yellow.setText("")
236 self.blue.setText("")
239 entry = self.getCurrentConfigPath()
242 self.diseqccommand("stop")
243 self.isMoving = False
244 self.stopOnLock = False
246 self.diseqccommand("moveWest", 0)
248 self.updateColors("move")
249 elif entry == "limits":
250 self.diseqccommand("limitOff")
251 elif entry == "tune":
252 self.session.openWithCallback(self.tune, TunerScreen, self.feid)
253 elif entry == "goto0":
254 print "move to position 0"
255 self.diseqccommand("moveTo", 0)
258 entry = self.getCurrentConfigPath()
261 self.diseqccommand("stop")
262 self.isMoving = False
263 self.stopOnLock = False
266 self.stopOnLock = True
267 self.diseqccommand("moveWest", 0)
268 self.updateColors("move")
269 elif entry == "finemove":
270 print "stepping west"
271 self.diseqccommand("moveWest", 0xFF) # one step
272 elif entry == "storage":
273 print "store at position", int(self.positioner_storage.value)
274 self.diseqccommand("store", int(self.positioner_storage.value))
275 elif entry == "limits":
276 self.diseqccommand("limitWest")
279 entry = self.getCurrentConfigPath()
282 self.diseqccommand("stop")
283 self.isMoving = False
284 self.stopOnLock = False
287 self.stopOnLock = True
288 self.diseqccommand("moveEast", 0)
289 self.updateColors("move")
290 elif entry == "finemove":
291 print "stepping east"
292 self.diseqccommand("moveEast", 0xFF) # one step
293 elif entry == "storage":
294 print "move to position", int(self.positioner_storage.value)
295 self.diseqccommand("moveTo", int(self.positioner_storage.value))
296 elif entry == "limits":
297 self.diseqccommand("limitEast")
300 entry = self.getCurrentConfigPath()
303 self.diseqccommand("stop")
304 self.isMoving = False
305 self.stopOnLock = False
307 self.diseqccommand("moveEast", 0)
309 self.updateColors("move")
311 elif entry == "limits":
312 self.diseqccommand("limitOn")
314 def diseqccommand(self, cmd, param = 0):
315 self.diseqc.command(cmd, param)
318 def updateStatus(self):
320 self.frontend.getFrontendStatus(self.frontendStatus)
321 self["snr_db"].update()
322 self["snr_percentage"].update()
323 self["ber_value"].update()
324 self["snr_bar"].update()
325 self["ber_bar"].update()
326 self["lock_state"].update()
327 transponderdata = self.tuner.getTransponderData()
328 self["frequency_value"].setText(str(transponderdata.get("frequency")))
329 self["symbolrate_value"].setText(str(transponderdata.get("symbol_rate")))
330 self["fec_value"].setText(str(transponderdata.get("fec_inner")))
331 if self.frontendStatus.get("tuner_locked", 0) == 1 and self.isMoving and self.stopOnLock:
332 self.diseqccommand("stop")
333 self.isMoving = False
334 self.stopOnLock = False
335 self.updateColors(self.getCurrentConfigPath())
336 self.statusTimer.start(50, True)
338 def tune(self, transponder):
339 if transponder is not None:
340 self.tuner.tune(transponder)
343 def __init__(self, frontend):
344 self.frontend = frontend
346 def command(self, what, param = 0):
348 cmd = eDVBDiseqcCommand()
349 if what == "moveWest":
350 string = 'e03169' + ("%02x" % param)
351 elif what == "moveEast":
352 string = 'e03168' + ("%02x" % param)
353 elif what == "moveTo":
354 string = 'e0316b' + ("%02x" % param)
355 elif what == "store":
356 string = 'e0316a' + ("%02x" % param)
357 elif what == "limitOn":
359 elif what == "limitOff":
361 elif what == "limitEast":
363 elif what == "limitWest":
366 string = 'e03160' #positioner stop
368 print "diseqc command:",
370 cmd.setCommandString(string)
371 self.frontend.setTone(iDVBFrontend.toneOff)
372 sleep(0.015) # wait 15msec after disable tone
373 self.frontend.sendDiseqc(cmd)
374 if string == 'e03160': #positioner stop
376 self.frontend.sendDiseqc(cmd) # send 2nd time
379 def __init__(self, frontend):
380 self.frontend = frontend
382 def tune(self, transponder):
383 print "tuning to transponder with data", transponder
384 parm = eDVBFrontendParametersSatellite()
385 parm.frequency = transponder[0] * 1000
386 parm.symbol_rate = transponder[1] * 1000
387 parm.polarisation = transponder[2]
388 parm.fec = transponder[3]
389 parm.inversion = transponder[4]
390 parm.orbital_position = transponder[5]
391 parm.system = 0 # FIXMEE !! HARDCODED DVB-S (add support for DVB-S2)
392 parm.modulation = 1 # FIXMEE !! HARDCODED QPSK
393 feparm = eDVBFrontendParameters()
394 feparm.setDVBS(parm, True)
395 self.lastparm = feparm
397 self.frontend.tune(feparm)
401 self.frontend.tune(self.lastparm)
403 def getTransponderData(self):
406 self.frontend.getTransponderData(ret, 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:
505 tps.append(str(x[1]) + "," + str(x[2]) + "," + pol + "," + fec)
506 tuning.transponder = ConfigSelection(choices=tps)
509 returnvalue = (0, 0, 0, 0, 0, 0)
510 satpos = int(tuning.sat.value)
511 if tuning.type.value == "manual_transponder":
513 self.scan_sat.frequency.value,
514 self.scan_sat.symbolrate.value,
515 self.scan_sat.polarization.index,
516 self.scan_sat.fec.index,
517 self.scan_sat.inversion.index,
519 elif tuning.type.value == "predefined_transponder":
520 transponder = nimmanager.getTransponders(satpos)[tuning.transponder.index]
521 returnvalue = (int(transponder[1] / 1000), int(transponder[2] / 1000), transponder[3], transponder[4], 2, satpos)
522 self.close(returnvalue)
527 class RotorNimSelection(Screen):
529 <screen position="140,165" size="400,100" title="select Slot">
530 <widget name="nimlist" position="20,10" size="360,75" />
533 def __init__(self, session):
534 Screen.__init__(self, session)
536 nimlist = nimmanager.getNimListOfType("DVB-S")
539 nimMenuList.append((nimmanager.nim_slots[x].friendly_full_description, x))
541 self["nimlist"] = MenuList(nimMenuList)
543 self["actions"] = ActionMap(["OkCancelActions"],
545 "ok": self.okbuttonClick ,
549 def okbuttonClick(self):
550 selection = self["nimlist"].getCurrent()
551 self.session.open(PositionerSetup, selection[1])
553 def PositionerMain(session, **kwargs):
554 nimList = nimmanager.getNimListOfType("DVB-S")
555 if len(nimList) == 0:
556 session.open(MessageBox, _("No positioner capable frontend found."), MessageBox.TYPE_ERROR)
558 if session.nav.RecordTimer.isRecording():
559 session.open(MessageBox, _("A recording is currently running. Please stop the recording before trying to configure the positioner."), MessageBox.TYPE_ERROR)
563 configured_rotor_sats = nimmanager.getRotorSatListForNim(x)
564 if len(configured_rotor_sats) != 0:
566 if len(usableNims) == 1:
567 session.open(PositionerSetup, usableNims[0])
568 elif len(usableNims) > 1:
569 session.open(RotorNimSelection)
571 session.open(MessageBox, _("No tuner is configured for use with a diseqc positioner!"), MessageBox.TYPE_ERROR)
573 def PositionerSetupStart(menuid, **kwargs):
575 return [(_("Positioner setup"), PositionerMain, "positioner_setup", None)]
579 def Plugins(**kwargs):
580 if (nimmanager.hasNimType("DVB-S")):
581 return PluginDescriptor(name=_("Positioner setup"), description="Setup your positioner", where = PluginDescriptor.WHERE_MENU, fnc=PositionerSetupStart)