Support DVB-S2X.
[vuplus_dvbapp] / 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 NumberActionMap, 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 Components.ConfigList import ConfigListScreen
19 from Components.config import config, ConfigSubsection, ConfigSelection, ConfigInteger, getConfigListEntry
20 from Tools.Transponder import ConvertToHumanReadable
21
22 from time import sleep
23
24 class PositionerSetup(Screen):
25         skin = """
26                 <screen position="100,100" size="560,400" title="Positioner setup..." >
27                         <widget name="list" position="100,0" size="350,155" />
28
29                         <widget name="red" position="0,155" size="140,80" backgroundColor="red" halign="center" valign="center" font="Regular;21" />
30                         <widget name="green" position="140,155" size="140,80" backgroundColor="green" halign="center" valign="center" font="Regular;21" />
31                         <widget name="yellow" position="280,155" size="140,80" backgroundColor="yellow" halign="center" valign="center" font="Regular;21" />
32                         <widget name="blue" position="420,155" size="140,80" backgroundColor="blue" halign="center" valign="center" font="Regular;21" />
33
34                         <widget name="snr_db" position="60,245" size="150,22" halign="center" valign="center" font="Regular;21" />
35                         <eLabel text="SNR:" position="0,270" size="60,22" font="Regular;21" />
36                         <eLabel text="BER:" position="0,295" size="60,22" font="Regular;21" />
37                         <eLabel text="Lock:" position="0,320" size="60,22" font="Regular;21" />
38                         <widget name="snr_percentage" position="220,270" size="60,22" font="Regular;21" />
39                         <widget name="ber_value" position="220,295" size="60,22" font="Regular;21" />
40                         <widget name="lock_state" position="60,320" size="150,22" font="Regular;21" />
41                         <widget name="snr_bar" position="60,270" size="150,22" />
42                         <widget name="ber_bar" position="60,295" size="150,22" />
43
44                         <eLabel text="Frequency:" position="300,245" size="120,22" font="Regular;21" />
45                         <eLabel text="Symbolrate:" position="300,270" size="120,22" font="Regular;21" />
46                         <eLabel text="FEC:" position="300,295" size="120,22" font="Regular;21" />
47                         <widget name="frequency_value" position="420,245" size="120,22" font="Regular;21" />
48                         <widget name="symbolrate_value" position="420,270" size="120,22" font="Regular;21" />
49                         <widget name="fec_value" position="420,295" size="120,22" font="Regular;21" />
50                 </screen>"""
51         def __init__(self, session, feid):
52                 self.skin = PositionerSetup.skin
53                 Screen.__init__(self, session)
54                 self.feid = feid
55                 self.oldref = None
56
57                 cur = { }
58                 if not self.openFrontend():
59                         self.oldref = session.nav.getCurrentlyPlayingServiceReference()
60                         service = session.nav.getCurrentService()
61                         feInfo = service and service.frontendInfo()
62                         if feInfo:
63                                 cur = feInfo.getTransponderData(True)
64                         del feInfo
65                         del service
66                         session.nav.stopService() # try to disable foreground service
67                         if not self.openFrontend():
68                                 if session.pipshown: # try to disable pip
69                                         service = self.session.pip.pipservice
70                                         feInfo = service and service.frontendInfo()
71                                         if feInfo:
72                                                 cur = feInfo.getTransponderData()
73                                         del feInfo
74                                         del service
75                                         session.pipshown = False
76                                         del session.pip
77                                         if not self.openFrontend():
78                                                 self.frontend = None # in normal case this should not happen
79                 
80                 self.frontendStatus = { }
81                 self.diseqc = Diseqc(self.frontend)
82                 self.tuner = Tuner(self.frontend, True) #True means we dont like that the normal sec stuff sends commands to the rotor!
83
84                 tp = ( cur.get("frequency", 0) / 1000,
85                         cur.get("symbol_rate", 0) / 1000,
86                         cur.get("polarization", eDVBFrontendParametersSatellite.Polarisation_Horizontal),
87                         cur.get("fec_inner", eDVBFrontendParametersSatellite.FEC_Auto),
88                         cur.get("inversion", eDVBFrontendParametersSatellite.Inversion_Unknown),
89                         cur.get("orbital_position", 0),
90                         cur.get("system", eDVBFrontendParametersSatellite.System_DVB_S),
91                         cur.get("modulation", eDVBFrontendParametersSatellite.Modulation_QPSK),
92                         cur.get("rolloff", eDVBFrontendParametersSatellite.RollOff_alpha_0_35),
93                         cur.get("pilot", eDVBFrontendParametersSatellite.Pilot_Unknown),
94                         cur.get("is_id", -1),
95                         cur.get("pls_mode", eDVBFrontendParametersSatellite.PLS_Unknown),
96                         cur.get("pls_code", 0))
97
98                 self.tuner.tune(tp)
99                 self.createConfig()
100                 
101                 self.isMoving = False
102                 self.stopOnLock = False
103                 
104                 self.red = Label("")
105                 self["red"] = self.red
106                 self.green = Label("")
107                 self["green"] = self.green
108                 self.yellow = Label("")
109                 self["yellow"] = self.yellow
110                 self.blue = Label("")
111                 self["blue"] = self.blue
112
113                 self.list = []
114                 self["list"] = ConfigList(self.list)
115                 self.createSetup()
116
117                 self["snr_db"] = TunerInfo(TunerInfo.SNR_DB, statusDict = self.frontendStatus)
118                 self["snr_percentage"] = TunerInfo(TunerInfo.SNR_PERCENTAGE, statusDict = self.frontendStatus)
119                 self["ber_value"] = TunerInfo(TunerInfo.BER_VALUE, statusDict = self.frontendStatus)
120                 self["snr_bar"] = TunerInfo(TunerInfo.SNR_BAR, statusDict = self.frontendStatus)
121                 self["ber_bar"] = TunerInfo(TunerInfo.BER_BAR, statusDict = self.frontendStatus)
122                 self["lock_state"] = TunerInfo(TunerInfo.LOCK_STATE, statusDict = self.frontendStatus)
123
124                 self["frequency_value"] = Label("")
125                 self["symbolrate_value"] = Label("")
126                 self["fec_value"] = Label("")
127                 
128                 self["actions"] = ActionMap(["DirectionActions", "OkCancelActions", "ColorActions"],
129                 {
130                         "ok": self.go,
131                         "cancel": self.keyCancel,
132                         "up": self.up,
133                         "down": self.down,
134                         "left": self.left,
135                         "right": self.right,
136                         "red": self.redKey,
137                         "green": self.greenKey,
138                         "yellow": self.yellowKey,
139                         "blue": self.blueKey,
140                 }, -1)
141                 
142                 self.updateColors("tune")
143                 
144                 self.statusTimer = eTimer()
145                 self.statusTimer.callback.append(self.updateStatus)
146                 self.statusTimer.start(50, True)
147                 self.onClose.append(self.__onClose)
148
149         def __onClose(self):
150                 self.session.nav.playService(self.oldref)
151
152         def restartPrevService(self, yesno):
153                 if yesno:
154                         if self.frontend:
155                                 self.frontend = None
156                                 del self.raw_channel
157                 else:
158                         self.oldref=None
159                 self.close(None)        
160
161         def keyCancel(self):
162                 if self.oldref:
163                         self.session.openWithCallback(self.restartPrevService, MessageBox, _("Zap back to service before positioner setup?"), MessageBox.TYPE_YESNO)
164                 else:
165                         self.restartPrevService(False)
166
167         def openFrontend(self):
168                 res_mgr = eDVBResourceManager.getInstance()
169                 if res_mgr:
170                         self.raw_channel = res_mgr.allocateRawChannel(self.feid)
171                         if self.raw_channel:
172                                 self.frontend = self.raw_channel.getFrontend()
173                                 if self.frontend:
174                                         return True
175                                 else:
176                                         print "getFrontend failed"
177                         else:
178                                 print "getRawChannel failed"
179                 else:
180                         print "getResourceManager instance failed"
181                 return False
182
183         def createConfig(self):
184                 self.positioner_tune = ConfigNothing()
185                 self.positioner_move = ConfigNothing()
186                 self.positioner_finemove = ConfigNothing()
187                 self.positioner_limits = ConfigNothing()
188                 self.positioner_goto0 = ConfigNothing()
189                 storepos = []
190                 for x in range(1,255):
191                         storepos.append(str(x))
192                 self.positioner_storage = ConfigSelection(choices = storepos)
193
194         def createSetup(self):
195                 self.list.append((_("Tune"), self.positioner_tune, "tune"))
196                 self.list.append((_("Positioner movement"), self.positioner_move, "move"))
197                 self.list.append((_("Positioner fine movement"), self.positioner_finemove, "finemove"))
198                 self.list.append((_("Set limits"), self.positioner_limits, "limits"))
199                 self.list.append((_("Positioner storage"), self.positioner_storage, "storage"))
200                 self.list.append((_("Goto 0"), self.positioner_goto0, "goto0"))
201                 self["list"].l.setList(self.list)
202
203         def go(self):
204                 pass
205
206         def getCurrentConfigPath(self):
207                 return self["list"].getCurrent()[2]
208
209         def up(self):
210                 if not self.isMoving:
211                         self["list"].instance.moveSelection(self["list"].instance.moveUp)
212                         self.updateColors(self.getCurrentConfigPath())
213
214         def down(self):
215                 if not self.isMoving:
216                         self["list"].instance.moveSelection(self["list"].instance.moveDown)
217                         self.updateColors(self.getCurrentConfigPath())
218
219         def left(self):
220                 self["list"].handleKey(KEY_LEFT)
221
222         def right(self):
223                 self["list"].handleKey(KEY_RIGHT)
224
225         def updateColors(self, entry):
226                 if entry == "tune":
227                         self.red.setText(_("Tune"))
228                         self.green.setText("")
229                         self.yellow.setText("")
230                         self.blue.setText("")
231                 elif entry == "move":
232                         if self.isMoving:
233                                 self.red.setText(_("Stop"))
234                                 self.green.setText(_("Stop"))
235                                 self.yellow.setText(_("Stop"))
236                                 self.blue.setText(_("Stop"))
237                         else:
238                                 self.red.setText(_("Move west"))
239                                 self.green.setText(_("Search west"))
240                                 self.yellow.setText(_("Search east"))
241                                 self.blue.setText(_("Move east"))
242                 elif entry == "finemove":
243                         self.red.setText("")
244                         self.green.setText(_("Step west"))
245                         self.yellow.setText(_("Step east"))
246                         self.blue.setText("")
247                 elif entry == "limits":
248                         self.red.setText(_("Limits off"))
249                         self.green.setText(_("Limit west"))
250                         self.yellow.setText(_("Limit east"))
251                         self.blue.setText(_("Limits on"))
252                 elif entry == "storage":
253                         self.red.setText("")
254                         self.green.setText(_("Store position"))
255                         self.yellow.setText(_("Goto position"))
256                         self.blue.setText("")
257                 elif entry == "goto0":
258                         self.red.setText(_("Goto 0"))
259                         self.green.setText("")
260                         self.yellow.setText("")
261                         self.blue.setText("")
262                 else:
263                         self.red.setText("")
264                         self.green.setText("")
265                         self.yellow.setText("")
266                         self.blue.setText("")
267
268         def redKey(self):
269                 entry = self.getCurrentConfigPath()
270                 if entry == "move":
271                         if self.isMoving:
272                                 self.diseqccommand("stop")
273                                 self.isMoving = False
274                                 self.stopOnLock = False
275                         else:
276                                 self.diseqccommand("moveWest", 0)
277                                 self.isMoving = True
278                         self.updateColors("move")
279                 elif entry == "limits":
280                         self.diseqccommand("limitOff")
281                 elif entry == "tune":
282                         fe_data = { }
283                         self.frontend.getFrontendData(fe_data)
284                         self.frontend.getTransponderData(fe_data, True)
285                         feparm = self.tuner.lastparm.getDVBS()
286                         fe_data["orbital_position"] = feparm.orbital_position
287                         self.session.openWithCallback(self.tune, TunerScreen, self.feid, fe_data)
288                 elif entry == "goto0":
289                         print "move to position 0"
290                         self.diseqccommand("moveTo", 0)
291
292         def greenKey(self):
293                 entry = self.getCurrentConfigPath()
294                 if entry == "move":
295                         if self.isMoving:
296                                 self.diseqccommand("stop")
297                                 self.isMoving = False
298                                 self.stopOnLock = False
299                         else:
300                                 self.isMoving = True
301                                 self.stopOnLock = True
302                                 self.diseqccommand("moveWest", 0)
303                         self.updateColors("move")
304                 elif entry == "finemove":
305                         print "stepping west"
306                         self.diseqccommand("moveWest", 0xFF) # one step
307                 elif entry == "storage":
308                         print "store at position", int(self.positioner_storage.value)
309                         self.diseqccommand("store", int(self.positioner_storage.value))
310                         
311                 elif entry == "limits":
312                         self.diseqccommand("limitWest")
313
314         def yellowKey(self):
315                 entry = self.getCurrentConfigPath()
316                 if entry == "move":
317                         if self.isMoving:
318                                 self.diseqccommand("stop")
319                                 self.isMoving = False
320                                 self.stopOnLock = False
321                         else:
322                                 self.isMoving = True
323                                 self.stopOnLock = True
324                                 self.diseqccommand("moveEast", 0)
325                         self.updateColors("move")
326                 elif entry == "finemove":
327                         print "stepping east"
328                         self.diseqccommand("moveEast", 0xFF) # one step
329                 elif entry == "storage":
330                         print "move to position", int(self.positioner_storage.value)
331                         self.diseqccommand("moveTo", int(self.positioner_storage.value))
332                 elif entry == "limits":
333                         self.diseqccommand("limitEast")
334
335         def blueKey(self):
336                 entry = self.getCurrentConfigPath()
337                 if entry == "move":
338                         if self.isMoving:
339                                 self.diseqccommand("stop")
340                                 self.isMoving = False
341                                 self.stopOnLock = False
342                         else:
343                                 self.diseqccommand("moveEast", 0)
344                                 self.isMoving = True
345                         self.updateColors("move")
346                         print "moving east"
347                 elif entry == "limits":
348                         self.diseqccommand("limitOn")
349
350         def diseqccommand(self, cmd, param = 0):
351                 self.diseqc.command(cmd, param)
352                 self.tuner.retune()
353
354         def updateStatus(self):
355                 if self.frontend:
356                         self.frontend.getFrontendStatus(self.frontendStatus)
357                 self["snr_db"].update()
358                 self["snr_percentage"].update()
359                 self["ber_value"].update()
360                 self["snr_bar"].update()
361                 self["ber_bar"].update()
362                 self["lock_state"].update()
363                 transponderdata = ConvertToHumanReadable(self.tuner.getTransponderData(), "DVB-S")
364                 self["frequency_value"].setText(str(transponderdata.get("frequency")))
365                 self["symbolrate_value"].setText(str(transponderdata.get("symbol_rate")))
366                 self["fec_value"].setText(str(transponderdata.get("fec_inner")))
367                 if self.frontendStatus.get("tuner_locked", 0) == 1 and self.isMoving and self.stopOnLock:
368                         self.diseqccommand("stop")
369                         self.isMoving = False
370                         self.stopOnLock = False
371                         self.updateColors(self.getCurrentConfigPath())
372                 self.statusTimer.start(50, True)
373
374         def tune(self, transponder):
375                 if transponder is not None:
376                         self.tuner.tune(transponder)
377
378 class Diseqc:
379         def __init__(self, frontend):
380                 self.frontend = frontend
381
382         def command(self, what, param = 0):
383                 if self.frontend:
384                         cmd = eDVBDiseqcCommand()
385                         if what == "moveWest":
386                                 string = 'e03169' + ("%02x" % param)
387                         elif what == "moveEast":
388                                 string = 'e03168' + ("%02x" % param)
389                         elif what == "moveTo":
390                                 string = 'e0316b' + ("%02x" % param)
391                         elif what == "store":
392                                 string = 'e0316a' + ("%02x" % param)
393                         elif what == "limitOn":
394                                 string = 'e0316a00'
395                         elif what == "limitOff":
396                                 string = 'e03163'
397                         elif what == "limitEast":
398                                 string = 'e03166'
399                         elif what == "limitWest":
400                                 string = 'e03167'
401                         else:
402                                 string = 'e03160' #positioner stop
403                         
404                         print "diseqc command:",
405                         print string
406                         cmd.setCommandString(string)
407                         self.frontend.setTone(iDVBFrontend.toneOff)
408                         sleep(0.015) # wait 15msec after disable tone
409                         self.frontend.sendDiseqc(cmd)
410                         if string == 'e03160': #positioner stop
411                                 sleep(0.05)
412                                 self.frontend.sendDiseqc(cmd) # send 2nd time
413
414 class TunerScreen(ConfigListScreen, Screen):
415         skin = """
416                 <screen position="90,100" size="520,400" title="Tune">
417                         <widget name="config" position="20,10" size="460,350" scrollbarMode="showOnDemand" />
418                         <widget name="introduction" position="20,360" size="350,30" font="Regular;23" />
419                 </screen>"""
420
421         def __init__(self, session, feid, fe_data):
422                 self.feid = feid
423                 self.fe_data = fe_data
424                 Screen.__init__(self, session)
425                 ConfigListScreen.__init__(self, None)
426                 self.createConfig(fe_data)
427                 self.createSetup()
428                 self.tuning.sat.addNotifier(self.tuningSatChanged)
429                 self.tuning.type.addNotifier(self.tuningTypeChanged)
430                 self.scan_sat.system.addNotifier(self.systemChanged)
431                 self.scan_sat.system_dvbs2x.addNotifier(self.systemChanged)
432                 self.scan_sat.is_id_bool.addNotifier(self.isIdChanged, initial_call = False)
433                 self.scan_sat.pls_mode.addNotifier(self.plsModeChanged, initial_call = False)
434
435                 self["actions"] = NumberActionMap(["SetupActions"],
436                 {
437                         "ok": self.keyGo,
438                         "cancel": self.keyCancel,
439                 }, -2)
440
441                 self["introduction"] = Label(_(" "))
442
443         def createSetup(self):
444                 self.list = []
445                 self.list.append(getConfigListEntry(_('Tune'), self.tuning.type) )
446                 self.list.append(getConfigListEntry(_('Satellite'), self.tuning.sat)    )
447
448                 self.is_id_boolEntry = None
449                 self.plsModeEntry = None
450                 nim = nimmanager.nim_slots[self.feid]
451                 if self.tuning.type.value == "manual_transponder":
452                         scan_sat_system_value = self.scan_sat.system.value
453                         if nim.isCompatible("DVB-S2X"):
454                                 scan_sat_system_value = self.scan_sat.system_dvbs2x.value
455                                 self.list.append(getConfigListEntry(_('System'), self.scan_sat.system_dvbs2x))
456                         elif nim.isCompatible("DVB-S2"):
457                                 self.list.append(getConfigListEntry(_('System'), self.scan_sat.system))
458                         else:
459                                 # downgrade to dvb-s, in case a -s2 config was active
460                                 self.scan_sat.system.value = eDVBFrontendParametersSatellite.System_DVB_S
461                         self.list.append(getConfigListEntry(_('Frequency'), self.scan_sat.frequency))
462                         self.list.append(getConfigListEntry(_('Inversion'), self.scan_sat.inversion))
463                         self.list.append(getConfigListEntry(_('Symbol rate'), self.scan_sat.symbolrate))
464                         self.list.append(getConfigListEntry(_('Polarization'), self.scan_sat.polarization))
465                         if scan_sat_system_value == eDVBFrontendParametersSatellite.System_DVB_S:
466                                 self.list.append(getConfigListEntry(_("FEC"), self.scan_sat.fec))
467                         elif scan_sat_system_value == eDVBFrontendParametersSatellite.System_DVB_S2:
468                                 self.list.append(getConfigListEntry(_("FEC"), self.scan_sat.fec_s2))
469                                 self.modulationEntry = getConfigListEntry(_('Modulation'), self.scan_sat.modulation)
470                                 self.list.append(self.modulationEntry)
471                                 self.list.append(getConfigListEntry(_('Roll-off'), self.scan_sat.rolloff))
472                                 self.list.append(getConfigListEntry(_('Pilot'), self.scan_sat.pilot))
473                         elif scan_sat_system_value == eDVBFrontendParametersSatellite.System_DVB_S2X:
474                                 if self.scan_sat.modulation_dvbs2x.value == eDVBFrontendParametersSatellite.Modulation_QPSK:
475                                         self.list.append(getConfigListEntry(_("FEC"), self.scan_sat.fec_s2x_qpsk))
476                                 elif self.scan_sat.modulation_dvbs2x.value == eDVBFrontendParametersSatellite.Modulation_8PSK:
477                                         self.list.append(getConfigListEntry(_("FEC"), self.scan_sat.fec_s2x_8psk))
478                                 elif self.scan_sat.modulation_dvbs2x.value == eDVBFrontendParametersSatellite.Modulation_8APSK:
479                                         self.list.append(getConfigListEntry(_("FEC"), self.scan_sat.fec_s2x_8apsk))
480                                 elif self.scan_sat.modulation_dvbs2x.value == eDVBFrontendParametersSatellite.Modulation_16APSK:
481                                         self.list.append(getConfigListEntry(_("FEC"), self.scan_sat.fec_s2x_16apsk))
482                                 elif self.scan_sat.modulation_dvbs2x.value == eDVBFrontendParametersSatellite.Modulation_32APSK:
483                                         self.list.append(getConfigListEntry(_("FEC"), self.scan_sat.fec_s2x_32apsk))
484                                 self.modulationEntry = getConfigListEntry(_('Modulation'), self.scan_sat.modulation_dvbs2x)
485                                 self.list.append(self.modulationEntry)
486                                 self.list.append(getConfigListEntry(_('Roll-off'), self.scan_sat.rolloff))
487                                 self.list.append(getConfigListEntry(_('Pilot'), self.scan_sat.pilot))
488                         if scan_sat_system_value in (eDVBFrontendParametersSatellite.System_DVB_S2, eDVBFrontendParametersSatellite.System_DVB_S2X):
489                                 if nim.isMultistream():
490                                         self.is_id_boolEntry = getConfigListEntry(_('Transport Stream Type'), self.scan_sat.is_id_bool)
491                                         self.list.append(self.is_id_boolEntry)
492                                         if self.scan_sat.is_id_bool.value:
493                                                 self.list.append(getConfigListEntry(_('Input Stream ID'), self.scan_sat.is_id))
494                                                 self.plsModeEntry = getConfigListEntry(_('PLS Mode'), self.scan_sat.pls_mode)
495                                                 self.list.append(self.plsModeEntry)
496                                                 if self.scan_sat.pls_mode.value != eDVBFrontendParametersSatellite.PLS_Unknown:
497                                                         self.list.append(getConfigListEntry(_('PLS Code'), self.scan_sat.pls_code))
498                 elif self.tuning.type.value == "predefined_transponder":
499                         self.list.append(getConfigListEntry(_("Transponder"), self.tuning.transponder))
500                 self["config"].list = self.list
501                 self["config"].l.setList(self.list)
502
503         def createConfig(self, frontendData):
504                 satlist = nimmanager.getRotorSatListForNim(self.feid)
505                 orb_pos = self.fe_data.get("orbital_position", None)
506                 self.tuning = ConfigSubsection()
507                 self.tuning.type = ConfigSelection(
508                         default = "manual_transponder",
509                         choices = { "manual_transponder" : _("Manual transponder"),
510                                                 "predefined_transponder" : _("Predefined transponder") } )
511                 self.tuning.sat = ConfigSatlist(list = satlist)
512                 if orb_pos is not None:
513                         for x in satlist:
514                                 opos = str(orb_pos)
515                                 if x[0] == orb_pos and self.tuning.sat.value != opos:
516                                         self.tuning.sat.value = opos
517                         del self.fe_data["orbital_position"]
518
519                 self.updateTransponders()
520
521                 defaultSat = {
522                         "orbpos": 192,
523                         "system": eDVBFrontendParametersSatellite.System_DVB_S,
524                         "frequency": 11836,
525                         "inversion": eDVBFrontendParametersSatellite.Inversion_Unknown,
526                         "symbolrate": 27500,
527                         "polarization": eDVBFrontendParametersSatellite.Polarisation_Horizontal,
528                         "fec": eDVBFrontendParametersSatellite.FEC_Auto,
529                         "fec_s2": eDVBFrontendParametersSatellite.FEC_9_10,
530                         "fec_s2x_qpsk": eDVBFrontendParametersSatellite.FEC_13_45,
531                         "fec_s2x_8psk": eDVBFrontendParametersSatellite.FEC_23_36,
532                         "fec_s2x_8apsk": eDVBFrontendParametersSatellite.FEC_5_9_L,
533                         "fec_s2x_16apsk": eDVBFrontendParametersSatellite.FEC_1_2_L,
534                         "fec_s2x_32apsk": eDVBFrontendParametersSatellite.FEC_2_3_L,
535                         "modulation": eDVBFrontendParametersSatellite.Modulation_QPSK,
536                         "modulation_s2x": eDVBFrontendParametersSatellite.Modulation_QPSK,
537                         "is_id": -1,
538                         "pls_mode": eDVBFrontendParametersSatellite.PLS_Unknown,
539                         "pls_code": 0 }
540
541                 if frontendData is not None:
542                         ttype = frontendData.get("tuner_type", "UNKNOWN")
543                         defaultSat["system"] = frontendData.get("system", eDVBFrontendParametersSatellite.System_DVB_S)
544                         defaultSat["frequency"] = frontendData.get("frequency", 0) / 1000
545                         defaultSat["inversion"] = frontendData.get("inversion", eDVBFrontendParametersSatellite.Inversion_Unknown)
546                         defaultSat["symbolrate"] = frontendData.get("symbol_rate", 0) / 1000
547                         defaultSat["polarization"] = frontendData.get("polarization", eDVBFrontendParametersSatellite.Polarisation_Horizontal)
548                         defaultSat["orbpos"] = frontendData.get("orbital_position", 0)
549
550                         defaultSat["modulation"] = frontendData.get("modulation", eDVBFrontendParametersSatellite.Modulation_QPSK)
551                         defaultSat["modulation_s2x"] = frontendData.get("modulation", eDVBFrontendParametersSatellite.Modulation_QPSK)
552
553                         if defaultSat["modulation"] > eDVBFrontendParametersSatellite.Modulation_8PSK:
554                                 defaultSat["modulation"] = eDVBFrontendParametersSatellite.Modulation_8PSK
555
556                         if defaultSat["system"] == eDVBFrontendParametersSatellite.System_DVB_S2:
557                                 defaultSat["fec_s2"] = frontendData.get("fec_inner", eDVBFrontendParametersSatellite.FEC_Auto)
558                         elif defaultSat["system"] == eDVBFrontendParametersSatellite.System_DVB_S2X:
559                                 if defaultSat["modulation_s2x"] == eDVBFrontendParametersSatellite.Modulation_QPSK:
560                                         defaultSat["fec_s2x_qpsk"] = frontendData.get("fec_inner", eDVBFrontendParametersSatellite.FEC_13_45)
561                                 elif defaultSat["modulation_s2x"] == eDVBFrontendParametersSatellite.Modulation_8PSK:
562                                         defaultSat["fec_s2x_8psk"] = frontendData.get("fec_inner", eDVBFrontendParametersSatellite.FEC_23_36)
563                                 elif defaultSat["modulation_s2x"] == eDVBFrontendParametersSatellite.Modulation_8APSK:
564                                         defaultSat["fec_s2x_8apsk"] = frontendData.get("fec_inner", eDVBFrontendParametersSatellite.FEC_5_9_L)
565                                 elif defaultSat["modulation_s2x"] == eDVBFrontendParametersSatellite.Modulation_16APSK:
566                                         defaultSat["fec_s2x_16apsk"] = frontendData.get("fec_inner", eDVBFrontendParametersSatellite.FEC_1_2_L)
567                                 elif defaultSat["modulation_s2x"] == eDVBFrontendParametersSatellite.Modulation_32APSK:
568                                         defaultSat["fec_s2x_32apsk"] = frontendData.get("fec_inner", eDVBFrontendParametersSatellite.FEC_2_3_L)
569                         else:
570                                 defaultSat["fec"] = frontendData.get("fec_inner", eDVBFrontendParametersSatellite.FEC_Auto)
571
572                         if defaultSat["system"] in (eDVBFrontendParametersSatellite.System_DVB_S2, eDVBFrontendParametersSatellite.System_DVB_S2X):
573                                 defaultSat["rolloff"] = frontendData.get("rolloff", eDVBFrontendParametersSatellite.RollOff_alpha_0_35)
574                                 defaultSat["pilot"] = frontendData.get("pilot", eDVBFrontendParametersSatellite.Pilot_Unknown)
575                                 defaultSat["is_id"] = frontendData.get("is_id", defaultSat["is_id"])
576                                 defaultSat["pls_mode"] = frontendData.get("pls_mode", defaultSat["pls_mode"])
577                                 defaultSat["pls_code"] = frontendData.get("pls_code", defaultSat["pls_code"])
578
579                 self.scan_sat = ConfigSubsection()
580
581                 sat_choices = [
582                                 (eDVBFrontendParametersSatellite.System_DVB_S, _("DVB-S")),
583                                 (eDVBFrontendParametersSatellite.System_DVB_S2, _("DVB-S2"))]
584
585                 sat_choices_dvbs2x = [
586                         (eDVBFrontendParametersSatellite.System_DVB_S, _("DVB-S")),
587                         (eDVBFrontendParametersSatellite.System_DVB_S2, _("DVB-S2")),
588                         (eDVBFrontendParametersSatellite.System_DVB_S2X, _("DVB-S2X"))]
589
590                 self.scan_sat.system = ConfigSelection(default = defaultSat["system"], choices = sat_choices)
591                 self.scan_sat.system_dvbs2x = ConfigSelection(default = defaultSat["system"], choices = sat_choices_dvbs2x)
592                 self.scan_sat.frequency = ConfigInteger(default = defaultSat["frequency"], limits = (1, 99999))
593                 self.scan_sat.inversion = ConfigSelection(default = defaultSat["inversion"], choices = [
594                         (eDVBFrontendParametersSatellite.Inversion_Off, _("Off")),
595                         (eDVBFrontendParametersSatellite.Inversion_On, _("On")),
596                         (eDVBFrontendParametersSatellite.Inversion_Unknown, _("Auto"))])
597                 self.scan_sat.symbolrate = ConfigInteger(default = defaultSat["symbolrate"], limits = (1, 99999))
598                 self.scan_sat.polarization = ConfigSelection(default = defaultSat["polarization"], choices = [
599                         (eDVBFrontendParametersSatellite.Polarisation_Horizontal, _("horizontal")),
600                         (eDVBFrontendParametersSatellite.Polarisation_Vertical, _("vertical")),
601                         (eDVBFrontendParametersSatellite.Polarisation_CircularLeft, _("circular left")),
602                         (eDVBFrontendParametersSatellite.Polarisation_CircularRight, _("circular right"))])
603                 self.scan_sat.fec = ConfigSelection(default = defaultSat["fec"], choices = [
604                         (eDVBFrontendParametersSatellite.FEC_Auto, _("Auto")),
605                         (eDVBFrontendParametersSatellite.FEC_1_2, "1/2"),
606                         (eDVBFrontendParametersSatellite.FEC_2_3, "2/3"),
607                         (eDVBFrontendParametersSatellite.FEC_3_4, "3/4"),
608                         (eDVBFrontendParametersSatellite.FEC_5_6, "5/6"),
609                         (eDVBFrontendParametersSatellite.FEC_7_8, "7/8"),
610                         (eDVBFrontendParametersSatellite.FEC_None, _("None"))])
611                 self.scan_sat.fec_s2 = ConfigSelection(default = defaultSat["fec_s2"], choices = [
612                         (eDVBFrontendParametersSatellite.FEC_1_2, "1/2"),
613                         (eDVBFrontendParametersSatellite.FEC_2_3, "2/3"),
614                         (eDVBFrontendParametersSatellite.FEC_3_4, "3/4"),
615                         (eDVBFrontendParametersSatellite.FEC_3_5, "3/5"),
616                         (eDVBFrontendParametersSatellite.FEC_4_5, "4/5"),
617                         (eDVBFrontendParametersSatellite.FEC_5_6, "5/6"),
618                         (eDVBFrontendParametersSatellite.FEC_7_8, "7/8"),
619                         (eDVBFrontendParametersSatellite.FEC_8_9, "8/9"),
620                         (eDVBFrontendParametersSatellite.FEC_9_10, "9/10")])
621                 self.scan_sat.fec_s2x_qpsk = ConfigSelection(default = defaultSat["fec_s2x_qpsk"], choices = [
622                         (eDVBFrontendParametersSatellite.FEC_13_45, "13/45"),
623                         (eDVBFrontendParametersSatellite.FEC_9_20, "9/20"),
624                         (eDVBFrontendParametersSatellite.FEC_11_20, "11/20")])
625
626                 self.scan_sat.fec_s2x_8psk = ConfigSelection(default = defaultSat["fec_s2x_8psk"], choices = [
627                         (eDVBFrontendParametersSatellite.FEC_23_36, "23/36"),
628                         (eDVBFrontendParametersSatellite.FEC_25_36, "25/36"),
629                         (eDVBFrontendParametersSatellite.FEC_13_18, "13/28")])
630
631                 self.scan_sat.fec_s2x_8apsk = ConfigSelection(default = defaultSat["fec_s2x_8apsk"], choices = [
632                         (eDVBFrontendParametersSatellite.FEC_5_9_L, "5/9-L"),
633                         (eDVBFrontendParametersSatellite.FEC_26_45_L, "26/45-L")])
634
635                 self.scan_sat.fec_s2x_16apsk = ConfigSelection(default = defaultSat["fec_s2x_16apsk"], choices = [
636                         (eDVBFrontendParametersSatellite.FEC_1_2_L, "1/2-L"),
637                         (eDVBFrontendParametersSatellite.FEC_8_15_L, "8/15-L"),
638                         (eDVBFrontendParametersSatellite.FEC_5_9_L, "5/9-L"),
639                         (eDVBFrontendParametersSatellite.FEC_26_45, "26/45"),
640                         (eDVBFrontendParametersSatellite.FEC_3_5, "3/5"),
641                         (eDVBFrontendParametersSatellite.FEC_3_5_L, "3/5-L"),
642                         (eDVBFrontendParametersSatellite.FEC_28_45, "28/45"),
643                         (eDVBFrontendParametersSatellite.FEC_23_36, "23/36"),
644                         (eDVBFrontendParametersSatellite.FEC_2_3_L, "2/3-L"),
645                         (eDVBFrontendParametersSatellite.FEC_25_36, "25/36"),
646                         (eDVBFrontendParametersSatellite.FEC_13_18, "13/18"),
647                         (eDVBFrontendParametersSatellite.FEC_7_9, "7/9"),
648                         (eDVBFrontendParametersSatellite.FEC_77_90, "77/90")])
649
650                 self.scan_sat.fec_s2x_32apsk = ConfigSelection(default = defaultSat["fec_s2x_32apsk"], choices = [
651                         (eDVBFrontendParametersSatellite.FEC_2_3_L, "2/3-L"),
652                         (eDVBFrontendParametersSatellite.FEC_32_45, "32/45"),
653                         (eDVBFrontendParametersSatellite.FEC_11_15, "11/15"),
654                         (eDVBFrontendParametersSatellite.FEC_7_9, "7/9")])
655                 self.scan_sat.modulation = ConfigSelection(default = defaultSat["modulation"], choices = [
656                         (eDVBFrontendParametersSatellite.Modulation_QPSK, "QPSK"),
657                         (eDVBFrontendParametersSatellite.Modulation_8PSK, "8PSK")])
658                 self.scan_sat.modulation_dvbs2x = ConfigSelection(default = defaultSat["modulation_s2x"], choices = [
659                         (eDVBFrontendParametersSatellite.Modulation_QPSK, "QPSK"),
660                         (eDVBFrontendParametersSatellite.Modulation_8PSK, "8PSK"),
661                         (eDVBFrontendParametersSatellite.Modulation_8APSK, "8APSK"),
662                         (eDVBFrontendParametersSatellite.Modulation_16APSK, "16APSK"),
663                         (eDVBFrontendParametersSatellite.Modulation_32APSK, "32APSK")])
664                 self.scan_sat.rolloff = ConfigSelection(default = defaultSat.get("rolloff", eDVBFrontendParametersSatellite.RollOff_alpha_0_35), choices = [
665                         (eDVBFrontendParametersSatellite.RollOff_alpha_0_35, "0.35"),
666                         (eDVBFrontendParametersSatellite.RollOff_alpha_0_25, "0.25"),
667                         (eDVBFrontendParametersSatellite.RollOff_alpha_0_20, "0.20")])
668                 self.scan_sat.pilot = ConfigSelection(default = defaultSat.get("pilot", eDVBFrontendParametersSatellite.Pilot_Unknown), choices = [
669                         (eDVBFrontendParametersSatellite.Pilot_Off, _("Off")),
670                         (eDVBFrontendParametersSatellite.Pilot_On, _("On")),
671                         (eDVBFrontendParametersSatellite.Pilot_Unknown, _("Auto"))])
672                 self.scan_sat.is_id = ConfigInteger(default = defaultSat["is_id"] if defaultSat["is_id"] != -1 else 0, limits = (0, 255))
673                 self.scan_sat.is_id_bool = ConfigSelection(default = defaultSat["is_id"] != -1, choices = [(True, _("Multistream")),(False, _("Ordinary"))])
674                 self.scan_sat.pls_mode = ConfigSelection(default = defaultSat["pls_mode"], choices = [
675                                 (eDVBFrontendParametersSatellite.PLS_Root, _("Root")),
676                                 (eDVBFrontendParametersSatellite.PLS_Gold, _("Gold")),
677                                 (eDVBFrontendParametersSatellite.PLS_Combo, _("Combo")),
678                                 (eDVBFrontendParametersSatellite.PLS_Unknown, _("Auto"))])
679                 self.scan_sat.pls_code = ConfigInteger(default = defaultSat["pls_code"], limits = (0, 262143))
680
681         def tuningSatChanged(self, *parm):
682                 self.updateTransponders()
683                 self.createSetup()
684
685         def tuningTypeChanged(self, *parm):
686                 self.createSetup()
687
688         def systemChanged(self, *parm):
689                 self.createSetup()
690
691         def isIdChanged(self, *parm):
692                 self.createSetup()
693
694         def plsModeChanged(self, *parm):
695                 self.createSetup()
696
697         def updateTransponders(self):
698                 if len(self.tuning.sat.choices):
699                         transponderlist = nimmanager.getTransponders(int(self.tuning.sat.value))
700                         tps = []
701                         cnt=0
702                         for x in transponderlist:
703                                 if x[3] == 0:
704                                         pol = "H"
705                                 elif x[3] == 1:
706                                         pol = "V"
707                                 elif x[3] == 2:
708                                         pol = "CL"
709                                 elif x[3] == 3:
710                                         pol = "CR"
711                                 else:
712                                         pol = "??"
713
714                                 fec_desc = ("FEC Auto", "FEC 1/2", "FEC 2/3", "FEC 3/4", "FEC 5/6", "FEC 7/8", "FEC 8/9", "FEC 3/5", "FEC 4/5", "FEC 9/10", \
715                                                         "FEC Unknown", "FEC Unknown", "FEC Unknown", "FEC Unknown", "FEC Unknown", "FEC None", \
716                                                         "FEC_13_45", "FEC_9_20", "FEC_11_20", "FEC_23_36", "FEC_25_36", \
717                                                         "FEC_13_18", "FEC_26_45", "FEC_28_45", "FEC_7_9", "FEC_77_90", \
718                                                         "FEC_32_45", "FEC_11_15", "FEC_1_2_L", "FEC_8_15_L", "FEC_3_5_L", \
719                                                         "FEC_2_3_L", "FEC_5_9_L", "FEC_26_45_L")
720                                 if x[4] > len(fec_desc)-1:
721                                         fec = "FEC Unknown"
722                                 else:
723                                         fec = fec_desc[x[4]]
724                                 tps.append(str(x[1]) + "," + str(x[2]) + "," + pol + "," + fec)
725                         self.tuning.transponder = ConfigSelection(choices=tps)
726
727         def keyLeft(self):
728                 ConfigListScreen.keyLeft(self)
729
730         def keyRight(self):
731                 ConfigListScreen.keyRight(self)
732
733         def keyGo(self):
734                 returnvalue = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 3, 0)
735                 satpos = int(self.tuning.sat.value)
736                 nim = nimmanager.nim_slots[self.feid]
737                 if self.tuning.type.value == "manual_transponder":
738                         system = self.scan_sat.system.value
739                         modulation = self.scan_sat.modulation.value
740                         if nim.isCompatible("DVB-S2X"):
741                                 system = self.scan_sat.system_dvbs2x.value
742                                 modulation = self.scan_sat.modulation_dvbs2x.value
743
744                         if system == eDVBFrontendParametersSatellite.System_DVB_S:
745                                 fec = self.scan_sat.fec.value
746                         elif system == eDVBFrontendParametersSatellite.System_DVB_S2:
747                                 fec = self.scan_sat.fec_s2.value
748                         elif system == eDVBFrontendParametersSatellite.System_DVB_S2X:
749                                 if modulation == eDVBFrontendParametersSatellite.Modulation_QPSK:
750                                         fec = self.scan_sat.fec_s2x_qpsk.value
751                                 elif modulation == eDVBFrontendParametersSatellite.Modulation_8PSK:
752                                         fec = self.scan_sat.fec_s2x_8psk.value
753                                 elif modulation == eDVBFrontendParametersSatellite.Modulation_8APSK:
754                                         fec = self.scan_sat.fec_s2x_8apsk.value
755                                 elif modulation == eDVBFrontendParametersSatellite.Modulation_16APSK:
756                                         fec = self.scan_sat.fec_s2x_16apsk.value
757                                 elif modulation == eDVBFrontendParametersSatellite.Modulation_32APSK:
758                                         fec = self.scan_sat.fec_s2x_32apsk.value
759                         else:
760                                 fec = self.scan_sat.fec.value
761
762                         is_id = -1
763                         pls_mode = eDVBFrontendParametersSatellite.PLS_Unknown
764                         pls_code = 0
765                         if self.scan_sat.is_id_bool.value:
766                                 is_id = self.scan_sat.is_id.value
767                                 pls_mode = self.scan_sat.pls_mode.value
768                                 if pls_mode == eDVBFrontendParametersSatellite.PLS_Unknown:
769                                         pls_code = 0
770                                 else:
771                                         pls_code = self.scan_sat.pls_code.value
772
773                         returnvalue = (
774                                 self.scan_sat.frequency.value,
775                                 self.scan_sat.symbolrate.value,
776                                 self.scan_sat.polarization.value,
777                                 fec,
778                                 self.scan_sat.inversion.value,
779                                 satpos,
780                                 system,
781                                 modulation,
782                                 self.scan_sat.rolloff.value,
783                                 self.scan_sat.pilot.value,
784                                 is_id,
785                                 pls_mode,
786                                 pls_code)
787                 elif self.tuning.type.value == "predefined_transponder":
788                         transponder = nimmanager.getTransponders(satpos)[self.tuning.transponder.index]
789                         returnvalue = (transponder[1] / 1000, transponder[2] / 1000,
790                                 transponder[3], transponder[4], 2, satpos, transponder[5], transponder[6], transponder[8], transponder[9], transponder[10], transponder[11], transponder[12])
791                 self.close(returnvalue)
792
793         def keyCancel(self):
794                 self.close(None)
795
796 class RotorNimSelection(Screen):
797         skin = """
798                 <screen position="140,165" size="400,130" title="select Slot">
799                         <widget name="nimlist" position="20,10" size="360,100" />
800                 </screen>"""
801
802         def __init__(self, session):
803                 Screen.__init__(self, session)
804
805                 nimlist = nimmanager.getNimListOfType("DVB-S")
806                 nimMenuList = []
807                 for x in nimlist:
808                         nimMenuList.append((nimmanager.nim_slots[x].friendly_full_description, x))
809                 
810                 self["nimlist"] = MenuList(nimMenuList)
811
812                 self["actions"] = ActionMap(["OkCancelActions"],
813                 {
814                         "ok": self.okbuttonClick ,
815                         "cancel": self.close
816                 }, -1)
817
818         def okbuttonClick(self):
819                 selection = self["nimlist"].getCurrent()
820                 self.session.open(PositionerSetup, selection[1])
821
822 def PositionerMain(session, **kwargs):
823         nimList = nimmanager.getNimListOfType("DVB-S")
824         if len(nimList) == 0:
825                 session.open(MessageBox, _("No positioner capable frontend found."), MessageBox.TYPE_ERROR)
826         else:
827                 if session.nav.RecordTimer.isRecording():
828                         session.open(MessageBox, _("A recording is currently running. Please stop the recording before trying to configure the positioner."), MessageBox.TYPE_ERROR)
829                 else:
830                         usableNims = []
831                         for x in nimList:
832                                 configured_rotor_sats = nimmanager.getRotorSatListForNim(x)
833                                 if len(configured_rotor_sats) != 0:
834                                         usableNims.append(x)
835                         if len(usableNims) == 1:
836                                 session.open(PositionerSetup, usableNims[0])
837                         elif len(usableNims) > 1:
838                                 session.open(RotorNimSelection)
839                         else:
840                                 session.open(MessageBox, _("No tuner is configured for use with a diseqc positioner!"), MessageBox.TYPE_ERROR)
841
842 def PositionerSetupStart(menuid, **kwargs):
843         if menuid == "scan":
844                 return [(_("Positioner setup"), PositionerMain, "positioner_setup", None)]
845         else:
846                 return []
847
848 def Plugins(**kwargs):
849         if (nimmanager.hasNimType("DVB-S")):
850                 return PluginDescriptor(name=_("Positioner setup"), description="Setup your positioner", where = PluginDescriptor.WHERE_MENU, needsRestart = False, fnc=PositionerSetupStart)
851         else:
852                 return []