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