Satfinder: fix set value "nothing" if not sat list for tuner
[openblackhole/openblackhole-enigma2.git] / lib / python / Plugins / SystemPlugins / Satfinder / plugin.py
1 from enigma import eDVBResourceManager,\
2         eDVBFrontendParametersSatellite, eDVBFrontendParametersTerrestrial
3
4 from Screens.ScanSetup import ScanSetup, buildTerTransponder
5 from Screens.ServiceScan import ServiceScan
6 from Screens.MessageBox import MessageBox
7 from Plugins.Plugin import PluginDescriptor
8
9 from Components.Sources.FrontendStatus import FrontendStatus
10 from Components.ActionMap import ActionMap
11 from Components.NimManager import nimmanager, getConfigSatlist
12 from Components.config import config, ConfigSelection, getConfigListEntry
13 from Components.TuneTest import Tuner
14 from Tools.Transponder import getChannelNumber, channel2frequency
15
16 class Satfinder(ScanSetup, ServiceScan):
17         def __init__(self, session):
18                 self.initcomplete = False
19                 service = session and session.nav.getCurrentService()
20                 feinfo = service and service.frontendInfo()
21                 self.frontendData = feinfo and feinfo.getAll(True)
22                 del feinfo
23                 del service
24
25                 self.typeOfTuningEntry = None
26                 self.systemEntry = None
27                 self.satfinderTunerEntry = None
28                 self.satEntry = None
29                 self.typeOfInputEntry = None
30
31                 ScanSetup.__init__(self, session)
32                 self.setTitle(_("Satfinder"))
33                 self["introduction"].setText(_("Press OK to scan"))
34                 self["Frontend"] = FrontendStatus(frontend_source = lambda : self.frontend, update_interval = 100)
35
36                 self["actions"] = ActionMap(["SetupActions", "ColorActions"],
37                 {
38                         "save": self.keyGoScan,
39                         "ok": self.keyGoScan,
40                         "cancel": self.keyCancel,
41                 }, -3)
42
43                 self.initcomplete = True
44                 self.session.postScanService = self.session.nav.getCurrentlyPlayingServiceOrGroup()
45                 self.onClose.append(self.__onClose)
46                 self.onShow.append(self.prepareFrontend)
47
48         def openFrontend(self):
49                 res_mgr = eDVBResourceManager.getInstance()
50                 if res_mgr:
51                         self.raw_channel = res_mgr.allocateRawChannel(self.feid)
52                         if self.raw_channel:
53                                 self.frontend = self.raw_channel.getFrontend()
54                                 if self.frontend:
55                                         return True
56                 return False
57
58         def prepareFrontend(self):
59                 self.frontend = None
60                 if not self.openFrontend():
61                         self.session.nav.stopService()
62                         if not self.openFrontend():
63                                 if self.session.pipshown:
64                                         from Screens.InfoBar import InfoBar
65                                         InfoBar.instance and hasattr(InfoBar.instance, "showPiP") and InfoBar.instance.showPiP()
66                                         if not self.openFrontend():
67                                                 self.frontend = None # in normal case this should not happen
68                 self.tuner = Tuner(self.frontend)
69                 self.retune(None)
70
71         def __onClose(self):
72                 self.session.nav.playService(self.session.postScanService)
73
74         def newConfig(self):
75                 cur = self["config"].getCurrent()
76                 if cur in (self.typeOfTuningEntry, self.systemEntry, self.typeOfInputEntry):
77                         self.createSetup()
78                 elif cur == self.satfinderTunerEntry:
79                         self.feid = int(self.satfinder_scan_nims.value)
80                         self.createSetup()
81                         self.prepareFrontend()
82                         if self.frontend == None:
83                                 msg = _("Tuner not available.")
84                                 if self.session.nav.RecordTimer.isRecording():
85                                         msg += _("\nRecording in progress.")
86                                 self.session.open(MessageBox, msg, MessageBox.TYPE_ERROR)
87                 elif cur == self.satEntry:
88                         self.createSetup()
89                 else:
90                         self.retune(None)
91
92         def createSetup(self):
93                 self.list = []
94                 self.satfinderTunerEntry = getConfigListEntry(_("Tuner"), self.satfinder_scan_nims)
95                 self.list.append(self.satfinderTunerEntry)
96                 if nimmanager.nim_slots[int(self.satfinder_scan_nims.value)].isCompatible("DVB-S"):
97                         self.tuning_sat = self.scan_satselection[self.getSelectedSatIndex(self.feid)]
98                         self.satEntry = getConfigListEntry(_('Satellite'), self.tuning_sat)
99                         self.list.append(self.satEntry)
100                         self.typeOfTuningEntry = getConfigListEntry(_('Tune'), self.tuning_type)
101                         if len(nimmanager.getTransponders(int(self.tuning_sat.value))) < 1: # Only offer 'predefined transponder' if some transponders exist
102                                 self.tuning_type.value = "single_transponder"
103                         else:
104                                 self.list.append(self.typeOfTuningEntry)
105
106                         nim = nimmanager.nim_slots[self.feid]
107
108                         if self.tuning_type.value == "single_transponder":
109                                 if nim.isCompatible("DVB-S2"):
110                                         self.systemEntry = getConfigListEntry(_('System'), self.scan_sat.system)
111                                         self.list.append(self.systemEntry)
112                                 else:
113                                         # downgrade to dvb-s, in case a -s2 config was active
114                                         self.scan_sat.system.value = eDVBFrontendParametersSatellite.System_DVB_S
115                                 self.list.append(getConfigListEntry(_('Frequency'), self.scan_sat.frequency))
116                                 self.list.append(getConfigListEntry(_('Polarization'), self.scan_sat.polarization))
117                                 self.list.append(getConfigListEntry(_('Symbol rate'), self.scan_sat.symbolrate))
118                                 self.list.append(getConfigListEntry(_('Inversion'), self.scan_sat.inversion))
119                                 if self.scan_sat.system.value == eDVBFrontendParametersSatellite.System_DVB_S:
120                                         self.list.append(getConfigListEntry(_("FEC"), self.scan_sat.fec))
121                                 elif self.scan_sat.system.value == eDVBFrontendParametersSatellite.System_DVB_S2:
122                                         self.list.append(getConfigListEntry(_("FEC"), self.scan_sat.fec_s2))
123                                         self.modulationEntry = getConfigListEntry(_('Modulation'), self.scan_sat.modulation)
124                                         self.list.append(self.modulationEntry)
125                                         self.list.append(getConfigListEntry(_('Roll-off'), self.scan_sat.rolloff))
126                                         self.list.append(getConfigListEntry(_('Pilot'), self.scan_sat.pilot))
127                         elif self.tuning_type.value == "predefined_transponder":
128                                 self.updatePreDefTransponders()
129                                 self.list.append(getConfigListEntry(_("Transponder"), self.preDefTransponders))
130                 elif nimmanager.nim_slots[int(self.satfinder_scan_nims.value)].isCompatible("DVB-C"):
131                         self.typeOfTuningEntry = getConfigListEntry(_('Tune'), self.tuning_type)
132                         if config.Nims[self.feid].cable.scan_type.value != "provider" or len(nimmanager.getTranspondersCable(int(self.satfinder_scan_nims.value))) < 1: # only show 'predefined transponder' if in provider mode and transponders exist
133                                 self.tuning_type.value = "single_transponder"
134                         else:
135                                 self.list.append(self.typeOfTuningEntry)
136                         if self.tuning_type.value == "single_transponder":
137                                 self.list.append(getConfigListEntry(_("Frequency"), self.scan_cab.frequency))
138                                 self.list.append(getConfigListEntry(_("Inversion"), self.scan_cab.inversion))
139                                 self.list.append(getConfigListEntry(_("Symbol rate"), self.scan_cab.symbolrate))
140                                 self.list.append(getConfigListEntry(_("Modulation"), self.scan_cab.modulation))
141                                 self.list.append(getConfigListEntry(_("FEC"), self.scan_cab.fec))
142                         elif self.tuning_type.value == "predefined_transponder":
143                                 self.scan_nims.value = self.satfinder_scan_nims.value
144                                 self.predefinedCabTranspondersList()
145                                 self.list.append(getConfigListEntry(_('Transponder'), self.CableTransponders))
146                 elif nimmanager.nim_slots[int(self.satfinder_scan_nims.value)].isCompatible("DVB-T"):
147                         self.typeOfTuningEntry = getConfigListEntry(_('Tune'), self.tuning_type)
148                         region = nimmanager.getTerrestrialDescription(int(self.satfinder_scan_nims.value))
149                         if len(nimmanager.getTranspondersTerrestrial(region)) < 1: # Only offer 'predefined transponder' if some transponders exist
150                                 self.tuning_type.value = "single_transponder"
151                         else:
152                                 self.list.append(self.typeOfTuningEntry)
153                         if self.tuning_type.value == "single_transponder":
154                                 if nimmanager.nim_slots[int(self.satfinder_scan_nims.value)].isCompatible("DVB-T2"):
155                                         self.systemEntryTerr = getConfigListEntry(_('System'), self.scan_ter.system)
156                                         self.list.append(self.systemEntryTerr)
157                                 else:
158                                         self.scan_ter.system.value = eDVBFrontendParametersTerrestrial.System_DVB_T
159                                 self.typeOfInputEntry = getConfigListEntry(_("Use frequency or channel"), self.scan_input_as)
160                                 if self.ter_channel_input:
161                                         self.list.append(self.typeOfInputEntry)
162                                 else:
163                                         self.scan_input_as.value = self.scan_input_as.choices[0]
164                                 if self.ter_channel_input and self.scan_input_as.value == "channel":
165                                         channel = getChannelNumber(self.scan_ter.frequency.value*1000, self.ter_tnumber)
166                                         if channel:
167                                                 self.scan_ter.channel.value = int(channel.replace("+","").replace("-",""))
168                                         self.list.append(getConfigListEntry(_("Channel"), self.scan_ter.channel))
169                                 else:
170                                         prev_val = self.scan_ter.frequency.value
171                                         self.scan_ter.frequency.value = channel2frequency(self.scan_ter.channel.value, self.ter_tnumber)/1000
172                                         if self.scan_ter.frequency.value == 474000:
173                                                 self.scan_ter.frequency.value = prev_val
174                                         self.list.append(getConfigListEntry(_("Frequency"), self.scan_ter.frequency))
175                                 self.list.append(getConfigListEntry(_("Inversion"), self.scan_ter.inversion))
176                                 self.list.append(getConfigListEntry(_("Bandwidth"), self.scan_ter.bandwidth))
177                                 self.list.append(getConfigListEntry(_("Code rate HP"), self.scan_ter.fechigh))
178                                 self.list.append(getConfigListEntry(_("Code rate LP"), self.scan_ter.feclow))
179                                 self.list.append(getConfigListEntry(_("Modulation"), self.scan_ter.modulation))
180                                 self.list.append(getConfigListEntry(_("Transmission mode"), self.scan_ter.transmission))
181                                 self.list.append(getConfigListEntry(_("Guard interval"), self.scan_ter.guard))
182                                 self.list.append(getConfigListEntry(_("Hierarchy info"), self.scan_ter.hierarchy))
183                                 if self.scan_ter.system.value == eDVBFrontendParametersTerrestrial.System_DVB_T2:
184                                         self.list.append(getConfigListEntry(_('PLP ID'), self.scan_ter.plp_id))
185                         elif self.tuning_type.value == "predefined_transponder":
186                                 self.scan_nims.value = self.satfinder_scan_nims.value
187                                 self.predefinedTerrTranspondersList()
188                                 self.list.append(getConfigListEntry(_('Transponder'), self.TerrestrialTransponders))
189                 self.retune(None)
190                 self["config"].list = self.list
191                 self["config"].l.setList(self.list)
192
193         def createConfig(self, foo):
194                 self.tuning_type = ConfigSelection(default = "predefined_transponder", choices = [("single_transponder", _("User defined transponder")), ("predefined_transponder", _("Predefined transponder"))])
195                 self.orbital_position = 192
196                 if self.frontendData and self.frontendData.has_key('orbital_position'):
197                         self.orbital_position = self.frontendData['orbital_position']
198                 ScanSetup.createConfig(self, self.frontendData)
199
200                 for x in (self.scan_sat.frequency,
201                         self.scan_sat.inversion, self.scan_sat.symbolrate,
202                         self.scan_sat.polarization, self.scan_sat.fec, self.scan_sat.pilot,
203                         self.scan_sat.fec_s2, self.scan_sat.fec, self.scan_sat.modulation,
204                         self.scan_sat.rolloff, self.scan_sat.system,
205                         self.scan_ter.channel, self.scan_ter.frequency, self.scan_ter.inversion,
206                         self.scan_ter.bandwidth, self.scan_ter.fechigh, self.scan_ter.feclow,
207                         self.scan_ter.modulation, self.scan_ter.transmission,
208                         self.scan_ter.guard, self.scan_ter.hierarchy, self.scan_ter.plp_id,
209                         self.scan_cab.frequency, self.scan_cab.inversion, self.scan_cab.symbolrate,
210                         self.scan_cab.modulation, self.scan_cab.fec):
211                         x.addNotifier(self.retune, initial_call = False)
212
213                 satfinder_nim_list = []
214                 for n in nimmanager.nim_slots:
215                         if not (n.isCompatible("DVB-S") or n.isCompatible("DVB-T") or n.isCompatible("DVB-C")):
216                                 continue
217                         if n.config_mode  in ("loopthrough", "satposdepends", "nothing"):
218                                 continue
219                         if n.isCompatible("DVB-S") and n.config_mode == "advanced" and len(nimmanager.getSatListForNim(n.slot)) < 1:
220                                 continue
221                         satfinder_nim_list.append((str(n.slot), n.friendly_full_description))
222                 self.satfinder_scan_nims = ConfigSelection(choices = satfinder_nim_list)
223                 if self.frontendData is not None and len(satfinder_nim_list) > 0: # open the plugin with the currently active NIM as default
224                         self.satfinder_scan_nims.setValue(str(self.frontendData.get("tuner_number", satfinder_nim_list[0][0])))
225
226                 self.feid = int(self.satfinder_scan_nims.value)
227
228                 self.satList = []
229                 self.scan_satselection = []
230                 for slot in nimmanager.nim_slots:
231                         if slot.isCompatible("DVB-S"):
232                                 self.satList.append(nimmanager.getSatListForNim(slot.slot))
233                                 self.scan_satselection.append(getConfigSatlist(self.orbital_position, self.satList[slot.slot]))
234                         else:
235                                 self.satList.append(None)
236
237                 if self.frontendData:
238                         ttype = self.frontendData.get("tuner_type", "UNKNOWN")
239                         if ttype == "DVB-S" and self.predefinedTranspondersList(self.getSelectedSatIndex(self.feid)) is None and len(nimmanager.getTransponders(self.getSelectedSatIndex(self.feid))) > 0:
240                                 self.tuning_type.value = "single_transponder"
241                         elif ttype == "DVB-T" and self.predefinedTerrTranspondersList() is None and len(nimmanager.getTranspondersTerrestrial(nimmanager.getTerrestrialDescription(self.feid))) > 0:
242                                 self.tuning_type.value = "single_transponder"
243                         elif ttype == "DVB-C" and self.predefinedCabTranspondersList() is None and len(nimmanager.getTranspondersCable(self.feid)) > 0:
244                                 self.tuning_type.value = "single_transponder"
245
246         def getSelectedSatIndex(self, v):
247                 index    = 0
248                 none_cnt = 0
249                 for n in self.satList:
250                         if self.satList[index] is None:
251                                 none_cnt += 1
252                         if index == int(v):
253                                 return index-none_cnt
254                         index += 1
255                 return -1
256
257         def updatePreDefTransponders(self):
258                 ScanSetup.predefinedTranspondersList(self, self.tuning_sat.orbital_position)
259
260         def retuneCab(self, configElement):
261                 if not nimmanager.nim_slots[int(self.satfinder_scan_nims.value)].isCompatible("DVB-C"):
262                         return
263                 if self.initcomplete:
264                         if self.tuning_type.value == "single_transponder":
265                                 transponder = (
266                                         self.scan_cab.frequency.value*1000,
267                                         self.scan_cab.symbolrate.value*1000,
268                                         self.scan_cab.modulation.value,
269                                         self.scan_cab.fec.value,
270                                         self.scan_cab.inversion.value
271                                 )
272                                 if self.initcomplete:
273                                         self.tuner.tuneCab(transponder)
274                                 self.transponder = transponder
275                         elif self.tuning_type.value == "predefined_transponder":
276                                 tps = nimmanager.getTranspondersCable(int(self.satfinder_scan_nims.value))
277                                 if len(tps) > self.CableTransponders.index :
278                                         tp = tps[self.CableTransponders.index]
279                                         # tp = 0 transponder type, 1 freq, 2 sym, 3 mod, 4 fec, 5 inv, 6 sys
280                                         transponder = (tp[1], tp[2], tp[3], tp[4], tp[5])
281                                         if self.initcomplete:
282                                                 self.tuner.tuneCab(transponder)
283                                         self.transponder = transponder
284
285         def retuneTerr(self, configElement):
286                 if not nimmanager.nim_slots[int(self.satfinder_scan_nims.value)].isCompatible("DVB-T"):
287                         return self.retuneCab(configElement)
288                 if self.initcomplete:
289                         if self.scan_input_as.value == "channel":
290                                 frequency = channel2frequency(self.scan_ter.channel.value, self.ter_tnumber)
291                         else:
292                                 frequency = self.scan_ter.frequency.value * 1000
293                         if self.tuning_type.value == "single_transponder":
294                                 transponder = [
295                                         2, #TERRESTRIAL
296                                         frequency,
297                                         self.scan_ter.bandwidth.value,
298                                         self.scan_ter.modulation.value,
299                                         self.scan_ter.fechigh.value,
300                                         self.scan_ter.feclow.value,
301                                         self.scan_ter.guard.value,
302                                         self.scan_ter.transmission.value,
303                                         self.scan_ter.hierarchy.value,
304                                         self.scan_ter.inversion.value,
305                                         self.scan_ter.system.value,
306                                         self.scan_ter.plp_id.value]
307                                 if self.initcomplete:
308                                         self.tuner.tuneTerr(transponder[1], transponder[9], transponder[2], transponder[4], transponder[5], transponder[3], transponder[7], transponder[6], transponder[8], transponder[10], transponder[11])
309                                 self.transponder = transponder
310                         elif self.tuning_type.value == "predefined_transponder":
311                                 region = nimmanager.getTerrestrialDescription(int(self.satfinder_scan_nims.value))
312                                 tps = nimmanager.getTranspondersTerrestrial(region)
313                                 if len(tps) > self.TerrestrialTransponders.index :
314                                         transponder = tps[self.TerrestrialTransponders.index]
315                                         # frequency 1, inversion 9, bandwidth 2, fechigh 4, feclow 5, modulation 3, transmission 7, guard 6, hierarchy 8, system 10, plpid 11
316                                         if self.initcomplete:
317                                                 self.tuner.tuneTerr(transponder[1], transponder[9], transponder[2], transponder[4], transponder[5], transponder[3], transponder[7], transponder[6], transponder[8], transponder[10], transponder[11])
318                                         self.transponder = transponder
319
320         def retune(self, configElement): # satellite
321                 if not nimmanager.nim_slots[int(self.satfinder_scan_nims.value)].isCompatible("DVB-S"):
322                         return self.retuneTerr(configElement)
323                 if not self.tuning_sat.value:
324                         return
325                 satpos = int(self.tuning_sat.value)
326                 if self.tuning_type.value == "single_transponder":
327                         if self.scan_sat.system.value == eDVBFrontendParametersSatellite.System_DVB_S2:
328                                 fec = self.scan_sat.fec_s2.value
329                         else:
330                                 fec = self.scan_sat.fec.value
331                         transponder = (
332                                 self.scan_sat.frequency.value,
333                                 self.scan_sat.symbolrate.value,
334                                 self.scan_sat.polarization.value,
335                                 fec,
336                                 self.scan_sat.inversion.value,
337                                 satpos,
338                                 self.scan_sat.system.value,
339                                 self.scan_sat.modulation.value,
340                                 self.scan_sat.rolloff.value,
341                                 self.scan_sat.pilot.value)
342                         if self.initcomplete:
343                                 self.tuner.tune(transponder)
344                         self.transponder = transponder
345                 elif self.tuning_type.value == "predefined_transponder":
346                         tps = nimmanager.getTransponders(satpos)
347                         if len(tps) > self.preDefTransponders.index:
348                                 tp = tps[self.preDefTransponders.index]
349                                 transponder = (tp[1] / 1000, tp[2] / 1000,
350                                         tp[3], tp[4], 2, satpos, tp[5], tp[6], tp[8], tp[9])
351                                 if self.initcomplete:
352                                         self.tuner.tune(transponder)
353                                 self.transponder = transponder
354
355         def keyGoScan(self):
356                 self.frontend = None
357                 if self.raw_channel:
358                         del(self.raw_channel)
359                 tlist = []
360                 if nimmanager.nim_slots[int(self.satfinder_scan_nims.value)].isCompatible("DVB-S"):
361                         self.addSatTransponder(tlist,
362                                 self.transponder[0], # frequency
363                                 self.transponder[1], # sr
364                                 self.transponder[2], # pol
365                                 self.transponder[3], # fec
366                                 self.transponder[4], # inversion
367                                 self.tuning_sat.orbital_position,
368                                 self.transponder[6], # system
369                                 self.transponder[7], # modulation
370                                 self.transponder[8], # rolloff
371                                 self.transponder[9]  # pilot
372                         )
373                 elif nimmanager.nim_slots[int(self.satfinder_scan_nims.value)].isCompatible("DVB-T"):
374                         parm = buildTerTransponder(
375                                 self.transponder[1],  # frequency
376                                 self.transponder[9],  # inversion
377                                 self.transponder[2],  # bandwidth
378                                 self.transponder[4],  # fechigh
379                                 self.transponder[5],  # feclow
380                                 self.transponder[3],  # modulation
381                                 self.transponder[7],  # transmission
382                                 self.transponder[6],  # guard
383                                 self.transponder[8],  # hierarchy
384                                 self.transponder[10], # system
385                                 self.transponder[11]  # plpid
386                         )
387                         tlist.append(parm)
388                 else: # DVB-C
389                         self.addCabTransponder(tlist,
390                                 self.transponder[0], # frequency
391                                 self.transponder[1], # sr
392                                 self.transponder[2], # modulation
393                                 self.transponder[3], # fec_inner
394                                 self.transponder[4]  # inversion
395                         )
396                 self.startScan(tlist, self.feid)
397
398         def startScan(self, tlist, feid):
399                 flags = 0
400                 networkid = 0
401                 self.session.openWithCallback(self.startScanCallback, ServiceScan, [{"transponders": tlist, "feid": feid, "flags": flags, "networkid": networkid}])
402
403         def startScanCallback(self, answer=None):
404                 if answer:
405                         self.doCloseRecursive()
406
407         def keyCancel(self):
408                 if self.session.postScanService and self.frontend:
409                         self.frontend = None
410                         del self.raw_channel
411                 self.close(False)
412
413         def doCloseRecursive(self):
414                 if self.session.postScanService and self.frontend:
415                         self.frontend = None
416                         del self.raw_channel
417                 self.close(True)
418
419 def SatfinderMain(session, close=None, **kwargs):
420         nims = nimmanager.nim_slots
421         nimList = []
422         for n in nims:
423                 if not (n.isCompatible("DVB-S") or n.isCompatible("DVB-T") or n.isCompatible("DVB-C")):
424                         continue
425                 if n.config_mode in ("loopthrough", "satposdepends", "nothing"):
426                         continue
427                 if n.isCompatible("DVB-S") and n.config_mode in ("advanced", "simple") and len(nimmanager.getSatListForNim(n.slot)) < 1:
428                         config.Nims[n.slot].configMode.value = "nothing"
429                         config.Nims[n.slot].configMode.save()
430                         continue
431                 nimList.append(n)
432
433         if len(nimList) == 0:
434                 session.open(MessageBox, _("No satellite, terrestrial or cable tuner is configured. Please check your tuner setup."), MessageBox.TYPE_ERROR)
435         else:
436                 session.openWithCallback(close, Satfinder)
437
438 def SatfinderStart(menuid, **kwargs):
439         if menuid == "scan":
440                 return [(_("Satfinder"), SatfinderMain, "satfinder", None)]
441         else:
442                 return []
443
444 def Plugins(**kwargs):
445         if nimmanager.hasNimType("DVB-S") or nimmanager.hasNimType("DVB-T") or nimmanager.hasNimType("DVB-C"):
446                 return PluginDescriptor(name=_("Satfinder"), description=_("Helps setting up your antenna"), where = PluginDescriptor.WHERE_MENU, needsRestart = False, fnc=SatfinderStart)
447         else:
448                 return []