1 from Screens.Satconfig import NimSelection
2 from Screens.Screen import Screen
3 from Screens.TextBox import TextBox
5 from Plugins.Plugin import PluginDescriptor
7 from Components.ActionMap import ActionMap, NumberActionMap
8 from Components.NimManager import nimmanager
9 from Components.ResourceManager import resourcemanager
10 from Components.Sources.FrontendStatus import FrontendStatus
11 from Components.TuneTest import TuneTest
12 from Components.Sources.List import List
13 from Components.Sources.Progress import Progress
14 from Components.Sources.StaticText import StaticText
15 from Components.ConfigList import ConfigListScreen
16 from Components.config import getConfigListEntry, ConfigSelection
20 # setResultParameter(parameter)
29 def setResultType(self, type):
32 def setResultParameter(self, parameter):
33 if self.type == self.TYPE_BYORBPOS:
34 self.orbpos = parameter
35 elif self.type == self.TYPE_BYINDEX:
36 self.index = parameter
38 def getTextualResultForIndex(self, index):
40 text += "%s:\n" % self.getTextualIndexRepresentation(index)
42 failed, successful = self.results[index]["failed"], self.results[index]["successful"]
43 countfailed = len(failed)
44 countsuccessful = len(successful)
45 countall = countfailed + countsuccessful
46 percentfailed = round(countfailed / float(countall + 0.0001) * 100)
47 percentsuccessful = round(countsuccessful / float(countall + 0.0001) * 100)
48 text += "Tested %d transponders\n%d (%d %%) transponders succeeded\n%d (%d %%) transponders failed\n" % (countall, countsuccessful, percentsuccessful, countfailed, percentfailed)
51 for transponder in failed:
52 reasons[transponder[2]] = reasons.get(transponder[2], [])
53 reasons[transponder[2]].append(transponder)
54 if transponder[2] == "pids_failed":
55 print transponder[2], "-", transponder[3]
57 text += "The %d unsuccessful tuning attempts failed for the following reasons:\n" % countfailed
59 for reason in reasons.keys():
60 text += "%s: %d transponders failed\n" % (reason, len(reasons[reason]))
62 for reason in reasons.keys():
64 text += "%s previous planes:\n" % reason
65 for transponder in reasons[reason]:
66 if transponder[1] is not None:
67 text += self.getTextualIndexRepresentation(self.getIndexForTransponder(transponder[1]))
69 text += "No transponder tuned"
70 text += " ==> " + self.getTextualIndexRepresentation(self.getIndexForTransponder(transponder[0]))
72 if countsuccessful > 0:
74 text += "Successfully tuned transponders' previous planes:\n"
75 for transponder in successful:
76 if transponder[1] is not None:
77 text += self.getTextualIndexRepresentation(self.getIndexForTransponder(transponder[1]))
79 text += "No transponder tuned"
80 text += " ==> " + self.getTextualIndexRepresentation(self.getIndexForTransponder(transponder[0]))
84 def getTextualResult(self):
86 if self.type == self.TYPE_BYINDEX:
87 text += self.getTextualResultForIndex(self.index)
88 elif self.type == self.TYPE_BYORBPOS:
89 for index in self.results.keys():
90 if index[2] == self.orbpos:
91 text += self.getTextualResultForIndex(index)
92 text += "\n-----------------------------------------------------\n"
96 class DiseqcTester(Screen, TuneTest, ResultParser):
98 <screen position="90,100" size="520,400" title="DiSEqC Tester" >
99 <!--ePixmap pixmap="skin_default/icons/dish_scan.png" position="5,25" zPosition="0" size="119,110" transparent="1" alphatest="on" />
100 <widget source="Frontend" render="Label" position="190,10" zPosition="2" size="260,20" font="Regular;19" halign="center" valign="center" transparent="1">
101 <convert type="FrontendInfo">SNRdB</convert>
103 <eLabel name="snr" text="SNR:" position="120,35" size="60,22" font="Regular;21" halign="right" transparent="1" />
104 <widget source="Frontend" render="Progress" position="190,35" size="260,20" pixmap="skin_default/bar_snr.png" borderWidth="2" borderColor="#cccccc">
105 <convert type="FrontendInfo">SNR</convert>
107 <widget source="Frontend" render="Label" position="460,35" size="60,22" font="Regular;21">
108 <convert type="FrontendInfo">SNR</convert>
110 <eLabel name="agc" text="AGC:" position="120,60" size="60,22" font="Regular;21" halign="right" transparent="1" />
111 <widget source="Frontend" render="Progress" position="190,60" size="260,20" pixmap="skin_default/bar_snr.png" borderWidth="2" borderColor="#cccccc">
112 <convert type="FrontendInfo">AGC</convert>
114 <widget source="Frontend" render="Label" position="460,60" size="60,22" font="Regular;21">
115 <convert type="FrontendInfo">AGC</convert>
117 <eLabel name="ber" text="BER:" position="120,85" size="60,22" font="Regular;21" halign="right" transparent="1" />
118 <widget source="Frontend" render="Progress" position="190,85" size="260,20" pixmap="skin_default/bar_ber.png" borderWidth="2" borderColor="#cccccc">
119 <convert type="FrontendInfo">BER</convert>
121 <widget source="Frontend" render="Label" position="460,85" size="60,22" font="Regular;21">
122 <convert type="FrontendInfo">BER</convert>
124 <eLabel name="lock" text="Lock:" position="120,115" size="60,22" font="Regular;21" halign="right" />
125 <widget source="Frontend" render="Pixmap" pixmap="skin_default/icons/lock_on.png" position="190,110" zPosition="1" size="38,31" alphatest="on">
126 <convert type="FrontendInfo">LOCK</convert>
127 <convert type="ConditionalShowHide" />
129 <widget source="Frontend" render="Pixmap" pixmap="skin_default/icons/lock_off.png" position="190,110" zPosition="1" size="38,31" alphatest="on">
130 <convert type="FrontendInfo">LOCK</convert>
131 <convert type="ConditionalShowHide">Invert</convert>
133 <widget source="progress_list" render="Listbox" position="0,0" size="510,150" scrollbarMode="showOnDemand">
134 <convert type="TemplatedMultiContent">
136 MultiContentEntryText(pos = (10, 0), size = (330, 25), flags = RT_HALIGN_LEFT, text = 1), # index 1 is the index name,
137 MultiContentEntryText(pos = (330, 0), size = (150, 25), flags = RT_HALIGN_RIGHT, text = 2) # index 2 is the status,
139 "fonts": [gFont("Regular", 20)],
144 <eLabel name="overall_progress" text="Overall progress:" position="20,162" size="480,22" font="Regular;21" halign="center" transparent="1" />
145 <widget source="overall_progress" render="Progress" position="20,192" size="480,20" borderWidth="2" backgroundColor="#254f7497" />
146 <eLabel name="overall_progress" text="Progress:" position="20,222" size="480,22" font="Regular;21" halign="center" transparent="1" />
147 <widget source="sub_progress" render="Progress" position="20,252" size="480,20" borderWidth="2" backgroundColor="#254f7497" />
149 <eLabel name="" text="Failed:" position="20,282" size="140,22" font="Regular;21" halign="left" transparent="1" />
150 <widget source="failed_counter" render="Label" position="160,282" size="100,20" font="Regular;21" />
152 <eLabel name="" text="Succeeded:" position="20,312" size="140,22" font="Regular;21" halign="left" transparent="1" />
153 <widget source="succeeded_counter" render="Label" position="160,312" size="100,20" font="Regular;21" />
155 <eLabel name="" text="With errors:" position="20,342" size="140,22" font="Regular;21" halign="left" transparent="1" />
156 <widget source="witherrors_counter" render="Label" position="160,342" size="100,20" font="Regular;21" />
158 <eLabel name="" text="Not tested:" position="20,372" size="140,22" font="Regular;21" halign="left" transparent="1" />
159 <widget source="untestable_counter" render="Label" position="160,372" size="100,20" font="Regular;21" />
161 <widget source="CmdText" render="Label" position="300,282" size="180,200" font="Regular;21" />
166 TEST_TYPE_COMPLETE = 2
167 def __init__(self, session, feid, test_type = TEST_TYPE_QUICK, loopsfailed = 3, loopssuccessful = 1):
168 Screen.__init__(self, session)
170 self.test_type = test_type
171 self.loopsfailed = loopsfailed
172 self.loopssuccessful = loopssuccessful
174 self["actions"] = NumberActionMap(["SetupActions"],
177 "cancel": self.keyCancel,
180 TuneTest.__init__(self, feid, stopOnSuccess = self.loopssuccessful, stopOnError = self.loopsfailed)
181 #self["Frontend"] = FrontendStatus(frontend_source = lambda : self.frontend, update_interval = 100)
182 self["overall_progress"] = Progress()
183 self["sub_progress"] = Progress()
185 self["failed_counter"] = StaticText("0")
186 self["succeeded_counter"] = StaticText("0")
187 self["witherrors_counter"] = StaticText("0")
188 self["untestable_counter"] = StaticText("0")
191 self["progress_list"] = List(self.list)
192 self["progress_list"].onSelectionChanged.append(self.selectionChanged)
194 self["CmdText"] = StaticText(_("Please wait while scanning is in progress..."))
197 self.readTransponderList()
202 self.resultsstatus = {}
204 self.onLayoutFinish.append(self.go)
206 def getProgressListComponent(self, index, status):
207 return (index, self.getTextualIndexRepresentation(index), status)
209 def clearProgressList(self):
211 self["progress_list"].list = self.list
213 def addProgressListItem(self, index):
214 if index in self.indexlist:
215 for entry in self.list:
216 if entry[0] == index:
217 self.changeProgressListStatus(index, "working")
219 self.list.append(self.getProgressListComponent(index, _("working")))
220 self["progress_list"].list = self.list
221 self["progress_list"].setIndex(len(self.list) - 1)
223 def changeProgressListStatus(self, index, status):
227 for entry in self.list:
228 if entry[0] == index:
229 self.newlist.append(self.getProgressListComponent(index, status))
232 self.newlist.append(entry)
234 self.list = self.newlist
235 self["progress_list"].list = self.list
236 self["progress_list"].setIndex(indexpos)
238 def readTransponderList(self):
239 for sat in nimmanager.getSatListForNim(self.feid):
240 for transponder in nimmanager.getTransponders(sat[0]):
242 mytransponder = (transponder[1] / 1000, transponder[2] / 1000, transponder[3], transponder[4], transponder[5], sat[0], None, None, transponder[10], transponder[11])
243 self.analyseTransponder(mytransponder)
245 def getIndexForTransponder(self, transponder):
247 if transponder[0] < 11700:
252 polarisation = transponder[2]
256 index = (band, polarisation, sat)
259 # sort the transponder into self.transponderlist
260 def analyseTransponder(self, transponder):
261 index = self.getIndexForTransponder(transponder)
262 if index not in self.indexlist:
263 self.indexlist[index] = []
264 self.indexlist[index].append(transponder)
265 #print "self.indexlist:", self.indexlist
267 # returns a string for the user representing a human readable output for index
268 def getTextualIndexRepresentation(self, index):
269 print "getTextualIndexRepresentation:", index
272 text += nimmanager.getSatDescription(index[2]) + ", "
277 text += "High Band, "
285 def fillTransponderList(self):
286 self.clearTransponder()
287 print "----------- fillTransponderList"
288 print "index:", self.currentlyTestedIndex
289 keys = self.indexlist.keys()
290 if self.getContinueScanning():
291 print "index:", self.getTextualIndexRepresentation(self.currentlyTestedIndex)
292 for transponder in self.indexlist[self.currentlyTestedIndex]:
293 self.addTransponder(transponder)
294 print "transponderList:", self.transponderlist
299 def progressCallback(self, progress):
300 if progress[0] != self["sub_progress"].getRange():
301 self["sub_progress"].setRange(progress[0])
302 self["sub_progress"].setValue(progress[1])
304 # logic for scanning order of transponders
305 # on go getFirstIndex is called
306 def getFirstIndex(self):
307 # TODO use other function to scan more randomly
308 if self.test_type == self.TEST_TYPE_QUICK:
310 keys = self.indexlist.keys()
311 keys.sort(key = lambda a: a[2]) # sort by orbpos
312 self["overall_progress"].setRange(len(keys))
313 self["overall_progress"].setValue(self.myindex)
316 # after each index is finished, getNextIndex is called to get the next index to scan
317 def getNextIndex(self):
318 # TODO use other function to scan more randomly
319 if self.test_type == self.TEST_TYPE_QUICK:
321 keys = self.indexlist.keys()
322 keys.sort(key = lambda a: a[2]) # sort by orbpos
324 self["overall_progress"].setValue(self.myindex)
325 if self.myindex < len(keys):
326 return keys[self.myindex]
330 # after each index is finished and the next index is returned by getNextIndex
331 # the algorithm checks, if we should continue scanning
332 def getContinueScanning(self):
333 if self.test_type == self.TEST_TYPE_QUICK:
334 return (self.myindex < len(self.indexlist.keys()))
336 def addResult(self, index, status, failedTune, successfullyTune):
337 self.results[index] = self.results.get(index, {"failed": [], "successful": [], "status": None})
338 self.resultsstatus[status] = self.resultsstatus.get(status, [])
340 self.results[index]["status"] = status
341 self.results[index]["failed"] = failedTune
342 self.results[index]["successful"] = successfullyTune
344 self.resultsstatus[status].append(index)
346 def finishedChecking(self):
347 print "finishedChecking"
348 TuneTest.finishedChecking(self)
350 if not self.results.has_key(self.currentlyTestedIndex):
351 self.results[self.currentlyTestedIndex] = {"failed": [], "successful": [], "status": None}
353 if len(self.failedTune) > 0 and len(self.successfullyTune) > 0:
354 self.changeProgressListStatus(self.currentlyTestedIndex, "with errors")
355 self["witherrors_counter"].setText(str(int(self["witherrors_counter"].getText()) + 1))
356 self.addResult(self.currentlyTestedIndex, "with_errors", self.failedTune, self.successfullyTune)
357 elif len(self.failedTune) == 0 and len(self.successfullyTune) == 0:
358 self.changeProgressListStatus(self.currentlyTestedIndex, "not tested")
359 self["untestable_counter"].setText(str(int(self["untestable_counter"].getText()) + 1))
360 self.addResult(self.currentlyTestedIndex, "untestable", self.failedTune, self.successfullyTune)
361 elif len(self.failedTune) > 0:
362 self.changeProgressListStatus(self.currentlyTestedIndex, "failed")
363 self["failed_counter"].setText(str(int(self["failed_counter"].getText()) + len(self.failedTune)))
364 self.addResult(self.currentlyTestedIndex, "failed", self.failedTune, self.successfullyTune)
366 self.changeProgressListStatus(self.currentlyTestedIndex, "successful")
367 self["succeeded_counter"].setText(str(int(self["succeeded_counter"].getText()) + len(self.successfullyTune)))
368 self.addResult(self.currentlyTestedIndex, "successful", self.failedTune, self.successfullyTune)
371 #self["failed_counter"].setText(str(int(self["failed_counter"].getText()) + len(self.failedTune)))
372 #self["succeeded_counter"].setText(str(int(self["succeeded_counter"].getText()) + len(self.successfullyTune)))
373 #if len(self.failedTune) == 0 and len(self.successfullyTune) == 0:
374 #self["untestable_counter"].setText(str(int(self["untestable_counter"].getText()) + 1))
376 self.currentlyTestedIndex = self.getNextIndex()
377 self.addProgressListItem(self.currentlyTestedIndex)
379 if self.fillTransponderList():
380 self.run(checkPIDs = True)
383 self["progress_list"].setIndex(0)
384 print "results:", self.results
385 print "resultsstatus:", self.resultsstatus
389 self["failed_counter"].setText("0")
390 self["succeeded_counter"].setText("0")
391 self["untestable_counter"].setText("0")
392 self.currentlyTestedIndex = self.getFirstIndex()
394 self.clearProgressList()
395 self.addProgressListItem(self.currentlyTestedIndex)
397 if self.fillTransponderList():
404 print "selectedIndex:", self["progress_list"].getCurrent()[0]
406 index = self["progress_list"].getCurrent()[0]
407 #self.setResultType(ResultParser.TYPE_BYORBPOS)
408 #self.setResultParameter(index[2])
409 self.setResultType(ResultParser.TYPE_BYINDEX)
410 self.setResultParameter(index)
411 self.session.open(TextBox, self.getTextualResult())
413 def selectionChanged(self):
414 print "selection changed"
415 if len(self.list) > 0 and not self.running:
416 self["CmdText"].setText(_("Press OK to get further details for %s") % str(self["progress_list"].getCurrent()[1]))
418 class DiseqcTesterTestTypeSelection(Screen, ConfigListScreen):
419 skin = """<screen position="80,95" size="560,412" title="DiSEqC Tester Test Settings">
420 <widget name="config" position="10,10" size="540,402" scrollbarMode="showOnDemand" />
423 def __init__(self, session, feid):
424 Screen.__init__(self, session)
428 ConfigListScreen.__init__(self, self.list)
430 self["actions"] = ActionMap(["SetupActions"],
432 "cancel": self.keyCancel
437 def createSetup(self):
438 self.testtype = ConfigSelection(choices={"quick": _("Quick")}, default = "quick")
439 self.testtypeEntry = getConfigListEntry(_("Test Type"), self.testtype)
440 self.list.append(self.testtypeEntry)
442 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")
443 self.loopsfailedEntry = getConfigListEntry(_("Stop testing plane after # failed transponders"), self.loopsfailed)
444 self.list.append(self.loopsfailedEntry)
446 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")
447 self.loopssuccessfulEntry = getConfigListEntry(_("Stop testing plane after # successful transponders"), self.loopssuccessful)
448 self.list.append(self.loopssuccessfulEntry)
450 self["config"].list = self.list
451 self["config"].l.setList(self.list)
454 print self.testtype.getValue()
455 testtype = DiseqcTester.TEST_TYPE_QUICK
456 if self.testtype.getValue() == "quick":
457 testtype = DiseqcTester.TEST_TYPE_QUICK
458 elif self.testtype.getValue() == "random":
459 testtype = DiseqcTester.TEST_TYPE_RANDOM
460 elif self.testtype.getValue() == "complete":
461 testtype = DiseqcTester.TEST_TYPE_COMPLETE
462 self.session.open(DiseqcTester, feid = self.feid, test_type = testtype, loopsfailed = int(self.loopsfailed.value), loopssuccessful = int(self.loopssuccessful.value))
467 class DiseqcTesterNimSelection(NimSelection):
469 <screen position="160,123" size="400,330" title="Choose Tuner">
470 <widget source="nimlist" render="Listbox" position="0,0" size="380,300" scrollbarMode="showOnDemand">
471 <convert type="TemplatedMultiContent">
473 MultiContentEntryText(pos = (10, 5), size = (360, 30), flags = RT_HALIGN_LEFT, text = 1), # index 1 is the nim name,
474 MultiContentEntryText(pos = (50, 30), size = (320, 30), font = 1, flags = RT_HALIGN_LEFT, text = 2), # index 2 is a description of the nim settings,
476 "fonts": [gFont("Regular", 20), gFont("Regular", 15)],
483 def __init__(self, session, args = None):
484 NimSelection.__init__(self, session)
486 def setResultClass(self):
487 #self.resultclass = DiseqcTester
488 self.resultclass = DiseqcTesterTestTypeSelection
490 def showNim(self, nim):
491 nimConfig = nimmanager.getNimConfig(nim.slot)
492 if nim.isCompatible("DVB-S"):
493 if nimConfig.configMode.value in ["loopthrough", "equal", "satposdepends", "nothing"]:
495 if nimConfig.configMode.value == "simple":
496 if nimConfig.diseqcMode.value == "positioner":
501 def DiseqcTesterMain(session, **kwargs):
502 session.open(DiseqcTesterNimSelection)
504 def autostart(reason, **kwargs):
505 resourcemanager.addResource("DiseqcTester", DiseqcTesterMain)
507 def Plugins(**kwargs):
508 return [ PluginDescriptor(name="DiSEqC Tester", description=_("Test DiSEqC settings"), where = PluginDescriptor.WHERE_PLUGINMENU, fnc=DiseqcTesterMain),
509 PluginDescriptor(where = PluginDescriptor.WHERE_AUTOSTART, fnc = autostart)]