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]))
63 def getTextualResult(self):
65 if self.type == self.TYPE_BYINDEX:
66 text += self.getTextualResultForIndex(self.index)
67 elif self.type == self.TYPE_BYORBPOS:
68 for index in self.results.keys():
69 if index[2] == self.orbpos:
70 text += self.getTextualResultForIndex(index)
71 text += "\n-----------------------------------------------------\n"
75 class DiseqcTester(Screen, TuneTest, ResultParser):
77 <screen position="90,100" size="520,400" title="DiSEqC Tester" >
78 <!--ePixmap pixmap="skin_default/icons/dish_scan.png" position="5,25" zPosition="0" size="119,110" transparent="1" alphatest="on" />
79 <widget source="Frontend" render="Label" position="190,10" zPosition="2" size="260,20" font="Regular;19" halign="center" valign="center" transparent="1">
80 <convert type="FrontendInfo">SNRdB</convert>
82 <eLabel name="snr" text="SNR:" position="120,35" size="60,22" font="Regular;21" halign="right" transparent="1" />
83 <widget source="Frontend" render="Progress" position="190,35" size="260,20" pixmap="skin_default/bar_snr.png" borderWidth="2" borderColor="#cccccc">
84 <convert type="FrontendInfo">SNR</convert>
86 <widget source="Frontend" render="Label" position="460,35" size="60,22" font="Regular;21">
87 <convert type="FrontendInfo">SNR</convert>
89 <eLabel name="agc" text="AGC:" position="120,60" size="60,22" font="Regular;21" halign="right" transparent="1" />
90 <widget source="Frontend" render="Progress" position="190,60" size="260,20" pixmap="skin_default/bar_snr.png" borderWidth="2" borderColor="#cccccc">
91 <convert type="FrontendInfo">AGC</convert>
93 <widget source="Frontend" render="Label" position="460,60" size="60,22" font="Regular;21">
94 <convert type="FrontendInfo">AGC</convert>
96 <eLabel name="ber" text="BER:" position="120,85" size="60,22" font="Regular;21" halign="right" transparent="1" />
97 <widget source="Frontend" render="Progress" position="190,85" size="260,20" pixmap="skin_default/bar_ber.png" borderWidth="2" borderColor="#cccccc">
98 <convert type="FrontendInfo">BER</convert>
100 <widget source="Frontend" render="Label" position="460,85" size="60,22" font="Regular;21">
101 <convert type="FrontendInfo">BER</convert>
103 <eLabel name="lock" text="Lock:" position="120,115" size="60,22" font="Regular;21" halign="right" />
104 <widget source="Frontend" render="Pixmap" pixmap="skin_default/icons/lock_on.png" position="190,110" zPosition="1" size="38,31" alphatest="on">
105 <convert type="FrontendInfo">LOCK</convert>
106 <convert type="ConditionalShowHide" />
108 <widget source="Frontend" render="Pixmap" pixmap="skin_default/icons/lock_off.png" position="190,110" zPosition="1" size="38,31" alphatest="on">
109 <convert type="FrontendInfo">LOCK</convert>
110 <convert type="ConditionalShowHide">Invert</convert>
112 <widget source="progress_list" render="Listbox" position="0,0" size="510,150" scrollbarMode="showOnDemand">
113 <convert type="TemplatedMultiContent">
115 MultiContentEntryText(pos = (10, 0), size = (330, 25), flags = RT_HALIGN_LEFT, text = 1), # index 1 is the index name,
116 MultiContentEntryText(pos = (330, 0), size = (150, 25), flags = RT_HALIGN_RIGHT, text = 2) # index 2 is the status,
118 "fonts": [gFont("Regular", 20)],
123 <eLabel name="overall_progress" text="Overall progress:" position="20,162" size="480,22" font="Regular;21" halign="center" transparent="1" />
124 <widget source="overall_progress" render="Progress" position="20,192" size="480,20" borderWidth="2" backgroundColor="#254f7497" />
125 <eLabel name="overall_progress" text="Progress:" position="20,222" size="480,22" font="Regular;21" halign="center" transparent="1" />
126 <widget source="sub_progress" render="Progress" position="20,252" size="480,20" borderWidth="2" backgroundColor="#254f7497" />
128 <eLabel name="" text="Failed:" position="20,282" size="140,22" font="Regular;21" halign="left" transparent="1" />
129 <widget source="failed_counter" render="Label" position="160,282" size="100,20" font="Regular;21" />
131 <eLabel name="" text="Succeeded:" position="20,312" size="140,22" font="Regular;21" halign="left" transparent="1" />
132 <widget source="succeeded_counter" render="Label" position="160,312" size="100,20" font="Regular;21" />
134 <eLabel name="" text="With errors:" position="20,342" size="140,22" font="Regular;21" halign="left" transparent="1" />
135 <widget source="witherrors_counter" render="Label" position="160,342" size="100,20" font="Regular;21" />
137 <eLabel name="" text="Not tested:" position="20,372" size="140,22" font="Regular;21" halign="left" transparent="1" />
138 <widget source="untestable_counter" render="Label" position="160,372" size="100,20" font="Regular;21" />
140 <widget source="CmdText" render="Label" position="300,282" size="180,200" font="Regular;21" />
145 TEST_TYPE_COMPLETE = 2
146 def __init__(self, session, feid, test_type = TEST_TYPE_QUICK, loopsfailed = 3, loopssuccessful = 1):
147 Screen.__init__(self, session)
149 self.test_type = test_type
150 self.loopsfailed = loopsfailed
151 self.loopssuccessful = loopssuccessful
153 self["actions"] = NumberActionMap(["SetupActions"],
156 "cancel": self.keyCancel,
159 TuneTest.__init__(self, feid, stopOnSuccess = self.loopssuccessful, stopOnError = self.loopsfailed)
160 #self["Frontend"] = FrontendStatus(frontend_source = lambda : self.frontend, update_interval = 100)
161 self["overall_progress"] = Progress()
162 self["sub_progress"] = Progress()
164 self["failed_counter"] = StaticText("0")
165 self["succeeded_counter"] = StaticText("0")
166 self["witherrors_counter"] = StaticText("0")
167 self["untestable_counter"] = StaticText("0")
170 self["progress_list"] = List(self.list)
171 self["progress_list"].onSelectionChanged.append(self.selectionChanged)
173 self["CmdText"] = StaticText(_("Please wait while scanning is in progress..."))
176 self.readTransponderList()
181 self.resultsstatus = {}
183 self.onLayoutFinish.append(self.go)
185 def getProgressListComponent(self, index, status):
186 return (index, self.getTextualIndexRepresentation(index), status)
188 def clearProgressList(self):
190 self["progress_list"].list = self.list
192 def addProgressListItem(self, index):
193 if index in self.indexlist:
194 for entry in self.list:
195 if entry[0] == index:
196 self.changeProgressListStatus(index, "working")
198 self.list.append(self.getProgressListComponent(index, _("working")))
199 self["progress_list"].list = self.list
200 self["progress_list"].setIndex(len(self.list) - 1)
202 def changeProgressListStatus(self, index, status):
206 for entry in self.list:
207 if entry[0] == index:
208 self.newlist.append(self.getProgressListComponent(index, status))
211 self.newlist.append(entry)
213 self.list = self.newlist
214 self["progress_list"].list = self.list
215 self["progress_list"].setIndex(indexpos)
217 def readTransponderList(self):
218 for sat in nimmanager.getSatListForNim(self.feid):
219 for transponder in nimmanager.getTransponders(sat[0]):
221 mytransponder = (transponder[1] / 1000, transponder[2] / 1000, transponder[3], transponder[4], transponder[5], sat[0], None, None, transponder[10], transponder[11])
222 self.analyseTransponder(mytransponder)
224 def getIndexForTransponder(self, transponder):
226 if transponder[0] < 11700:
231 polarisation = transponder[2]
235 index = (band, polarisation, sat)
238 # sort the transponder into self.transponderlist
239 def analyseTransponder(self, transponder):
240 index = self.getIndexForTransponder(transponder)
241 if index not in self.indexlist:
242 self.indexlist[index] = []
243 self.indexlist[index].append(transponder)
244 #print "self.indexlist:", self.indexlist
246 # returns a string for the user representing a human readable output for index
247 def getTextualIndexRepresentation(self, index):
248 print "getTextualIndexRepresentation:", index
251 text += nimmanager.getSatDescription(index[2]) + ", "
256 text += "High Band, "
264 def fillTransponderList(self):
265 self.clearTransponder()
266 print "----------- fillTransponderList"
267 print "index:", self.currentlyTestedIndex
268 keys = self.indexlist.keys()
269 if self.getContinueScanning():
270 print "index:", self.getTextualIndexRepresentation(self.currentlyTestedIndex)
271 for transponder in self.indexlist[self.currentlyTestedIndex]:
272 self.addTransponder(transponder)
273 print "transponderList:", self.transponderlist
278 def progressCallback(self, progress):
279 if progress[0] != self["sub_progress"].getRange():
280 self["sub_progress"].setRange(progress[0])
281 self["sub_progress"].setValue(progress[1])
283 # logic for scanning order of transponders
284 # on go getFirstIndex is called
285 def getFirstIndex(self):
286 # TODO use other function to scan more randomly
287 if self.test_type == self.TEST_TYPE_QUICK:
289 keys = self.indexlist.keys()
290 keys.sort(key = lambda a: a[2]) # sort by orbpos
291 self["overall_progress"].setRange(len(keys))
292 self["overall_progress"].setValue(self.myindex)
295 # after each index is finished, getNextIndex is called to get the next index to scan
296 def getNextIndex(self):
297 # TODO use other function to scan more randomly
298 if self.test_type == self.TEST_TYPE_QUICK:
300 keys = self.indexlist.keys()
301 keys.sort(key = lambda a: a[2]) # sort by orbpos
303 self["overall_progress"].setValue(self.myindex)
304 if self.myindex < len(keys):
305 return keys[self.myindex]
309 # after each index is finished and the next index is returned by getNextIndex
310 # the algorithm checks, if we should continue scanning
311 def getContinueScanning(self):
312 if self.test_type == self.TEST_TYPE_QUICK:
313 return (self.myindex < len(self.indexlist.keys()))
315 def addResult(self, index, status, failedTune, successfullyTune):
316 self.results[index] = self.results.get(index, {"failed": [], "successful": [], "status": None})
317 self.resultsstatus[status] = self.resultsstatus.get(status, [])
319 self.results[index]["status"] = status
320 self.results[index]["failed"] = failedTune
321 self.results[index]["successful"] = successfullyTune
323 self.resultsstatus[status].append(index)
325 def finishedChecking(self):
326 print "finishedChecking"
327 TuneTest.finishedChecking(self)
329 if not self.results.has_key(self.currentlyTestedIndex):
330 self.results[self.currentlyTestedIndex] = {"failed": [], "successful": [], "status": None}
332 if len(self.failedTune) > 0 and len(self.successfullyTune) > 0:
333 self.changeProgressListStatus(self.currentlyTestedIndex, "with errors")
334 self["witherrors_counter"].setText(str(int(self["witherrors_counter"].getText()) + 1))
335 self.addResult(self.currentlyTestedIndex, "with_errors", self.failedTune, self.successfullyTune)
336 elif len(self.failedTune) == 0 and len(self.successfullyTune) == 0:
337 self.changeProgressListStatus(self.currentlyTestedIndex, "not tested")
338 self["untestable_counter"].setText(str(int(self["untestable_counter"].getText()) + 1))
339 self.addResult(self.currentlyTestedIndex, "untestable", self.failedTune, self.successfullyTune)
340 elif len(self.failedTune) > 0:
341 self.changeProgressListStatus(self.currentlyTestedIndex, "failed")
342 self["failed_counter"].setText(str(int(self["failed_counter"].getText()) + len(self.failedTune)))
343 self.addResult(self.currentlyTestedIndex, "failed", self.failedTune, self.successfullyTune)
345 self.changeProgressListStatus(self.currentlyTestedIndex, "successful")
346 self["succeeded_counter"].setText(str(int(self["succeeded_counter"].getText()) + len(self.successfullyTune)))
347 self.addResult(self.currentlyTestedIndex, "successful", self.failedTune, self.successfullyTune)
350 #self["failed_counter"].setText(str(int(self["failed_counter"].getText()) + len(self.failedTune)))
351 #self["succeeded_counter"].setText(str(int(self["succeeded_counter"].getText()) + len(self.successfullyTune)))
352 #if len(self.failedTune) == 0 and len(self.successfullyTune) == 0:
353 #self["untestable_counter"].setText(str(int(self["untestable_counter"].getText()) + 1))
355 self.currentlyTestedIndex = self.getNextIndex()
356 self.addProgressListItem(self.currentlyTestedIndex)
358 if self.fillTransponderList():
359 self.run(checkPIDs = True)
362 self["progress_list"].setIndex(0)
363 print "results:", self.results
364 print "resultsstatus:", self.resultsstatus
368 self["failed_counter"].setText("0")
369 self["succeeded_counter"].setText("0")
370 self["untestable_counter"].setText("0")
371 self.currentlyTestedIndex = self.getFirstIndex()
373 self.clearProgressList()
374 self.addProgressListItem(self.currentlyTestedIndex)
376 if self.fillTransponderList():
383 print "selectedIndex:", self["progress_list"].getCurrent()[0]
385 index = self["progress_list"].getCurrent()[0]
386 #self.setResultType(ResultParser.TYPE_BYORBPOS)
387 #self.setResultParameter(index[2])
388 self.setResultType(ResultParser.TYPE_BYINDEX)
389 self.setResultParameter(index)
390 self.session.open(TextBox, self.getTextualResult())
392 def selectionChanged(self):
393 print "selection changed"
394 if len(self.list) > 0 and not self.running:
395 self["CmdText"].setText(_("Press OK to get further details for %s") % str(self["progress_list"].getCurrent()[1]))
397 class DiseqcTesterTestTypeSelection(Screen, ConfigListScreen):
398 skin = """<screen position="80,95" size="560,412" title="DiSEqC Tester Test Settings">
399 <widget name="config" position="10,10" size="540,402" scrollbarMode="showOnDemand" />
402 def __init__(self, session, feid):
403 Screen.__init__(self, session)
407 ConfigListScreen.__init__(self, self.list)
409 self["actions"] = ActionMap(["SetupActions"],
411 "cancel": self.keyCancel
416 def createSetup(self):
417 self.testtype = ConfigSelection(choices={"quick": _("Quick")}, default = "quick")
418 self.testtypeEntry = getConfigListEntry(_("Test Type"), self.testtype)
419 self.list.append(self.testtypeEntry)
421 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")
422 self.loopsfailedEntry = getConfigListEntry(_("Stop testing plane after # failed transponders"), self.loopsfailed)
423 self.list.append(self.loopsfailedEntry)
425 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")
426 self.loopssuccessfulEntry = getConfigListEntry(_("Stop testing plane after # successful transponders"), self.loopssuccessful)
427 self.list.append(self.loopssuccessfulEntry)
429 self["config"].list = self.list
430 self["config"].l.setList(self.list)
433 print self.testtype.getValue()
434 testtype = DiseqcTester.TEST_TYPE_QUICK
435 if self.testtype.getValue() == "quick":
436 testtype = DiseqcTester.TEST_TYPE_QUICK
437 elif self.testtype.getValue() == "random":
438 testtype = DiseqcTester.TEST_TYPE_RANDOM
439 elif self.testtype.getValue() == "complete":
440 testtype = DiseqcTester.TEST_TYPE_COMPLETE
441 self.session.open(DiseqcTester, feid = self.feid, test_type = testtype, loopsfailed = int(self.loopsfailed.value), loopssuccessful = int(self.loopssuccessful.value))
446 class DiseqcTesterNimSelection(NimSelection):
448 <screen position="160,123" size="400,330" title="Choose Tuner">
449 <widget source="nimlist" render="Listbox" position="0,0" size="380,300" scrollbarMode="showOnDemand">
450 <convert type="TemplatedMultiContent">
452 MultiContentEntryText(pos = (10, 5), size = (360, 30), flags = RT_HALIGN_LEFT, text = 1), # index 1 is the nim name,
453 MultiContentEntryText(pos = (50, 30), size = (320, 30), font = 1, flags = RT_HALIGN_LEFT, text = 2), # index 2 is a description of the nim settings,
455 "fonts": [gFont("Regular", 20), gFont("Regular", 15)],
462 def __init__(self, session, args = None):
463 NimSelection.__init__(self, session)
465 def setResultClass(self):
466 #self.resultclass = DiseqcTester
467 self.resultclass = DiseqcTesterTestTypeSelection
469 def showNim(self, nim):
470 nimConfig = nimmanager.getNimConfig(nim.slot)
471 if nim.isCompatible("DVB-S"):
472 if nimConfig.configMode.value in ["loopthrough", "equal", "satposdepends", "nothing"]:
474 if nimConfig.configMode.value == "simple":
475 if nimConfig.diseqcMode.value == "positioner":
480 def DiseqcTesterMain(session, **kwargs):
481 session.open(DiseqcTesterNimSelection)
483 def autostart(reason, **kwargs):
484 resourcemanager.addResource("DiseqcTester", DiseqcTesterMain)
486 def Plugins(**kwargs):
487 return [ PluginDescriptor(name="DiSEqC Tester", description=_("Test DiSEqC settings"), where = PluginDescriptor.WHERE_PLUGINMENU, fnc=DiseqcTesterMain),
488 PluginDescriptor(where = PluginDescriptor.WHERE_AUTOSTART, fnc = autostart)]