27aedde36fa8d5e045e6b2ed3ad59fb7b8a6726e
[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 = _("Preparing scanning... \nPlease wait a few minutes.")
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
237         def updateSatList(self):
238                 self.satList = []
239                 for slot in nimmanager.nim_slots:
240                         if slot.isCompatible("DVB-S"):
241                                 self.satList.append(nimmanager.getSatListForNim(slot.slot))
242                         else:
243                                 self.satList.append(None)
244
245         def createConfig(self, frontendData):
246                 defaultSat = {"orbpos": 192, "frequency": 11836, "polarization": eDVBFrontendParametersSatellite.Polarisation_Horizontal}
247
248                 if frontendData is not None:
249                         ttype = frontendData.get("tuner_type", "UNKNOWN")
250                         defaultSat["orbpos"] = frontendData.get("orbital_position", 0)
251                         defaultSat["frequency"] = frontendData.get("frequency", 0) / 1000
252                         defaultSat["polarization"] = frontendData.get("polarization", eDVBFrontendParametersSatellite.Polarisation_Horizontal)
253                         
254                         self.scan_sat = ConfigSubsection()
255                         self.scan_networkScan = ConfigYesNo(default = False)
256                         
257                         # blindscan add
258                         self.blindscan_hi = ConfigSelection(default = "low", choices = [("low", _("low")), ("high", _("high"))])
259
260                         #ConfigYesNo(default = True)
261                         self.blindscan_start_frequency = ConfigInteger(default = 950*1000000)
262                         self.blindscan_stop_frequency = ConfigInteger(default = 2150*1000000)
263                         self.blindscan_start_symbol = ConfigInteger(default = 2*1000000)
264                         self.blindscan_stop_symbol = ConfigInteger(default = 45*1000000)
265
266                         nim_list = []
267                         # collect all nims which are *not* set to "nothing"
268                         for n in nimmanager.nim_slots:
269                                 if n.config_mode == "nothing":
270                                         continue
271                                 if n.config_mode == "advanced" and len(nimmanager.getSatListForNim(n.slot)) < 1:
272                                         continue
273                                 if n.config_mode in ("loopthrough", "satposdepends"):
274                                         root_id = nimmanager.sec.getRoot(n.slot_id, int(n.config.connectedTo.value))
275                                         if n.type == nimmanager.nim_slots[root_id].type: # check if connected from a DVB-S to DVB-S2 Nim or vice versa
276                                                 continue
277                                 nim_list.append((str(n.slot), n.friendly_full_description))
278
279                         self.scan_nims = ConfigSelection(choices = nim_list)
280
281                         # status
282                         self.scan_snr = ConfigSlider()
283                         self.scan_snr.enabled = False
284                         self.scan_agc = ConfigSlider()
285                         self.scan_agc.enabled = False
286                         self.scan_ber = ConfigSlider()
287                         self.scan_ber.enabled = False
288
289                         # sat
290                         self.scan_sat.frequency = ConfigInteger(default = defaultSat["frequency"], limits = (1, 99999))
291                         self.scan_sat.polarization = ConfigSelection(default = defaultSat["polarization"], choices = [
292                                 (eDVBFrontendParametersSatellite.Polarisation_Horizontal, _("horizontal")),
293                                 (eDVBFrontendParametersSatellite.Polarisation_Vertical, _("vertical")),
294                                 (eDVBFrontendParametersSatellite.Polarisation_CircularLeft, _("circular left")),
295                                 (eDVBFrontendParametersSatellite.Polarisation_CircularRight, _("circular right"))])
296                         self.scan_scansat = {}
297                         for sat in nimmanager.satList:
298                                 self.scan_scansat[sat[0]] = ConfigYesNo(default = False)
299                         
300                         self.scan_satselection = []
301                         for slot in nimmanager.nim_slots:
302                                 if slot.isCompatible("DVB-S"):
303                                         self.scan_satselection.append(getConfigSatlist(defaultSat["orbpos"], self.satList[slot.slot]))
304                                 else:
305                                         self.scan_satselection.append(None)
306                         return True
307                         
308         def newConfig(self):
309                 cur = self["config"].getCurrent()
310                 print "cur is", cur
311                 if cur == self.tunerEntry or \
312                         cur == self.systemEntry or \
313                         (self.modulationEntry and self.systemEntry[1].value == eDVBFrontendParametersSatellite.System_DVB_S2 and cur == self.modulationEntry):
314                         self.createSetup()
315
316         def keyLeft(self):
317                 ConfigListScreen.keyLeft(self)
318                 self.newConfig()
319
320         def keyRight(self):
321                 ConfigListScreen.keyRight(self)
322                 self.newConfig()
323                 
324         def updateStatus(self):
325                 print "updatestatus"
326
327         def keyGo(self):
328                 if self.scan_nims.value == "":
329                         return
330                 tlist = []
331                 flags = None
332                 removeAll = True
333                 index_to_scan = int(self.scan_nims.value)
334                 
335                 if self.scan_nims == [ ]:
336                         self.session.open(MessageBox, _("No tuner is enabled!\nPlease setup your tuner settings before you start a service scan."), MessageBox.TYPE_ERROR)
337                         return
338
339                 nim = nimmanager.nim_slots[index_to_scan]
340                 print "nim", nim.slot
341                 if nim.isCompatible("DVB-S") :
342                         print "is compatible with DVB-S"
343                 else:
344                         print "is not compatible with DVB-S"
345                         return
346
347                 flags = self.scan_networkScan.value and eComponentScan.scanNetworkSearch or 0
348                 for x in self["config"].list:
349                         x[1].save()
350
351                 self.flags = flags
352                 self.feid = index_to_scan
353                 self.tlist = []
354                 orbpos = self.satList[index_to_scan][self.scan_satselection[index_to_scan].index]
355                 self.startSatBlindscanSearch(index_to_scan, orbpos, self.session)
356                         
357         def keyCancel(self):
358                 for x in self["config"].list:
359                         x[1].cancel()
360                 self.session.nav.playService(self.current_play_service)
361                 self.close()
362
363         def startScan(self, tlist, flags, feid, networkid = 0):
364                 if len(tlist):
365                         self.session.open(ServiceScan, [{"transponders": tlist, "feid": feid, "flags": flags, "networkid": networkid}])
366                 else:
367                         self.session.open(MessageBox, _("Nothing to scan!\nPlease setup your tuner settings before you start a service scan."), MessageBox.TYPE_ERROR)
368
369         def createSetup(self):
370                 self.list = []
371                 self.multiscanlist = []
372                 index_to_scan = int(self.scan_nims.value)
373                 print "ID: ", index_to_scan
374
375                 self.tunerEntry = getConfigListEntry(_("Tuner"), self.scan_nims)
376                 self.list.append(self.tunerEntry)
377                 
378                 if self.scan_nims == [ ]:
379                         return
380                 
381                 self.systemEntry = None
382                 self.modulationEntry = None
383                 nim = nimmanager.nim_slots[index_to_scan]
384                 
385                 self.scan_networkScan.value = False
386                 if nim.isCompatible("DVB-S") :
387                         self.list.append(getConfigListEntry(_('Satellite'), self.scan_satselection[index_to_scan]))
388                         self.list.append(getConfigListEntry(_('Scan start frequency'), self.blindscan_start_frequency))
389                         self.list.append(getConfigListEntry(_('Scan stop frequency'), self.blindscan_stop_frequency))
390                         self.list.append(getConfigListEntry(_("Polarity"), self.scan_sat.polarization))
391                         self.list.append(getConfigListEntry(_("Scan band"), self.blindscan_hi))
392                         self.list.append(getConfigListEntry(_('Scan start symbolrate'), self.blindscan_start_symbol))
393                         self.list.append(getConfigListEntry(_('Scan stop symbolrate'), self.blindscan_stop_symbol))
394                         self["config"].list = self.list
395                         self["config"].l.setList(self.list)
396                 else:
397                         self.session.open(MessageBox, _("Please setup DVB-S Tuner"), MessageBox.TYPE_ERROR)
398
399 def main(session, **kwargs):
400         session.open(Blindscan)
401                                                            
402 def Plugins(**kwargs):            
403         return PluginDescriptor(name=_("Blindscan"), description="scan type(DVB-S)", where = PluginDescriptor.WHERE_PLUGINMENU, fnc=main)
404