3cf48fb8797b4141e2a8ae180da893edf66227f0
[enigma2.git] / lib / python / Plugins / SystemPlugins / Satfinder / plugin.py
1 from enigma import eTimer, 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.TunerInfo import TunerInfo
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,240" scrollbarMode="showOnDemand" />
45                         <widget name="introduction" position="20,360" zPosition="-10" size="350,30" font="Regular;23" />
46                         <widget name="snr" text="SNR:" position="0,245" size="60,22" font="Regular;21" />
47                         <widget name="agc" text="AGC:" position="0,270" size="60,22" font="Regular;21" />
48                         <widget name="ber" text="BER:" position="0,295" size="60,22" font="Regular;21" />
49                         <widget name="lock" text="Lock:" position="0,320" size="60,22" font="Regular;21" />
50                         <widget name="snr_percentage" position="220,245" size="60,22" font="Regular;21" />
51                         <widget name="agc_percentage" position="220,270" size="60,22" font="Regular;21" />
52                         <widget name="ber_value" position="220,295" size="60,22" font="Regular;21" />
53                         <widget name="lock_state" position="60,320" size="150,22" font="Regular;21" />
54                         <widget name="snr_bar" position="60,245" size="150,22" />
55                         <widget name="agc_bar" position="60,270" size="150,22" />
56                         <widget name="ber_bar" position="60,295" size="150,22" />
57                 </screen>"""
58
59         def openFrontend(self):
60                 res_mgr = eDVBResourceManager.getInstance()
61                 if res_mgr:
62                         self.raw_channel = res_mgr.allocateRawChannel(self.feid)
63                         if self.raw_channel:
64                                 self.frontend = self.raw_channel.getFrontend()
65                                 if self.frontend:
66                                         return True
67                                 else:
68                                         print "getFrontend failed"
69                         else:
70                                 print "getRawChannel failed"
71                 else:
72                         print "getResourceManager instance failed"
73                 return False
74
75         def __init__(self, session, feid):
76                 self.initcomplete = False
77                 self.feid = feid
78                 self.oldref = None
79                 self.frontendStatus = { }
80                 
81                 if not self.openFrontend():
82                         self.oldref = session.nav.getCurrentlyPlayingServiceReference()
83                         session.nav.stopService() # try to disable foreground service
84                         if not self.openFrontend():
85                                 if session.pipshown: # try to disable pip
86                                         session.pipshown = False
87                                         del session.pip
88                                         if not self.openFrontend():
89                                                 self.frontend = None # in normal case this should not happen
90
91                 ScanSetup.__init__(self, session)
92                 self.tuner = Tuner(self.frontend)
93                 
94                 self["snr"] = Label()
95                 self["agc"] = Label()
96                 self["ber"] = Label()
97                 self["lock"] = Label()
98                 self["snr_percentage"] = TunerInfo(TunerInfo.SNR_PERCENTAGE, statusDict = self.frontendStatus)
99                 self["agc_percentage"] = TunerInfo(TunerInfo.AGC_PERCENTAGE, statusDict = self.frontendStatus)
100                 self["ber_value"] = TunerInfo(TunerInfo.BER_VALUE, statusDict = self.frontendStatus)
101                 self["snr_bar"] = TunerInfo(TunerInfo.SNR_BAR, statusDict = self.frontendStatus)
102                 self["agc_bar"] = TunerInfo(TunerInfo.AGC_BAR, statusDict = self.frontendStatus)
103                 self["ber_bar"] = TunerInfo(TunerInfo.BER_BAR, statusDict = self.frontendStatus)
104                 self["lock_state"] = TunerInfo(TunerInfo.LOCK_STATE, statusDict = self.frontendStatus)
105                 
106                 self["introduction"].setText("")
107
108                 self.statusTimer = eTimer()
109                 self.statusTimer.timeout.get().append(self.updateStatus)
110                 self.statusTimer.start(50, False)
111                 self.initcomplete = True
112
113         def updateStatus(self):
114                 if self.frontend:
115                         self.frontend.getFrontendStatus(self.frontendStatus)
116                 else:
117                         self.frontendStatus.clear()
118                 self["snr_percentage"].update()
119                 self["agc_percentage"].update()
120                 self["ber_value"].update()
121                 self["snr_bar"].update()
122                 self["agc_bar"].update()
123                 self["ber_bar"].update()
124                 self["lock_state"].update()
125
126         def createSetup(self):
127                 self.typeOfTuningEntry = None
128                 self.satEntry = None
129                 
130                 self.list = []
131                 self.typeOfTuningEntry = getConfigListEntry(_('Tune'), self.tuning_type)
132                 self.list.append(self.typeOfTuningEntry)
133                 self.satEntry = getConfigListEntry(_('Satellite'), self.tuning_sat)
134                 self.list.append(self.satEntry)
135                 if self.tuning_type.value == "manual_transponder":
136                         self.list.append(getConfigListEntry(_('Frequency'), self.scan_sat.frequency))
137                         self.list.append(getConfigListEntry(_('Inversion'), self.scan_sat.inversion))
138                         self.list.append(getConfigListEntry(_('Symbol Rate'), self.scan_sat.symbolrate))
139                         self.list.append(getConfigListEntry(_("Polarity"), self.scan_sat.polarization))
140                         self.list.append(getConfigListEntry(_("FEC"), self.scan_sat.fec))
141                 elif self.tuning_transponder and self.tuning_type.value == "predefined_transponder":
142                         self.list.append(getConfigListEntry(_("Transponder"), self.tuning_transponder))
143                 self["config"].list = self.list
144                 self["config"].l.setList(self.list)
145
146         def newConfig(self):
147                 if self["config"].getCurrent() == self.typeOfTuningEntry:
148                         self.createSetup()
149                 elif self["config"].getCurrent() == self.satEntry:
150                         self.updateSats()
151                         self.createSetup()
152
153         def sat_changed(self, config_element):
154                 self.newConfig()
155                 self.retune(config_element)
156
157         def retune(self, configElement):
158                 returnvalue = (0, 0, 0, 0, 0, 0, 0)
159                 satpos = self.tuning_sat.orbital_position
160                 
161                 if satpos is not None:
162                         if self.tuning_type.value == "manual_transponder":
163                                 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)
164                         elif self.tuning_type.value == "predefined_transponder":
165                                 transponder = nimmanager.getTransponders(satpos)[self.tuning_transponder.index]
166                                 returnvalue = (int(transponder[1] / 1000), int(transponder[2] / 1000), transponder[3], transponder[4], 2, satpos)
167                         self.tune(returnvalue)
168
169         def createConfig(self, foo):
170                 self.tuning_transponder = None
171                 self.tuning_type = ConfigSelection(choices = [("manual_transponder", _("Manual transponder")), ("predefined_transponder", _("Predefined transponder"))])
172                 self.tuning_sat = getConfigSatlist(192, nimmanager.getSatListForNim(self.feid))
173                 ScanSetup.createConfig(self, None)
174                 
175                 self.updateSats()
176                 
177                 self.tuning_type.addNotifier(self.retune, initial_call = False)
178                 self.tuning_sat.addNotifier(self.sat_changed, initial_call = False)
179                 self.scan_sat.frequency.addNotifier(self.retune, initial_call = False)
180                 self.scan_sat.inversion.addNotifier(self.retune, initial_call = False)
181                 self.scan_sat.symbolrate.addNotifier(self.retune, initial_call = False)
182                 self.scan_sat.polarization.addNotifier(self.retune, initial_call = False)
183                 self.scan_sat.fec.addNotifier(self.retune, initial_call = False)
184
185         def updateSats(self):
186                 orb_pos = self.tuning_sat.orbital_position
187                 if orb_pos is not None:
188                         transponderlist = nimmanager.getTransponders(orb_pos)
189                         list = []
190                         for x in transponderlist:
191                                 if x[3] == 0:
192                                         pol = "H"
193                                 elif x[3] == 1:
194                                         pol = "V"
195                                 elif x[3] == 2:
196                                         pol = "CL"
197                                 elif x[3] == 3:
198                                         pol = "CR"
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] == 5:
212                                         fec = "FEC_8_9"
213                                 elif x[4] == 6:
214                                         fec = "FEC_None"
215                                 list.append(str(x[1]) + "," + str(x[2]) + "," + pol + "," + fec)
216                         self.tuning_transponder = ConfigSelection(choices = list)
217                         self.tuning_transponder.addNotifier(self.retune, initial_call = False)
218
219         def keyGo(self):
220                 self.retune(self.tuning_type)
221
222         def restartPrevService(self, yesno):
223                 if yesno:
224                         if self.frontend:
225                                 self.frontend = None
226                                 del self.raw_channel
227                         self.session.nav.playService(self.oldref)
228                 self.close(None)
229
230         def keyCancel(self):
231                 if self.oldref:
232                         self.session.openWithCallback(self.restartPrevService, MessageBox, _("Zap back to service before satfinder?"), MessageBox.TYPE_YESNO)
233                 else:
234                         self.restartPrevService(False)
235
236         def tune(self, transponder):
237                 if self.initcomplete:
238                         if transponder is not None:
239                                 self.tuner.tune(transponder)
240
241 class NimSelection(Screen):
242         skin = """
243                 <screen position="140,165" size="400,100" title="select Slot">
244                         <widget name="nimlist" position="20,10" size="360,75" />
245                 </screen>"""
246                 
247         def __init__(self, session):
248                 Screen.__init__(self, session)
249
250                 nimlist = nimmanager.getNimListOfType("DVB-S")
251                 nimMenuList = []
252                 for x in nimlist:
253                         nimMenuList.append((nimmanager.nim_slots[x].friendly_full_description, x))
254
255                 self["nimlist"] = MenuList(nimMenuList)
256
257                 self["actions"] = ActionMap(["OkCancelActions"],
258                 {
259                         "ok": self.okbuttonClick ,
260                         "cancel": self.close
261                 }, -1)
262
263         def okbuttonClick(self):
264                 selection = self["nimlist"].getCurrent()[1]
265                 self.session.open(Satfinder, selection)
266
267 def SatfinderMain(session, **kwargs):
268         nimList = nimmanager.getNimListOfType("DVB-S")
269         if len(nimList) == 0:
270                 session.open(MessageBox, _("No satellite frontend found!!"), MessageBox.TYPE_ERROR)
271         else:
272                 if session.nav.RecordTimer.isRecording():
273                         session.open(MessageBox, _("A recording is currently running. Please stop the recording before trying to start the satfinder."), MessageBox.TYPE_ERROR)
274                 else:
275                         if len(nimList) == 1:
276                                 session.open(Satfinder, nimList[0])
277                         else:
278                                 session.open(NimSelection)
279
280 def SatfinderStart(menuid):
281         if menuid == "scan":
282                 return [(_("Satfinder"), SatfinderMain)]
283         else:
284                 return []
285
286 def Plugins(**kwargs):
287         if (nimmanager.hasNimType("DVB-T")):
288                 return PluginDescriptor(name=_("Satfinder"), description="Helps setting up your dish", where = PluginDescriptor.WHERE_SETUP, fnc=SatfinderStart)
289         else:
290                 return []