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