Merge commit 'origin/master' into tmbinc/FixTimingBugs
[enigma2.git] / lib / python / Components / TuneTest.py
1 from enigma import eDVBFrontendParametersSatellite, eDVBFrontendParameters, eDVBResourceManager, eTimer
2
3 class Tuner:
4         def __init__(self, frontend):
5                 self.frontend = frontend
6
7         # transponder = (frequency, symbolrate, polarisation, fec, inversion, orbpos, system, modulation, rolloff, pilot, tsid, onid)
8         #                    0         1             2         3       4         5       6        7          8       9      10    11
9         def tune(self, transponder):
10                 if self.frontend:
11                         print "tuning to transponder with data", transponder
12                         parm = eDVBFrontendParametersSatellite()
13                         parm.frequency = transponder[0] * 1000
14                         parm.symbol_rate = transponder[1] * 1000
15                         parm.polarisation = transponder[2]
16                         parm.fec = transponder[3]
17                         parm.inversion = transponder[4]
18                         parm.orbital_position = transponder[5]
19                         parm.system = transponder[6]
20                         parm.modulation = transponder[7]
21                         parm.rolloff = transponder[8]
22                         parm.pilot = transponder[9]
23                         feparm = eDVBFrontendParameters()
24                         feparm.setDVBS(parm)
25                         self.lastparm = feparm
26                         self.frontend.tune(feparm)
27
28         def retune(self):
29                 if self.frontend:
30                         self.frontend.tune(self.lastparm)
31
32         def getTransponderData(self):
33                 ret = { }
34                 if self.frontend:
35                         self.frontend.getTransponderData(ret, True)
36                 return ret
37
38 # tunes a list of transponders and checks, if they lock and optionally checks the onid/tsid combination
39 # 1) add transponders with addTransponder()
40 # 2) call run(<checkPIDs = True>)
41 # 3) finishedChecking() is called, when the run is finished
42 class TuneTest:
43         def __init__(self, feid, stopOnSuccess = -1, stopOnError = -1):
44                 self.stopOnSuccess = stopOnSuccess
45                 self.stopOnError = stopOnError
46                 self.feid = feid
47                 self.transponderlist = []
48                 self.currTuned = None
49                 print "TuneTest for feid %d" % self.feid
50                 if not self.openFrontend():
51                         self.oldref = self.session.nav.getCurrentlyPlayingServiceReference()
52                         self.session.nav.stopService() # try to disable foreground service
53                         if not self.openFrontend():
54                                 if self.session.pipshown: # try to disable pip
55                                         self.session.pipshown = False
56                                         del self.session.pip
57                                         if not self.openFrontend():
58                                                 self.frontend = None # in normal case this should not happen
59                 self.tuner = Tuner(self.frontend)
60                 self.timer = eTimer()
61                 self.timer.callback.append(self.updateStatus)
62                 
63         def gotTsidOnid(self, tsid, onid):
64                 print "******** got tsid, onid:", tsid, onid
65                 if tsid is not None and onid is not None:
66                         self.pidStatus = self.INTERNAL_PID_STATUS_SUCCESSFUL
67                         self.tsid = tsid
68                         self.onid = onid
69                 else:
70                         self.pidStatus = self.INTERNAL_PID_STATUS_FAILED
71                         self.tsid = -1
72                         self.onid = -1
73                 self.timer.start(100, True)
74                         
75         def updateStatus(self):
76                 dict = {}
77                 self.frontend.getFrontendStatus(dict)
78                 stop = False
79                 
80                 print "status:", dict
81                 if dict["tuner_state"] == "TUNING":
82                         print "TUNING"
83                         self.timer.start(100, True)
84                         self.progressCallback((self.getProgressLength(), self.tuningtransponder, self.STATUS_TUNING, self.currTuned))
85                 elif self.checkPIDs and self.pidStatus == self.INTERNAL_PID_STATUS_NOOP:
86                         print "2nd choice"
87                         if dict["tuner_state"] == "LOCKED":
88                                 print "acquiring TSID/ONID"
89                                 self.raw_channel.requestTsidOnid(self.gotTsidOnid)
90                                 self.pidStatus = self.INTERNAL_PID_STATUS_WAITING
91                         else:
92                                 self.pidStatus = self.INTERNAL_PID_STATUS_FAILED
93                 elif self.checkPIDs and self.pidStatus == self.INTERNAL_PID_STATUS_WAITING:
94                         print "waiting for pids"                        
95                 else:
96                         if dict["tuner_state"] == "LOSTLOCK" or dict["tuner_state"] == "FAILED":
97                                 self.tuningtransponder = self.nextTransponder()
98                                 self.failedTune.append([self.currTuned, self.oldTuned, "tune_failed"])
99                                 if self.stopOnError != -1 and self.stopOnError <= len(self.failedTune):
100                                         stop = True
101                         elif dict["tuner_state"] == "LOCKED":
102                                 pidsFailed = False
103                                 if self.checkPIDs:
104                                         if self.currTuned is not None:
105                                                 if self.tsid != self.currTuned[10] or self.onid != self.currTuned[11]:
106                                                         self.failedTune.append([self.currTuned, self.oldTuned, "pids_failed", {"real": (self.tsid, self.onid), "expected": (self.currTuned[10], self.currTuned[11])}])
107                                                         pidsFailed = True
108                                                 else:
109                                                         self.successfullyTune.append([self.currTuned, self.oldTuned])
110                                                         if self.stopOnSuccess != -1 and self.stopOnSuccess <= len(self.successfullyTune):
111                                                                 stop = True
112                                 elif not self.checkPIDs or (self.checkPids and not pidsFailed):  
113                                         self.successfullyTune.append([self.currTuned, self.oldTuned])
114                                         if self.stopOnSuccess != -1 and self.stopOnSuccess <= len(self.successfullyTune):
115                                                                 stop = True
116                                 self.tuningtransponder = self.nextTransponder()
117                         else:
118                                 print "************* tuner_state:", dict["tuner_state"]
119                                 
120                         self.progressCallback((self.getProgressLength(), self.tuningtransponder, self.STATUS_NOOP, self.currTuned))
121                         
122                         if not stop:
123                                 self.tune()
124                 if self.tuningtransponder < len(self.transponderlist) and not stop:
125                         if self.pidStatus != self.INTERNAL_PID_STATUS_WAITING:
126                                 self.timer.start(100, True)
127                                 print "restart timer"
128                         else:
129                                 print "not restarting timers (waiting for pids)"
130                 else:
131                         self.progressCallback((self.getProgressLength(), len(self.transponderlist), self.STATUS_DONE, self.currTuned))
132                         print "finishedChecking"
133                         self.finishedChecking()
134                                 
135         def firstTransponder(self):
136                 print "firstTransponder:"
137                 index = 0
138                 if self.checkPIDs:
139                         print "checkPIDs-loop"
140                         # check for tsid != -1 and onid != -1 
141                         print "index:", index
142                         print "len(self.transponderlist):", len(self.transponderlist)
143                         while (index < len(self.transponderlist) and (self.transponderlist[index][10] == -1 or self.transponderlist[index][11] == -1)):
144                                 index += 1
145                 print "FirstTransponder final index:", index
146                 return index
147         
148         def nextTransponder(self):
149                 print "getting next transponder", self.tuningtransponder
150                 index = self.tuningtransponder + 1
151                 if self.checkPIDs:
152                         print "checkPIDs-loop"
153                         # check for tsid != -1 and onid != -1 
154                         print "index:", index
155                         print "len(self.transponderlist):", len(self.transponderlist)
156                         while (index < len(self.transponderlist) and (self.transponderlist[index][10] == -1 or self.transponderlist[index][11] == -1)):
157                                 index += 1
158
159                 print "next transponder index:", index
160                 return index
161         
162         def finishedChecking(self):
163                 print "finished testing"
164                 print "successfull:", self.successfullyTune
165                 print "failed:", self.failedTune
166         
167         def openFrontend(self):
168                 res_mgr = eDVBResourceManager.getInstance()
169                 if res_mgr:
170                         self.raw_channel = res_mgr.allocateRawChannel(self.feid)
171                         if self.raw_channel:
172                                 self.frontend = self.raw_channel.getFrontend()
173                                 if self.frontend:
174                                         return True
175                                 else:
176                                         print "getFrontend failed"
177                         else:
178                                 print "getRawChannel failed"
179                 else:
180                         print "getResourceManager instance failed"
181                 return False
182
183         def tune(self):
184                 print "tuning to", self.tuningtransponder
185                 if self.tuningtransponder < len(self.transponderlist):
186                         self.pidStatus = self.INTERNAL_PID_STATUS_NOOP
187                         self.oldTuned = self.currTuned
188                         self.currTuned = self.transponderlist[self.tuningtransponder]
189                         self.tuner.tune(self.transponderlist[self.tuningtransponder])           
190
191         INTERNAL_PID_STATUS_NOOP = 0
192         INTERNAL_PID_STATUS_WAITING = 1
193         INTERNAL_PID_STATUS_SUCCESSFUL = 2
194         INTERNAL_PID_STATUS_FAILED = 3
195         
196         def run(self, checkPIDs = False):
197                 self.checkPIDs = checkPIDs
198                 self.pidStatus = self.INTERNAL_PID_STATUS_NOOP
199                 self.failedTune = []
200                 self.successfullyTune = []
201                 self.tuningtransponder = self.firstTransponder()
202                 self.tune()
203                 self.progressCallback((self.getProgressLength(), self.tuningtransponder, self.STATUS_START, self.currTuned))
204                 self.timer.start(100, True)
205         
206         # transponder = (frequency, symbolrate, polarisation, fec, inversion, orbpos, <system>, <modulation>, <rolloff>, <pilot>, <tsid>, <onid>)
207         #                    0         1             2         3       4         5       6        7              8         9        10       11
208         def addTransponder(self, transponder):
209                 self.transponderlist.append(transponder)
210                 
211         def clearTransponder(self):
212                 self.transponderlist = []
213                 
214         def getProgressLength(self):
215                 count = 0
216                 if self.stopOnError == -1:
217                         count = len(self.transponderlist)
218                 else:
219                         if count < self.stopOnError:
220                                 count = self.stopOnError
221                 if self.stopOnSuccess == -1:
222                         count = len(self.transponderlist)
223                 else:
224                         if count < self.stopOnSuccess:
225                                 count = self.stopOnSuccess
226                 return count
227                 
228         STATUS_START = 0
229         STATUS_TUNING = 1
230         STATUS_DONE = 2
231         STATUS_NOOP = 3
232         # can be overwritten
233         # progress = (range, value, status, transponder)
234         def progressCallback(self, progress):
235                 pass