provider-selection is now possible for cable and terrestrial
[enigma2.git] / lib / python / Components / NimManager.py
1 from config import config       #global config instance
2
3 from config import configElement
4 from config import ConfigSubsection
5 from config import ConfigSlider
6 from config import configSelection
7 from config import configSequence
8 from config import configsequencearg
9 from config import configSatlist
10
11 from enigma import *
12
13 import xml.dom.minidom
14 from xml.dom import EMPTY_NAMESPACE
15 from skin import elementsWithTag
16 from Tools import XMLTools
17
18 from xml.sax import make_parser
19 from xml.sax.handler import ContentHandler
20
21 def tryOpen(filename):
22         try:
23                 procFile = open(filename)
24         except IOError:
25                 return ""
26         return procFile
27
28 class SecConfigure:
29         def addLNBSimple(self, slotid, orbpos, toneburstmode, diseqcmode, diseqcpos):
30                 #simple defaults
31                 sec = eDVBSatelliteEquipmentControl.getInstance()
32                 sec.addLNB()
33                 sec.setLNBTunerMask(1 << slotid)
34                 sec.setLNBLOFL(9750000)
35                 sec.setLNBLOFH(10600000)
36                 sec.setLNBThreshold(11750000)
37                 sec.setRepeats(0)
38                 sec.setFastDiSEqC(0)
39                 sec.setSeqRepeat(0)
40                 sec.setVoltageMode(0) #HV
41                 sec.setToneMode(0)              #HILO
42                 sec.setCommandOrder(0)
43                 #user values
44                 sec.setDiSEqCMode(diseqcmode)
45                 sec.setToneburst(toneburstmode)
46                 sec.setCommittedCommand(diseqcpos)
47                 #print "set orbpos to:" + str(orbpos)
48                 sec.addSatellite(orbpos)
49                 self.satList.append(orbpos)
50
51         def getSatList(self):
52                 return self.satList
53
54         def update(self):
55                 eDVBSatelliteEquipmentControl.getInstance().clear()
56                 self.satList = []
57
58                 for slot in self.NimManager.nimslots:
59                         x = slot.slotid
60                         nim = config.Nims[x]
61                         if slot.nimType == self.NimManager.nimType["DVB-S"]:
62                                 print "slot: " + str(x) + " configmode: " + str(nim.configMode.value)
63                                 if nim.configMode.value == 0:           #simple config
64                                         if nim.diseqcMode.value == 0:                   #single
65                                                 self.addLNBSimple(x, int(nim.diseqcA.vals[nim.diseqcA.value][1]), 0, 0, 4)
66                                         elif nim.diseqcMode.value == 1:         #Toneburst A/B
67                                                 self.addLNBSimple(x, int(nim.diseqcA.vals[nim.diseqcA.value][1]), 1, 0, 4)
68                                                 self.addLNBSimple(x, int(nim.diseqcB.vals[nim.diseqcB.value][1]), 1, 0, 4)
69                                         elif nim.diseqcMode.value == 2:         #DiSEqC A/B
70                                                 self.addLNBSimple(x, int(nim.diseqcA.vals[nim.diseqcA.value][1]), 0, 1, 0)
71                                                 self.addLNBSimple(x, int(nim.diseqcB.vals[nim.diseqcB.value][1]), 0, 1, 1)
72                                         elif nim.diseqcMode.value == 3:         #DiSEqC A/B/C/D
73                                                 self.addLNBSimple(x, int(nim.diseqcA.vals[nim.diseqcA.value][1]), 0, 1, 0)
74                                                 self.addLNBSimple(x, int(nim.diseqcB.vals[nim.diseqcB.value][1]), 0, 1, 1)
75                                                 self.addLNBSimple(x, int(nim.diseqcC.vals[nim.diseqcC.value][1]), 0, 1, 2)
76                                                 self.addLNBSimple(x, int(nim.diseqcD.vals[nim.diseqcD.value][1]), 0, 1, 3)
77                                         elif nim.diseqcMode.value == 4:         #Positioner
78                                                 print "FIXME: positioner suppport"
79                                         pass
80                                 else:                                                                                                                                   #advanced config
81                                         print "FIXME add support for advanced config"
82                 
83         def __init__(self, nimmgr):
84                 self.NimManager = nimmgr
85                 self.update()
86                 
87 class boundFunction:
88         def __init__(self, fnc, *args):
89                 self.fnc = fnc
90                 self.args = args
91         def __call__(self, *args):
92                 self.fnc(*self.args + args)
93
94 class nimSlot:
95         def __init__(self, slotid, nimtype, name):
96                 self.slotid = slotid
97                 self.nimType = nimtype
98                 self.name = name
99
100 class NimManager:
101         class parseSats(ContentHandler):
102                 def __init__(self, satList, satellites, transponders):
103                         self.isPointsElement, self.isReboundsElement = 0, 0
104                         self.satList = satList
105                         self.satellites = satellites
106                         self.transponders = transponders
107         
108                 def startElement(self, name, attrs):
109                         if (name == "sat"):
110                                 #print "found sat " + attrs.get('name',"") + " " + str(attrs.get('position',""))
111                                 tpos = attrs.get('position',"")
112                                 tname = attrs.get('name',"")
113                                 self.satellites[tpos] = tname
114                                 self.satList.append( (tname, tpos) )
115                                 self.parsedSat = int(tpos)
116                         elif (name == "transponder"):
117                                 freq = int(attrs.get('frequency',""))
118                                 sr = int(attrs.get('symbol_rate',""))
119                                 pol = int(attrs.get('polarization',""))
120                                 fec = int(attrs.get('fec_inner',""))
121                                 if self.parsedSat in self.transponders:
122                                         pass
123                                 else:
124                                         self.transponders[self.parsedSat] = [ ]
125
126                                 self.transponders[self.parsedSat].append((0, freq, sr, pol, fec))
127
128         class parseCables(ContentHandler):
129                 def __init__(self, cablesList, transponders):
130                         self.isPointsElement, self.isReboundsElement = 0, 0
131                         self.cablesList = cablesList
132                         self.transponders = transponders
133         
134                 def startElement(self, name, attrs):
135                         if (name == "cable"):
136                                 #print "found sat " + attrs.get('name',"") + " " + str(attrs.get('position',""))
137                                 tname = attrs.get('name',"")
138                                 self.cablesList.append(str(tname))
139                                 self.parsedCab = str(tname)
140                         elif (name == "transponder"):
141                                 freq = int(attrs.get('frequency',""))
142                                 sr = int(attrs.get('symbol_rate',""))
143                                 mod = int(attrs.get('modulation',""))
144                                 fec = int(attrs.get('fec_inner',""))
145                                 if self.parsedCab in self.transponders:
146                                         pass
147                                 else:
148                                         self.transponders[self.parsedCab] = [ ]
149
150                                 self.transponders[self.parsedCab].append((0, freq, sr, mod, fec))
151
152         class parseTerrestrials(ContentHandler):
153                 def __init__(self, terrestrialsList, transponders):
154                         self.isPointsElement, self.isReboundsElement = 0, 0
155                         self.terrestrialsList = terrestrialsList
156                         self.transponders = transponders
157         
158                 def startElement(self, name, attrs):
159                         if (name == "terrestrial"):
160                                 #print "found sat " + attrs.get('name',"") + " " + str(attrs.get('position',""))
161                                 tname = attrs.get('name',"")
162                                 tflags = attrs.get('flags',"")
163                                 self.terrestrialsList.append((tname, tflags))
164                                 self.parsedTer = str(tname)
165                         elif (name == "transponder"):
166                                 # TODO finish this!
167                                 freq = int(attrs.get('centre_frequency',""))
168                                 bw = int(attrs.get('bandwidth',""))
169                                 const = int(attrs.get('constellation',""))
170                                 crh = int(attrs.get('code_rate_hp',""))
171                                 crl = int(attrs.get('code_rate_lp',""))
172                                 guard = int(attrs.get('guard_interval',""))
173                                 transm = int(attrs.get('transmission_mode',""))
174                                 hierarchy = int(attrs.get('hierarchy_information',""))
175                                 inv = int(attrs.get('inversion',""))
176                                 if self.parsedTer in self.transponders:
177                                         pass
178                                 else:
179                                         self.transponders[self.parsedTer] = [ ]
180
181                                 self.transponders[self.parsedTer].append((0, freq, bw, const, crh, crl, guard, transm, hierarchy, inv))
182
183         def getTransponders(self, pos):
184                 return self.transponders[pos]
185
186         def getConfiguredSats(self):
187                 return self.sec.getSatList()
188
189         def getSatDescription(self, pos):
190                 return self.satellites[str(pos)]
191
192         def readSatsfromFile(self):
193                 self.satellites = { }
194                 self.transponders = { }
195                 self.transponderscable = { }
196                 self.transpondersterrestrial = { }              
197
198                 if (self.hasNimType(self.nimType["DVB-S"])):
199                         print "Reading satellites.xml"
200                         parser = make_parser()
201                         satHandler = self.parseSats(self.satList, self.satellites, self.transponders)
202                         parser.setContentHandler(satHandler)
203                         parser.parse('/etc/tuxbox/satellites.xml')
204                 if (self.hasNimType(self.nimType["DVB-C"])):
205                         print "Reading cables.xml"
206                         cabHandler = self.parseCables(self.cablesList, self.transponderscable)
207                         parser.setContentHandler(cabHandler)
208                         parser.parse('/etc/tuxbox/cables.xml')
209
210                 if (self.hasNimType(self.nimType["DVB-T"])):
211                         print "Reading terrestrial.xml"
212                         terHandler = self.parseTerrestrials(self.terrestrialsList, self.transpondersterrestrial)
213                         parser.setContentHandler(terHandler)
214                         parser.parse('/etc/tuxbox/terrestrial.xml')
215                 
216         def parseProc(self):
217                 self.nimTypes = {}
218                 self.nimNames = {}              
219                 self.nimSocketCount = 0
220                 nimfile = tryOpen("/proc/bus/nim_sockets")
221
222                 if nimfile == "":
223                                 return self.nimType["empty/unknown"]
224                         
225                 lastsocket = -1
226
227                 while 1:                
228                         line = nimfile.readline()
229                         if line == "":
230                                 break
231                         if line.strip().startswith("NIM Socket"):
232                                 parts = line.strip().split(" ")
233                                 id = int(parts[2][:1])
234                                 lastsocket = int(id)
235                                 self.nimSocketCount += 1
236                         elif line.strip().startswith("Type:"):
237                                 self.nimTypes[lastsocket] = str(line.strip()[6:])
238                         elif line.strip().startswith("Name:"):
239                                 self.nimNames[lastsocket] = str(line.strip()[6:])
240                         elif line.strip().startswith("empty"):
241                                 self.nimNames[lastsocket] = _("N/A")
242                                 self.nimTypes[lastsocket] = "empty/unknown"
243
244                 nimfile.close()
245                 
246
247         def getNimType(self, slotID):
248                 return self.nimType[self.nimTypes[slotID]]
249
250         def getNimName(self, slotID):
251                 return self.nimNames[slotID]
252
253         def getNimSocketCount(self):
254                 return self.nimSocketCount
255         
256         def hasNimType(self, chktype):
257                 for id, type in self.nimTypes.items():
258                         if (chktype == self.nimType[str(type)]):
259                                 return True
260                 return False
261
262         def getConfigPrefix(self, slotid):
263                 return "config.Nim" + ("A","B","C","D")[slotid] + "."
264                         
265         def __init__(self):
266                 #use as enum
267                 self.nimType = {                "empty/unknown": -1,
268                                                                                                 "DVB-S": 0,
269                                                                                                 "DVB-C": 1,
270                                                                                                 "DVB-T": 2}
271                 self.satList = [ ]
272                 self.cablesList = []
273                 self.terrestrialsList = []
274                                                                                                 
275                 self.parseProc()
276
277                 self.readSatsfromFile()                                                 
278                 
279                 self.nimCount = self.getNimSocketCount()
280                 
281                 self.nimslots = [ ]
282                 x = 0
283                 while x < self.nimCount:
284                         tType = self.getNimType(x)
285                         tName = self.getNimName(x)
286                         tNim = nimSlot(x, tType, tName)
287                         self.nimslots.append(tNim)
288                         x += 1
289                 
290                 InitNimManager(self)    #init config stuff
291
292         def nimList(self):
293                 list = [ ]
294                 for slot in self.nimslots:
295                         nimText = _("Socket ") + ("A", "B", "C", "D")[slot.slotid] + ": "
296                         if slot.nimType == -1:
297                                 nimText += _("empty/unknown")
298                         else:
299                                 nimText += slot.name + " ("     
300                                 nimText += ("DVB-S", "DVB-C", "DVB-T")[slot.nimType] + ")"
301                         list.append((nimText, slot))
302                 return list
303         
304         def getSatListForNim(self, slotid):
305                 list = []
306                 if (self.getNimType(slotid) != self.nimType["empty/unknown"]):
307                         #print "slotid:", slotid
308                         
309                         #print "self.satellites:", self.satList[config.Nims[slotid].diseqcA.value]
310                         #print "diseqcA:", config.Nims[slotid].diseqcA.value
311                         if (config.Nims[slotid].diseqcMode.value <= 3):
312                                 list.append(self.satList[config.Nims[slotid].diseqcA.value])
313                         if (0 < config.Nims[slotid].diseqcMode.value <= 3):
314                                 list.append(self.satList[config.Nims[slotid].diseqcB.value])
315                         if (config.Nims[slotid].diseqcMode.value == 3):
316                                 list.append(self.satList[config.Nims[slotid].diseqcC.value])
317                                 list.append(self.satList[config.Nims[slotid].diseqcD.value])
318                 return list
319
320         #callbacks for c++ config
321         def nimConfigModeChanged(self, slotid, mode):
322                 #print "nimConfigModeChanged set to " + str(mode)
323                 pass
324         def nimDiseqcModeChanged(self, slotid, mode):
325                 #print "nimDiseqcModeChanged set to " + str(mode)
326                 pass
327         def nimPortAChanged(self, slotid, val):
328                 #print "nimDiseqcA set to " + str(slotid) + " val:" + str(val)
329                 pass
330         def nimPortBChanged(self, slotid, val):
331                 #print "nimDiseqcA set to " + str(slotid) + " val:" + str(val)
332                 #print "nimDiseqcB set to " + str(val)
333                 pass
334         def nimPortCChanged(self, slotid, val):
335                 #print "nimDiseqcC set to " + str(val)
336                 pass
337         def nimPortDChanged(self, slotid, val):
338                 #print "nimDiseqcD set to " + str(val)
339                 pass
340
341
342 def InitNimManager(nimmgr):
343         config.Nims = []
344         for x in range(nimmgr.nimCount):
345                 config.Nims.append(ConfigSubsection())
346                 
347         def nimConfigModeChanged(slotid, configElement):
348                 nimmgr.nimConfigModeChanged(slotid, configElement.value)
349         def nimDiseqcModeChanged(slotid, configElement):
350                 nimmgr.nimDiseqcModeChanged(slotid, configElement.value)
351                 
352         def nimPortAChanged(slotid, configElement):
353                 nimmgr.nimPortAChanged(slotid, configElement.vals[configElement.value][1])
354         def nimPortBChanged(slotid, configElement):
355                 nimmgr.nimPortBChanged(slotid, configElement.vals[configElement.value][1])
356         def nimPortCChanged(slotid, configElement):
357                 nimmgr.nimPortCChanged(slotid, configElement.vals[configElement.value][1])
358         def nimPortDChanged(slotid, configElement):
359                 nimmgr.nimPortDChanged(slotid, configElement.vals[configElement.value][1])
360
361         for slot in nimmgr.nimslots:
362                 x = slot.slotid
363                 cname = nimmgr.getConfigPrefix(x)
364                 nim = config.Nims[x]
365                 
366                 if slot.nimType == nimmgr.nimType["DVB-S"]:
367                         nim.configMode = configElement(cname + "configMode", configSelection, 0, (_("Simple"), _("Advanced")));
368                         nim.diseqcMode = configElement(cname + "diseqcMode", configSelection, 2, (_("Single"), _("Toneburst A/B"), _("DiSEqC A/B"), _("DiSEqC A/B/C/D"), _("Positioner")));
369                         nim.diseqcA = configElement(cname + "diseqcA", configSatlist, 192, nimmgr.satList);
370                         nim.diseqcB = configElement(cname + "diseqcB", configSatlist, 130, nimmgr.satList);
371                         nim.diseqcC = configElement(cname + "diseqcC", configSatlist, 0, nimmgr.satList);
372                         nim.diseqcD = configElement(cname + "diseqcD", configSatlist, 0, nimmgr.satList);
373                         nim.longitude = configElement(cname + "longitude", configSequence, [0,0], configsequencearg.get("FLOAT", [(0,90),(0,999)]));
374                         nim.latitude = configElement(cname + "latitude", configSequence, [0,0], configsequencearg.get("FLOAT", [(0,90),(0,999)]));
375                         
376                         #perhaps the instance of the slot is more useful?
377                         nim.configMode.addNotifier(boundFunction(nimConfigModeChanged,x))
378                         nim.diseqcMode.addNotifier(boundFunction(nimDiseqcModeChanged,x))
379                         nim.diseqcA.addNotifier(boundFunction(nimPortAChanged,int(x)))
380                         nim.diseqcB.addNotifier(boundFunction(nimPortBChanged,x))
381                         nim.diseqcC.addNotifier(boundFunction(nimPortCChanged,x))
382                         nim.diseqcD.addNotifier(boundFunction(nimPortDChanged,x))
383                 elif slot.nimType == nimmgr.nimType["DVB-C"]:
384                         nim.cable = configElement(cname + "cable", configSelection, 0, nimmgr.cablesList);
385                 elif slot.nimType == nimmgr.nimType["DVB-T"]:
386                         nim.cable = configElement(cname + "terrestrial", configSelection, 0, nimmgr.terrestrialsList);
387                 else:
388                         print "pls add support for this frontend type!"         
389
390         nimmgr.sec = SecConfigure(nimmgr)
391
392 nimmanager = NimManager()