Satfinder/plugin.py: fix nimselection size, add support for DVB-S2
[enigma2.git] / lib / python / Plugins / SystemPlugins / Satfinder / plugin.py
1 from enigma import eDVBResourceManager,\
2         eDVBFrontendParametersSatellite, eDVBFrontendParameters
3
4 from Screens.Screen import Screen
5 from Screens.ScanSetup import ScanSetup
6 from Screens.MessageBox import MessageBox
7 from Plugins.Plugin import PluginDescriptor
8
9 from Components.Label import Label
10 from Components.Sources.FrontendStatus import FrontendStatus
11 from Components.ActionMap import ActionMap
12 from Components.NimManager import nimmanager, getConfigSatlist
13 from Components.MenuList import MenuList
14 from Components.config import ConfigSelection, getConfigListEntry
15
16 class Tuner:
17         def __init__(self, frontend):
18                 self.frontend = frontend
19                 
20         def tune(self, transponder):
21                 if self.frontend:
22                         print "tuning to transponder with data", transponder
23                         parm = eDVBFrontendParametersSatellite()
24                         parm.frequency = transponder[0] * 1000
25                         parm.symbol_rate = transponder[1] * 1000
26                         parm.polarisation = transponder[2]
27                         parm.fec = transponder[3]
28                         parm.inversion = transponder[4]
29                         parm.orbital_position = transponder[5]
30                         parm.system = transponder[6]
31                         parm.modulation = transponder[7]
32                         parm.rolloff = transponder[8]
33                         parm.pilot = transponder[9]
34                         feparm = eDVBFrontendParameters()
35                         feparm.setDVBS(parm, True)
36                         self.lastparm = feparm
37                         self.frontend.tune(feparm)
38
39         def retune(self):
40                 if self.frontend:
41                         self.frontend.tune(self.lastparm)
42
43 class Satfinder(ScanSetup):
44         def openFrontend(self):
45                 res_mgr = eDVBResourceManager.getInstance()
46                 if res_mgr:
47                         self.raw_channel = res_mgr.allocateRawChannel(self.feid)
48                         if self.raw_channel:
49                                 self.frontend = self.raw_channel.getFrontend()
50                                 if self.frontend:
51                                         return True
52                                 else:
53                                         print "getFrontend failed"
54                         else:
55                                 print "getRawChannel failed"
56                 else:
57                         print "getResourceManager instance failed"
58                 return False
59
60         def __init__(self, session, feid):
61                 self.initcomplete = False
62                 self.feid = feid
63                 self.oldref = None
64
65                 if not self.openFrontend():
66                         self.oldref = session.nav.getCurrentlyPlayingServiceReference()
67                         session.nav.stopService() # try to disable foreground service
68                         if not self.openFrontend():
69                                 if session.pipshown: # try to disable pip
70                                         session.pipshown = False
71                                         del session.pip
72                                         if not self.openFrontend():
73                                                 self.frontend = None # in normal case this should not happen
74
75                 ScanSetup.__init__(self, session)
76                 self.tuner = Tuner(self.frontend)
77                 self["introduction"].setText("")
78                 self["Frontend"] = FrontendStatus(frontend_source = lambda : self.frontend, update_interval = 100)
79                 self.initcomplete = True
80                 self.onClose.append(self.__onClose)
81
82         def __onClose(self):
83                 self.session.nav.playService(self.oldref)
84
85         def createSetup(self):
86                 self.typeOfTuningEntry = None
87                 self.satEntry = None
88                 
89                 self.list = []
90
91                 self.typeOfTuningEntry = getConfigListEntry(_('Tune'), self.tuning_type)
92                 self.list.append(self.typeOfTuningEntry)
93                 self.satEntry = getConfigListEntry(_('Satellite'), self.tuning_sat)
94                 self.list.append(self.satEntry)
95
96                 nim = nimmanager.nim_slots[self.feid]
97
98                 self.systemEntry = None
99                 if self.tuning_type.value == "manual_transponder":
100                         if nim.isCompatible("DVB-S2"):
101                                 self.systemEntry = getConfigListEntry(_('System'), self.scan_sat.system)
102                                 self.list.append(self.systemEntry)
103                         else:
104                                 # downgrade to dvb-s, in case a -s2 config was active
105                                 self.scan_sat.system.value = "dvb-s"
106                         self.list.append(getConfigListEntry(_('Frequency'), self.scan_sat.frequency))
107                         self.list.append(getConfigListEntry(_('Inversion'), self.scan_sat.inversion))
108                         self.list.append(getConfigListEntry(_('Symbol Rate'), self.scan_sat.symbolrate))
109                         self.list.append(getConfigListEntry(_("Polarity"), self.scan_sat.polarization))
110                         if self.scan_sat.system.value == "dvb-s":
111                                 self.list.append(getConfigListEntry(_("FEC"), self.scan_sat.fec))
112                         elif self.scan_sat.system.value == "dvb-s2":
113                                 self.list.append(getConfigListEntry(_("FEC"), self.scan_sat.fec_s2))
114                                 self.modulationEntry = getConfigListEntry(_('Modulation'), self.scan_sat.modulation)
115                                 self.list.append(self.modulationEntry)
116                                 self.list.append(getConfigListEntry(_('Rolloff'), self.scan_sat.rolloff))
117                                 self.list.append(getConfigListEntry(_('Pilot'), self.scan_sat.pilot))
118                 elif self.tuning_transponder and self.tuning_type.value == "predefined_transponder":
119                         self.list.append(getConfigListEntry(_("Transponder"), self.tuning_transponder))
120                 self["config"].list = self.list
121                 self["config"].l.setList(self.list)
122
123         def newConfig(self):
124                 cur = self["config"].getCurrent()
125                 if cur in (self.typeOfTuningEntry, self.systemEntry):
126                         self.createSetup()
127                 elif cur == self.satEntry:
128                         self.updateSats()
129                         self.createSetup()
130
131         def sat_changed(self, config_element):
132                 self.newConfig()
133                 self.retune(config_element)
134
135         def retune(self, configElement):
136                 returnvalue = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
137                 satpos = int(self.tuning_sat.value)
138                 if self.tuning_type.value == "manual_transponder":
139                         if self.scan_sat.system.value == "dvb-s2":
140                                 fec = self.scan_sat.fec_s2.value
141                         else:
142                                 fec = self.scan_sat.fec.value
143                         returnvalue = (
144                                 self.scan_sat.frequency.value,
145                                 self.scan_sat.symbolrate.value,
146                                 self.scan_sat.polarization.index,
147                                 { "auto": 0,
148                                    "1_2": 1,
149                                    "2_3": 2,
150                                    "3_4": 3,
151                                    "5_6": 4,
152                                    "7_8": 5,
153                                    "8_9": 6,
154                                    "3_5": 7,
155                                    "4_5": 8,
156                                    "9_10": 9,
157                                    "none": 15 }[fec],
158                                 self.scan_sat.inversion.index,
159                                 satpos,
160                                 self.scan_sat.system.index,
161                                 self.scan_sat.modulation.index == 1 and 2 or 1,
162                                 self.scan_sat.rolloff.index,
163                                 self.scan_sat.pilot.index)
164                         self.tune(returnvalue)
165                 elif self.tuning_type.value == "predefined_transponder":
166                         tps = nimmanager.getTransponders(satpos)
167                         l = len(tps)
168                         if l > self.tuning_transponder.index:
169                                 transponder = tps[self.tuning_transponder.index]
170                                 returnvalue = (int(transponder[1] / 1000), int(transponder[2] / 1000),
171                                         transponder[3], transponder[4], 2, satpos, transponder[5], transponder[6], transponder[8], transponder[9])
172                                 self.tune(returnvalue)
173
174         def createConfig(self, foo):
175                 self.tuning_transponder = None
176                 self.tuning_type = ConfigSelection(choices = [("manual_transponder", _("Manual transponder")), ("predefined_transponder", _("Predefined transponder"))])
177                 self.tuning_sat = getConfigSatlist(192, nimmanager.getSatListForNim(self.feid))
178                 ScanSetup.createConfig(self, None)
179                 
180                 self.updateSats()
181
182                 for x in (self.tuning_type, self.tuning_sat, self.scan_sat.frequency,
183                         self.scan_sat.inversion, self.scan_sat.symbolrate,
184                         self.scan_sat.polarization, self.scan_sat.fec, self.scan_sat.pilot,
185                         self.scan_sat.fec_s2, self.scan_sat.fec, self.scan_sat.modulation,
186                         self.scan_sat.rolloff, self.scan_sat.system):
187                         x.addNotifier(self.retune, initial_call = False)
188
189         def updateSats(self):
190                 orb_pos = self.tuning_sat.orbital_position
191                 if orb_pos is not None:
192                         transponderlist = nimmanager.getTransponders(orb_pos)
193                         list = []
194                         default = None
195                         for x in transponderlist:
196                                 if x[3] == 0:
197                                         pol = "H"
198                                 elif x[3] == 1:
199                                         pol = "V"
200                                 elif x[3] == 2:
201                                         pol = "CL"
202                                 elif x[3] == 3:
203                                         pol = "CR"
204                                 else:
205                                         pol = "??"
206                                 if x[4] == 0:
207                                         fec = "FEC_AUTO"
208                                 elif x[4] == 1:
209                                         fec = "FEC_1_2"
210                                 elif x[4] == 2:
211                                         fec = "FEC_2_3"
212                                 elif x[4] == 3:
213                                         fec = "FEC_3_4"
214                                 elif x[4] == 4:
215                                         fec = "FEC_5_6"
216                                 elif x[4] == 5:
217                                         fec = "FEC_7_8"
218                                 elif x[4] == 6:
219                                         fec = "FEC_8_9"
220                                 elif x[4] == 7:
221                                         fec = "FEC_3_5"
222                                 elif x[4] == 8:
223                                         fec = "FEC_4_5"
224                                 elif x[4] == 9:
225                                         fec = "FEC_9_10"
226                                 elif x[4] == 15:
227                                         fec = "FEC_None"
228                                 else:
229                                         fec = "FEC_Unknown"
230                                 e = str(x[1]) + "," + str(x[2]) + "," + pol + "," + fec
231                                 if default is None:
232                                         default = e
233                                 list.append(e)
234                         self.tuning_transponder = ConfigSelection(choices = list, default = default)
235                         self.tuning_transponder.addNotifier(self.retune, initial_call = False)
236
237         def keyGo(self):
238                 self.retune(self.tuning_type)
239
240         def restartPrevService(self, yesno):
241                 if yesno:
242                         if self.frontend:
243                                 self.frontend = None
244                                 del self.raw_channel
245                 else:
246                         self.oldref = None
247                 self.close(None)
248
249         def keyCancel(self):
250                 if self.oldref:
251                         self.session.openWithCallback(self.restartPrevService, MessageBox, _("Zap back to service before satfinder?"), MessageBox.TYPE_YESNO)
252                 else:
253                         self.restartPrevService(False)
254
255         def tune(self, transponder):
256                 if self.initcomplete:
257                         if transponder is not None:
258                                 self.tuner.tune(transponder)
259
260 class SatNimSelection(Screen):
261         skin = """
262                 <screen position="140,165" size="400,130" title="select Slot">
263                         <widget name="nimlist" position="20,10" size="360,100" />
264                 </screen>"""
265                 
266         def __init__(self, session):
267                 Screen.__init__(self, session)
268
269                 nimlist = nimmanager.getNimListOfType("DVB-S")
270                 nimMenuList = []
271                 for x in nimlist:
272                         nimMenuList.append((nimmanager.nim_slots[x].friendly_full_description, x))
273
274                 self["nimlist"] = MenuList(nimMenuList)
275
276                 self["actions"] = ActionMap(["OkCancelActions"],
277                 {
278                         "ok": self.okbuttonClick ,
279                         "cancel": self.close
280                 }, -1)
281
282         def okbuttonClick(self):
283                 selection = self["nimlist"].getCurrent()[1]
284                 self.session.open(Satfinder, selection)
285
286 def SatfinderMain(session, **kwargs):
287         nimList = nimmanager.getNimListOfType("DVB-S")
288         if len(nimList) == 0:
289                 session.open(MessageBox, _("No satellite frontend found!!"), MessageBox.TYPE_ERROR)
290         else:
291                 if session.nav.RecordTimer.isRecording():
292                         session.open(MessageBox, _("A recording is currently running. Please stop the recording before trying to start the satfinder."), MessageBox.TYPE_ERROR)
293                 else:
294                         if len(nimList) == 1:
295                                 session.open(Satfinder, nimList[0])
296                         else:
297                                 session.open(SatNimSelection)
298
299 def SatfinderStart(menuid, **kwargs):
300         if menuid == "scan":
301                 return [(_("Satfinder"), SatfinderMain, "satfinder", None)]
302         else:
303                 return []
304
305 def Plugins(**kwargs):
306         if (nimmanager.hasNimType("DVB-S")):
307                 return PluginDescriptor(name=_("Satfinder"), description="Helps setting up your dish", where = PluginDescriptor.WHERE_MENU, fnc=SatfinderStart)
308         else:
309                 return []