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