1 from Screens.Satconfig import NimSelection
2 from Screens.Screen import Screen
3 from Screens.TextBox import TextBox
4 from Screens.MessageBox import MessageBox
6 from Plugins.Plugin import PluginDescriptor
8 from Components.ActionMap import ActionMap, NumberActionMap
9 from Components.NimManager import nimmanager
10 from Components.ResourceManager import resourcemanager
11 from Components.Sources.FrontendStatus import FrontendStatus
12 from Components.TuneTest import TuneTest
13 from Components.Sources.List import List
14 from Components.Sources.Progress import Progress
15 from Components.Sources.StaticText import StaticText
16 from Components.ConfigList import ConfigListScreen
17 from Components.config import getConfigListEntry, ConfigSelection, ConfigYesNo
18 from Components.Harddisk import harddiskmanager
24 # setResultParameter(parameter)
33 def setResultType(self, type):
36 def setResultParameter(self, parameter):
37 if self.type == self.TYPE_BYORBPOS:
38 self.orbpos = parameter
39 elif self.type == self.TYPE_BYINDEX:
40 self.index = parameter
42 def getTextualResultForIndex(self, index, logfulltransponders = False):
44 text += "%s:\n" % self.getTextualIndexRepresentation(index)
46 failed, successful = self.results[index]["failed"], self.results[index]["successful"]
47 countfailed = len(failed)
48 countsuccessful = len(successful)
49 countall = countfailed + countsuccessful
50 percentfailed = round(countfailed / float(countall + 0.0001) * 100)
51 percentsuccessful = round(countsuccessful / float(countall + 0.0001) * 100)
52 text += "Tested %d transponders\n%d (%d %%) transponders succeeded\n%d (%d %%) transponders failed\n" % (countall, countsuccessful, percentsuccessful, countfailed, percentfailed)
55 for transponder in failed:
56 reasons[transponder[2]] = reasons.get(transponder[2], [])
57 reasons[transponder[2]].append(transponder)
58 if transponder[2] == "pids_failed":
59 print transponder[2], "-", transponder[3]
61 text += "The %d unsuccessful tuning attempts failed for the following reasons:\n" % countfailed
63 for reason in reasons.keys():
64 text += "%s: %d transponders failed\n" % (reason, len(reasons[reason]))
66 for reason in reasons.keys():
68 text += "%s previous planes:\n" % reason
69 for transponder in reasons[reason]:
70 if transponder[1] is not None:
71 text += self.getTextualIndexRepresentation(self.getIndexForTransponder(transponder[1]))
73 text += "No transponder tuned"
74 text += " ==> " + self.getTextualIndexRepresentation(self.getIndexForTransponder(transponder[0]))
76 if logfulltransponders:
77 text += str(transponder[1])
79 text += str(transponder[0])
81 if reason == "pids_failed":
82 text += "(tsid, onid): "
83 text += str(transponder[3]['real'])
84 text += "(read from sat) != "
85 text += str(transponder[3]['expected'])
86 text += "(read from file)"
89 if countsuccessful > 0:
91 text += "Successfully tuned transponders' previous planes:\n"
92 for transponder in successful:
93 if transponder[1] is not None:
94 text += self.getTextualIndexRepresentation(self.getIndexForTransponder(transponder[1]))
96 text += "No transponder tuned"
97 text += " ==> " + self.getTextualIndexRepresentation(self.getIndexForTransponder(transponder[0]))
101 def getTextualResult(self):
103 if self.type == self.TYPE_BYINDEX:
104 text += self.getTextualResultForIndex(self.index)
105 elif self.type == self.TYPE_BYORBPOS:
106 for index in self.results.keys():
107 if index[2] == self.orbpos:
108 text += self.getTextualResultForIndex(index)
109 text += "\n-----------------------------------------------------\n"
110 elif self.type == self.TYPE_ALL:
112 for index in self.results.keys():
114 orderedResults[orbpos] = orderedResults.get(orbpos, [])
115 orderedResults[orbpos].append(index)
116 ordered_orbpos = orderedResults.keys()
117 ordered_orbpos.sort()
118 for orbpos in ordered_orbpos:
119 text += "\n*****************************************\n"
120 text += "Orbital position %s:" % str(orbpos)
121 text += "\n*****************************************\n"
122 for index in orderedResults[orbpos]:
123 text += self.getTextualResultForIndex(index, logfulltransponders = True)
124 text += "\n-----------------------------------------------------\n"
129 class DiseqcTester(Screen, TuneTest, ResultParser):
131 <screen position="90,100" size="520,400" title="DiSEqC Tester" >
132 <!--ePixmap pixmap="skin_default/icons/dish_scan.png" position="5,25" zPosition="0" size="119,110" transparent="1" alphatest="on" />
133 <widget source="Frontend" render="Label" position="190,10" zPosition="2" size="260,20" font="Regular;19" halign="center" valign="center" transparent="1">
134 <convert type="FrontendInfo">SNRdB</convert>
136 <eLabel name="snr" text="SNR:" position="120,35" size="60,22" font="Regular;21" halign="right" transparent="1" />
137 <widget source="Frontend" render="Progress" position="190,35" size="260,20" pixmap="skin_default/bar_snr.png" borderWidth="2" borderColor="#cccccc">
138 <convert type="FrontendInfo">SNR</convert>
140 <widget source="Frontend" render="Label" position="460,35" size="60,22" font="Regular;21">
141 <convert type="FrontendInfo">SNR</convert>
143 <eLabel name="agc" text="AGC:" position="120,60" size="60,22" font="Regular;21" halign="right" transparent="1" />
144 <widget source="Frontend" render="Progress" position="190,60" size="260,20" pixmap="skin_default/bar_snr.png" borderWidth="2" borderColor="#cccccc">
145 <convert type="FrontendInfo">AGC</convert>
147 <widget source="Frontend" render="Label" position="460,60" size="60,22" font="Regular;21">
148 <convert type="FrontendInfo">AGC</convert>
150 <eLabel name="ber" text="BER:" position="120,85" size="60,22" font="Regular;21" halign="right" transparent="1" />
151 <widget source="Frontend" render="Progress" position="190,85" size="260,20" pixmap="skin_default/bar_ber.png" borderWidth="2" borderColor="#cccccc">
152 <convert type="FrontendInfo">BER</convert>
154 <widget source="Frontend" render="Label" position="460,85" size="60,22" font="Regular;21">
155 <convert type="FrontendInfo">BER</convert>
157 <eLabel name="lock" text="Lock:" position="120,115" size="60,22" font="Regular;21" halign="right" />
158 <widget source="Frontend" render="Pixmap" pixmap="skin_default/icons/lock_on.png" position="190,110" zPosition="1" size="38,31" alphatest="on">
159 <convert type="FrontendInfo">LOCK</convert>
160 <convert type="ConditionalShowHide" />
162 <widget source="Frontend" render="Pixmap" pixmap="skin_default/icons/lock_off.png" position="190,110" zPosition="1" size="38,31" alphatest="on">
163 <convert type="FrontendInfo">LOCK</convert>
164 <convert type="ConditionalShowHide">Invert</convert>
166 <widget source="progress_list" render="Listbox" position="0,0" size="510,150" scrollbarMode="showOnDemand">
167 <convert type="TemplatedMultiContent">
169 MultiContentEntryText(pos = (10, 0), size = (330, 25), flags = RT_HALIGN_LEFT, text = 1), # index 1 is the index name,
170 MultiContentEntryText(pos = (330, 0), size = (150, 25), flags = RT_HALIGN_RIGHT, text = 2) # index 2 is the status,
172 "fonts": [gFont("Regular", 20)],
177 <eLabel name="overall_progress" text="Overall progress:" position="20,162" size="480,22" font="Regular;21" halign="center" transparent="1" />
178 <widget source="overall_progress" render="Progress" position="20,192" size="480,20" borderWidth="2" backgroundColor="#254f7497" />
179 <eLabel name="overall_progress" text="Progress:" position="20,222" size="480,22" font="Regular;21" halign="center" transparent="1" />
180 <widget source="sub_progress" render="Progress" position="20,252" size="480,20" borderWidth="2" backgroundColor="#254f7497" />
182 <eLabel name="" text="Failed:" position="20,282" size="140,22" font="Regular;21" halign="left" transparent="1" />
183 <widget source="failed_counter" render="Label" position="160,282" size="100,20" font="Regular;21" />
185 <eLabel name="" text="Succeeded:" position="20,312" size="140,22" font="Regular;21" halign="left" transparent="1" />
186 <widget source="succeeded_counter" render="Label" position="160,312" size="100,20" font="Regular;21" />
188 <eLabel name="" text="With errors:" position="20,342" size="140,22" font="Regular;21" halign="left" transparent="1" />
189 <widget source="witherrors_counter" render="Label" position="160,342" size="100,20" font="Regular;21" />
191 <eLabel name="" text="Not tested:" position="20,372" size="140,22" font="Regular;21" halign="left" transparent="1" />
192 <widget source="untestable_counter" render="Label" position="160,372" size="100,20" font="Regular;21" />
194 <widget source="CmdText" render="Label" position="300,282" size="180,200" font="Regular;21" />
199 TEST_TYPE_COMPLETE = 2
200 def __init__(self, session, feid, test_type = TEST_TYPE_QUICK, loopsfailed = 3, loopssuccessful = 1, log = False):
201 Screen.__init__(self, session)
203 self.test_type = test_type
204 self.loopsfailed = loopsfailed
205 self.loopssuccessful = loopssuccessful
208 self["actions"] = NumberActionMap(["SetupActions"],
211 "cancel": self.keyCancel,
214 TuneTest.__init__(self, feid, stopOnSuccess = self.loopssuccessful, stopOnError = self.loopsfailed)
215 #self["Frontend"] = FrontendStatus(frontend_source = lambda : self.frontend, update_interval = 100)
216 self["overall_progress"] = Progress()
217 self["sub_progress"] = Progress()
219 self["failed_counter"] = StaticText("0")
220 self["succeeded_counter"] = StaticText("0")
221 self["witherrors_counter"] = StaticText("0")
222 self["untestable_counter"] = StaticText("0")
225 self["progress_list"] = List(self.list)
226 self["progress_list"].onSelectionChanged.append(self.selectionChanged)
228 self["CmdText"] = StaticText(_("Please wait while scanning is in progress..."))
231 self.readTransponderList()
236 self.resultsstatus = {}
238 self.onLayoutFinish.append(self.go)
240 def getProgressListComponent(self, index, status):
241 return (index, self.getTextualIndexRepresentation(index), status)
243 def clearProgressList(self):
245 self["progress_list"].list = self.list
247 def addProgressListItem(self, index):
248 if index in self.indexlist:
249 for entry in self.list:
250 if entry[0] == index:
251 self.changeProgressListStatus(index, "working")
253 self.list.append(self.getProgressListComponent(index, _("working")))
254 self["progress_list"].list = self.list
255 self["progress_list"].setIndex(len(self.list) - 1)
257 def changeProgressListStatus(self, index, status):
261 for entry in self.list:
262 if entry[0] == index:
263 self.newlist.append(self.getProgressListComponent(index, status))
266 self.newlist.append(entry)
268 self.list = self.newlist
269 self["progress_list"].list = self.list
270 self["progress_list"].setIndex(indexpos)
272 def readTransponderList(self):
273 for sat in nimmanager.getSatListForNim(self.feid):
274 for transponder in nimmanager.getTransponders(sat[0]):
276 mytransponder = (transponder[1] / 1000, transponder[2] / 1000, transponder[3], transponder[4], transponder[7], sat[0], transponder[5], transponder[6], transponder[8], transponder[9], transponder[10], transponder[11])
277 self.analyseTransponder(mytransponder)
279 def getIndexForTransponder(self, transponder):
281 if transponder[0] < 11700:
286 polarisation = transponder[2]
290 index = (band, polarisation, sat)
293 # sort the transponder into self.transponderlist
294 def analyseTransponder(self, transponder):
295 index = self.getIndexForTransponder(transponder)
296 if index not in self.indexlist:
297 self.indexlist[index] = []
298 self.indexlist[index].append(transponder)
299 #print "self.indexlist:", self.indexlist
301 # returns a string for the user representing a human readable output for index
302 def getTextualIndexRepresentation(self, index):
303 print "getTextualIndexRepresentation:", index
306 text += nimmanager.getSatDescription(index[2]) + ", "
311 text += "High Band, "
319 def fillTransponderList(self):
320 self.clearTransponder()
321 print "----------- fillTransponderList"
322 print "index:", self.currentlyTestedIndex
323 keys = self.indexlist.keys()
324 if self.getContinueScanning():
325 print "index:", self.getTextualIndexRepresentation(self.currentlyTestedIndex)
326 for transponder in self.indexlist[self.currentlyTestedIndex]:
327 self.addTransponder(transponder)
328 print "transponderList:", self.transponderlist
333 def progressCallback(self, progress):
334 if progress[0] != self["sub_progress"].getRange():
335 self["sub_progress"].setRange(progress[0])
336 self["sub_progress"].setValue(progress[1])
338 # logic for scanning order of transponders
339 # on go getFirstIndex is called
340 def getFirstIndex(self):
341 # TODO use other function to scan more randomly
342 if self.test_type == self.TEST_TYPE_QUICK:
344 keys = self.indexlist.keys()
345 keys.sort(key = lambda a: a[2]) # sort by orbpos
346 self["overall_progress"].setRange(len(keys))
347 self["overall_progress"].setValue(self.myindex)
349 elif self.test_type == self.TEST_TYPE_RANDOM:
350 self.randomkeys = self.indexlist.keys()
351 random.shuffle(self.randomkeys)
353 self["overall_progress"].setRange(len(self.randomkeys))
354 self["overall_progress"].setValue(self.myindex)
355 return self.randomkeys[0]
356 elif self.test_type == self.TEST_TYPE_COMPLETE:
357 keys = self.indexlist.keys()
361 successorindex[index] = []
362 for otherindex in keys:
363 if otherindex != index:
364 successorindex[index].append(otherindex)
365 random.shuffle(successorindex[index])
370 if currindex is None or len(successorindex[currindex]) == 0:
372 for index in successorindex.keys():
373 if len(successorindex[index]) > 0:
375 self.keylist.append(currindex)
377 if currindex == oldindex:
380 currindex = successorindex[currindex].pop()
381 self.keylist.append(currindex)
382 print "self.keylist:", self.keylist
384 self["overall_progress"].setRange(len(self.keylist))
385 self["overall_progress"].setValue(self.myindex)
386 return self.keylist[0]
389 # after each index is finished, getNextIndex is called to get the next index to scan
390 def getNextIndex(self):
391 # TODO use other function to scan more randomly
392 if self.test_type == self.TEST_TYPE_QUICK:
394 keys = self.indexlist.keys()
395 keys.sort(key = lambda a: a[2]) # sort by orbpos
397 self["overall_progress"].setValue(self.myindex)
398 if self.myindex < len(keys):
399 return keys[self.myindex]
402 elif self.test_type == self.TEST_TYPE_RANDOM:
404 keys = self.randomkeys
406 self["overall_progress"].setValue(self.myindex)
407 if self.myindex < len(keys):
408 return keys[self.myindex]
411 elif self.test_type == self.TEST_TYPE_COMPLETE:
415 self["overall_progress"].setValue(self.myindex)
416 if self.myindex < len(keys):
417 return keys[self.myindex]
421 # after each index is finished and the next index is returned by getNextIndex
422 # the algorithm checks, if we should continue scanning
423 def getContinueScanning(self):
424 if self.test_type == self.TEST_TYPE_QUICK or self.test_type == self.TEST_TYPE_RANDOM:
425 return (self.myindex < len(self.indexlist.keys()))
426 elif self.test_type == self.TEST_TYPE_COMPLETE:
427 return (self.myindex < len(self.keylist))
429 def addResult(self, index, status, failedTune, successfullyTune):
430 self.results[index] = self.results.get(index, {"failed": [], "successful": [], "status": None, "internalstatus": None})
431 self.resultsstatus[status] = self.resultsstatus.get(status, [])
433 oldstatus = self.results[index]["internalstatus"]
434 if oldstatus is None:
435 self.results[index]["status"] = status
436 elif oldstatus == "successful":
437 if status == "failed":
438 self.results[index]["status"] = "with_errors"
439 elif status == "successful":
440 self.results[index]["status"] = oldstatus
441 elif status == "with_errors":
442 self.results[index]["status"] = "with_errors"
443 elif status == "not_tested":
444 self.results[index]["status"] = oldstatus
445 elif oldstatus == "failed":
446 if status == "failed":
447 self.results[index]["status"] = oldstatus
448 elif status == "successful":
449 self.results[index]["status"] = "with_errors"
450 elif status == "with_errors":
451 self.results[index]["status"] = "with_errors"
452 elif status == "not_tested":
453 self.results[index]["status"] = oldstatus
454 elif oldstatus == "with_errors":
455 if status == "failed":
456 self.results[index]["status"] = oldstatus
457 elif status == "successful":
458 self.results[index]["status"] = oldstatus
459 elif status == "with_errors":
460 self.results[index]["status"] = oldstatus
461 elif status == "not_tested":
462 self.results[index]["status"] = oldstatus
463 elif oldstatus == "not_tested":
464 self.results[index]["status"] = status
466 if self.results[index]["status"] != "working":
467 self.results[index]["internalstatus"] = self.results[index]["status"]
468 self.results[index]["failed"] = failedTune + self.results[index]["failed"]
469 self.results[index]["successful"] = successfullyTune + self.results[index]["successful"]
471 self.resultsstatus[status].append(index)
473 def finishedChecking(self):
474 print "finishedChecking"
475 TuneTest.finishedChecking(self)
477 if not self.results.has_key(self.currentlyTestedIndex):
478 self.results[self.currentlyTestedIndex] = {"failed": [], "successful": [], "status": None, "internalstatus": None}
480 if len(self.failedTune) > 0 and len(self.successfullyTune) > 0:
481 self.changeProgressListStatus(self.currentlyTestedIndex, "with errors")
482 self["witherrors_counter"].setText(str(int(self["witherrors_counter"].getText()) + 1))
483 self.addResult(self.currentlyTestedIndex, "with_errors", self.failedTune, self.successfullyTune)
484 elif len(self.failedTune) == 0 and len(self.successfullyTune) == 0:
485 self.changeProgressListStatus(self.currentlyTestedIndex, "not tested")
486 self["untestable_counter"].setText(str(int(self["untestable_counter"].getText()) + 1))
487 self.addResult(self.currentlyTestedIndex, "untestable", self.failedTune, self.successfullyTune)
488 elif len(self.failedTune) > 0:
489 self.changeProgressListStatus(self.currentlyTestedIndex, "failed")
490 #self["failed_counter"].setText(str(int(self["failed_counter"].getText()) + len(self.failedTune)))
491 self["failed_counter"].setText(str(int(self["failed_counter"].getText()) + 1))
492 self.addResult(self.currentlyTestedIndex, "failed", self.failedTune, self.successfullyTune)
494 self.changeProgressListStatus(self.currentlyTestedIndex, "successful")
495 #self["succeeded_counter"].setText(str(int(self["succeeded_counter"].getText()) + len(self.successfullyTune)))
496 self["succeeded_counter"].setText(str(int(self["succeeded_counter"].getText()) + 1))
497 self.addResult(self.currentlyTestedIndex, "successful", self.failedTune, self.successfullyTune)
500 #self["failed_counter"].setText(str(int(self["failed_counter"].getText()) + len(self.failedTune)))
501 #self["succeeded_counter"].setText(str(int(self["succeeded_counter"].getText()) + len(self.successfullyTune)))
502 #if len(self.failedTune) == 0 and len(self.successfullyTune) == 0:
503 #self["untestable_counter"].setText(str(int(self["untestable_counter"].getText()) + 1))
505 self.currentlyTestedIndex = self.getNextIndex()
506 self.addProgressListItem(self.currentlyTestedIndex)
508 if self.fillTransponderList():
509 self.run(checkPIDs = True)
512 self["progress_list"].setIndex(0)
513 print "results:", self.results
514 print "resultsstatus:", self.resultsstatus
516 file = open("/media/hdd/diseqctester.log", "w")
517 self.setResultType(ResultParser.TYPE_ALL)
518 file.write(self.getTextualResult())
520 self.session.open(MessageBox, text=_("The results have been written to %s.") % "/media/hdd/diseqctester.log", type = MessageBox.TYPE_INFO)
524 self["failed_counter"].setText("0")
525 self["succeeded_counter"].setText("0")
526 self["untestable_counter"].setText("0")
527 self.currentlyTestedIndex = self.getFirstIndex()
529 self.clearProgressList()
530 self.addProgressListItem(self.currentlyTestedIndex)
532 if self.fillTransponderList():
539 print "selectedIndex:", self["progress_list"].getCurrent()[0]
541 index = self["progress_list"].getCurrent()[0]
542 #self.setResultType(ResultParser.TYPE_BYORBPOS)
543 #self.setResultParameter(index[2])
544 self.setResultType(ResultParser.TYPE_BYINDEX)
545 self.setResultParameter(index)
546 #self.setResultType(ResultParser.TYPE_ALL)
547 self.session.open(TextBox, self.getTextualResult())
549 def selectionChanged(self):
550 print "selection changed"
551 if len(self.list) > 0 and not self.running:
552 self["CmdText"].setText(_("Press OK to get further details for %s") % str(self["progress_list"].getCurrent()[1]))
554 class DiseqcTesterTestTypeSelection(Screen, ConfigListScreen):
555 skin = """<screen position="80,95" size="560,412" title="DiSEqC Tester Test Settings">
556 <widget name="config" position="10,10" size="540,402" scrollbarMode="showOnDemand" />
559 def __init__(self, session, feid):
560 Screen.__init__(self, session)
564 ConfigListScreen.__init__(self, self.list)
566 self["actions"] = ActionMap(["SetupActions"],
568 "cancel": self.keyCancel
573 def createSetup(self):
574 self.testtype = ConfigSelection(choices={"quick": _("Quick"), "random": _("Random"), "complete": _("Complete")}, default = "quick")
575 self.testtypeEntry = getConfigListEntry(_("Test Type"), self.testtype)
576 self.list.append(self.testtypeEntry)
578 self.loopsfailed = ConfigSelection(choices={"-1": "Every known", "1": "1", "2": "2", "3": "3", "4": "4", "5": "5", "6": "6", "7": "7", "8": "8"}, default = "3")
579 self.loopsfailedEntry = getConfigListEntry(_("Stop testing plane after # failed transponders"), self.loopsfailed)
580 self.list.append(self.loopsfailedEntry)
582 self.loopssuccessful = ConfigSelection(choices={"-1": "Every known", "1": "1", "2": "2", "3": "3", "4": "4", "5": "5", "6": "6", "7": "7", "8": "8"}, default = "1")
583 self.loopssuccessfulEntry = getConfigListEntry(_("Stop testing plane after # successful transponders"), self.loopssuccessful)
584 self.list.append(self.loopssuccessfulEntry)
586 self.log = ConfigYesNo(False)
587 if harddiskmanager.HDDCount() > 0:
588 self.logEntry = getConfigListEntry(_("Log results to harddisk"), self.log)
589 self.list.append(self.logEntry)
591 self["config"].list = self.list
592 self["config"].l.setList(self.list)
595 print self.testtype.getValue()
596 testtype = DiseqcTester.TEST_TYPE_QUICK
597 if self.testtype.getValue() == "quick":
598 testtype = DiseqcTester.TEST_TYPE_QUICK
599 elif self.testtype.getValue() == "random":
600 testtype = DiseqcTester.TEST_TYPE_RANDOM
601 elif self.testtype.getValue() == "complete":
602 testtype = DiseqcTester.TEST_TYPE_COMPLETE
603 self.session.open(DiseqcTester, feid = self.feid, test_type = testtype, loopsfailed = int(self.loopsfailed.value), loopssuccessful = int(self.loopssuccessful.value), log = self.log.value)
608 class DiseqcTesterNimSelection(NimSelection):
610 <screen position="160,123" size="400,330" title="Choose Tuner">
611 <widget source="nimlist" render="Listbox" position="0,0" size="380,300" scrollbarMode="showOnDemand">
612 <convert type="TemplatedMultiContent">
614 MultiContentEntryText(pos = (10, 5), size = (360, 30), flags = RT_HALIGN_LEFT, text = 1), # index 1 is the nim name,
615 MultiContentEntryText(pos = (50, 30), size = (320, 30), font = 1, flags = RT_HALIGN_LEFT, text = 2), # index 2 is a description of the nim settings,
617 "fonts": [gFont("Regular", 20), gFont("Regular", 15)],
624 def __init__(self, session, args = None):
625 NimSelection.__init__(self, session)
627 def setResultClass(self):
628 #self.resultclass = DiseqcTester
629 self.resultclass = DiseqcTesterTestTypeSelection
631 def showNim(self, nim):
632 nimConfig = nimmanager.getNimConfig(nim.slot)
633 if nim.isCompatible("DVB-S"):
634 if nimConfig.configMode.value in ("loopthrough", "equal", "satposdepends", "nothing"):
636 if nimConfig.configMode.value == "simple":
637 if nimConfig.diseqcMode.value == "positioner":
642 def DiseqcTesterMain(session, **kwargs):
643 session.open(DiseqcTesterNimSelection)
645 def autostart(reason, **kwargs):
646 resourcemanager.addResource("DiseqcTester", DiseqcTesterMain)
648 def Plugins(**kwargs):
649 return [ PluginDescriptor(name="DiSEqC Tester", description=_("Test DiSEqC settings"), where = PluginDescriptor.WHERE_PLUGINMENU, fnc=DiseqcTesterMain),
650 PluginDescriptor(where = PluginDescriptor.WHERE_AUTOSTART, fnc = autostart)]