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