bug fix
[vuplus_dvbapp] / lib / python / Plugins / SystemPlugins / Blindscan / plugin.py
1 from Plugins.Plugin import PluginDescriptor
2
3 from Screens.Screen import Screen
4 from Screens.ServiceScan import ServiceScan
5 from Screens.MessageBox import MessageBox
6 from Screens.DefaultWizard import DefaultWizard
7
8 from Components.Label import Label
9 from Components.TuneTest import Tuner
10 from Components.ConfigList import ConfigListScreen
11 from Components.Sources.StaticText import StaticText
12 from Components.ActionMap import NumberActionMap, ActionMap
13 from Components.NimManager import nimmanager, getConfigSatlist
14 from Components.config import config, ConfigSubsection, ConfigSelection, ConfigYesNo, ConfigInteger, getConfigListEntry, ConfigSlider, ConfigEnableDisable
15
16 from Tools.HardwareInfo import HardwareInfo
17 from Tools.Directories import resolveFilename, SCOPE_DEFAULTPARTITIONMOUNTDIR, SCOPE_DEFAULTDIR, SCOPE_DEFAULTPARTITION
18
19 from enigma import eTimer, eDVBFrontendParametersSatellite, eComponentScan, eDVBSatelliteEquipmentControl, eDVBFrontendParametersTerrestrial, eDVBFrontendParametersCable, eConsoleAppContainer, eDVBResourceManager
20
21 class SatBlindscanSearchSupport:
22         def blindTransponderSearchSessionClosed(self, *val):
23                 self.blind_search_container.appClosed.remove(self.blindScanSearchClosed)
24                 self.blind_search_container.dataAvail.remove(self.getBlindTransponderData)
25                 if val and len(val):
26                         if val[0]:
27                                 self.tlist = self.__tlist
28                                 print self.__tlist
29                 if self.frontend:
30                         self.frontend = None
31                         del self.raw_channel
32
33                 self.blind_search_container.sendCtrlC()
34                 import time
35                 time.sleep(2)
36
37                 self.blind_search_container = None
38                 self.blind_search_container = None
39                 self.__tlist = None
40
41                 if self.tlist is None:
42                         self.tlist = []
43                 else:
44                         self.startScan(self.tlist, self.flags, self.feid)
45                 
46         def blindScanSearchClosed(self, retval):
47                 self.blind_search_session.close(True)
48
49         def getBlindTransponderData(self, str):
50                 str = self.remainingdata + str
51                 #split in lines
52                 lines = str.split('\n')
53                 #'str' should end with '\n', so when splitting, the last line should be empty. If this is not the case, we received an incomplete line
54                 if len(lines[-1]):
55                         #remember this data for next time
56                         self.remainingdata = lines[-1]
57                         lines = lines[0:-1]
58                 else:
59                         self.remainingdata = ""
60
61                 for line in lines:
62                         data = line.split()
63                         if len(data):
64                                 print data
65                                 if data[0] == 'OK':
66                                         parm = eDVBFrontendParametersSatellite()
67                                         sys = {         "DVB-S" : eDVBFrontendParametersSatellite.System_DVB_S,
68                                                         "DVB-S2" : eDVBFrontendParametersSatellite.System_DVB_S2        }
69                                         qam = {         "QPSK" : parm.Modulation_QPSK,
70                                                         "8PSK" : parm.Modulation_8PSK }
71                                         inv = {         "INVERSION_OFF" : parm.Inversion_Off,
72                                                         "INVERSION_ON" : parm.Inversion_On,
73                                                         "INVERSION_AUTO" : parm.Inversion_Unknown }
74                                         fec = {         "FEC_AUTO" : parm.FEC_Auto,
75                                                         "FEC_1_2" : parm.FEC_1_2,
76                                                         "FEC_2_3" : parm.FEC_2_3,
77                                                         "FEC_3_4" : parm.FEC_3_4,
78                                                         "FEC_5_6": parm.FEC_5_6,
79                                                         "FEC_7_8" : parm.FEC_7_8,
80                                                         "FEC_8_9" : parm.FEC_8_9,
81                                                         "FEC_3_5" : parm.FEC_3_5,
82                                                         "FEC_9_10" : parm.FEC_9_10,
83                                                         "FEC_NONE" : parm.FEC_None }
84                                         roll = {        "ROLLOFF_20" : parm.RollOff_alpha_0_20,
85                                                         "ROLLOFF_25" : parm.RollOff_alpha_0_25,
86                                                         "ROLLOFF_35" : parm.RollOff_alpha_0_35 }
87                                         pilot = {       "PILOT_ON" : parm.Pilot_On,
88                                                         "PILOT_OFF" : parm.Pilot_Off }
89                                         pol = { "HORIZONTAL" : parm.Polarisation_Horizontal,
90                                                         "VERTICAL" : parm.Polarisation_Vertical }
91
92                                         sat = self.satList[0][self.scan_satselection[0].index]
93                                         parm.orbital_position = sat[0]
94                                         
95                                         parm.polarisation = pol[data[1]]
96                                         parm.frequency = int(data[2])
97                                         parm.symbol_rate = int(data[3])
98                                         parm.system = sys[data[4]]
99                                         parm.inversion = inv[data[5]]
100                                         parm.pilot = pilot[data[6]]
101                                         parm.fec = fec[data[7]]
102                                         parm.modulation = qam[data[8]]
103                                         parm.rolloff = roll[data[9]]
104                                         self.__tlist.append(parm)
105                                         flags = None
106
107         def openFrontend(self):
108                 res_mgr = eDVBResourceManager.getInstance()
109                 if res_mgr:
110                         self.raw_channel = res_mgr.allocateRawChannel(self.feid)
111                         if self.raw_channel:
112                                 self.frontend = self.raw_channel.getFrontend()
113                                 if self.frontend:
114                                         return True
115                                 else:
116                                         print "getFrontend failed"
117                         else:
118                                 print "getRawChannel failed"
119                 else:
120                         print "getResourceManager instance failed"
121                 return False
122
123         def startSatBlindscanSearch(self, nim_idx, orbpos, session):
124                 if self.blindscan_start_frequency.value < 950*1000000 or self.blindscan_start_frequency.value > 2150*1000000 :
125                         self.session.open(MessageBox, _("Please check again.\nStart frequency must be between 950 and 2150."), MessageBox.TYPE_ERROR)
126                         return
127                 if self.blindscan_stop_frequency.value < 950*1000000 or self.blindscan_stop_frequency.value > 2150*1000000 :
128                         self.session.open(MessageBox, _("Please check again.\nStop frequency must be between 950 and 2150."), MessageBox.TYPE_ERROR)
129                         return
130                 if self.blindscan_start_frequency.value > self.blindscan_stop_frequency.value :
131                         self.session.open(MessageBox, _("Please check again.\nFrequency : start value is larger than stop value."), MessageBox.TYPE_ERROR)
132                         return
133                 if self.blindscan_start_symbol.value < 2*1000000 or self.blindscan_start_symbol.value > 45*1000000 :
134                         self.session.open(MessageBox, _("Please check again.\nStart symbolrate must be between 2MHz and 45MHz."), MessageBox.TYPE_ERROR)
135                         return
136                 if self.blindscan_stop_symbol.value < 2*1000000 or self.blindscan_stop_symbol.value > 45*1000000 :
137                         self.session.open(MessageBox, _("Please check again.\nStop symbolrate must be between 2MHz and 45MHz."), MessageBox.TYPE_ERROR)
138                         return
139                 if self.blindscan_start_symbol.value > self.blindscan_stop_symbol.value :
140                         self.session.open(MessageBox, _("Please check again.\nSymbolrate : start value is larger than stop value."), MessageBox.TYPE_ERROR)
141                         return
142                 
143                 self.__tlist = [ ]
144                 self.remainingdata = ""
145                 self.feid = nim_idx
146                 if not self.openFrontend():
147                         self.oldref = session.nav.getCurrentlyPlayingServiceReference()
148                         session.nav.stopService() # try to disable foreground service
149                         if not self.openFrontend():
150                                 if session.pipshown: # try to disable pip
151                                         session.pipshown = False
152                                         del session.pip
153                                         if not self.openFrontend():
154                                                 self.frontend = None # in normal case this should not happen
155
156                 self.tuner = Tuner(self.frontend)
157                 sat = self.satList[0][self.scan_satselection[0].index]
158
159                 tab_hilow               = {"high" : 1, "low" : 0}
160                 returnvalue     = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
161                 if tab_hilow[self.blindscan_hi.value]:
162                         self.scan_sat.frequency.value = 12515
163                 else:
164                         self.scan_sat.frequency.value = 11015
165                 returnvalue = (self.scan_sat.frequency.value,
166                                          0,
167                                          self.scan_sat.polarization.value,
168                                          0,
169                                          0,
170                                          int(orbpos[0]),
171                                          eDVBFrontendParametersSatellite.System_DVB_S,
172                                          0,
173                                          0,
174                                          0)
175                 self.tuner.tune(returnvalue)
176
177                 self.blind_search_container = eConsoleAppContainer()
178                 self.blind_search_container.appClosed.append(self.blindScanSearchClosed)
179                 self.blind_search_container.dataAvail.append(self.getBlindTransponderData)
180                 cmd = "/usr/lib/enigma2/python/Plugins/SystemPlugins/Blindscan/vuplus_blindscan %d %d %d %d %d %d %d" % (self.blindscan_start_frequency.value/1000000, self.blindscan_stop_frequency.value/1000000, self.blindscan_start_symbol.value/1000000, self.blindscan_stop_symbol.value/1000000, self.scan_sat.polarization.value, tab_hilow[self.blindscan_hi.value], self.feid)
181                 print "prepared command : ", cmd
182                 self.blind_search_container.execute(cmd)
183                 
184                 tmpstr = _("Blindscan takes some minute.")
185                 self.blind_search_session = self.session.openWithCallback(self.blindTransponderSearchSessionClosed, MessageBox, tmpstr, MessageBox.TYPE_INFO)
186
187 class Blindscan(ConfigListScreen, Screen, SatBlindscanSearchSupport):
188         skin="""
189                 <screen name="Blindscan" position="center,center" size="560,250" title="Blindscan">
190                         <ePixmap pixmap="Vu_HD/buttons/red.png" position="5,0" size="140,40" alphatest="on" />
191                         <ePixmap pixmap="Vu_HD/buttons/green.png" position="145,0" size="140,40" alphatest="on" />
192                         <ePixmap pixmap="Vu_HD/buttons/button_off.png" position="285,0" size="140,40" alphatest="on" />
193                         <ePixmap pixmap="Vu_HD/buttons/button_off.png" position="425,0" size="140,40" alphatest="on" />
194                         <widget source="key_red" render="Label" position="20,0" zPosition="1" size="115,30" font="Regular;20" halign="center" valign="center" transparent="1" />
195                         <widget source="key_green" render="Label" position="160,0" zPosition="1" size="115,30" font="Regular;20" halign="center" valign="center" transparent="1" />
196                         <widget name="config" position="5,50" size="550,200" scrollbarMode="showOnDemand" />
197                 </screen>
198                 """
199         def __init__(self, session): 
200                 Screen.__init__(self, session)
201
202                 self.updateSatList()
203                 self.service = session.nav.getCurrentService()
204                 self.current_play_service = self.session.nav.getCurrentlyPlayingServiceReference()
205                 self.feinfo = None
206                 self.networkid = 0
207                 frontendData = None
208                 if self.service is not None:
209                         self.feinfo = self.service.frontendInfo()
210                         frontendData = self.feinfo and self.feinfo.getAll(True)
211                 
212                 self.createConfig(frontendData)
213
214                 del self.feinfo
215                 del self.service
216
217                 self["actions"] = ActionMap(["OkCancelActions", "ShortcutActions", "WizardActions", "ColorActions", "SetupActions", ],
218                 {
219                         "red": self.keyCancel,
220                         "green": self.keyGo,
221                         "ok": self.keyGo,
222                         "cancel": self.keyCancel,
223                 }, -2)
224
225                 self.statusTimer = eTimer()
226                 self.statusTimer.callback.append(self.updateStatus)
227
228                 self.list = []
229                 ConfigListScreen.__init__(self, self.list)
230                 
231                 self["key_red"] = StaticText(_("Exit"))
232                 self["key_green"] = StaticText("Start")
233                 
234                 #if not self.scan_nims.value == "":
235                 #       self.createSetup()
236                 try:
237                         if not self.scan_nims.value == "":
238                                 self.createSetup()
239                 except:
240                         self["actions"] = ActionMap(["OkCancelActions", "ShortcutActions", "WizardActions", "ColorActions", "SetupActions", ],
241                         {
242                                 "red": self.keyCancel,
243                                 "green": self.keyNone,
244                                 "ok": self.keyNone,
245                                 "cancel": self.keyCancel,
246                         }, -2)
247                         self["key_red"] = StaticText(_("Exit"))
248                         self["key_green"] = StaticText(" ")
249
250         def keyNone(self):
251                 None
252                 
253         def updateSatList(self):
254                 self.satList = []
255                 for slot in nimmanager.nim_slots:
256                         if slot.isCompatible("DVB-S"):
257                                 self.satList.append(nimmanager.getSatListForNim(slot.slot))
258                         else:
259                                 self.satList.append(None)
260
261         def createConfig(self, frontendData):
262                 defaultSat = {
263                         "orbpos": 192,
264                         "system": eDVBFrontendParametersSatellite.System_DVB_S,
265                         "frequency": 11836,
266                         "inversion": eDVBFrontendParametersSatellite.Inversion_Unknown,
267                         "symbolrate": 27500,
268                         "polarization": eDVBFrontendParametersSatellite.Polarisation_Horizontal,
269                         "fec": eDVBFrontendParametersSatellite.FEC_Auto,
270                         "fec_s2": eDVBFrontendParametersSatellite.FEC_9_10,
271                         "modulation": eDVBFrontendParametersSatellite.Modulation_QPSK }
272                 if frontendData is not None:
273                         ttype = frontendData.get("tuner_type", "UNKNOWN")
274                         if ttype == "DVB-S":
275                                 defaultSat["system"] = frontendData.get("system", eDVBFrontendParametersSatellite.System_DVB_S)
276                                 defaultSat["frequency"] = frontendData.get("frequency", 0) / 1000
277                                 defaultSat["inversion"] = frontendData.get("inversion", eDVBFrontendParametersSatellite.Inversion_Unknown)
278                                 defaultSat["symbolrate"] = frontendData.get("symbol_rate", 0) / 1000
279                                 defaultSat["polarization"] = frontendData.get("polarization", eDVBFrontendParametersSatellite.Polarisation_Horizontal)
280                                 if defaultSat["system"] == eDVBFrontendParametersSatellite.System_DVB_S2:
281                                         defaultSat["fec_s2"] = frontendData.get("fec_inner", eDVBFrontendParametersSatellite.FEC_Auto)
282                                         defaultSat["rolloff"] = frontendData.get("rolloff", eDVBFrontendParametersSatellite.RollOff_alpha_0_35)
283                                         defaultSat["pilot"] = frontendData.get("pilot", eDVBFrontendParametersSatellite.Pilot_Unknown)
284                                 else:
285                                         defaultSat["fec"] = frontendData.get("fec_inner", eDVBFrontendParametersSatellite.FEC_Auto)
286                                 defaultSat["modulation"] = frontendData.get("modulation", eDVBFrontendParametersSatellite.Modulation_QPSK)
287                                 defaultSat["orbpos"] = frontendData.get("orbital_position", 0)
288                                 
289                 self.scan_sat = ConfigSubsection()
290                 self.scan_networkScan = ConfigYesNo(default = False)
291                 
292                 # blindscan add
293                 self.blindscan_hi = ConfigSelection(default = "low", choices = [("low", _("low")), ("high", _("high"))])
294
295                 #ConfigYesNo(default = True)
296                 self.blindscan_start_frequency = ConfigInteger(default = 950*1000000)
297                 self.blindscan_stop_frequency = ConfigInteger(default = 2150*1000000)
298                 self.blindscan_start_symbol = ConfigInteger(default = 2*1000000)
299                 self.blindscan_stop_symbol = ConfigInteger(default = 45*1000000)
300
301                 nim_list = []
302                 # collect all nims which are *not* set to "nothing"
303                 for n in nimmanager.nim_slots:
304                         if n.config_mode == "nothing":
305                                 continue
306                         if n.config_mode == "advanced" and len(nimmanager.getSatListForNim(n.slot)) < 1:
307                                 continue
308                         if n.config_mode in ("loopthrough", "satposdepends"):
309                                 root_id = nimmanager.sec.getRoot(n.slot_id, int(n.config.connectedTo.value))
310                                 if n.type == nimmanager.nim_slots[root_id].type: # check if connected from a DVB-S to DVB-S2 Nim or vice versa
311                                         continue
312                         nim_list.append((str(n.slot), n.friendly_full_description))
313
314                 self.scan_nims = ConfigSelection(choices = nim_list)
315         
316                 # status
317                 self.scan_snr = ConfigSlider()
318                 self.scan_snr.enabled = False
319                 self.scan_agc = ConfigSlider()
320                 self.scan_agc.enabled = False
321                 self.scan_ber = ConfigSlider()
322                 self.scan_ber.enabled = False
323
324                 # sat
325                 self.scan_sat.frequency = ConfigInteger(default = defaultSat["frequency"], limits = (1, 99999))
326                 self.scan_sat.polarization = ConfigSelection(default = defaultSat["polarization"], choices = [
327                         (eDVBFrontendParametersSatellite.Polarisation_Horizontal, _("horizontal")),
328                         (eDVBFrontendParametersSatellite.Polarisation_Vertical, _("vertical")),
329                         (eDVBFrontendParametersSatellite.Polarisation_CircularLeft, _("circular left")),
330                         (eDVBFrontendParametersSatellite.Polarisation_CircularRight, _("circular right"))])
331                 self.scan_scansat = {}
332                 for sat in nimmanager.satList:
333                         self.scan_scansat[sat[0]] = ConfigYesNo(default = False)
334                 
335                 self.scan_satselection = []
336                 for slot in nimmanager.nim_slots:
337                         if slot.isCompatible("DVB-S"):
338                                 self.scan_satselection.append(getConfigSatlist(defaultSat["orbpos"], self.satList[slot.slot]))
339                         else:
340                                 self.scan_satselection.append(None)
341                 return True
342                         
343                         
344         def newConfig(self):
345                 cur = self["config"].getCurrent()
346                 print "cur is", cur
347                 if cur == self.tunerEntry or \
348                         cur == self.systemEntry or \
349                         (self.modulationEntry and self.systemEntry[1].value == eDVBFrontendParametersSatellite.System_DVB_S2 and cur == self.modulationEntry):
350                         self.createSetup()
351
352         def keyLeft(self):
353                 ConfigListScreen.keyLeft(self)
354                 self.newConfig()
355
356         def keyRight(self):
357                 ConfigListScreen.keyRight(self)
358                 self.newConfig()
359                 
360         def updateStatus(self):
361                 print "updatestatus"
362
363         def keyGo(self):
364                 if self.scan_nims.value == "":
365                         return
366                 tlist = []
367                 flags = None
368                 removeAll = True
369                 index_to_scan = int(self.scan_nims.value)
370                 
371                 if self.scan_nims == [ ]:
372                         self.session.open(MessageBox, _("No tuner is enabled!\nPlease setup your tuner settings before you start a service scan."), MessageBox.TYPE_ERROR)
373                         return
374
375                 nim = nimmanager.nim_slots[index_to_scan]
376                 print "nim", nim.slot
377                 if nim.isCompatible("DVB-S") :
378                         print "is compatible with DVB-S"
379                 else:
380                         print "is not compatible with DVB-S"
381                         return
382
383                 flags = self.scan_networkScan.value and eComponentScan.scanNetworkSearch or 0
384                 for x in self["config"].list:
385                         x[1].save()
386
387                 self.flags = flags
388                 self.feid = index_to_scan
389                 self.tlist = []
390                 orbpos = self.satList[index_to_scan][self.scan_satselection[index_to_scan].index]
391                 self.startSatBlindscanSearch(index_to_scan, orbpos, self.session)
392                         
393         def keyCancel(self):
394                 for x in self["config"].list:
395                         x[1].cancel()
396                 self.session.nav.playService(self.current_play_service)
397                 self.close()
398
399         def startScan(self, tlist, flags, feid, networkid = 0):
400                 if len(tlist):
401                         self.session.open(ServiceScan, [{"transponders": tlist, "feid": feid, "flags": flags, "networkid": networkid}])
402                 else:
403                         self.session.open(MessageBox, _("Nothing to scan!\nPlease setup your tuner settings before you start a service scan."), MessageBox.TYPE_ERROR)
404
405         def createSetup(self):
406                 self.list = []
407                 self.multiscanlist = []
408                 index_to_scan = int(self.scan_nims.value)
409                 print "ID: ", index_to_scan
410
411                 self.tunerEntry = getConfigListEntry(_("Tuner"), self.scan_nims)
412                 self.list.append(self.tunerEntry)
413                 
414                 if self.scan_nims == [ ]:
415                         return
416                 
417                 self.systemEntry = None
418                 self.modulationEntry = None
419                 nim = nimmanager.nim_slots[index_to_scan]
420                 
421                 self.scan_networkScan.value = False
422                 if nim.isCompatible("DVB-S") :
423                         self.list.append(getConfigListEntry(_('Satellite'), self.scan_satselection[index_to_scan]))
424                         self.list.append(getConfigListEntry(_('Scan start frequency'), self.blindscan_start_frequency))
425                         self.list.append(getConfigListEntry(_('Scan stop frequency'), self.blindscan_stop_frequency))
426                         self.list.append(getConfigListEntry(_("Polarity"), self.scan_sat.polarization))
427                         self.list.append(getConfigListEntry(_("Scan band"), self.blindscan_hi))
428                         self.list.append(getConfigListEntry(_('Scan start symbolrate'), self.blindscan_start_symbol))
429                         self.list.append(getConfigListEntry(_('Scan stop symbolrate'), self.blindscan_stop_symbol))
430                         self["config"].list = self.list
431                         self["config"].l.setList(self.list)
432                 else:
433                         self.session.open(MessageBox, _("Please setup DVB-S Tuner"), MessageBox.TYPE_ERROR)
434
435
436 def main(session, **kwargs):
437         session.open(Blindscan)
438                                                            
439 def Plugins(**kwargs):            
440         return PluginDescriptor(name=_("Blindscan"), description="scan type(DVB-S)", where = PluginDescriptor.WHERE_PLUGINMENU, fnc=main)
441