1 from Plugins.Plugin import PluginDescriptor
3 from Screens.Screen import Screen
4 from Screens.ServiceScan import ServiceScan
5 from Screens.MessageBox import MessageBox
6 from Screens.DefaultWizard import DefaultWizard
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
16 from Tools.HardwareInfo import HardwareInfo
17 from Tools.Directories import resolveFilename, SCOPE_DEFAULTPARTITIONMOUNTDIR, SCOPE_DEFAULTDIR, SCOPE_DEFAULTPARTITION
19 from enigma import eTimer, eDVBFrontendParametersSatellite, eComponentScan, eDVBSatelliteEquipmentControl, eDVBFrontendParametersTerrestrial, eDVBFrontendParametersCable, eConsoleAppContainer, eDVBResourceManager, getDesktop
21 _supportNimType = { 'AVL1208':'', 'AVL6222':'6222_', 'AVL6211':'6211_'}
23 class Blindscan(ConfigListScreen, Screen):
25 <screen position="center,center" size="560,390" title="Blindscan">
26 <ePixmap pixmap="skin_default/buttons/red.png" position="40,10" size="140,40" alphatest="on" />
27 <ePixmap pixmap="skin_default/buttons/green.png" position="210,10" size="140,40" alphatest="on" />
28 <ePixmap pixmap="skin_default/buttons/blue.png" position="380,10" size="140,40" alphatest="on" />
30 <widget source="key_red" render="Label" position="40,10" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" foregroundColor="#ffffff" transparent="1"/>
31 <widget source="key_green" render="Label" position="210,10" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" foregroundColor="#ffffff" transparent="1"/>
32 <widget source="key_blue" render="Label" position="380,10" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" foregroundColor="#ffffff" transparent="1"/>
34 <widget name="config" position="5,70" size="550,280" scrollbarMode="showOnDemand" />
35 <widget name="introduction" position="0,365" size="560,20" font="Regular;20" halign="center" />
39 def __init__(self, session):
40 Screen.__init__(self, session)
42 self.current_play_service = self.session.nav.getCurrentlyPlayingServiceReference()
46 for slot in nimmanager.nim_slots:
47 if slot.isCompatible("DVB-S"):
48 self.satList.append(nimmanager.getSatListForNim(slot.slot))
50 self.satList.append(None)
58 ConfigListScreen.__init__(self, self.list)
59 if self.scan_nims.value != None and self.scan_nims.value != "" :
60 self["actions"] = ActionMap(["OkCancelActions", "ShortcutActions", "WizardActions", "ColorActions", "SetupActions", ],
62 "red": self.keyCancel,
66 "cancel": self.keyCancel,
68 self["key_red"] = StaticText(_("Exit"))
69 self["key_green"] = StaticText("Scan")
70 self["key_blue"] = StaticText("Scan All")
71 self["introduction"] = Label(_("Press Green/OK to start the scan"))
74 self["actions"] = ActionMap(["OkCancelActions", "ShortcutActions", "WizardActions", "ColorActions", "SetupActions", ],
76 "red": self.keyCancel,
77 "green": self.keyNone,
80 "cancel": self.keyCancel,
82 self["key_red"] = StaticText(_("Exit"))
83 self["key_green"] = StaticText(" ")
84 self["key_blue"] = StaticText(" ")
85 self["introduction"] = Label(_("Please setup your tuner configuration."))
87 self.i2c_mapping_table = None
88 self.nimSockets = self.ScanNimsocket()
91 def ScanNimsocket(self):
93 fp = file('/proc/bus/nim_sockets')
95 sNo, sName, sI2C = -1, "", -1
98 if line.startswith('NIM Socket'):
99 sNo, sName, sI2C = -1, '', -1
100 try: sNo = line.split()[2][:-1]
102 elif line.startswith('I2C_Device:'):
103 try: sI2C = line.split()[1]
105 elif line.startswith('Name:'):
106 try: sName = line.split()[3][4:-1]
108 if sNo >= 0 and sName != "":
110 _nimSocket[sNo] = [sName, sI2C]
111 else: _nimSocket[sNo] = [sName]
113 print "parsed nimsocket :", _nimSocket
116 def makeNimSocket(self, nimname=""):
118 self.i2c_mapping_table = {0:2, 1:3, 2:1, 3:0}
119 if self.nimSockets is not None:
120 for XX in self.nimSockets.keys():
121 nimsocket = self.nimSockets[XX]
122 if len(nimsocket) > 1:
123 try: self.i2c_mapping_table[int(XX)] = int(nimsocket[1])
126 print "i2c_mapping_table :", self.i2c_mapping_table, ", is_exist_i2c :", is_exist_i2c
127 if is_exist_i2c: return
129 if nimname == "AVL6222":
130 model = file('/proc/stb/info/vumodel').read().strip()
132 self.i2c_mapping_table = {0:3, 1:3, 2:1, 3:0}
133 elif model == "duo2":
134 nimdata = self.nimSockets['0']
136 if nimdata[0] == "AVL6222":
137 self.i2c_mapping_table = {0:2, 1:2, 2:4, 3:4}
138 else: self.i2c_mapping_table = {0:2, 1:4, 2:4, 3:0}
139 except: self.i2c_mapping_table = {0:2, 1:4, 2:4, 3:0}
140 else: self.i2c_mapping_table = {0:2, 1:4, 2:0, 3:0}
141 else: self.i2c_mapping_table = {0:2, 1:3, 2:1, 3:0}
143 def getNimSocket(self, slot_number):
144 if slot_number < 0 or slot_number > 3:
146 return self.i2c_mapping_table[slot_number]
150 def callbackNone(self, *retval):
153 def openFrontend(self):
154 res_mgr = eDVBResourceManager.getInstance()
156 self.raw_channel = res_mgr.allocateRawChannel(self.feid)
158 self.frontend = self.raw_channel.getFrontend()
162 print "getFrontend failed"
164 print "getRawChannel failed"
166 print "getResourceManager instance failed"
169 def createConfig(self):
174 "system": eDVBFrontendParametersSatellite.System_DVB_S,
176 "inversion": eDVBFrontendParametersSatellite.Inversion_Unknown,
178 "polarization": eDVBFrontendParametersSatellite.Polarisation_Horizontal,
179 "fec": eDVBFrontendParametersSatellite.FEC_Auto,
180 "fec_s2": eDVBFrontendParametersSatellite.FEC_9_10,
181 "modulation": eDVBFrontendParametersSatellite.Modulation_QPSK
184 self.service = self.session.nav.getCurrentService()
185 if self.service is not None:
186 self.feinfo = self.service.frontendInfo()
187 frontendData = self.feinfo and self.feinfo.getAll(True)
188 if frontendData is not None:
189 ttype = frontendData.get("tuner_type", "UNKNOWN")
191 defaultSat["system"] = frontendData.get("system", eDVBFrontendParametersSatellite.System_DVB_S)
192 defaultSat["frequency"] = frontendData.get("frequency", 0) / 1000
193 defaultSat["inversion"] = frontendData.get("inversion", eDVBFrontendParametersSatellite.Inversion_Unknown)
194 defaultSat["symbolrate"] = frontendData.get("symbol_rate", 0) / 1000
195 defaultSat["polarization"] = frontendData.get("polarization", eDVBFrontendParametersSatellite.Polarisation_Horizontal)
196 if defaultSat["system"] == eDVBFrontendParametersSatellite.System_DVB_S2:
197 defaultSat["fec_s2"] = frontendData.get("fec_inner", eDVBFrontendParametersSatellite.FEC_Auto)
198 defaultSat["rolloff"] = frontendData.get("rolloff", eDVBFrontendParametersSatellite.RollOff_alpha_0_35)
199 defaultSat["pilot"] = frontendData.get("pilot", eDVBFrontendParametersSatellite.Pilot_Unknown)
201 defaultSat["fec"] = frontendData.get("fec_inner", eDVBFrontendParametersSatellite.FEC_Auto)
202 defaultSat["modulation"] = frontendData.get("modulation", eDVBFrontendParametersSatellite.Modulation_QPSK)
203 defaultSat["orbpos"] = frontendData.get("orbital_position", 0)
208 self.scan_sat = ConfigSubsection()
209 self.scan_networkScan = ConfigYesNo(default = False)
212 self.blindscan_hi = ConfigSelection(default = "hi_low", choices = [("low", _("low")), ("high", _("high")), ("hi_low", _("hi_low"))])
214 #ConfigYesNo(default = True)
215 self.blindscan_start_frequency = ConfigInteger(default = 950*1000000)
216 self.blindscan_stop_frequency = ConfigInteger(default = 2150*1000000)
217 self.blindscan_start_symbol = ConfigInteger(default = 2*1000000)
218 self.blindscan_stop_symbol = ConfigInteger(default = 45*1000000)
219 self.scan_clearallservices = ConfigYesNo(default = False)
220 self.scan_onlyfree = ConfigYesNo(default = False)
222 # collect all nims which are *not* set to "nothing"
224 for n in nimmanager.nim_slots:
225 if n.config_mode == "nothing":
227 if n.config_mode == "advanced" and len(nimmanager.getSatListForNim(n.slot)) < 1:
229 if n.config_mode in ("loopthrough", "satposdepends"):
230 root_id = nimmanager.sec.getRoot(n.slot_id, int(n.config.connectedTo.value))
231 if n.type == nimmanager.nim_slots[root_id].type: # check if connected from a DVB-S to DVB-S2 Nim or vice versa
233 if n.isCompatible("DVB-S"):
234 nim_list.append((str(n.slot), n.friendly_full_description))
235 self.scan_nims = ConfigSelection(choices = nim_list)
238 self.scan_sat.frequency = ConfigInteger(default = defaultSat["frequency"], limits = (1, 99999))
239 #self.scan_sat.polarization = ConfigSelection(default = defaultSat["polarization"], choices = [
240 self.scan_sat.polarization = ConfigSelection(default = eDVBFrontendParametersSatellite.Polarisation_CircularRight + 1, choices = [
241 (eDVBFrontendParametersSatellite.Polarisation_CircularRight + 1, _("horizontal_vertical")),
242 (eDVBFrontendParametersSatellite.Polarisation_Horizontal, _("horizontal")),
243 (eDVBFrontendParametersSatellite.Polarisation_Vertical, _("vertical")),
244 (eDVBFrontendParametersSatellite.Polarisation_CircularLeft, _("circular left")),
245 (eDVBFrontendParametersSatellite.Polarisation_CircularRight, _("circular right"))])
246 self.scan_scansat = {}
247 for sat in nimmanager.satList:
248 self.scan_scansat[sat[0]] = ConfigYesNo(default = False)
250 self.scan_satselection = []
251 for slot in nimmanager.nim_slots:
252 if slot.isCompatible("DVB-S"):
253 self.scan_satselection.append(getConfigSatlist(defaultSat["orbpos"], self.satList[slot.slot]))
256 def getSelectedSatIndex(self, v):
259 for n in self.satList:
260 if self.satList[index] == None:
261 none_cnt = none_cnt + 1
263 return (index-none_cnt)
267 def createSetup(self):
269 self.multiscanlist = []
270 index_to_scan = int(self.scan_nims.value)
271 print "ID: ", index_to_scan
273 self.tunerEntry = getConfigListEntry(_("Tuner"), self.scan_nims)
274 self.list.append(self.tunerEntry)
276 if self.scan_nims == [ ]:
279 self.systemEntry = None
280 self.modulationEntry = None
281 nim = nimmanager.nim_slots[index_to_scan]
283 self.scan_networkScan.value = False
284 if nim.isCompatible("DVB-S") :
285 self.list.append(getConfigListEntry(_('Satellite'), self.scan_satselection[self.getSelectedSatIndex(index_to_scan)]))
286 self.list.append(getConfigListEntry(_('Scan start frequency'), self.blindscan_start_frequency))
287 self.list.append(getConfigListEntry(_('Scan stop frequency'), self.blindscan_stop_frequency))
288 self.list.append(getConfigListEntry(_("Polarity"), self.scan_sat.polarization))
289 self.list.append(getConfigListEntry(_("Scan band"), self.blindscan_hi))
290 self.list.append(getConfigListEntry(_('Scan start symbolrate'), self.blindscan_start_symbol))
291 self.list.append(getConfigListEntry(_('Scan stop symbolrate'), self.blindscan_stop_symbol))
292 self.list.append(getConfigListEntry(_("Clear before scan"), self.scan_clearallservices))
293 self.list.append(getConfigListEntry(_("Only Free scan"), self.scan_onlyfree))
294 self["config"].list = self.list
295 self["config"].l.setList(self.list)
298 cur = self["config"].getCurrent()
300 if cur == self.tunerEntry or \
301 cur == self.systemEntry or \
302 (self.modulationEntry and self.systemEntry[1].value == eDVBFrontendParametersSatellite.System_DVB_S2 and cur == self.modulationEntry):
305 def checkSettings(self):
306 if self.blindscan_start_frequency.value < 950*1000000 or self.blindscan_start_frequency.value > 2150*1000000 :
307 self.session.open(MessageBox, _("Please check again.\nStart frequency must be between 950 and 2150."), MessageBox.TYPE_ERROR)
309 if self.blindscan_stop_frequency.value < 950*1000000 or self.blindscan_stop_frequency.value > 2150*1000000 :
310 self.session.open(MessageBox, _("Please check again.\nStop frequency must be between 950 and 2150."), MessageBox.TYPE_ERROR)
312 if self.blindscan_start_frequency.value > self.blindscan_stop_frequency.value :
313 self.session.open(MessageBox, _("Please check again.\nFrequency : start value is larger than stop value."), MessageBox.TYPE_ERROR)
315 if self.blindscan_start_symbol.value < 2*1000000 or self.blindscan_start_symbol.value > 45*1000000 :
316 self.session.open(MessageBox, _("Please check again.\nStart symbolrate must be between 2MHz and 45MHz."), MessageBox.TYPE_ERROR)
318 if self.blindscan_stop_symbol.value < 2*1000000 or self.blindscan_stop_symbol.value > 45*1000000 :
319 self.session.open(MessageBox, _("Please check again.\nStop symbolrate must be between 2MHz and 45MHz."), MessageBox.TYPE_ERROR)
321 if self.blindscan_start_symbol.value > self.blindscan_stop_symbol.value :
322 self.session.open(MessageBox, _("Please check again.\nSymbolrate : start value is larger than stop value."), MessageBox.TYPE_ERROR)
327 ConfigListScreen.keyLeft(self)
331 ConfigListScreen.keyRight(self)
335 self.session.nav.playService(self.current_play_service)
336 for x in self["config"].list:
341 if self.checkSettings() == False:
345 eDVBFrontendParametersSatellite.Polarisation_Horizontal : "horizontal",
346 eDVBFrontendParametersSatellite.Polarisation_Vertical : "vertical",
347 eDVBFrontendParametersSatellite.Polarisation_CircularLeft : "circular left",
348 eDVBFrontendParametersSatellite.Polarisation_CircularRight : "circular right",
349 eDVBFrontendParametersSatellite.Polarisation_CircularRight + 1 : "horizontal_vertical"
355 idx_selected_sat = int(self.getSelectedSatIndex(self.scan_nims.value))
356 tmp_list=[self.satList[int(self.scan_nims.value)][self.scan_satselection[idx_selected_sat].index]]
358 if self.blindscan_hi.value == "hi_low" :
359 tmp_band=["low","high"]
361 tmp_band=[self.blindscan_hi.value]
363 if self.scan_sat.polarization.value == eDVBFrontendParametersSatellite.Polarisation_CircularRight + 1 :
364 tmp_pol=["horizontal","vertical"]
366 tmp_pol=[tab_pol[self.scan_sat.polarization.value]]
368 self.doRun(tmp_list, tmp_pol, tmp_band)
371 if self.checkSettings() == False:
375 tmp_band=["low","high"]
376 tmp_pol=["horizontal","vertical"]
378 for slot in nimmanager.nim_slots:
379 device_name = "/dev/dvb/adapter0/frontend%d" % (slot.slot)
380 if slot.isCompatible("DVB-S") and int(self.scan_nims.value) == slot.slot:
381 for s in self.satList[slot.slot]:
383 self.doRun(tmp_list, tmp_pol, tmp_band)
385 def doRun(self, tmp_list, tmp_pol, tmp_band):
386 def GetCommand(nimIdx):
387 _nimSocket = self.nimSockets
389 sName = _nimSocket[str(nimIdx)][0]
390 sType = _supportNimType[sName]
391 return "vuplus_%(TYPE)sblindscan"%{'TYPE':sType}, sName
393 return "vuplus_blindscan", ""
394 self.binName,nimName = GetCommand(self.scan_nims.value)
396 self.makeNimSocket(nimName)
397 if self.binName is None:
398 self.session.open(MessageBox, "Blindscan is not supported in " + nimName + " tuner.", MessageBox.TYPE_ERROR)
399 print nimName + " is not support blindscan."
407 self.total_list.append([x,y,z])
408 print "add scan item : ", x, ", ", y, ", ", z
410 self.max_count = len(self.total_list)
411 self.is_runable = True
412 self.running_count = 0
413 self.clockTimer = eTimer()
414 self.clockTimer.callback.append(self.doClock)
415 self.clockTimer.start(1000)
420 if self.running_count >= self.max_count:
421 self.clockTimer.stop()
423 self.clockTimer = None
426 orb = self.total_list[self.running_count][0]
427 pol = self.total_list[self.running_count][1]
428 band = self.total_list[self.running_count][2]
429 self.running_count = self.running_count + 1
430 print "running status-[%d] : [%d][%s][%s]" %(self.running_count, orb[0], pol, band)
431 if self.running_count == self.max_count:
433 self.prepareScanData(orb, pol, band, is_scan)
435 def prepareScanData(self, orb, pol, band, is_scan):
436 self.is_runable = False
437 self.orb_position = orb[0]
438 self.feid = int(self.scan_nims.value)
439 tab_hilow = {"high" : 1, "low" : 0}
441 "horizontal" : eDVBFrontendParametersSatellite.Polarisation_Horizontal,
442 "vertical" : eDVBFrontendParametersSatellite.Polarisation_Vertical,
443 "circular left" : eDVBFrontendParametersSatellite.Polarisation_CircularLeft,
444 "circular right" : eDVBFrontendParametersSatellite.Polarisation_CircularRight
447 returnvalue = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
449 if not self.openFrontend():
450 self.oldref = self.session.nav.getCurrentlyPlayingServiceReference()
451 self.session.nav.stopService()
452 if not self.openFrontend():
453 if self.session.pipshown:
454 self.session.pipshown = False
456 if not self.openFrontend():
458 self.tuner = Tuner(self.frontend)
461 self.scan_sat.frequency.value = 12515
463 self.scan_sat.frequency.value = 11015
464 returnvalue = (self.scan_sat.frequency.value,
470 eDVBFrontendParametersSatellite.System_DVB_S,
474 self.tuner.tune(returnvalue)
476 if self.getNimSocket(self.feid) < 0:
477 print "can't find i2c number!!"
480 cmd = "%s %d %d %d %d %d %d %d %d" % (self.binName, self.blindscan_start_frequency.value/1000000, self.blindscan_stop_frequency.value/1000000, self.blindscan_start_symbol.value/1000000, self.blindscan_stop_symbol.value/1000000, tab_pol[pol], tab_hilow[band], self.feid, self.getNimSocket(self.feid))
482 print "prepared command : [%s]" % (cmd)
483 self.blindscan_container = eConsoleAppContainer()
484 self.blindscan_container.appClosed.append(self.blindscanContainerClose)
485 self.blindscan_container.dataAvail.append(self.blindscanContainerAvail)
486 self.blindscan_container.execute(cmd)
488 tmpstr = "Look for available transponders.\nThis works will take several minutes.\n\n - Current Status : %d/%d\n - Orbital Positions : %s\n - Polarization : %s\n - Bandwidth : %s" %(self.running_count, self.max_count, orb[1], pol, band)
490 self.blindscan_session = self.session.openWithCallback(self.blindscanSessionClose, MessageBox, _(tmpstr), MessageBox.TYPE_INFO)
492 self.blindscan_session = self.session.openWithCallback(self.blindscanSessionNone, MessageBox, _(tmpstr), MessageBox.TYPE_INFO)
494 def blindscanContainerClose(self, retval):
495 lines = self.full_data.split('\n')
498 print "cnt :", len(data), ", data :", data
501 parm = eDVBFrontendParametersSatellite()
502 sys = { "DVB-S" : eDVBFrontendParametersSatellite.System_DVB_S,
503 "DVB-S2" : eDVBFrontendParametersSatellite.System_DVB_S2}
504 qam = { "QPSK" : parm.Modulation_QPSK,
505 "8PSK" : parm.Modulation_8PSK}
506 inv = { "INVERSION_OFF" : parm.Inversion_Off,
507 "INVERSION_ON" : parm.Inversion_On,
508 "INVERSION_AUTO" : parm.Inversion_Unknown}
509 fec = { "FEC_AUTO" : parm.FEC_Auto,
510 "FEC_1_2" : parm.FEC_1_2,
511 "FEC_2_3" : parm.FEC_2_3,
512 "FEC_3_4" : parm.FEC_3_4,
513 "FEC_5_6": parm.FEC_5_6,
514 "FEC_7_8" : parm.FEC_7_8,
515 "FEC_8_9" : parm.FEC_8_9,
516 "FEC_3_5" : parm.FEC_3_5,
517 "FEC_9_10" : parm.FEC_9_10,
518 "FEC_NONE" : parm.FEC_None}
519 roll ={ "ROLLOFF_20" : parm.RollOff_alpha_0_20,
520 "ROLLOFF_25" : parm.RollOff_alpha_0_25,
521 "ROLLOFF_35" : parm.RollOff_alpha_0_35}
522 pilot={ "PILOT_ON" : parm.Pilot_On,
523 "PILOT_OFF" : parm.Pilot_Off}
524 pol = { "HORIZONTAL" : parm.Polarisation_Horizontal,
525 "VERTICAL" : parm.Polarisation_Vertical}
527 parm.orbital_position = self.orb_position
528 parm.polarisation = pol[data[1]]
529 parm.frequency = int(data[2])
530 parm.symbol_rate = int(data[3])
531 parm.system = sys[data[4]]
532 parm.inversion = inv[data[5]]
533 parm.pilot = pilot[data[6]]
534 parm.fec = fec[data[7]]
535 parm.modulation = qam[data[8]]
536 parm.rolloff = roll[data[9]]
537 self.tmp_tplist.append(parm)
540 self.blindscan_session.close(True)
542 def blindscanContainerAvail(self, str):
544 #if str.startswith("OK"):
545 self.full_data = self.full_data + str
547 def blindscanSessionNone(self, *val):
549 self.blindscan_container.sendCtrlC()
550 self.blindscan_container = None
559 self.running_count = self.max_count
561 self.is_runable = True
563 def blindscanSessionClose(self, *val):
564 self.blindscanSessionNone(val[0])
566 if self.tmp_tplist != None and self.tmp_tplist != []:
567 for p in self.tmp_tplist:
568 print "data : [%d][%d][%d][%d][%d][%d][%d][%d][%d][%d]" % (p.orbital_position, p.polarisation, p.frequency, p.symbol_rate, p.system, p.inversion, p.pilot, p.fec, p.modulation, p.modulation)
570 self.startScan(self.tmp_tplist, self.feid)
572 msg = "No found transponders!!\nPlease check the satellite connection, or scan other search condition."
574 msg = "Blindscan was canceled by the user."
575 self.session.openWithCallback(self.callbackNone, MessageBox, _(msg), MessageBox.TYPE_INFO, timeout=10)
578 def startScan(self, tlist, feid, networkid = 0):
579 self.scan_session = None
582 if self.scan_clearallservices.value:
583 flags |= eComponentScan.scanRemoveServices
585 flags |= eComponentScan.scanDontRemoveUnscanned
586 if self.scan_onlyfree.value:
587 flags |= eComponentScan.scanOnlyFree
588 self.session.open(ServiceScan, [{"transponders": tlist, "feid": feid, "flags": flags, "networkid": networkid}])
590 def main(session, **kwargs):
591 session.open(Blindscan)
593 def Plugins(**kwargs):
594 return PluginDescriptor(name=_("Blindscan"), description="scan type(DVB-S)", where = PluginDescriptor.WHERE_PLUGINMENU, fnc=main)