rewrite ServiceEventTracker and PerServiceBase service event handle code
[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
119         def createSetup(self):
120                 self.typeOfTuningEntry = None
121                 self.satEntry = None
122                 
123                 self.list = []
124                 self.typeOfTuningEntry = getConfigListEntry(_('Tune'), self.tuning_type)
125                 self.list.append(self.typeOfTuningEntry)
126                 self.satEntry = getConfigListEntry(_('Satellite'), self.tuning_sat)
127                 self.list.append(self.satEntry)
128                 if self.tuning_type.value == "manual_transponder":
129                         self.list.append(getConfigListEntry(_('Frequency'), self.scan_sat.frequency))
130                         self.list.append(getConfigListEntry(_('Inversion'), self.scan_sat.inversion))
131                         self.list.append(getConfigListEntry(_('Symbol Rate'), self.scan_sat.symbolrate))
132                         self.list.append(getConfigListEntry(_("Polarity"), self.scan_sat.polarization))
133                         self.list.append(getConfigListEntry(_("FEC"), self.scan_sat.fec))
134                 elif self.tuning_transponder and self.tuning_type.value == "predefined_transponder":
135                         self.list.append(getConfigListEntry(_("Transponder"), self.tuning_transponder))
136                 self["config"].list = self.list
137                 self["config"].l.setList(self.list)
138
139         def newConfig(self):
140                 if self["config"].getCurrent() == self.typeOfTuningEntry:
141                         self.createSetup()
142                 elif self["config"].getCurrent() == self.satEntry:
143                         self.updateSats()
144                         self.createSetup()
145
146         def sat_changed(self, config_element):
147                 self.newConfig()
148                 self.retune(config_element)
149
150         def retune(self, configElement):
151                 returnvalue = (0, 0, 0, 0, 0, 0, 0)
152                 satpos = self.tuning_sat.orbital_position
153                 
154                 if satpos is not None:
155                         if self.tuning_type.value == "manual_transponder":
156                                 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)
157                         elif self.tuning_type.value == "predefined_transponder":
158                                 transponder = nimmanager.getTransponders(satpos)[self.tuning_transponder.index]
159                                 returnvalue = (int(transponder[1] / 1000), int(transponder[2] / 1000), transponder[3], transponder[4], 2, satpos)
160                         self.tune(returnvalue)
161
162         def createConfig(self, foo):
163                 self.tuning_transponder = None
164                 self.tuning_type = ConfigSelection(choices = [("manual_transponder", _("Manual transponder")), ("predefined_transponder", _("Predefined transponder"))])
165                 self.tuning_sat = getConfigSatlist(192, nimmanager.getSatListForNim(self.feid))
166                 ScanSetup.createConfig(self, None)
167                 
168                 self.updateSats()
169                 
170                 self.tuning_type.addNotifier(self.retune, initial_call = False)
171                 self.tuning_sat.addNotifier(self.sat_changed, initial_call = False)
172                 self.scan_sat.frequency.addNotifier(self.retune, initial_call = False)
173                 self.scan_sat.inversion.addNotifier(self.retune, initial_call = False)
174                 self.scan_sat.symbolrate.addNotifier(self.retune, initial_call = False)
175                 self.scan_sat.polarization.addNotifier(self.retune, initial_call = False)
176                 self.scan_sat.fec.addNotifier(self.retune, initial_call = False)
177
178         def updateSats(self):
179                 orb_pos = self.tuning_sat.orbital_position
180                 if orb_pos is not None:
181                         transponderlist = nimmanager.getTransponders(orb_pos)
182                         list = []
183                         for x in transponderlist:
184                                 if x[3] == 0:
185                                         pol = "H"
186                                 elif x[3] == 1:
187                                         pol = "V"
188                                 elif x[3] == 2:
189                                         pol = "CL"
190                                 elif x[3] == 3:
191                                         pol = "CR"
192                                 else:
193                                         pol = "??"
194                                 if x[4] == 0:
195                                         fec = "FEC_AUTO"
196                                 elif x[4] == 1:
197                                         fec = "FEC_1_2"
198                                 elif x[4] == 2:
199                                         fec = "FEC_2_3"
200                                 elif x[4] == 3:
201                                         fec = "FEC_3_4"
202                                 elif x[4] == 4:
203                                         fec = "FEC_5_6"
204                                 elif x[4] == 5:
205                                         fec = "FEC_7_8"
206                                 elif x[4] == 6:
207                                         fec = "FEC_8_9"
208                                 elif x[4] == 7:
209                                         fec = "FEC_3_5"
210                                 elif x[4] == 8:
211                                         fec = "FEC_4_5"
212                                 elif x[4] == 9:
213                                         fec = "FEC_9_10"
214                                 elif x[4] == 15:
215                                         fec = "FEC_None"
216                                 else:
217                                         fec = "FEC_Unknown"
218                                 list.append(str(x[1]) + "," + str(x[2]) + "," + pol + "," + fec)
219                         self.tuning_transponder = ConfigSelection(choices = list)
220                         self.tuning_transponder.addNotifier(self.retune, initial_call = False)
221
222         def keyGo(self):
223                 self.retune(self.tuning_type)
224
225         def restartPrevService(self, yesno):
226                 if yesno:
227                         if self.frontend:
228                                 self.frontend = None
229                                 del self.raw_channel
230                         self.session.nav.playService(self.oldref)
231                 self.close(None)
232
233         def keyCancel(self):
234                 if self.oldref:
235                         self.session.openWithCallback(self.restartPrevService, MessageBox, _("Zap back to service before satfinder?"), MessageBox.TYPE_YESNO)
236                 else:
237                         self.restartPrevService(False)
238
239         def tune(self, transponder):
240                 if self.initcomplete:
241                         if transponder is not None:
242                                 self.tuner.tune(transponder)
243
244 class NimSelection(Screen):
245         skin = """
246                 <screen position="140,165" size="400,100" title="select Slot">
247                         <widget name="nimlist" position="20,10" size="360,75" />
248                 </screen>"""
249                 
250         def __init__(self, session):
251                 Screen.__init__(self, session)
252
253                 nimlist = nimmanager.getNimListOfType("DVB-S")
254                 nimMenuList = []
255                 for x in nimlist:
256                         nimMenuList.append((nimmanager.nim_slots[x].friendly_full_description, x))
257
258                 self["nimlist"] = MenuList(nimMenuList)
259
260                 self["actions"] = ActionMap(["OkCancelActions"],
261                 {
262                         "ok": self.okbuttonClick ,
263                         "cancel": self.close
264                 }, -1)
265
266         def okbuttonClick(self):
267                 selection = self["nimlist"].getCurrent()[1]
268                 self.session.open(Satfinder, selection)
269
270 def SatfinderMain(session, **kwargs):
271         nimList = nimmanager.getNimListOfType("DVB-S")
272         if len(nimList) == 0:
273                 session.open(MessageBox, _("No satellite frontend found!!"), MessageBox.TYPE_ERROR)
274         else:
275                 if session.nav.RecordTimer.isRecording():
276                         session.open(MessageBox, _("A recording is currently running. Please stop the recording before trying to start the satfinder."), MessageBox.TYPE_ERROR)
277                 else:
278                         if len(nimList) == 1:
279                                 session.open(Satfinder, nimList[0])
280                         else:
281                                 session.open(NimSelection)
282
283 def SatfinderStart(menuid, **kwargs):
284         if menuid == "scan":
285                 return [(_("Satfinder"), SatfinderMain, "satfinder", None)]
286         else:
287                 return []
288
289 def Plugins(**kwargs):
290         if (nimmanager.hasNimType("DVB-S")):
291                 return PluginDescriptor(name=_("Satfinder"), description="Helps setting up your dish", where = PluginDescriptor.WHERE_MENU, fnc=SatfinderStart)
292         else:
293                 return []