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,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 = transponder[6]
392 parm.modulation = transponder[7]
393 parm.rolloff = transponder[8]
394 parm.pilot = transponder[9]
395 feparm = eDVBFrontendParameters()
396 feparm.setDVBS(parm, True)
397 self.lastparm = feparm
399 self.frontend.tune(feparm)
403 self.frontend.tune(self.lastparm)
405 def getTransponderData(self):
408 self.frontend.getTransponderData(ret, True)
413 class TunerScreen(ScanSetup):
415 <screen position="90,100" size="520,400" title="Tune">
416 <widget name="config" position="20,10" size="460,350" scrollbarMode="showOnDemand" />
417 <widget name="introduction" position="20,360" size="350,30" font="Regular;23" />
420 def __init__(self, session, feid):
422 ScanSetup.__init__(self, session)
423 self["introduction"].setText("")
425 def createSetup(self):
426 self.typeOfTuningEntry = None
429 self.typeOfTuningEntry = getConfigListEntry(_('Tune'), tuning.type)
430 self.list.append(self.typeOfTuningEntry)
431 self.satEntry = getConfigListEntry(_('Satellite'), tuning.sat)
432 self.list.append(self.satEntry)
433 nim = nimmanager.nim_slots[self.feid]
434 self.systemEntry = None
436 if tuning.type.value == "manual_transponder":
437 if nim.isCompatible("DVB-S2"):
438 self.systemEntry = getConfigListEntry(_('System'), self.scan_sat.system)
439 self.list.append(self.systemEntry)
441 # downgrade to dvb-s, in case a -s2 config was active
442 self.scan_sat.system.value = "dvb-s"
443 self.list.append(getConfigListEntry(_('Frequency'), self.scan_sat.frequency))
444 self.list.append(getConfigListEntry(_('Inversion'), self.scan_sat.inversion))
445 self.list.append(getConfigListEntry(_('Symbol Rate'), self.scan_sat.symbolrate))
446 self.list.append(getConfigListEntry(_("Polarity"), self.scan_sat.polarization))
447 if self.scan_sat.system.value == "dvb-s":
448 self.list.append(getConfigListEntry(_("FEC"), self.scan_sat.fec))
449 elif self.scan_sat.system.value == "dvb-s2":
450 self.list.append(getConfigListEntry(_("FEC"), self.scan_sat.fec_s2))
451 self.modulationEntry = getConfigListEntry(_('Modulation'), self.scan_sat.modulation)
452 self.list.append(self.modulationEntry)
453 self.list.append(getConfigListEntry(_('Rolloff'), self.scan_sat.rolloff))
454 self.list.append(getConfigListEntry(_('Pilot'), self.scan_sat.pilot))
455 elif tuning.type.value == "predefined_transponder":
456 self.list.append(getConfigListEntry(_("Transponder"), tuning.transponder))
457 self["config"].list = self.list
458 self["config"].l.setList(self.list)
461 if self["config"].getCurrent() in (self.typeOfTuningEntry, self.satEntry, self.systemEntry):
464 def createConfig(self, foo):
467 tuning = ConfigSubsection()
468 tuning.type = ConfigSelection(
469 default = "manual_transponder",
470 choices = { "manual_transponder" : _("Manual transponder"),
471 "predefined_transponder" : _("Predefined transponder") } )
472 tuning.sat = ConfigSatlist(list=nimmanager.getRotorSatListForNim(self.feid))
473 tuning.sat.addNotifier(self.tuningSatChanged)
474 self.updateTransponders()
475 TunerScreenConfigCreated = True
476 ScanSetup.createConfig(self, None)
478 def tuningSatChanged(self, *parm):
479 self.updateTransponders()
481 def updateTransponders(self):
482 if len(tuning.sat.choices):
483 transponderlist = nimmanager.getTransponders(int(tuning.sat.value))
486 for x in transponderlist:
521 tps.append(str(x[1]) + "," + str(x[2]) + "," + pol + "," + fec)
522 tuning.transponder = ConfigSelection(choices=tps)
525 returnvalue = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
526 satpos = int(tuning.sat.value)
527 if tuning.type.value == "manual_transponder":
528 if self.scan_sat.system.value == "dvb-s2":
529 fec = self.scan_sat.fec_s2.value
531 fec = self.scan_sat.fec.value
533 self.scan_sat.frequency.value,
534 self.scan_sat.symbolrate.value,
535 self.scan_sat.polarization.index,
547 self.scan_sat.inversion.index,
549 self.scan_sat.system.index,
550 self.scan_sat.modulation.index,
551 self.scan_sat.rolloff.index,
552 self.scan_sat.pilot.index)
553 elif tuning.type.value == "predefined_transponder":
554 transponder = nimmanager.getTransponders(satpos)[tuning.transponder.index]
555 returnvalue = (int(transponder[1] / 1000), int(transponder[2] / 1000),
556 transponder[3], transponder[4], 2, satpos, transponder[5], transponder[6], transponder[8], transponder[9])
557 self.close(returnvalue)
562 class RotorNimSelection(Screen):
564 <screen position="140,165" size="400,130" title="select Slot">
565 <widget name="nimlist" position="20,10" size="360,75" />
568 def __init__(self, session):
569 Screen.__init__(self, session)
571 nimlist = nimmanager.getNimListOfType("DVB-S")
574 nimMenuList.append((nimmanager.nim_slots[x].friendly_full_description, x))
576 self["nimlist"] = MenuList(nimMenuList)
578 self["actions"] = ActionMap(["OkCancelActions"],
580 "ok": self.okbuttonClick ,
584 def okbuttonClick(self):
585 selection = self["nimlist"].getCurrent()
586 self.session.open(PositionerSetup, selection[1])
588 def PositionerMain(session, **kwargs):
589 nimList = nimmanager.getNimListOfType("DVB-S")
590 if len(nimList) == 0:
591 session.open(MessageBox, _("No positioner capable frontend found."), MessageBox.TYPE_ERROR)
593 if session.nav.RecordTimer.isRecording():
594 session.open(MessageBox, _("A recording is currently running. Please stop the recording before trying to configure the positioner."), MessageBox.TYPE_ERROR)
598 configured_rotor_sats = nimmanager.getRotorSatListForNim(x)
599 if len(configured_rotor_sats) != 0:
601 if len(usableNims) == 1:
602 session.open(PositionerSetup, usableNims[0])
603 elif len(usableNims) > 1:
604 session.open(RotorNimSelection)
606 session.open(MessageBox, _("No tuner is configured for use with a diseqc positioner!"), MessageBox.TYPE_ERROR)
608 def PositionerSetupStart(menuid, **kwargs):
610 return [(_("Positioner setup"), PositionerMain, "positioner_setup", None)]
614 def Plugins(**kwargs):
615 if (nimmanager.hasNimType("DVB-S")):
616 return PluginDescriptor(name=_("Positioner setup"), description="Setup your positioner", where = PluginDescriptor.WHERE_MENU, fnc=PositionerSetupStart)