fix possible deathscreen on sat change (with predefind transponders)
[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                         elif self.tuning_type.value == "predefined_transponder":
162                                 transponder = nimmanager.getTransponders(satpos)[self.tuning_transponder.index]
163                                 returnvalue = (int(transponder[1] / 1000), int(transponder[2] / 1000), transponder[3], transponder[4], 2, satpos)
164                         self.tune(returnvalue)
165
166         def createConfig(self, foo):
167                 self.tuning_transponder = None
168                 self.tuning_type = ConfigSelection(choices = [("manual_transponder", _("Manual transponder")), ("predefined_transponder", _("Predefined transponder"))])
169                 self.tuning_sat = getConfigSatlist(192, nimmanager.getSatListForNim(self.feid))
170                 ScanSetup.createConfig(self, None)
171                 
172                 self.updateSats()
173                 
174                 self.tuning_type.addNotifier(self.retune, initial_call = False)
175                 self.tuning_sat.addNotifier(self.sat_changed, initial_call = False)
176                 self.scan_sat.frequency.addNotifier(self.retune, initial_call = False)
177                 self.scan_sat.inversion.addNotifier(self.retune, initial_call = False)
178                 self.scan_sat.symbolrate.addNotifier(self.retune, initial_call = False)
179                 self.scan_sat.polarization.addNotifier(self.retune, initial_call = False)
180                 self.scan_sat.fec.addNotifier(self.retune, initial_call = False)
181
182         def updateSats(self):
183                 orb_pos = self.tuning_sat.orbital_position
184                 if orb_pos is not None:
185                         transponderlist = nimmanager.getTransponders(orb_pos)
186                         list = []
187                         default = None
188                         for x in transponderlist:
189                                 if x[3] == 0:
190                                         pol = "H"
191                                 elif x[3] == 1:
192                                         pol = "V"
193                                 elif x[3] == 2:
194                                         pol = "CL"
195                                 elif x[3] == 3:
196                                         pol = "CR"
197                                 else:
198                                         pol = "??"
199                                 if x[4] == 0:
200                                         fec = "FEC_AUTO"
201                                 elif x[4] == 1:
202                                         fec = "FEC_1_2"
203                                 elif x[4] == 2:
204                                         fec = "FEC_2_3"
205                                 elif x[4] == 3:
206                                         fec = "FEC_3_4"
207                                 elif x[4] == 4:
208                                         fec = "FEC_5_6"
209                                 elif x[4] == 5:
210                                         fec = "FEC_7_8"
211                                 elif x[4] == 6:
212                                         fec = "FEC_8_9"
213                                 elif x[4] == 7:
214                                         fec = "FEC_3_5"
215                                 elif x[4] == 8:
216                                         fec = "FEC_4_5"
217                                 elif x[4] == 9:
218                                         fec = "FEC_9_10"
219                                 elif x[4] == 15:
220                                         fec = "FEC_None"
221                                 else:
222                                         fec = "FEC_Unknown"
223                                 e = str(x[1]) + "," + str(x[2]) + "," + pol + "," + fec
224                                 if default is None:
225                                         default = e
226                                 list.append(e)
227                         self.tuning_transponder = ConfigSelection(choices = list, default = default)
228                         self.tuning_transponder.addNotifier(self.retune, initial_call = False)
229
230         def keyGo(self):
231                 self.retune(self.tuning_type)
232
233         def restartPrevService(self, yesno):
234                 if yesno:
235                         if self.frontend:
236                                 self.frontend = None
237                                 del self.raw_channel
238                 else:
239                         self.oldref = None
240                 self.close(None)
241
242         def keyCancel(self):
243                 if self.oldref:
244                         self.session.openWithCallback(self.restartPrevService, MessageBox, _("Zap back to service before satfinder?"), MessageBox.TYPE_YESNO)
245                 else:
246                         self.restartPrevService(False)
247
248         def tune(self, transponder):
249                 if self.initcomplete:
250                         if transponder is not None:
251                                 self.tuner.tune(transponder)
252
253 class NimSelection(Screen):
254         skin = """
255                 <screen position="140,165" size="400,100" title="select Slot">
256                         <widget name="nimlist" position="20,10" size="360,75" />
257                 </screen>"""
258                 
259         def __init__(self, session):
260                 Screen.__init__(self, session)
261
262                 nimlist = nimmanager.getNimListOfType("DVB-S")
263                 nimMenuList = []
264                 for x in nimlist:
265                         nimMenuList.append((nimmanager.nim_slots[x].friendly_full_description, x))
266
267                 self["nimlist"] = MenuList(nimMenuList)
268
269                 self["actions"] = ActionMap(["OkCancelActions"],
270                 {
271                         "ok": self.okbuttonClick ,
272                         "cancel": self.close
273                 }, -1)
274
275         def okbuttonClick(self):
276                 selection = self["nimlist"].getCurrent()[1]
277                 self.session.open(Satfinder, selection)
278
279 def SatfinderMain(session, **kwargs):
280         nimList = nimmanager.getNimListOfType("DVB-S")
281         if len(nimList) == 0:
282                 session.open(MessageBox, _("No satellite frontend found!!"), MessageBox.TYPE_ERROR)
283         else:
284                 if session.nav.RecordTimer.isRecording():
285                         session.open(MessageBox, _("A recording is currently running. Please stop the recording before trying to start the satfinder."), MessageBox.TYPE_ERROR)
286                 else:
287                         if len(nimList) == 1:
288                                 session.open(Satfinder, nimList[0])
289                         else:
290                                 session.open(NimSelection)
291
292 def SatfinderStart(menuid, **kwargs):
293         if menuid == "scan":
294                 return [(_("Satfinder"), SatfinderMain, "satfinder", None)]
295         else:
296                 return []
297
298 def Plugins(**kwargs):
299         if (nimmanager.hasNimType("DVB-S")):
300                 return PluginDescriptor(name=_("Satfinder"), description="Helps setting up your dish", where = PluginDescriptor.WHERE_MENU, fnc=SatfinderStart)
301         else:
302                 return []