39a2e7437a20bd679c9756bf6b9b1df6747ae503
[openblackhole/openblackhole-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 from Plugins.Plugin import PluginDescriptor
6 from Components.ActionMap import ActionMap, NumberActionMap
7 from Components.NimManager import nimmanager
8 from Components.ResourceManager import resourcemanager
9 from Components.TuneTest import TuneTest
10 from Components.Label import Label
11 from Components.Sources.List import List
12 from Components.Sources.Progress import Progress
13 from Components.Sources.StaticText import StaticText
14 from Components.ConfigList import ConfigListScreen
15 from Components.config import getConfigListEntry, ConfigSelection, ConfigYesNo
16 import random
17
18 class ResultParser:
19         TYPE_BYORBPOS = 0
20         TYPE_BYINDEX = 1
21         TYPE_ALL = 2
22
23         def __init__(self):
24                 pass
25
26         def setResultType(self, type):
27                 self.type = type
28
29         def setResultParameter(self, parameter):
30                 if self.type == self.TYPE_BYORBPOS:
31                         self.orbpos = parameter
32                 elif self.type == self.TYPE_BYINDEX:
33                         self.index = parameter
34
35         def getTextualResultForIndex(self, index, logfulltransponders = False):
36                 text = ""
37                 text += "%s:\n" % self.getTextualIndexRepresentation(index)
38
39                 failed, successful = self.results[index]["failed"], self.results[index]["successful"]
40                 countfailed = len(failed)
41                 countsuccessful = len(successful)
42                 countall = countfailed + countsuccessful
43                 percentfailed = round(countfailed / float(countall + 0.0001) * 100)
44                 percentsuccessful = round(countsuccessful / float(countall + 0.0001) * 100)
45                 text += "Tested %d transponders\n%d (%d %%) transponders succeeded\n%d (%d %%) transponders failed\n" % (countall, countsuccessful, percentsuccessful, countfailed, percentfailed)
46                 reasons = {}
47                 completelist = []
48                 if countfailed > 0:
49                         for transponder in failed:
50                                 completelist.append({"transponder": transponder[0], "fedata": transponder[-1]})
51                                 reasons[transponder[2]] = reasons.get(transponder[2], [])
52                                 reasons[transponder[2]].append(transponder)
53                                 if transponder[2] == "pids_failed":
54                                         print transponder[2], "-", transponder[3]
55                         text += "The %d unsuccessful tuning attempts failed for the following reasons:\n" % countfailed
56                         for reason in reasons.keys():
57                                 text += "%s: %d transponders failed\n" % (reason, len(reasons[reason]))
58                         for reason in reasons.keys():
59                                 text += "\n"
60                                 text += "%s previous planes:\n" % reason
61                                 for transponder in reasons[reason]:
62                                         if transponder[1] is not None:
63                                                 text += self.getTextualIndexRepresentation(self.getIndexForTransponder(transponder[1]))
64                                         else:
65                                                 text += "No transponder tuned"
66                                         text += " ==> " + self.getTextualIndexRepresentation(self.getIndexForTransponder(transponder[0]))
67                                         text += "\n"
68                                         if logfulltransponders:
69                                                 text += str(transponder[1])
70                                                 text += " ==> "
71                                                 text += str(transponder[0])
72                                                 text += "\n"
73                                         if reason == "pids_failed":
74                                                 text += "(tsid, onid): "
75                                                 text += str(transponder[3]['real'])
76                                                 text += "(read from sat) != "
77                                                 text += str(transponder[3]['expected'])
78                                                 text += "(read from file)"
79                                                 text += "\n"
80                                         text += "\n"
81                 if countsuccessful > 0:
82                         text += "\n"
83                         text += "Successfully tuned transponders' previous planes:\n"
84                         for transponder in successful:
85                                 completelist.append({"transponder": transponder[0], "fedata": transponder[-1]})
86                                 if transponder[1] is not None:
87                                         text += self.getTextualIndexRepresentation(self.getIndexForTransponder(transponder[1]))
88                                 else:
89                                         text += "No transponder tuned"
90                                 text += " ==> " + self.getTextualIndexRepresentation(self.getIndexForTransponder(transponder[0]))
91                                 text += "\n"
92                 text += "------------------------------------------------\n"
93                 text += "complete transponderlist:\n"
94                 for entry in completelist:
95                         text += str(entry["transponder"]) + " -- " + str(entry["fedata"]) + "\n"
96                 return text
97
98         def getTextualResult(self):
99                 text = ""
100                 if self.type == self.TYPE_BYINDEX:
101                         text += self.getTextualResultForIndex(self.index)
102                 elif self.type == self.TYPE_BYORBPOS:
103                         for index in self.results.keys():
104                                 if index[2] == self.orbpos:
105                                         text += self.getTextualResultForIndex(index)
106                                         text += "\n-----------------------------------------------------\n"
107                 elif self.type == self.TYPE_ALL:
108                         orderedResults = {}
109                         for index in self.results.keys():
110                                 orbpos = index[2]
111                                 orderedResults[orbpos] = orderedResults.get(orbpos, [])
112                                 orderedResults[orbpos].append(index)
113                         ordered_orbpos = orderedResults.keys()
114                         ordered_orbpos.sort()
115                         for orbpos in ordered_orbpos:
116                                 text += "\n*****************************************\n"
117                                 text += "Orbital position %s:" % str(orbpos)
118                                 text += "\n*****************************************\n"
119                                 for index in orderedResults[orbpos]:
120                                         text += self.getTextualResultForIndex(index, logfulltransponders = True)
121                                         text += "\n-----------------------------------------------------\n"
122                 return text
123
124 class DiseqcTester(Screen, TuneTest, ResultParser):
125         skin = """
126                 <screen position="center,center" size="520,400" title="DiSEqC Tester" >
127                         <widget source="progress_list" render="Listbox" position="0,0" size="510,150" scrollbarMode="showOnDemand">
128                                 <convert type="TemplatedMultiContent">
129                                         {"template": [
130                                                         MultiContentEntryText(pos = (10, 0), size = (330, 25), flags = RT_HALIGN_LEFT, text = 1), # index 1 is the index name,
131                                                         MultiContentEntryText(pos = (330, 0), size = (150, 25), flags = RT_HALIGN_RIGHT, text = 2) # index 2 is the status,
132                                                 ],
133                                         "fonts": [gFont("Regular", 20)],
134                                         "itemHeight": 25
135                                         }
136                                 </convert>
137                         </widget>
138                         <widget name="Overall_progress" position="20,162" size="480,22" font="Regular;21" halign="center" transparent="1" />
139                         <widget source="overall_progress" render="Progress" position="20,192" size="480,20" borderWidth="2" backgroundColor="#254f7497" />
140                         <widget name="Progress"  position="20,222" size="480,22" font="Regular;21" halign="center" transparent="1" />
141                         <widget source="sub_progress" render="Progress" position="20,252" size="480,20" borderWidth="2" backgroundColor="#254f7497" />
142                         <widget name="Failed" position="20,282" size="140,22" font="Regular;21" halign="left" transparent="1" />
143                         <widget source="failed_counter" render="Label" position="160,282" size="100,20" font="Regular;21" />
144                         <widget name="Succeeded"  position="20,312" size="140,22" font="Regular;21" halign="left" transparent="1" />
145                         <widget source="succeeded_counter" render="Label" position="160,312" size="100,20" font="Regular;21" />
146                         <widget name="With_errors" position="20,342" size="140,22" font="Regular;21" halign="left" transparent="1" />
147                         <widget source="witherrors_counter" render="Label" position="160,342" size="100,20" font="Regular;21" />
148                         <widget name="Not_tested" position="20,372" size="140,22" font="Regular;21" halign="left" transparent="1" />
149                         <widget source="untestable_counter" render="Label" position="160,372" size="100,20" font="Regular;21" />
150                         <widget source="CmdText" render="Label" position="300,282" size="180,200" font="Regular;21" />
151                 </screen>"""
152
153         TEST_TYPE_QUICK = 0
154         TEST_TYPE_RANDOM = 1
155         TEST_TYPE_COMPLETE = 2
156
157         def __init__(self, session, feid, test_type = TEST_TYPE_QUICK, loopsfailed = 3, loopssuccessful = 1, log = False):
158                 Screen.__init__(self, session)
159                 self.setup_title = _("DiSEqC Tester")
160                 self.feid = feid
161                 self.test_type = test_type
162                 self.loopsfailed = loopsfailed
163                 self.loopssuccessful = loopssuccessful
164                 self.oldref = self.session.nav.getCurrentlyPlayingServiceReference()
165                 self.log = log
166                 self["Overall_progress"] = Label(_("Overall progress:"))
167                 self["Progress"] = Label(_("Progress:"))
168                 self["Failed"] = Label(_("Failed:"))
169                 self["Succeeded"] = Label(_("Succeeded:"))
170                 self["Not_tested"] = Label(_("Not tested:"))
171                 self["With_errors"] = Label (_("With errors:"))
172                 self["actions"] = NumberActionMap(["SetupActions"],
173                 {
174                         "ok": self.select,
175                         "cancel": self.keyCancel,
176                 }, -2)
177
178                 TuneTest.__init__(self, feid, stopOnSuccess = self.loopssuccessful, stopOnError = self.loopsfailed)
179                 self["overall_progress"] = Progress()
180                 self["sub_progress"] = Progress()
181                 self["failed_counter"] = StaticText("0")
182                 self["succeeded_counter"] = StaticText("0")
183                 self["witherrors_counter"] = StaticText("0")
184                 self["untestable_counter"] = StaticText("0")
185                 self.list = []
186                 self["progress_list"] = List(self.list)
187                 self["progress_list"].onSelectionChanged.append(self.selectionChanged)
188                 self["CmdText"] = StaticText(_("Please wait while scanning is in progress..."))
189                 self.indexlist = {}
190                 self.readTransponderList()
191                 self.running = False
192                 self.results = {}
193                 self.resultsstatus = {}
194                 self.onLayoutFinish.append(self.go)
195
196         def getProgressListComponent(self, index, status):
197                 return (index, self.getTextualIndexRepresentation(index), status)
198
199         def clearProgressList(self):
200                 self.list = []
201                 self["progress_list"].list = self.list
202
203         def addProgressListItem(self, index):
204                 if index in self.indexlist:
205                         for entry in self.list:
206                                 if entry[0] == index:
207                                         self.changeProgressListStatus(index, _("working"))
208                                         return
209                         self.list.append(self.getProgressListComponent(index, _("working")))
210                         self["progress_list"].list = self.list
211                         self["progress_list"].setIndex(len(self.list) - 1)
212
213         def changeProgressListStatus(self, index, status):
214                 self.newlist = []
215                 count = 0
216                 indexpos = 0
217                 for entry in self.list:
218                         if entry[0] == index:
219                                 self.newlist.append(self.getProgressListComponent(index, status))
220                                 indexpos = count
221                         else:
222                                 self.newlist.append(entry)
223                         count += 1
224                 self.list = self.newlist
225                 self["progress_list"].list = self.list
226                 self["progress_list"].setIndex(indexpos)
227
228         def readTransponderList(self):
229                 for sat in nimmanager.getSatListForNim(self.feid):
230                         for transponder in nimmanager.getTransponders(sat[0]):
231                                 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])
232                                 self.analyseTransponder(mytransponder)
233
234         def getIndexForTransponder(self, transponder):
235                 if transponder[0] < 11700:
236                         band = 1 # low
237                 else:
238                         band = 0 # high
239                 polarisation = transponder[2]
240                 sat = transponder[5]
241                 index = (band, polarisation, sat)
242                 return index
243
244         # sort the transponder into self.transponderlist
245         def analyseTransponder(self, transponder):
246                 index = self.getIndexForTransponder(transponder)
247                 if index not in self.indexlist:
248                         self.indexlist[index] = []
249                 self.indexlist[index].append(transponder)
250
251         # returns a string for the user representing a human readable output for index
252         def getTextualIndexRepresentation(self, index):
253                 print "getTextualIndexRepresentation:", index
254                 text = ""
255
256                 text += nimmanager.getSatDescription(index[2]) + ", "
257
258                 if index[0] == 1:
259                         text += "Low Band, "
260                 else:
261                         text += "High Band, "
262
263                 if index[1] == 0:
264                         text += "H"
265                 else:
266                         text += "V"
267                 return text
268
269         def fillTransponderList(self):
270                 self.clearTransponder()
271                 print "----------- fillTransponderList"
272                 print "index:", self.currentlyTestedIndex
273                 keys = self.indexlist.keys()
274                 if self.getContinueScanning():
275                         print "index:", self.getTextualIndexRepresentation(self.currentlyTestedIndex)
276                         for transponder in self.indexlist[self.currentlyTestedIndex]:
277                                 self.addTransponder(transponder)
278                         print "transponderList:", self.transponderlist
279                         return True
280                 else:
281                         return False
282
283         def progressCallback(self, progress):
284                 if progress[0] != self["sub_progress"].getRange():
285                         self["sub_progress"].setRange(progress[0])
286                 self["sub_progress"].setValue(progress[1])
287
288         # logic for scanning order of transponders
289         # on go getFirstIndex is called
290         def getFirstIndex(self):
291                 # TODO use other function to scan more randomly
292                 if self.test_type == self.TEST_TYPE_QUICK:
293                         self.myindex = 0
294                         keys = self.indexlist.keys()
295                         keys.sort(key = lambda a: a[2]) # sort by orbpos
296                         self["overall_progress"].setRange(len(keys))
297                         self["overall_progress"].setValue(self.myindex)
298                         return keys[0]
299                 elif self.test_type == self.TEST_TYPE_RANDOM:
300                         self.randomkeys = self.indexlist.keys()
301                         random.shuffle(self.randomkeys)
302                         self.myindex = 0
303                         self["overall_progress"].setRange(len(self.randomkeys))
304                         self["overall_progress"].setValue(self.myindex)
305                         return self.randomkeys[0]
306                 elif self.test_type == self.TEST_TYPE_COMPLETE:
307                         keys = self.indexlist.keys()
308                         print "keys:", keys
309                         successorindex = {}
310                         for index in keys:
311                                 successorindex[index] = []
312                                 for otherindex in keys:
313                                         if otherindex != index:
314                                                 successorindex[index].append(otherindex)
315                                 random.shuffle(successorindex[index])
316                         self.keylist = []
317                         stop = False
318                         currindex = None
319                         while not stop:
320                                 if currindex is None or len(successorindex[currindex]) == 0:
321                                         oldindex = currindex
322                                         for index in successorindex.keys():
323                                                 if len(successorindex[index]) > 0:
324                                                         currindex = index
325                                                         self.keylist.append(currindex)
326                                                         break
327                                         if currindex == oldindex:
328                                                 stop = True
329                                 else:
330                                         currindex = successorindex[currindex].pop()
331                                         self.keylist.append(currindex)
332                         print "self.keylist:", self.keylist
333                         self.myindex = 0
334                         self["overall_progress"].setRange(len(self.keylist))
335                         self["overall_progress"].setValue(self.myindex)
336                         return self.keylist[0]
337
338         # after each index is finished, getNextIndex is called to get the next index to scan
339         def getNextIndex(self):
340                 # TODO use other function to scan more randomly
341                 if self.test_type == self.TEST_TYPE_QUICK:
342                         self.myindex += 1
343                         keys = self.indexlist.keys()
344                         keys.sort(key = lambda a: a[2]) # sort by orbpos
345
346                         self["overall_progress"].setValue(self.myindex)
347                         if self.myindex < len(keys):
348                                 return keys[self.myindex]
349                         else:
350                                 return None
351                 elif self.test_type == self.TEST_TYPE_RANDOM:
352                         self.myindex += 1
353                         keys = self.randomkeys
354
355                         self["overall_progress"].setValue(self.myindex)
356                         if self.myindex < len(keys):
357                                 return keys[self.myindex]
358                         else:
359                                 return None
360                 elif self.test_type == self.TEST_TYPE_COMPLETE:
361                         self.myindex += 1
362                         keys = self.keylist
363
364                         self["overall_progress"].setValue(self.myindex)
365                         if self.myindex < len(keys):
366                                 return keys[self.myindex]
367                         else:
368                                 return None
369
370         # after each index is finished and the next index is returned by getNextIndex
371         # the algorithm checks, if we should continue scanning
372         def getContinueScanning(self):
373                 if self.test_type == self.TEST_TYPE_QUICK or self.test_type == self.TEST_TYPE_RANDOM:
374                         return (self.myindex < len(self.indexlist.keys()))
375                 elif self.test_type == self.TEST_TYPE_COMPLETE:
376                         return (self.myindex < len(self.keylist))
377
378         def addResult(self, index, status, failedTune, successfullyTune):
379                 self.results[index] = self.results.get(index, {"failed": [], "successful": [], "status": None, "internalstatus": None})
380                 self.resultsstatus[status] = self.resultsstatus.get(status, [])
381
382                 oldstatus = self.results[index]["internalstatus"]
383                 if oldstatus is None:
384                         self.results[index]["status"] = status
385                 elif oldstatus == _("successful"):
386                         if status == _("failed"):
387                                 self.results[index]["status"] = _("with_errors")
388                         elif status == _("successful"):
389                                 self.results[index]["status"] = oldstatus
390                         elif status == _("with_errors"):
391                                 self.results[index]["status"] = _("with_errors")
392                         elif status == _("not_tested"):
393                                 self.results[index]["status"] = oldstatus
394                 elif oldstatus == _("failed"):
395                         if status == _("failed"):
396                                 self.results[index]["status"] = oldstatus
397                         elif status == _("successful"):
398                                 self.results[index]["status"] = ("with_errors")
399                         elif status == _("with_errors"):
400                                 self.results[index]["status"] = _("with_errors")
401                         elif status == _("not_tested"):
402                                 self.results[index]["status"] = oldstatus
403                 elif oldstatus == _("with_errors"):
404                         if status == _("failed"):
405                                 self.results[index]["status"] = oldstatus
406                         elif status == _("successful"):
407                                 self.results[index]["status"] = oldstatus
408                         elif status == _("with_errors"):
409                                 self.results[index]["status"] = oldstatus
410                         elif status == _("not_tested"):
411                                 self.results[index]["status"] = oldstatus
412                 elif oldstatus == _("not_tested"):
413                         self.results[index]["status"] = status
414
415                 if self.results[index]["status"] != _("working"):
416                         self.results[index]["internalstatus"] = self.results[index]["status"] 
417                 self.results[index]["failed"] = failedTune + self.results[index]["failed"]
418                 self.results[index]["successful"] = successfullyTune + self.results[index]["successful"]
419
420                 self.resultsstatus[status].append(index)
421
422         def finishedChecking(self):
423                 print "finishedChecking"
424                 TuneTest.finishedChecking(self)
425
426                 if not self.results.has_key(self.currentlyTestedIndex):
427                         self.results[self.currentlyTestedIndex] = {"failed": [], "successful": [], "status": None, "internalstatus": None}
428
429                 if len(self.failedTune) > 0 and len(self.successfullyTune) > 0:
430                         self.changeProgressListStatus(self.currentlyTestedIndex, _("with errors"))
431                         self["witherrors_counter"].setText(str(int(self["witherrors_counter"].getText()) + 1))
432                         self.addResult(self.currentlyTestedIndex, _("with_errors"), self.failedTune, self.successfullyTune)
433                 elif len(self.failedTune) == 0 and len(self.successfullyTune) == 0:
434                         self.changeProgressListStatus(self.currentlyTestedIndex, _("not tested"))
435                         self["untestable_counter"].setText(str(int(self["untestable_counter"].getText()) + 1))
436                         self.addResult(self.currentlyTestedIndex, _("untestable"), self.failedTune, self.successfullyTune)
437                 elif len(self.failedTune) > 0:
438                         self.changeProgressListStatus(self.currentlyTestedIndex, _("failed"))
439                         self["failed_counter"].setText(str(int(self["failed_counter"].getText()) + 1))
440                         self.addResult(self.currentlyTestedIndex, _("failed"), self.failedTune, self.successfullyTune)
441                 else:
442                         self.changeProgressListStatus(self.currentlyTestedIndex, _("successful"))
443                         self["succeeded_counter"].setText(str(int(self["succeeded_counter"].getText()) + 1))
444                         self.addResult(self.currentlyTestedIndex, _("successful"), self.failedTune, self.successfullyTune)
445
446                 self.currentlyTestedIndex = self.getNextIndex()
447                 self.addProgressListItem(self.currentlyTestedIndex)
448
449                 if self.fillTransponderList():
450                         self.run()
451                 else:
452                         self.running = False
453                         self["progress_list"].setIndex(0)
454                         print "results:", self.results
455                         print "resultsstatus:", self.resultsstatus
456                         if self.log:
457                                 try:
458                                         file = open("/tmp/diseqctester.log", "w")
459                                         self.setResultType(ResultParser.TYPE_ALL)
460                                         file.write(self.getTextualResult())
461                                         file.close()
462                                         self.session.open(MessageBox, text = _("The results have been written to %s") % "/tmp/diseqctester.log", type = MessageBox.TYPE_INFO, timeout = 5)
463                                 except:
464                                         pass
465
466         def go(self):
467                 self.setTitle(self.setup_title)
468                 self.running = True
469                 self["failed_counter"].setText("0")
470                 self["succeeded_counter"].setText("0")
471                 self["untestable_counter"].setText("0")
472                 self.currentlyTestedIndex = self.getFirstIndex()
473
474                 self.clearProgressList()
475                 self.addProgressListItem(self.currentlyTestedIndex)
476
477                 if self.fillTransponderList():
478                         self.run()
479
480         def keyCancel(self):
481                 try:
482                         self.timer.stop()
483                         if hasattr(self, 'frontend'):
484                                 self.frontend = None
485                         if hasattr(self, 'raw_channel'):
486                                 del self.raw_channel
487                 except:
488                         pass
489                 self.session.nav.playService(self.oldref)
490                 self.close()
491
492         def select(self):
493                 print "selectedIndex:", self["progress_list"].getCurrent()[0]
494                 if not self.running:
495                         index = self["progress_list"].getCurrent()[0]
496                         self.setResultType(ResultParser.TYPE_BYINDEX)
497                         self.setResultParameter(index)
498                         self.session.open(TextBox, self.getTextualResult())
499
500         def selectionChanged(self):
501                 if len(self.list) > 0 and not self.running:
502                         self["CmdText"].setText(_("Press OK to get further details for %s") % str(self["progress_list"].getCurrent()[1]))
503
504 class DiseqcTesterTestTypeSelection(Screen, ConfigListScreen):
505
506         def __init__(self, session, feid):
507                 Screen.__init__(self, session)
508                 # for the skin: first try MediaPlayerSettings, then Setup, this allows individual skinning
509                 self.skinName = ["DiseqcTesterTestTypeSelection", "Setup" ]
510                 self.setup_title = _("DiSEqC-tester settings")
511                 self.onChangedEntry = [ ]
512                 self.feid = feid
513                 self.list = []
514                 ConfigListScreen.__init__(self, self.list, session = self.session, on_change = self.changedEntry)
515
516                 self["actions"] = ActionMap(["SetupActions", "MenuActions"],
517                         {
518                                 "cancel": self.keyCancel,
519                                 "save": self.keyOK,
520                                 "ok": self.keyOK,
521                                 "menu": self.closeRecursive,
522                         }, -2)
523
524                 self["key_red"] = StaticText(_("Cancel"))
525                 self["key_green"] = StaticText(_("OK"))
526
527                 self.createSetup()
528                 self.onLayoutFinish.append(self.__layoutFinished)
529
530         def __layoutFinished(self):
531                 self.setTitle(self.setup_title)
532
533         def createSetup(self):
534                 self.testtype = ConfigSelection(choices={"quick": _("Quick"), "random": _("Random"), "complete": _("Complete")}, default = "quick")
535                 self.testtypeEntry = getConfigListEntry(_("Test type"), self.testtype)
536                 self.list.append(self.testtypeEntry)
537
538                 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")
539                 self.loopsfailedEntry = getConfigListEntry(_("Stop testing plane after # failed transponders"), self.loopsfailed)
540                 self.list.append(self.loopsfailedEntry)
541
542                 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")
543                 self.loopssuccessfulEntry = getConfigListEntry(_("Stop testing plane after # successful transponders"), self.loopssuccessful)
544                 self.list.append(self.loopssuccessfulEntry)
545
546                 self.log = ConfigYesNo(False)
547                 self.logEntry = getConfigListEntry(_("Log results to /tmp"), self.log)
548                 self.list.append(self.logEntry)
549
550                 self["config"].list = self.list
551                 self["config"].l.setList(self.list)
552
553         def keyOK(self):
554                 print self.testtype.getValue()
555                 testtype = DiseqcTester.TEST_TYPE_QUICK
556                 if self.testtype.getValue() == "quick":
557                         testtype = DiseqcTester.TEST_TYPE_QUICK
558                 elif self.testtype.getValue() == "random":
559                         testtype = DiseqcTester.TEST_TYPE_RANDOM
560                 elif self.testtype.getValue() == "complete":
561                         testtype = DiseqcTester.TEST_TYPE_COMPLETE
562                 self.session.open(DiseqcTester, feid = self.feid, test_type = testtype, loopsfailed = int(self.loopsfailed.value), loopssuccessful = int(self.loopssuccessful.value), log = self.log.value)
563
564         def keyCancel(self):
565                 self.close()
566
567         # for summary:
568         def changedEntry(self):
569                 for x in self.onChangedEntry:
570                         x()
571
572         def getCurrentEntry(self):
573                 return self["config"].getCurrent()[0]
574
575         def getCurrentValue(self):
576                 return str(self["config"].getCurrent()[1].getText())
577
578         def createSummary(self):
579                 from Screens.Setup import SetupSummary
580                 return SetupSummary
581
582 class DiseqcTesterNimSelection(NimSelection):
583         skin = """
584                 <screen position="center,center" size="400,330" title="Choose Tuner">
585                 <widget source="nimlist" render="Listbox" position="0,0" size="380,300" scrollbarMode="showOnDemand">
586                         <convert type="TemplatedMultiContent">
587                                 {"template": [
588                                                 MultiContentEntryText(pos = (10, 5), size = (360, 30), flags = RT_HALIGN_LEFT, text = 1), # index 1 is the nim name,
589                                                 MultiContentEntryText(pos = (50, 30), size = (320, 34), font = 1, flags = RT_HALIGN_LEFT, text = 2), # index 2 is a description of the nim settings,
590                                         ],
591                                  "fonts": [gFont("Regular", 20), gFont("Regular", 15)],
592                                  "itemHeight": 70
593                                 }
594                         </convert>
595                 </widget>
596         </screen>"""
597
598         def __init__(self, session, args = None):
599                 NimSelection.__init__(self, session)
600                 self.setTitle(_("Choose Tuner"))
601
602         def setResultClass(self):
603                 self.resultclass = DiseqcTesterTestTypeSelection
604
605         def showNim(self, nim):
606                 nimConfig = nimmanager.getNimConfig(nim.slot)
607                 if nim.isCompatible("DVB-S"):
608                         if nimConfig.configMode.value in ("loopthrough", "equal", "satposdepends", "nothing"):
609                                 return False
610                         configured_sats = nimmanager.getSatListForNim(nim.slot)
611                         if len(configured_sats) == 0:
612                                 return False
613                         return True
614                 return False
615
616 def DiseqcTesterMain(session, **kwargs):
617         nimList = nimmanager.getNimListOfType("DVB-S")
618         if len(nimList) == 0:
619                 session.open(MessageBox, _("No satellite frontend found!"), MessageBox.TYPE_ERROR)
620         else:
621                 if session.nav.RecordTimer.isRecording():
622                         session.open(MessageBox, _("A recording is currently running. Please stop the recording before trying to start a testing DiSEqC."), MessageBox.TYPE_ERROR)
623                 else:
624                         session.open(DiseqcTesterNimSelection)
625
626 def DiseqcTesterStart(menuid, **kwargs):
627         if menuid == "scan":
628                 return [(_("DiSEqC Tester"), DiseqcTesterMain, "diseqc_tester", None)]
629         else:
630                 return []
631
632 def Plugins(**kwargs):
633         if (nimmanager.hasNimType("DVB-S")):
634                 return PluginDescriptor(name="DiSEqC Tester", description=_("Test DiSEqC settings"), where = PluginDescriptor.WHERE_MENU, fnc=DiseqcTesterStart)
635         else:
636                 return []