4.2.0r13
[enigma2.git] / usr / lib / enigma2 / python / Plugins / SystemPlugins / PositionerSetup / plugin.py
1 from enigma import eTimer, eDVBResourceManager, \
2         eDVBDiseqcCommand, eDVBFrontendParametersSatellite, \
3         iDVBFrontend
4
5 from Screens.Screen import Screen
6 from Screens.ScanSetup import ScanSetup
7 from Screens.MessageBox import MessageBox
8 from Plugins.Plugin import PluginDescriptor
9
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
17 from Components.TuneTest import Tuner
18 from Tools.Transponder import ConvertToHumanReadable
19
20 from time import sleep
21
22 class PositionerSetup(Screen):
23         skin = """
24                 <screen position="100,100" size="560,400" title="Positioner setup..." >
25                         <widget name="list" position="100,0" size="350,155" />
26
27                         <widget name="red" position="0,155" size="140,80" backgroundColor="red" halign="center" valign="center" font="Regular;21" />
28                         <widget name="green" position="140,155" size="140,80" backgroundColor="green" halign="center" valign="center" font="Regular;21" />
29                         <widget name="yellow" position="280,155" size="140,80" backgroundColor="yellow" halign="center" valign="center" font="Regular;21" />
30                         <widget name="blue" position="420,155" size="140,80" backgroundColor="blue" halign="center" valign="center" font="Regular;21" />
31
32                         <widget name="snr_db" position="60,245" size="150,22" halign="center" valign="center" font="Regular;21" />
33                         <eLabel text="SNR:" position="0,270" size="60,22" font="Regular;21" />
34                         <eLabel text="BER:" position="0,295" size="60,22" font="Regular;21" />
35                         <eLabel text="Lock:" position="0,320" size="60,22" font="Regular;21" />
36                         <widget name="snr_percentage" position="220,270" size="60,22" font="Regular;21" />
37                         <widget name="ber_value" position="220,295" size="60,22" font="Regular;21" />
38                         <widget name="lock_state" position="60,320" size="150,22" font="Regular;21" />
39                         <widget name="snr_bar" position="60,270" size="150,22" />
40                         <widget name="ber_bar" position="60,295" size="150,22" />
41
42                         <eLabel text="Frequency:" position="300,245" size="120,22" font="Regular;21" />
43                         <eLabel text="Symbolrate:" position="300,270" size="120,22" font="Regular;21" />
44                         <eLabel 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" />
48                 </screen>"""
49         def __init__(self, session, feid):
50                 self.skin = PositionerSetup.skin
51                 Screen.__init__(self, session)
52                 self.feid = feid
53                 self.oldref = None
54
55                 cur = { }
56                 if not self.openFrontend():
57                         self.oldref = session.nav.getCurrentlyPlayingServiceReference()
58                         service = session.nav.getCurrentService()
59                         feInfo = service and service.frontendInfo()
60                         if feInfo:
61                                 cur = feInfo.getTransponderData(True)
62                         del feInfo
63                         del service
64                         session.nav.stopService() # try to disable foreground service
65                         if not self.openFrontend():
66                                 if session.pipshown: # try to disable pip
67                                         service = self.session.pip.pipservice
68                                         feInfo = service and service.frontendInfo()
69                                         if feInfo:
70                                                 cur = feInfo.getTransponderData()
71                                         del feInfo
72                                         del service
73                                         session.pipshown = False
74                                         session.deleteDialog(session.pip)
75                                         del session.pip
76                                         if not self.openFrontend():
77                                                 self.frontend = None # in normal case this should not happen
78
79                 self.frontendStatus = { }
80                 self.diseqc = Diseqc(self.frontend)
81                 self.tuner = Tuner(self.frontend, True) #True means we dont like that the normal sec stuff sends commands to the rotor!
82
83                 tp = ( cur.get("frequency", 0) / 1000,
84                         cur.get("symbol_rate", 0) / 1000,
85                         cur.get("polarization", eDVBFrontendParametersSatellite.Polarisation_Horizontal),
86                         cur.get("fec_inner", eDVBFrontendParametersSatellite.FEC_Auto),
87                         cur.get("inversion", eDVBFrontendParametersSatellite.Inversion_Unknown),
88                         cur.get("orbital_position", 0),
89                         cur.get("system", eDVBFrontendParametersSatellite.System_DVB_S),
90                         cur.get("modulation", eDVBFrontendParametersSatellite.Modulation_QPSK),
91                         cur.get("rolloff", eDVBFrontendParametersSatellite.RollOff_alpha_0_35),
92                         cur.get("pilot", eDVBFrontendParametersSatellite.Pilot_Unknown))
93
94                 self.tuner.tune(tp)
95                 self.createConfig()
96
97                 self.isMoving = False
98                 self.stopOnLock = False
99
100                 self.red = Label("")
101                 self["red"] = self.red
102                 self.green = Label("")
103                 self["green"] = self.green
104                 self.yellow = Label("")
105                 self["yellow"] = self.yellow
106                 self.blue = Label("")
107                 self["blue"] = self.blue
108
109                 self.list = []
110                 self["list"] = ConfigList(self.list)
111                 self.createSetup()
112
113                 self["snr_db"] = TunerInfo(TunerInfo.SNR_DB, statusDict = self.frontendStatus)
114                 self["snr_percentage"] = TunerInfo(TunerInfo.SNR_PERCENTAGE, statusDict = self.frontendStatus)
115                 self["ber_value"] = TunerInfo(TunerInfo.BER_VALUE, statusDict = self.frontendStatus)
116                 self["snr_bar"] = TunerInfo(TunerInfo.SNR_BAR, statusDict = self.frontendStatus)
117                 self["ber_bar"] = TunerInfo(TunerInfo.BER_BAR, statusDict = self.frontendStatus)
118                 self["lock_state"] = TunerInfo(TunerInfo.LOCK_STATE, statusDict = self.frontendStatus)
119
120                 self["frequency_value"] = Label("")
121                 self["symbolrate_value"] = Label("")
122                 self["fec_value"] = Label("")
123
124                 self["actions"] = ActionMap(["DirectionActions", "OkCancelActions", "ColorActions"],
125                 {
126                         "ok": self.go,
127                         "cancel": self.keyCancel,
128                         "up": self.up,
129                         "down": self.down,
130                         "left": self.left,
131                         "right": self.right,
132                         "red": self.redKey,
133                         "green": self.greenKey,
134                         "yellow": self.yellowKey,
135                         "blue": self.blueKey,
136                 }, -1)
137
138                 self.updateColors("tune")
139
140                 self.statusTimer = eTimer()
141                 self.statusTimer_conn = self.statusTimer.timeout.connect(self.updateStatus)
142                 self.statusTimer.start(50, True)
143                 self.onClose.append(self.__onClose)
144
145         def __onClose(self):
146                 self.session.nav.playService(self.oldref)
147
148         def restartPrevService(self, yesno):
149                 if yesno:
150                         if self.frontend:
151                                 self.frontend = None
152                                 del self.raw_channel
153                 else:
154                         self.oldref=None
155                 self.close(None)
156
157         def keyCancel(self):
158                 if self.oldref:
159                         self.session.openWithCallback(self.restartPrevService, MessageBox, _("Zap back to service before positioner setup?"), MessageBox.TYPE_YESNO)
160                 else:
161                         self.restartPrevService(False)
162
163         def openFrontend(self):
164                 res_mgr = eDVBResourceManager.getInstance()
165                 if res_mgr:
166                         self.raw_channel = res_mgr.allocateRawChannel(self.feid)
167                         if self.raw_channel:
168                                 self.frontend = self.raw_channel.getFrontend()
169                                 if self.frontend:
170                                         return True
171                                 else:
172                                         print "getFrontend failed"
173                         else:
174                                 print "getRawChannel failed"
175                 else:
176                         print "getResourceManager instance failed"
177                 return False
178
179         def createConfig(self):
180                 self.positioner_tune = ConfigNothing()
181                 self.positioner_move = ConfigNothing()
182                 self.positioner_finemove = ConfigNothing()
183                 self.positioner_limits = ConfigNothing()
184                 self.positioner_goto0 = ConfigNothing()
185                 storepos = []
186                 for x in range(1,255):
187                         storepos.append(str(x))
188                 self.positioner_storage = ConfigSelection(choices = storepos)
189
190         def createSetup(self):
191                 self.list.append((_("Tune"), self.positioner_tune, "tune"))
192                 self.list.append((_("Positioner movement"), self.positioner_move, "move"))
193                 self.list.append((_("Positioner fine movement"), self.positioner_finemove, "finemove"))
194                 self.list.append((_("Set limits"), self.positioner_limits, "limits"))
195                 self.list.append((_("Positioner storage"), self.positioner_storage, "storage"))
196                 self.list.append((_("Goto 0"), self.positioner_goto0, "goto0"))
197                 self["list"].l.setList(self.list)
198
199         def go(self):
200                 pass
201
202         def getCurrentConfigPath(self):
203                 return self["list"].getCurrent()[2]
204
205         def up(self):
206                 if not self.isMoving:
207                         self["list"].instance.moveSelection(self["list"].instance.moveUp)
208                         self.updateColors(self.getCurrentConfigPath())
209
210         def down(self):
211                 if not self.isMoving:
212                         self["list"].instance.moveSelection(self["list"].instance.moveDown)
213                         self.updateColors(self.getCurrentConfigPath())
214
215         def left(self):
216                 self["list"].handleKey(KEY_LEFT)
217
218         def right(self):
219                 self["list"].handleKey(KEY_RIGHT)
220
221         def updateColors(self, entry):
222                 if entry == "tune":
223                         self.red.setText(_("Tune"))
224                         self.green.setText("")
225                         self.yellow.setText("")
226                         self.blue.setText("")
227                 elif entry == "move":
228                         if self.isMoving:
229                                 self.red.setText(_("Stop"))
230                                 self.green.setText(_("Stop"))
231                                 self.yellow.setText(_("Stop"))
232                                 self.blue.setText(_("Stop"))
233                         else:
234                                 self.red.setText(_("Move west"))
235                                 self.green.setText(_("Search west"))
236                                 self.yellow.setText(_("Search east"))
237                                 self.blue.setText(_("Move east"))
238                 elif entry == "finemove":
239                         self.red.setText("")
240                         self.green.setText(_("Step west"))
241                         self.yellow.setText(_("Step east"))
242                         self.blue.setText("")
243                 elif entry == "limits":
244                         self.red.setText(_("Limits off"))
245                         self.green.setText(_("Limit west"))
246                         self.yellow.setText(_("Limit east"))
247                         self.blue.setText(_("Limits on"))
248                 elif entry == "storage":
249                         self.red.setText("")
250                         self.green.setText(_("Store position"))
251                         self.yellow.setText(_("Goto position"))
252                         self.blue.setText("")
253                 elif entry == "goto0":
254                         self.red.setText(_("Goto 0"))
255                         self.green.setText("")
256                         self.yellow.setText("")
257                         self.blue.setText("")
258                 else:
259                         self.red.setText("")
260                         self.green.setText("")
261                         self.yellow.setText("")
262                         self.blue.setText("")
263
264         def redKey(self):
265                 entry = self.getCurrentConfigPath()
266                 if entry == "move":
267                         if self.isMoving:
268                                 self.diseqccommand("stop")
269                                 self.isMoving = False
270                                 self.stopOnLock = False
271                         else:
272                                 self.diseqccommand("moveWest", 0)
273                                 self.isMoving = True
274                         self.updateColors("move")
275                 elif entry == "limits":
276                         self.diseqccommand("limitOff")
277                 elif entry == "tune":
278                         fe_data = { }
279                         self.frontend.getFrontendData(fe_data)
280                         self.frontend.getTransponderData(fe_data, True)
281                         feparm = self.tuner.lastparm.getDVBS()
282                         fe_data["orbital_position"] = feparm.orbital_position
283                         self.session.openWithCallback(self.tune, TunerScreen, self.feid, fe_data)
284                 elif entry == "goto0":
285                         print "move to position 0"
286                         self.diseqccommand("moveTo", 0)
287
288         def greenKey(self):
289                 entry = self.getCurrentConfigPath()
290                 if entry == "move":
291                         if self.isMoving:
292                                 self.diseqccommand("stop")
293                                 self.isMoving = False
294                                 self.stopOnLock = False
295                         else:
296                                 self.isMoving = True
297                                 self.stopOnLock = True
298                                 self.diseqccommand("moveWest", 0)
299                         self.updateColors("move")
300                 elif entry == "finemove":
301                         print "stepping west"
302                         self.diseqccommand("moveWest", 0xFF) # one step
303                 elif entry == "storage":
304                         print "store at position", int(self.positioner_storage.value)
305                         self.diseqccommand("store", int(self.positioner_storage.value))
306
307                 elif entry == "limits":
308                         self.diseqccommand("limitWest")
309
310         def yellowKey(self):
311                 entry = self.getCurrentConfigPath()
312                 if entry == "move":
313                         if self.isMoving:
314                                 self.diseqccommand("stop")
315                                 self.isMoving = False
316                                 self.stopOnLock = False
317                         else:
318                                 self.isMoving = True
319                                 self.stopOnLock = True
320                                 self.diseqccommand("moveEast", 0)
321                         self.updateColors("move")
322                 elif entry == "finemove":
323                         print "stepping east"
324                         self.diseqccommand("moveEast", 0xFF) # one step
325                 elif entry == "storage":
326                         print "move to position", int(self.positioner_storage.value)
327                         self.diseqccommand("moveTo", int(self.positioner_storage.value))
328                 elif entry == "limits":
329                         self.diseqccommand("limitEast")
330
331         def blueKey(self):
332                 entry = self.getCurrentConfigPath()
333                 if entry == "move":
334                         if self.isMoving:
335                                 self.diseqccommand("stop")
336                                 self.isMoving = False
337                                 self.stopOnLock = False
338                         else:
339                                 self.diseqccommand("moveEast", 0)
340                                 self.isMoving = True
341                         self.updateColors("move")
342                         print "moving east"
343                 elif entry == "limits":
344                         self.diseqccommand("limitOn")
345
346         def diseqccommand(self, cmd, param = 0):
347                 self.diseqc.command(cmd, param)
348                 self.tuner.retune()
349
350         def updateStatus(self):
351                 if self.frontend:
352                         self.frontendStatus.clear()
353                         self.frontend.getFrontendStatus(self.frontendStatus)
354                 self["snr_db"].update()
355                 self["snr_percentage"].update()
356                 self["ber_value"].update()
357                 self["snr_bar"].update()
358                 self["ber_bar"].update()
359                 self["lock_state"].update()
360                 transponderdata = ConvertToHumanReadable(self.tuner.getTransponderData(), "DVB-S")
361                 self["frequency_value"].setText(str(transponderdata.get("frequency")))
362                 self["symbolrate_value"].setText(str(transponderdata.get("symbol_rate")))
363                 self["fec_value"].setText(str(transponderdata.get("fec_inner")))
364                 if self.frontendStatus.get("tuner_locked", 0) == 1 and self.isMoving and self.stopOnLock:
365                         self.diseqccommand("stop")
366                         self.isMoving = False
367                         self.stopOnLock = False
368                         self.updateColors(self.getCurrentConfigPath())
369                 self.statusTimer.start(50, True)
370
371         def tune(self, transponder):
372                 if transponder is not None:
373                         self.tuner.tune(transponder)
374
375 class Diseqc:
376         def __init__(self, frontend):
377                 self.frontend = frontend
378
379         def command(self, what, param = 0):
380                 if self.frontend:
381                         cmd = eDVBDiseqcCommand()
382                         if what == "moveWest":
383                                 string = 'e03169' + ("%02x" % param)
384                         elif what == "moveEast":
385                                 string = 'e03168' + ("%02x" % param)
386                         elif what == "moveTo":
387                                 string = 'e0316b' + ("%02x" % param)
388                         elif what == "store":
389                                 string = 'e0316a' + ("%02x" % param)
390                         elif what == "limitOn":
391                                 string = 'e0316a00'
392                         elif what == "limitOff":
393                                 string = 'e03163'
394                         elif what == "limitEast":
395                                 string = 'e03166'
396                         elif what == "limitWest":
397                                 string = 'e03167'
398                         else:
399                                 string = 'e03160' #positioner stop
400
401                         print "diseqc command:",
402                         print string
403                         cmd.setCommandString(string)
404                         self.frontend.setTone(iDVBFrontend.toneOff)
405                         sleep(0.015) # wait 15msec after disable tone
406                         self.frontend.sendDiseqc(cmd)
407                         if string == 'e03160': #positioner stop
408                                 sleep(0.05)
409                                 self.frontend.sendDiseqc(cmd) # send 2nd time
410
411 tuning = None
412
413 class TunerScreen(ScanSetup):
414         skin = """
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" />
418                 </screen>"""
419
420         def __init__(self, session, feid, fe_data):
421                 self.feid = feid
422                 self.fe_data = fe_data
423                 ScanSetup.__init__(self, session)
424                 self["introduction"].setText("")
425
426         def createSetup(self):
427                 self.typeOfTuningEntry = None
428                 self.satEntry = None
429                 self.list = []
430                 self.typeOfTuningEntry = getConfigListEntry(_('Tune'), tuning.type)
431                 self.list.append(self.typeOfTuningEntry)
432                 self.satEntry = getConfigListEntry(_('Satellite'), tuning.sat)
433                 self.list.append(self.satEntry)
434                 nim = nimmanager.nim_slots[self.feid]
435                 self.systemEntry = None
436
437                 if tuning.type.value == "manual_transponder":
438                         if nim.isCompatible("DVB-S2"):
439                                 self.systemEntry = getConfigListEntry(_('System'), self.scan_sat.system)
440                                 self.list.append(self.systemEntry)
441                         else:
442                                 # downgrade to dvb-s, in case a -s2 config was active
443                                 self.scan_sat.system.value = eDVBFrontendParametersSatellite.System_DVB_S
444                         self.list.append(getConfigListEntry(_('Frequency'), self.scan_sat.frequency))
445                         self.list.append(getConfigListEntry(_('Inversion'), self.scan_sat.inversion))
446                         self.list.append(getConfigListEntry(_('Symbol rate'), self.scan_sat.symbolrate))
447                         self.list.append(getConfigListEntry(_('Polarization'), self.scan_sat.polarization))
448                         if self.scan_sat.system.value == eDVBFrontendParametersSatellite.System_DVB_S:
449                                 self.list.append(getConfigListEntry(_("FEC"), self.scan_sat.fec))
450                         elif self.scan_sat.system.value == eDVBFrontendParametersSatellite.System_DVB_S2:
451                                 if self.scan_sat.modulation.value == eDVBFrontendParametersSatellite.Modulation_QPSK:
452                                         self.list.append(getConfigListEntry(_("FEC"), self.scan_sat.fec_s2_qpsk))
453                                 else:
454                                         self.list.append(getConfigListEntry(_("FEC"), self.scan_sat.fec_s2_8psk))
455                                 self.modulationEntry = getConfigListEntry(_('Modulation'), self.scan_sat.modulation)
456                                 self.list.append(self.modulationEntry)
457                                 self.list.append(getConfigListEntry(_('Roll-off'), self.scan_sat.rolloff))
458                                 self.list.append(getConfigListEntry(_('Pilot'), self.scan_sat.pilot))
459                 elif tuning.type.value == "predefined_transponder":
460                         self.list.append(getConfigListEntry(_("Transponder"), tuning.transponder))
461                 self["config"].list = self.list
462                 self["config"].l.setList(self.list)
463
464         def newConfig(self):
465                 if self["config"].getCurrent() in (self.typeOfTuningEntry, self.satEntry, self.systemEntry):
466                         self.createSetup()
467
468         def createConfig(self, foo):
469                 global tuning
470                 if not tuning:
471                         tuning = ConfigSubsection()
472                         tuning.type = ConfigSelection(
473                                 default = "manual_transponder",
474                                 choices = { "manual_transponder" : _("Manual transponder"),
475                                                         "predefined_transponder" : _("Predefined transponder") } )
476                         tuning.sat = ConfigSatlist(list=nimmanager.getRotorSatListForNim(self.feid))
477                         tuning.sat.addNotifier(self.tuningSatChanged)
478                         self.updateTransponders()
479                 orb_pos = self.fe_data.get("orbital_position", None)
480                 if orb_pos is not None:
481                         for x in nimmanager.getRotorSatListForNim(self.feid):
482                                 opos = str(orb_pos)
483                                 if x[0] == orb_pos and tuning.sat.value != opos:
484                                         tuning.sat.value = opos
485                         del self.fe_data["orbital_position"]
486                 ScanSetup.createConfig(self, self.fe_data)
487
488         def tuningSatChanged(self, *parm):
489                 self.updateTransponders()
490
491         def updateTransponders(self):
492                 if len(tuning.sat.choices):
493                         transponderlist = nimmanager.getTransponders(int(tuning.sat.value))
494                         tps = []
495                         cnt=0
496                         for x in transponderlist:
497                                 if x[3] == 0:
498                                         pol = "H"
499                                 elif x[3] == 1:
500                                         pol = "V"
501                                 elif x[3] == 2:
502                                         pol = "CL"
503                                 elif x[3] == 3:
504                                         pol = "CR"
505                                 else:
506                                         pol = "??"
507                                 if x[4] == 0:
508                                         fec = "FEC Auto"
509                                 elif x[4] == 1:
510                                         fec = "FEC 1/2"
511                                 elif x[4] == 2:
512                                         fec = "FEC 2/3"
513                                 elif x[4] == 3:
514                                         fec = "FEC 3/4"
515                                 elif x[4] == 4:
516                                         fec = "FEC 5/6"
517                                 elif x[4] == 5:
518                                         fec = "FEC 7/8"
519                                 elif x[4] == 6:
520                                         fec = "FEC 8/9"
521                                 elif x[4] == 7:
522                                         fec = "FEC 3/5"
523                                 elif x[4] == 8:
524                                         fec = "FEC 4/5"
525                                 elif x[4] == 9:
526                                         fec = "FEC 9/10"
527                                 elif x[4] == 15:
528                                         fec = "FEC None"
529                                 else:
530                                         fec = "FEC Unknown"
531                                 tps.append(str(x[1]) + "," + str(x[2]) + "," + pol + "," + fec)
532                         tuning.transponder = ConfigSelection(choices=tps)
533
534         def keyGo(self):
535                 returnvalue = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
536                 satpos = int(tuning.sat.value)
537                 if tuning.type.value == "manual_transponder":
538                         if self.scan_sat.system.value == eDVBFrontendParametersSatellite.System_DVB_S2:
539                                 if self.scan_sat.modulation.value == eDVBFrontendParametersSatellite.Modulation_QPSK:
540                                         fec = self.scan_sat.fec_s2_qpsk.value
541                                 else:
542                                         fec = self.scan_sat.fec_s2_8psk.value
543                         else:
544                                 fec = self.scan_sat.fec.value
545                         returnvalue = (
546                                 self.scan_sat.frequency.value,
547                                 self.scan_sat.symbolrate.value,
548                                 self.scan_sat.polarization.value,
549                                 fec,
550                                 self.scan_sat.inversion.value,
551                                 satpos,
552                                 self.scan_sat.system.value,
553                                 self.scan_sat.modulation.value,
554                                 self.scan_sat.rolloff.value,
555                                 self.scan_sat.pilot.value)
556                 elif tuning.type.value == "predefined_transponder":
557                         transponder = nimmanager.getTransponders(satpos)[tuning.transponder.index]
558                         returnvalue = (transponder[1] / 1000, transponder[2] / 1000,
559                                 transponder[3], transponder[4], 2, satpos, transponder[5], transponder[6], transponder[8], transponder[9])
560                 self.close(returnvalue)
561
562         def keyCancel(self):
563                 self.close(None)
564
565 class RotorNimSelection(Screen):
566         skin = """
567                 <screen position="140,165" size="400,130" title="select Slot">
568                         <widget name="nimlist" position="20,10" size="360,100" />
569                 </screen>"""
570
571         def __init__(self, session):
572                 Screen.__init__(self, session)
573
574                 nimlist = nimmanager.getNimListOfType("DVB-S")
575                 nimMenuList = []
576                 for x in nimlist:
577                         nimMenuList.append((nimmanager.nim_slots[x].friendly_full_description, x))
578
579                 self["nimlist"] = MenuList(nimMenuList)
580
581                 self["actions"] = ActionMap(["OkCancelActions"],
582                 {
583                         "ok": self.okbuttonClick ,
584                         "cancel": self.close
585                 }, -1)
586
587         def okbuttonClick(self):
588                 selection = self["nimlist"].getCurrent()
589                 self.session.open(PositionerSetup, selection[1])
590
591 def PositionerMain(session, **kwargs):
592         nimList = nimmanager.getNimListOfType("DVB-S")
593         if len(nimList) == 0:
594                 session.open(MessageBox, _("No positioner capable frontend found."), MessageBox.TYPE_ERROR)
595         else:
596                 if session.nav.RecordTimer.isRecording():
597                         session.open(MessageBox, _("A recording is currently running. Please stop the recording before trying to configure the positioner."), MessageBox.TYPE_ERROR)
598                 else:
599                         usableNims = []
600                         for x in nimList:
601                                 configured_rotor_sats = nimmanager.getRotorSatListForNim(x)
602                                 if len(configured_rotor_sats) != 0:
603                                         usableNims.append(x)
604                         if len(usableNims) == 1:
605                                 session.open(PositionerSetup, usableNims[0])
606                         elif len(usableNims) > 1:
607                                 session.open(RotorNimSelection)
608                         else:
609                                 session.open(MessageBox, _("No tuner is configured for use with a diseqc positioner!"), MessageBox.TYPE_ERROR)
610
611 def PositionerSetupStart(menuid, **kwargs):
612         if menuid == "scan":
613                 return [(_("Positioner setup"), PositionerMain, "positioner_setup", None)]
614         else:
615                 return []
616
617 def Plugins(**kwargs):
618         if (nimmanager.hasNimType("DVB-S")):
619                 return PluginDescriptor(name=_("Positioner setup"), description=_("Setup your positioner"), where = PluginDescriptor.WHERE_MENU, needsRestart = False, fnc=PositionerSetupStart)
620         else:
621                 return []