Merge commit 'origin/master' into tmbinc/FixTimingBugs
[enigma2.git] / lib / python / Plugins / SystemPlugins / DiseqcTester / plugin.py
1 from Screens.Satconfig import NimSelection
2 from Screens.Screen import Screen
3 from Screens.TextBox import TextBox
4 from Screens.MessageBox import MessageBox
5
6 from Plugins.Plugin import PluginDescriptor
7
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
19
20 import random
21
22 # always use:
23 # setResultType(type)
24 # setResultParameter(parameter)
25 # getTextualResult()
26 class ResultParser:
27         def __init__(self):
28                 pass
29         
30         TYPE_BYORBPOS = 0
31         TYPE_BYINDEX = 1
32         TYPE_ALL = 2
33         def setResultType(self, type):
34                 self.type = type
35                 
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
41                         
42         def getTextualResultForIndex(self, index, logfulltransponders = False):
43                 text = ""
44                 text += "%s:\n" % self.getTextualIndexRepresentation(index)
45                 
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)
53                 reasons = {}
54                 if countfailed > 0:
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]
60                                 
61                         text += "The %d unsuccessful tuning attempts failed for the following reasons:\n" % countfailed
62                         
63                         for reason in reasons.keys():
64                                 text += "%s: %d transponders failed\n" % (reason, len(reasons[reason]))
65                         
66                         for reason in reasons.keys():
67                                 text += "\n"
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]))
72                                         else:
73                                                 text += "No transponder tuned"
74                                         text += " ==> " + self.getTextualIndexRepresentation(self.getIndexForTransponder(transponder[0]))
75                                         text += "\n"
76                                         if logfulltransponders:
77                                                 text += str(transponder[1])
78                                                 text += " ==> "
79                                                 text += str(transponder[0])
80                                                 text += "\n"
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)"
87                                                 text += "\n"
88                                         text += "\n"
89                 if countsuccessful > 0:
90                         text += "\n"
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]))
95                                 else:
96                                         text += "No transponder tuned"
97                                 text += " ==> " + self.getTextualIndexRepresentation(self.getIndexForTransponder(transponder[0]))
98                                 text += "\n"
99                 return text
100
101         def getTextualResult(self):
102                 text = ""
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:
111                         orderedResults = {}
112                         for index in self.results.keys():
113                                 orbpos = index[2]
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"
125                         
126                                 
127                 return text
128
129 class DiseqcTester(Screen, TuneTest, ResultParser):
130         skin = """
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>
135                 </widget>
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>
139                 </widget>
140                 <widget source="Frontend" render="Label" position="460,35" size="60,22" font="Regular;21">
141                         <convert type="FrontendInfo">SNR</convert>
142                 </widget>
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>
146                 </widget>
147                 <widget source="Frontend" render="Label" position="460,60" size="60,22" font="Regular;21">
148                         <convert type="FrontendInfo">AGC</convert>
149                 </widget>
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>
153                 </widget>
154                 <widget source="Frontend" render="Label" position="460,85" size="60,22" font="Regular;21">
155                         <convert type="FrontendInfo">BER</convert>
156                 </widget>
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" />
161                 </widget>
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>
165                 </widget-->
166                 <widget source="progress_list" render="Listbox" position="0,0" size="510,150" scrollbarMode="showOnDemand">
167                         <convert type="TemplatedMultiContent">
168                                 {"template": [
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,
171                                         ],
172                                  "fonts": [gFont("Regular", 20)],
173                                  "itemHeight": 25
174                                 }
175                         </convert>
176                 </widget>
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" />
181                 
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" />
184                 
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" />
187                 
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" />
190                 
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" />
193                 
194                 <widget source="CmdText" render="Label" position="300,282" size="180,200" font="Regular;21" />
195                 </screen>"""
196                 
197         TEST_TYPE_QUICK = 0
198         TEST_TYPE_RANDOM = 1
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)
202                 self.feid = feid
203                 self.test_type = test_type
204                 self.loopsfailed = loopsfailed
205                 self.loopssuccessful = loopssuccessful
206                 self.log = log
207                 
208                 self["actions"] = NumberActionMap(["SetupActions"],
209                 {
210                         "ok": self.select,
211                         "cancel": self.keyCancel,
212                 }, -2)
213                 
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()
218                 
219                 self["failed_counter"] = StaticText("0")
220                 self["succeeded_counter"] = StaticText("0")
221                 self["witherrors_counter"] = StaticText("0")
222                 self["untestable_counter"] = StaticText("0")
223                 
224                 self.list = []
225                 self["progress_list"] = List(self.list)
226                 self["progress_list"].onSelectionChanged.append(self.selectionChanged)
227                 
228                 self["CmdText"] = StaticText(_("Please wait while scanning is in progress..."))
229                                 
230                 self.indexlist = {}
231                 self.readTransponderList()
232                 
233                 self.running = False
234                 
235                 self.results = {}
236                 self.resultsstatus = {}
237                 
238                 self.onLayoutFinish.append(self.go)
239                 
240         def getProgressListComponent(self, index, status):
241                 return (index, self.getTextualIndexRepresentation(index), status)
242         
243         def clearProgressList(self):
244                 self.list = []
245                 self["progress_list"].list = self.list
246         
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")
252                                         return
253                         self.list.append(self.getProgressListComponent(index, _("working")))
254                         self["progress_list"].list = self.list
255                         self["progress_list"].setIndex(len(self.list) - 1)
256
257         def changeProgressListStatus(self, index, status):
258                 self.newlist = []
259                 count = 0
260                 indexpos = 0
261                 for entry in self.list:
262                         if entry[0] == index:
263                                 self.newlist.append(self.getProgressListComponent(index, status))
264                                 indexpos = count
265                         else:
266                                 self.newlist.append(entry)
267                         count += 1
268                 self.list = self.newlist
269                 self["progress_list"].list = self.list
270                 self["progress_list"].setIndex(indexpos)
271
272         def readTransponderList(self):
273                 for sat in nimmanager.getSatListForNim(self.feid):
274                         for transponder in nimmanager.getTransponders(sat[0]):
275                                 #print transponder
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)
278
279         def getIndexForTransponder(self, transponder):
280                 
281                 if transponder[0] < 11700:
282                         band = 1 # low
283                 else:
284                         band = 0 # high
285                 
286                 polarisation = transponder[2]
287                 
288                 sat = transponder[5]
289                 
290                 index = (band, polarisation, sat)
291                 return index
292
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
300         
301         # returns a string for the user representing a human readable output for index 
302         def getTextualIndexRepresentation(self, index):
303                 print "getTextualIndexRepresentation:", index
304                 text = ""
305                 
306                 text += nimmanager.getSatDescription(index[2]) + ", "
307                 
308                 if index[0] == 1:
309                         text += "Low Band, "
310                 else:
311                         text += "High Band, "
312                         
313                 if index[1] == 0:
314                         text += "H"
315                 else:
316                         text += "V"
317                 return text
318         
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
329                         return True
330                 else:
331                         return False
332                 
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])
337
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:
343                         self.myindex = 0
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)
348                         return keys[0]
349                 elif self.test_type == self.TEST_TYPE_RANDOM:
350                         self.randomkeys = self.indexlist.keys()
351                         random.shuffle(self.randomkeys)
352                         self.myindex = 0
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()
358                         print "keys:", keys
359                         successorindex = {}
360                         for index in keys:
361                                 successorindex[index] = []
362                                 for otherindex in keys:
363                                         if otherindex != index:
364                                                 successorindex[index].append(otherindex)
365                                 random.shuffle(successorindex[index])
366                         self.keylist = []
367                         stop = False
368                         currindex = None
369                         while not stop:
370                                 if currindex is None or len(successorindex[currindex]) == 0:
371                                         oldindex = currindex
372                                         for index in successorindex.keys():
373                                                 if len(successorindex[index]) > 0:
374                                                         currindex = index
375                                                         self.keylist.append(currindex)
376                                                         break
377                                         if currindex == oldindex:
378                                                 stop = True
379                                 else:
380                                         currindex = successorindex[currindex].pop()
381                                         self.keylist.append(currindex)
382                         print "self.keylist:", self.keylist
383                         self.myindex = 0
384                         self["overall_progress"].setRange(len(self.keylist))
385                         self["overall_progress"].setValue(self.myindex)
386                         return self.keylist[0]
387
388                                         
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:
393                         self.myindex += 1
394                         keys = self.indexlist.keys()
395                         keys.sort(key = lambda a: a[2]) # sort by orbpos
396                         
397                         self["overall_progress"].setValue(self.myindex)
398                         if self.myindex < len(keys):
399                                 return keys[self.myindex]
400                         else:
401                                 return None
402                 elif self.test_type == self.TEST_TYPE_RANDOM:
403                         self.myindex += 1
404                         keys = self.randomkeys
405                         
406                         self["overall_progress"].setValue(self.myindex)
407                         if self.myindex < len(keys):
408                                 return keys[self.myindex]
409                         else:
410                                 return None
411                 elif self.test_type == self.TEST_TYPE_COMPLETE:
412                         self.myindex += 1
413                         keys = self.keylist
414                         
415                         self["overall_progress"].setValue(self.myindex)
416                         if self.myindex < len(keys):
417                                 return keys[self.myindex]
418                         else:
419                                 return None
420                                 
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))
428                 
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, [])
432
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
465                         
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"]
470                 
471                 self.resultsstatus[status].append(index)
472         
473         def finishedChecking(self):
474                 print "finishedChecking"
475                 TuneTest.finishedChecking(self)
476
477                 if not self.results.has_key(self.currentlyTestedIndex):
478                         self.results[self.currentlyTestedIndex] = {"failed": [], "successful": [], "status": None, "internalstatus": None}
479                 
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)
493                 else:
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)
498                         
499                         
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))
504                         
505                 self.currentlyTestedIndex = self.getNextIndex()
506                 self.addProgressListItem(self.currentlyTestedIndex)
507                 
508                 if self.fillTransponderList():
509                         self.run(checkPIDs = True)
510                 else:
511                         self.running = False
512                         self["progress_list"].setIndex(0)
513                         print "results:", self.results
514                         print "resultsstatus:", self.resultsstatus
515                         if self.log:
516                                 file = open("/media/hdd/diseqctester.log", "w")
517                                 self.setResultType(ResultParser.TYPE_ALL)
518                                 file.write(self.getTextualResult())
519                                 file.close()
520                                 self.session.open(MessageBox, text=_("The results have been written to %s.") % "/media/hdd/diseqctester.log", type = MessageBox.TYPE_INFO)
521
522         def go(self):
523                 self.running = True
524                 self["failed_counter"].setText("0")
525                 self["succeeded_counter"].setText("0")
526                 self["untestable_counter"].setText("0")
527                 self.currentlyTestedIndex = self.getFirstIndex()
528                 
529                 self.clearProgressList()
530                 self.addProgressListItem(self.currentlyTestedIndex)
531                 
532                 if self.fillTransponderList():
533                         self.run(True)
534
535         def keyCancel(self):
536                 self.close()
537                 
538         def select(self):
539                 print "selectedIndex:", self["progress_list"].getCurrent()[0]
540                 if not self.running:
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())
548         
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]))
553
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" />
557         </screen>
558         """
559         def __init__(self, session, feid):
560                 Screen.__init__(self, session)
561                 self.feid = feid
562                 
563                 self.list = []
564                 ConfigListScreen.__init__(self, self.list)
565                 
566                 self["actions"] = ActionMap(["SetupActions"],
567                 {
568                         "cancel": self.keyCancel
569                 }, -2)
570                 
571                 self.createSetup()
572                 
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)
577                 
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)
581                 
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)
585                 
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)
590                                         
591                 self["config"].list = self.list
592                 self["config"].l.setList(self.list)
593                 
594         def keyOK(self):
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)
604         
605         def keyCancel(self):
606                 self.close()
607
608 class DiseqcTesterNimSelection(NimSelection):
609         skin = """
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">
613                                 {"template": [
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,
616                                         ],
617                                  "fonts": [gFont("Regular", 20), gFont("Regular", 15)],
618                                  "itemHeight": 70
619                                 }
620                         </convert>
621                 </widget>
622         </screen>"""
623                 
624         def __init__(self, session, args = None):
625                 NimSelection.__init__(self, session)
626
627         def setResultClass(self):
628                 #self.resultclass = DiseqcTester
629                 self.resultclass = DiseqcTesterTestTypeSelection
630                 
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"):
635                                 return False
636                         if nimConfig.configMode.value == "simple":
637                                 if nimConfig.diseqcMode.value == "positioner":
638                                         return True
639                         return True
640                 return False
641
642 def DiseqcTesterMain(session, **kwargs):
643         session.open(DiseqcTesterNimSelection)
644         
645 def autostart(reason, **kwargs):
646         resourcemanager.addResource("DiseqcTester", DiseqcTesterMain)
647
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)]