Merge branch 'experimental' of git.opendreambox.org:/git/enigma2 into experimental
[enigma2.git] / lib / python / Components / NimManager.py
1 from Tools.HardwareInfo import HardwareInfo
2 from Tools.BoundFunction import boundFunction
3
4 from config import config, ConfigSubsection, ConfigSelection, ConfigFloat, \
5         ConfigSatlist, ConfigYesNo, ConfigInteger, ConfigSubList, ConfigNothing, \
6         ConfigSubDict, ConfigOnOff, ConfigDateTime
7
8 from enigma import eDVBSatelliteEquipmentControl as secClass, \
9         eDVBSatelliteLNBParameters as lnbParam, \
10         eDVBSatelliteDiseqcParameters as diseqcParam, \
11         eDVBSatelliteSwitchParameters as switchParam, \
12         eDVBSatelliteRotorParameters as rotorParam, \
13         eDVBResourceManager, eDVBDB
14
15 from time import localtime, mktime
16 from datetime import datetime
17 from Tools.BoundFunction import boundFunction
18
19 from Tools import Directories
20 import xml.etree.cElementTree
21
22 def getConfigSatlist(orbpos, satlist):
23         default_orbpos = None
24         for x in satlist:
25                 if x[0] == orbpos:
26                         default_orbpos = orbpos
27                         break
28         return ConfigSatlist(satlist, default_orbpos)
29
30 def tryOpen(filename):
31         try:
32                 procFile = open(filename)
33         except IOError:
34                 return None
35         return procFile
36
37 class SecConfigure:
38         def getConfiguredSats(self):
39                 return self.configuredSatellites
40
41         def addSatellite(self, sec, orbpos):
42                 sec.addSatellite(orbpos)
43                 self.configuredSatellites.add(orbpos)
44
45         def addLNBSimple(self, sec, slotid, diseqcmode, toneburstmode = diseqcParam.NO, diseqcpos = diseqcParam.SENDNO, orbpos = 0, longitude = 0, latitude = 0, loDirection = 0, laDirection = 0, turningSpeed = rotorParam.FAST, useInputPower=True, inputPowerDelta=50, fastDiSEqC = False, setVoltageTone = True, diseqc13V = False):
46                 if orbpos is None or orbpos == 3601:
47                         return
48                 #simple defaults
49                 sec.addLNB()
50                 tunermask = 1 << slotid
51                 if self.equal.has_key(slotid):
52                         for slot in self.equal[slotid]:
53                                 tunermask |= (1 << slot)
54                 if self.linked.has_key(slotid):
55                         for slot in self.linked[slotid]:
56                                 tunermask |= (1 << slot)
57                 sec.setLNBSatCR(-1)
58                 sec.setLNBNum(1)
59                 sec.setLNBLOFL(9750000)
60                 sec.setLNBLOFH(10600000)
61                 sec.setLNBThreshold(11700000)
62                 sec.setLNBIncreasedVoltage(lnbParam.OFF)
63                 sec.setRepeats(0)
64                 sec.setFastDiSEqC(fastDiSEqC)
65                 sec.setSeqRepeat(0)
66                 sec.setCommandOrder(0)
67
68                 #user values
69                 sec.setDiSEqCMode(diseqcmode)
70                 sec.setToneburst(toneburstmode)
71                 sec.setCommittedCommand(diseqcpos)
72                 sec.setUncommittedCommand(0) # SENDNO
73                 #print "set orbpos to:" + str(orbpos)
74
75                 if 0 <= diseqcmode < 3:
76                         self.addSatellite(sec, orbpos)
77                         if setVoltageTone:
78                                 if diseqc13V:
79                                         sec.setVoltageMode(switchParam.HV_13)
80                                 else:
81                                         sec.setVoltageMode(switchParam.HV)
82                                 sec.setToneMode(switchParam.HILO)
83                         else:
84                                 sec.setVoltageMode(switchParam._14V)
85                                 sec.setToneMode(switchParam.OFF)
86                 elif (diseqcmode == 3): # diseqc 1.2
87                         if self.satposdepends.has_key(slotid):
88                                 for slot in self.satposdepends[slotid]:
89                                         tunermask |= (1 << slot)
90                         sec.setLatitude(latitude)
91                         sec.setLaDirection(laDirection)
92                         sec.setLongitude(longitude)
93                         sec.setLoDirection(loDirection)
94                         sec.setUseInputpower(useInputPower)
95                         sec.setInputpowerDelta(inputPowerDelta)
96                         sec.setRotorTurningSpeed(turningSpeed)
97
98                         for x in self.NimManager.satList:
99                                 print "Add sat " + str(x[0])
100                                 self.addSatellite(sec, int(x[0]))
101                                 if diseqc13V:
102                                         sec.setVoltageMode(switchParam.HV_13)
103                                 else:
104                                         sec.setVoltageMode(switchParam.HV)
105                                 sec.setToneMode(switchParam.HILO)
106                                 sec.setRotorPosNum(0) # USALS
107                 
108                 sec.setLNBSlotMask(tunermask)
109
110         def setSatposDepends(self, sec, nim1, nim2):
111                 print "tuner", nim1, "depends on satpos of", nim2
112                 sec.setTunerDepends(nim1, nim2)
113
114         def linkNIMs(self, sec, nim1, nim2):
115                 print "link tuner", nim1, "to tuner", nim2
116                 sec.setTunerLinked(nim1, nim2)
117                 
118         def getRoot(self, slotid, connto):
119                 visited = []
120                 while (self.NimManager.getNimConfig(connto).configMode.value in ("satposdepends", "equal", "loopthrough")):
121                         connto = int(self.NimManager.getNimConfig(connto).connectedTo.value)
122                         if connto in visited: # prevent endless loop
123                                 return slotid
124                         visited.append(connto)
125                 return connto
126
127         def update(self):
128                 sec = secClass.getInstance()
129                 self.configuredSatellites = set()
130                 sec.clear() ## this do unlinking NIMs too !!
131                 print "sec config cleared"
132
133                 self.linked = { }
134                 self.satposdepends = { }
135                 self.equal = { }
136
137                 nim_slots = self.NimManager.nim_slots
138
139                 used_nim_slots = [ ]
140
141                 for slot in nim_slots:
142                         if slot.type is not None:
143                                 used_nim_slots.append((slot.slot, slot.description, slot.config.configMode.value != "nothing" and True or False, slot.isCompatible("DVB-S2")))
144                 eDVBResourceManager.getInstance().setFrontendSlotInformations(used_nim_slots)
145
146                 for slot in nim_slots:
147                         x = slot.slot
148                         nim = slot.config
149                         if slot.isCompatible("DVB-S"):
150                                 # save what nim we link to/are equal to/satposdepends to.
151                                 # this is stored in the *value* (not index!) of the config list
152                                 if nim.configMode.value == "equal":
153                                         connto = self.getRoot(x, int(nim.connectedTo.value))
154                                         if not self.equal.has_key(connto):
155                                                 self.equal[connto] = []
156                                         self.equal[connto].append(x)
157                                 elif nim.configMode.value == "loopthrough":
158                                         self.linkNIMs(sec, x, int(nim.connectedTo.value))
159                                         connto = self.getRoot(x, int(nim.connectedTo.value))
160                                         if not self.linked.has_key(connto):
161                                                 self.linked[connto] = []
162                                         self.linked[connto].append(x)
163                                 elif nim.configMode.value == "satposdepends":
164                                         self.setSatposDepends(sec, x, int(nim.connectedTo.value))
165                                         connto = self.getRoot(x, int(nim.connectedTo.value))
166                                         if not self.satposdepends.has_key(connto):
167                                                 self.satposdepends[connto] = []
168                                         self.satposdepends[connto].append(x)
169
170                 for slot in nim_slots:
171                         x = slot.slot
172                         nim = slot.config
173                         hw = HardwareInfo()
174                         if slot.isCompatible("DVB-S"):
175                                 print "slot: " + str(x) + " configmode: " + str(nim.configMode.value)
176                                 if nim.configMode.value in ( "loopthrough", "satposdepends", "nothing" ):
177                                         pass
178                                 else:
179                                         sec.setSlotNotLinked(x)
180                                         if nim.configMode.value == "equal":
181                                                 pass
182                                         elif nim.configMode.value == "simple":          #simple config
183                                                 print "diseqcmode: ", nim.diseqcMode.value
184                                                 if nim.diseqcMode.value == "single":                    #single
185                                                         if nim.simpleSingleSendDiSEqC.value:
186                                                                 self.addLNBSimple(sec, slotid = x, orbpos = nim.diseqcA.orbital_position, toneburstmode = diseqcParam.NO, diseqcmode = diseqcParam.V1_0, diseqcpos = diseqcParam.AA, diseqc13V = nim.diseqc13V.value)
187                                                         else:
188                                                                 self.addLNBSimple(sec, slotid = x, orbpos = nim.diseqcA.orbital_position, toneburstmode = diseqcParam.NO, diseqcmode = diseqcParam.NONE, diseqcpos = diseqcParam.SENDNO, diseqc13V = nim.diseqc13V.value)
189                                                 elif nim.diseqcMode.value == "toneburst_a_b":           #Toneburst A/B
190                                                         self.addLNBSimple(sec, slotid = x, orbpos = nim.diseqcA.orbital_position, toneburstmode = diseqcParam.A, diseqcmode = diseqcParam.V1_0, diseqcpos = diseqcParam.SENDNO, diseqc13V = nim.diseqc13V.value)
191                                                         self.addLNBSimple(sec, slotid = x, orbpos = nim.diseqcB.orbital_position, toneburstmode = diseqcParam.B, diseqcmode = diseqcParam.V1_0, diseqcpos = diseqcParam.SENDNO, diseqc13V = nim.diseqc13V.value)
192                                                 elif nim.diseqcMode.value == "diseqc_a_b":              #DiSEqC A/B
193                                                         fastDiSEqC = nim.simpleDiSEqCOnlyOnSatChange.value
194                                                         setVoltageTone = nim.simpleDiSEqCSetVoltageTone.value
195                                                         self.addLNBSimple(sec, slotid = x, orbpos = nim.diseqcA.orbital_position, toneburstmode = diseqcParam.NO, diseqcmode = diseqcParam.V1_0, diseqcpos = diseqcParam.AA, fastDiSEqC = fastDiSEqC, setVoltageTone = setVoltageTone, diseqc13V = nim.diseqc13V.value)
196                                                         self.addLNBSimple(sec, slotid = x, orbpos = nim.diseqcB.orbital_position, toneburstmode = diseqcParam.NO, diseqcmode = diseqcParam.V1_0, diseqcpos = diseqcParam.AB, fastDiSEqC = fastDiSEqC, setVoltageTone = setVoltageTone, diseqc13V = nim.diseqc13V.value)
197                                                 elif nim.diseqcMode.value == "diseqc_a_b_c_d":          #DiSEqC A/B/C/D
198                                                         fastDiSEqC = nim.simpleDiSEqCOnlyOnSatChange.value
199                                                         setVoltageTone = nim.simpleDiSEqCSetVoltageTone.value
200                                                         self.addLNBSimple(sec, slotid = x, orbpos = nim.diseqcA.orbital_position, toneburstmode = diseqcParam.NO, diseqcmode = diseqcParam.V1_0, diseqcpos = diseqcParam.AA, fastDiSEqC = fastDiSEqC, setVoltageTone = setVoltageTone, diseqc13V = nim.diseqc13V.value)
201                                                         self.addLNBSimple(sec, slotid = x, orbpos = nim.diseqcB.orbital_position, toneburstmode = diseqcParam.NO, diseqcmode = diseqcParam.V1_0, diseqcpos = diseqcParam.AB, fastDiSEqC = fastDiSEqC, setVoltageTone = setVoltageTone, diseqc13V = nim.diseqc13V.value)
202                                                         self.addLNBSimple(sec, slotid = x, orbpos = nim.diseqcC.orbital_position, toneburstmode = diseqcParam.NO, diseqcmode = diseqcParam.V1_0, diseqcpos = diseqcParam.BA, fastDiSEqC = fastDiSEqC, setVoltageTone = setVoltageTone, diseqc13V = nim.diseqc13V.value)
203                                                         self.addLNBSimple(sec, slotid = x, orbpos = nim.diseqcD.orbital_position, toneburstmode = diseqcParam.NO, diseqcmode = diseqcParam.V1_0, diseqcpos = diseqcParam.BB, fastDiSEqC = fastDiSEqC, setVoltageTone = setVoltageTone, diseqc13V = nim.diseqc13V.value)
204                                                 elif nim.diseqcMode.value == "positioner":              #Positioner
205                                                         if nim.latitudeOrientation.value == "north":
206                                                                 laValue = rotorParam.NORTH
207                                                         else:
208                                                                 laValue = rotorParam.SOUTH
209                                                         if nim.longitudeOrientation.value == "east":
210                                                                 loValue = rotorParam.EAST
211                                                         else:
212                                                                 loValue = rotorParam.WEST
213                                                         inputPowerDelta=nim.powerThreshold.value
214                                                         useInputPower=False
215                                                         turning_speed=0
216                                                         if nim.powerMeasurement.value:
217                                                                 useInputPower=True
218                                                                 turn_speed_dict = { "fast": rotorParam.FAST, "slow": rotorParam.SLOW }
219                                                                 if turn_speed_dict.has_key(nim.turningSpeed.value):
220                                                                         turning_speed = turn_speed_dict[nim.turningSpeed.value]
221                                                                 else:
222                                                                         beg_time = localtime(nim.fastTurningBegin.value)
223                                                                         end_time = localtime(nim.fastTurningEnd.value)
224                                                                         turning_speed = ((beg_time.tm_hour+1) * 60 + beg_time.tm_min + 1) << 16
225                                                                         turning_speed |= (end_time.tm_hour+1) * 60 + end_time.tm_min + 1
226                                                         self.addLNBSimple(sec, slotid = x, diseqcmode = 3,
227                                                                 longitude = nim.longitude.float,
228                                                                 loDirection = loValue,
229                                                                 latitude = nim.latitude.float,
230                                                                 laDirection = laValue,
231                                                                 turningSpeed = turning_speed,
232                                                                 useInputPower = useInputPower,
233                                                                 inputPowerDelta = inputPowerDelta,
234                                                                 diseqc13V = nim.diseqc13V.value)
235                                         elif nim.configMode.value == "advanced": #advanced config
236                                                 self.updateAdvanced(sec, x)
237                 print "sec config completed"
238
239         def updateAdvanced(self, sec, slotid):
240                 try:
241                         if config.Nims[slotid].advanced.unicableconnected is not None:
242                                 if config.Nims[slotid].advanced.unicableconnected.value == True:
243                                         config.Nims[slotid].advanced.unicableconnectedTo.save_forced = True
244                                         self.linkNIMs(sec, slotid, int(config.Nims[slotid].advanced.unicableconnectedTo.value))
245                                         connto = self.getRoot(slotid, int(config.Nims[slotid].advanced.unicableconnectedTo.value))
246                                         if not self.linked.has_key(connto):
247                                                 self.linked[connto] = []
248                                         self.linked[connto].append(slotid)
249                                 else:
250                                         config.Nims[slotid].advanced.unicableconnectedTo.save_forced = False
251                 except:
252                         pass
253
254                 lnbSat = {}
255                 for x in range(1,37):
256                         lnbSat[x] = []
257
258                 #wildcard for all satellites ( for rotor )
259                 for x in range(3601, 3605):
260                         lnb = int(config.Nims[slotid].advanced.sat[x].lnb.value)
261                         if lnb != 0:
262                                 for x in self.NimManager.satList:
263                                         print "add", x[0], "to", lnb
264                                         lnbSat[lnb].append(x[0])
265
266                 for x in self.NimManager.satList:
267                         lnb = int(config.Nims[slotid].advanced.sat[x[0]].lnb.value)
268                         if lnb != 0:
269                                 print "add", x[0], "to", lnb
270                                 lnbSat[lnb].append(x[0])
271
272                 for x in range(1,37):
273                         if len(lnbSat[x]) > 0:
274                                 currLnb = config.Nims[slotid].advanced.lnb[x]
275                                 sec.addLNB()
276
277                                 if x < 33:
278                                         sec.setLNBNum(x)
279
280                                 tunermask = 1 << slotid
281                                 if self.equal.has_key(slotid):
282                                         for slot in self.equal[slotid]:
283                                                 tunermask |= (1 << slot)
284                                 if self.linked.has_key(slotid):
285                                         for slot in self.linked[slotid]:
286                                                 tunermask |= (1 << slot)
287
288                                 if currLnb.lof.value != "unicable":
289                                         sec.setLNBSatCR(-1)
290
291                                 if currLnb.lof.value == "universal_lnb":
292                                         sec.setLNBLOFL(9750000)
293                                         sec.setLNBLOFH(10600000)
294                                         sec.setLNBThreshold(11700000)
295                                 elif currLnb.lof.value == "unicable":
296                                         def setupUnicable(configManufacturer, ProductDict):
297                                                 manufacturer_name = configManufacturer.value
298                                                 manufacturer = ProductDict[manufacturer_name]
299                                                 product_name = manufacturer.product.value
300                                                 sec.setLNBSatCR(manufacturer.scr[product_name].index)
301                                                 sec.setLNBSatCRvco(manufacturer.vco[product_name][manufacturer.scr[product_name].index].value*1000)
302                                                 sec.setLNBSatCRpositions(manufacturer.positions[product_name][0].value)
303                                                 sec.setLNBLOFL(manufacturer.lofl[product_name][0].value * 1000)
304                                                 sec.setLNBLOFH(manufacturer.lofh[product_name][0].value * 1000)
305                                                 sec.setLNBThreshold(manufacturer.loft[product_name][0].value * 1000)
306                                                 configManufacturer.save_forced = True
307                                                 manufacturer.product.save_forced = True
308                                                 manufacturer.vco[product_name][manufacturer.scr[product_name].index].save_forced = True
309
310                                         if currLnb.unicable.value == "unicable_user":
311 #TODO satpositions for satcruser
312                                                 sec.setLNBLOFL(currLnb.lofl.value * 1000)
313                                                 sec.setLNBLOFH(currLnb.lofh.value * 1000)
314                                                 sec.setLNBThreshold(currLnb.threshold.value * 1000)
315                                                 sec.setLNBSatCR(currLnb.satcruser.index)
316                                                 sec.setLNBSatCRvco(currLnb.satcrvcouser[currLnb.satcruser.index].value*1000)
317                                                 sec.setLNBSatCRpositions(1)     #HACK
318                                         elif currLnb.unicable.value == "unicable_matrix":
319                                                 setupUnicable(currLnb.unicableMatrixManufacturer, currLnb.unicableMatrix)
320                                         elif currLnb.unicable.value == "unicable_lnb":
321                                                 setupUnicable(currLnb.unicableLnbManufacturer, currLnb.unicableLnb)
322                                 elif currLnb.lof.value == "c_band":
323                                         sec.setLNBLOFL(5150000)
324                                         sec.setLNBLOFH(5150000)
325                                         sec.setLNBThreshold(5150000)
326                                 elif currLnb.lof.value == "user_defined":
327                                         sec.setLNBLOFL(currLnb.lofl.value * 1000)
328                                         sec.setLNBLOFH(currLnb.lofh.value * 1000)
329                                         sec.setLNBThreshold(currLnb.threshold.value * 1000)
330
331 #                               if currLnb.output_12v.value == "0V":
332 #                                       pass # nyi in drivers
333 #                               elif currLnb.output_12v.value == "12V":
334 #                                       pass # nyi in drivers
335
336                                 if currLnb.increased_voltage.value:
337                                         sec.setLNBIncreasedVoltage(lnbParam.ON)
338                                 else:
339                                         sec.setLNBIncreasedVoltage(lnbParam.OFF)
340
341                                 dm = currLnb.diseqcMode.value
342                                 if dm == "none":
343                                         sec.setDiSEqCMode(diseqcParam.NONE)
344                                 elif dm == "1_0":
345                                         sec.setDiSEqCMode(diseqcParam.V1_0)
346                                 elif dm == "1_1":
347                                         sec.setDiSEqCMode(diseqcParam.V1_1)
348                                 elif dm == "1_2":
349                                         sec.setDiSEqCMode(diseqcParam.V1_2)
350
351                                         if self.satposdepends.has_key(slotid):
352                                                 for slot in self.satposdepends[slotid]:
353                                                         tunermask |= (1 << slot)
354
355                                 if dm != "none":
356                                         if currLnb.toneburst.value == "none":
357                                                 sec.setToneburst(diseqcParam.NO)
358                                         elif currLnb.toneburst.value == "A":
359                                                 sec.setToneburst(diseqcParam.A)
360                                         elif currLnb.toneburst.value == "B":
361                                                 sec.setToneburst(diseqcParam.B)
362
363                                         # Committed Diseqc Command
364                                         cdc = currLnb.commitedDiseqcCommand.value
365
366                                         c = { "none": diseqcParam.SENDNO,
367                                                 "AA": diseqcParam.AA,
368                                                 "AB": diseqcParam.AB,
369                                                 "BA": diseqcParam.BA,
370                                                 "BB": diseqcParam.BB }
371
372                                         if c.has_key(cdc):
373                                                 sec.setCommittedCommand(c[cdc])
374                                         else:
375                                                 sec.setCommittedCommand(long(cdc))
376
377                                         sec.setFastDiSEqC(currLnb.fastDiseqc.value)
378
379                                         sec.setSeqRepeat(currLnb.sequenceRepeat.value)
380
381                                         if currLnb.diseqcMode.value == "1_0":
382                                                 currCO = currLnb.commandOrder1_0.value
383                                         else:
384                                                 currCO = currLnb.commandOrder.value
385
386                                                 udc = int(currLnb.uncommittedDiseqcCommand.value)
387                                                 if udc > 0:
388                                                         sec.setUncommittedCommand(0xF0|(udc-1))
389                                                 else:
390                                                         sec.setUncommittedCommand(0) # SENDNO
391
392                                                 sec.setRepeats({"none": 0, "one": 1, "two": 2, "three": 3}[currLnb.diseqcRepeats.value])
393
394                                         setCommandOrder = False
395
396                                         # 0 "committed, toneburst",
397                                         # 1 "toneburst, committed",
398                                         # 2 "committed, uncommitted, toneburst",
399                                         # 3 "toneburst, committed, uncommitted",
400                                         # 4 "uncommitted, committed, toneburst"
401                                         # 5 "toneburst, uncommitted, commmitted"
402                                         order_map = {"ct": 0, "tc": 1, "cut": 2, "tcu": 3, "uct": 4, "tuc": 5}
403                                         sec.setCommandOrder(order_map[currCO])
404
405                                 if dm == "1_2":
406                                         latitude = currLnb.latitude.float
407                                         sec.setLatitude(latitude)
408                                         longitude = currLnb.longitude.float
409                                         sec.setLongitude(longitude)
410                                         if currLnb.latitudeOrientation.value == "north":
411                                                 sec.setLaDirection(rotorParam.NORTH)
412                                         else:
413                                                 sec.setLaDirection(rotorParam.SOUTH)
414                                         if currLnb.longitudeOrientation.value == "east":
415                                                 sec.setLoDirection(rotorParam.EAST)
416                                         else:
417                                                 sec.setLoDirection(rotorParam.WEST)
418
419                                         if currLnb.powerMeasurement.value:
420                                                 sec.setUseInputpower(True)
421                                                 sec.setInputpowerDelta(currLnb.powerThreshold.value)
422                                                 turn_speed_dict = { "fast": rotorParam.FAST, "slow": rotorParam.SLOW }
423                                                 if turn_speed_dict.has_key(currLnb.turningSpeed.value):
424                                                         turning_speed = turn_speed_dict[currLnb.turningSpeed.value]
425                                                 else:
426                                                         beg_time = localtime(currLnb.fastTurningBegin.value)
427                                                         end_time = localtime(currLnb.fastTurningEnd.value)
428                                                         turning_speed = ((beg_time.tm_hour + 1) * 60 + beg_time.tm_min + 1) << 16
429                                                         turning_speed |= (end_time.tm_hour + 1) * 60 + end_time.tm_min + 1
430                                                 sec.setRotorTurningSpeed(turning_speed)
431                                         else:
432                                                 sec.setUseInputpower(False)
433
434                                 sec.setLNBSlotMask(tunermask)
435
436                                 sec.setLNBPrio(int(currLnb.prio.value))
437
438                                 # finally add the orbital positions
439                                 for y in lnbSat[x]:
440                                         self.addSatellite(sec, y)
441                                         if x > 32:
442                                                 satpos = x > 32 and (3604-(36 - x)) or y
443                                         else:
444                                                 satpos = y
445                                         currSat = config.Nims[slotid].advanced.sat[satpos]
446                                         if currSat.voltage.value == "polarization":
447                                                 if config.Nims[slotid].diseqc13V.value:
448                                                         sec.setVoltageMode(switchParam.HV_13)
449                                                 else:
450                                                         sec.setVoltageMode(switchParam.HV)
451                                         elif currSat.voltage.value == "13V":
452                                                 sec.setVoltageMode(switchParam._14V)
453                                         elif currSat.voltage.value == "18V":
454                                                 sec.setVoltageMode(switchParam._18V)
455
456                                         if currSat.tonemode.value == "band":
457                                                 sec.setToneMode(switchParam.HILO)
458                                         elif currSat.tonemode.value == "on":
459                                                 sec.setToneMode(switchParam.ON)
460                                         elif currSat.tonemode.value == "off":
461                                                 sec.setToneMode(switchParam.OFF)
462                                                 
463                                         if not currSat.usals.value and x < 34:
464                                                 sec.setRotorPosNum(currSat.rotorposition.value)
465                                         else:
466                                                 sec.setRotorPosNum(0) #USALS
467
468         def __init__(self, nimmgr):
469                 self.NimManager = nimmgr
470                 self.configuredSatellites = set()
471                 self.update()
472
473 class NIM(object):
474         def __init__(self, slot, type, description, has_outputs = True, internally_connectable = None, multi_type = {}):
475                 self.slot = slot
476
477                 if type not in ("DVB-S", "DVB-C", "DVB-T", "DVB-S2", None):
478                         print "warning: unknown NIM type %s, not using." % type
479                         type = None
480
481                 self.type = type
482                 self.description = description
483                 self.has_outputs = has_outputs
484                 self.internally_connectable = internally_connectable
485                 self.multi_type = multi_type
486
487         def isCompatible(self, what):
488                 compatible = {
489                                 None: (None,),
490                                 "DVB-S": ("DVB-S", None),
491                                 "DVB-C": ("DVB-C", None),
492                                 "DVB-T": ("DVB-T", None),
493                                 "DVB-S2": ("DVB-S", "DVB-S2", None)
494                         }
495                 return what in compatible[self.type]
496         
497         def getType(self):
498                 return self.type
499         
500         def connectableTo(self):
501                 connectable = {
502                                 "DVB-S": ("DVB-S", "DVB-S2"),
503                                 "DVB-C": ("DVB-C",),
504                                 "DVB-T": ("DVB-T",),
505                                 "DVB-S2": ("DVB-S", "DVB-S2")
506                         }
507                 return connectable[self.type]
508
509         def getSlotName(self):
510                 # get a friendly description for a slot name.
511                 # we name them "Tuner A/B/C/...", because that's what's usually written on the back
512                 # of the device.
513                 return _("Tuner ") + chr(ord('A') + self.slot)
514
515         slot_name = property(getSlotName)
516
517         def getSlotID(self):
518                 return chr(ord('A') + self.slot)
519         
520         def hasOutputs(self):
521                 return self.has_outputs
522         
523         def internallyConnectableTo(self):
524                 return self.internally_connectable
525         
526         def isMultiType(self):
527                 return (len(self.multi_type) > 0)
528         
529         # returns dict {<slotid>: <type>}
530         def getMultiTypeList(self):
531                 return self.multi_type
532
533         slot_id = property(getSlotID)
534
535         def getFriendlyType(self):
536                 return {
537                         "DVB-S": "DVB-S", 
538                         "DVB-T": "DVB-T",
539                         "DVB-S2": "DVB-S2",
540                         "DVB-C": "DVB-C",
541                         None: _("empty")
542                         }[self.type]
543
544         friendly_type = property(getFriendlyType)
545
546         def getFriendlyFullDescription(self):
547                 nim_text = self.slot_name + ": "
548                         
549                 if self.empty:
550                         nim_text += _("(empty)")
551                 else:
552                         nim_text += self.description + " (" + self.friendly_type + ")"
553                 
554                 return nim_text
555
556         friendly_full_description = property(getFriendlyFullDescription)
557         config_mode = property(lambda self: config.Nims[self.slot].configMode.value)
558         config = property(lambda self: config.Nims[self.slot])
559         empty = property(lambda self: self.type is None)
560
561 class NimManager:
562         def getConfiguredSats(self):
563                 return self.sec.getConfiguredSats()
564
565         def getTransponders(self, pos):
566                 if self.transponders.has_key(pos):
567                         return self.transponders[pos]
568                 else:
569                         return []
570
571         def getTranspondersCable(self, nim):
572                 nimConfig = config.Nims[nim]
573                 if nimConfig.configMode.value != "nothing" and nimConfig.cable.scan_type.value == "provider":
574                         return self.transponderscable[self.cablesList[nimConfig.cable.scan_provider.index][0]]
575                 return [ ]
576
577         def getTranspondersTerrestrial(self, region):
578                 return self.transpondersterrestrial[region]
579         
580         def getCableDescription(self, nim):
581                 return self.cablesList[config.Nims[nim].scan_provider.index][0]
582
583         def getCableFlags(self, nim):
584                 return self.cablesList[config.Nims[nim].scan_provider.index][1]
585
586         def getTerrestrialDescription(self, nim):
587                 return self.terrestrialsList[config.Nims[nim].terrestrial.index][0]
588
589         def getTerrestrialFlags(self, nim):
590                 return self.terrestrialsList[config.Nims[nim].terrestrial.index][1]
591
592         def getSatDescription(self, pos):
593                 return self.satellites[pos]
594
595         def sortFunc(self, x):
596                 orbpos = x[0]
597                 if orbpos > 1800:
598                         return orbpos - 3600
599                 else:
600                         return orbpos + 1800
601
602         def readTransponders(self):
603                 # read initial networks from file. we only read files which we are interested in,
604                 # which means only these where a compatible tuner exists.
605                 self.satellites = { }
606                 self.transponders = { }
607                 self.transponderscable = { }
608                 self.transpondersterrestrial = { }
609                 db = eDVBDB.getInstance()
610                 if self.hasNimType("DVB-S"):
611                         print "Reading satellites.xml"
612                         db.readSatellites(self.satList, self.satellites, self.transponders)
613                         self.satList.sort(key = self.sortFunc) # sort by orbpos
614                         #print "SATLIST", self.satList
615                         #print "SATS", self.satellites
616                         #print "TRANSPONDERS", self.transponders
617
618                 if self.hasNimType("DVB-C"):
619                         print "Reading cables.xml"
620                         db.readCables(self.cablesList, self.transponderscable)
621 #                       print "CABLIST", self.cablesList
622 #                       print "TRANSPONDERS", self.transponders
623
624                 if self.hasNimType("DVB-T"):
625                         print "Reading terrestrial.xml"
626                         db.readTerrestrials(self.terrestrialsList, self.transpondersterrestrial)
627 #                       print "TERLIST", self.terrestrialsList
628 #                       print "TRANSPONDERS", self.transpondersterrestrial
629
630         def enumerateNIMs(self):
631                 # enum available NIMs. This is currently very dreambox-centric and uses the /proc/bus/nim_sockets interface.
632                 # the result will be stored into nim_slots.
633                 # the content of /proc/bus/nim_sockets looks like:
634                 # NIM Socket 0:
635                 #          Type: DVB-S
636                 #          Name: BCM4501 DVB-S2 NIM (internal)
637                 # NIM Socket 1:
638                 #          Type: DVB-S
639                 #          Name: BCM4501 DVB-S2 NIM (internal)
640                 # NIM Socket 2:
641                 #          Type: DVB-T
642                 #          Name: Philips TU1216
643                 # NIM Socket 3:
644                 #          Type: DVB-S
645                 #          Name: Alps BSBE1 702A
646                 
647                 #
648                 # Type will be either "DVB-S", "DVB-S2", "DVB-T", "DVB-C" or None.
649
650                 # nim_slots is an array which has exactly one entry for each slot, even for empty ones.
651                 self.nim_slots = [ ]
652
653                 nimfile = tryOpen("/proc/bus/nim_sockets")
654
655                 if nimfile is None:
656                         return
657
658                 current_slot = None
659
660                 entries = {}
661                 for line in nimfile.readlines():
662                         if line == "":
663                                 break
664                         if line.strip().startswith("NIM Socket"):
665                                 parts = line.strip().split(" ")
666                                 current_slot = int(parts[2][:-1])
667                                 entries[current_slot] = {}
668                         elif line.strip().startswith("Type:"):
669                                 entries[current_slot]["type"] = str(line.strip()[6:])
670                         elif line.strip().startswith("Name:"):
671                                 entries[current_slot]["name"] = str(line.strip()[6:])
672                         elif line.strip().startswith("Has_Outputs:"):
673                                 input = str(line.strip()[len("Has_Outputs:") + 1:])
674                                 entries[current_slot]["has_outputs"] = (input == "yes")
675                         elif line.strip().startswith("Internally_Connectable:"):
676                                 input = int(line.strip()[len("Internally_Connectable:") + 1:])
677                                 entries[current_slot]["internally_connectable"] = input
678                         elif  line.strip().startswith("Mode"):
679                                 # "Mode 0: DVB-T" -> ["Mode 0", " DVB-T"]
680                                 split = line.strip().split(":")
681                                 # "Mode 0" -> ["Mode, "0"]
682                                 split2 = split[0].split(" ")
683                                 modes = entries[current_slot].get("multi_type", {})
684                                 modes[split2[1]] = split[1].strip()
685                                 entries[current_slot]["multi_type"] = modes
686                         elif line.strip().startswith("empty"):
687                                 entries[current_slot]["type"] = None
688                                 entries[current_slot]["name"] = _("N/A")
689                 nimfile.close()
690                 
691                 for id, entry in entries.items():
692                         if not (entry.has_key("name") and entry.has_key("type")):
693                                 entry["name"] =  _("N/A")
694                                 entry["type"] = None
695                         if not (entry.has_key("has_outputs")):
696                                 entry["has_outputs"] = True
697                         if not (entry.has_key("internally_connectable")):
698                                 entry["internally_connectable"] = None
699                         if not (entry.has_key("multi_type")):
700                                 entry["multi_type"] = {}
701                         self.nim_slots.append(NIM(slot = id, description = entry["name"], type = entry["type"], has_outputs = entry["has_outputs"], internally_connectable = entry["internally_connectable"], multi_type = entry["multi_type"]))
702
703         def hasNimType(self, chktype):
704                 for slot in self.nim_slots:
705                         if slot.isCompatible(chktype):
706                                 return True
707                         for type in slot.getMultiTypeList().values():
708                                 if chktype == type:
709                                         return True
710                 return False
711         
712         def getNimType(self, slotid):
713                 return self.nim_slots[slotid].type
714         
715         def getNimDescription(self, slotid):
716                 return self.nim_slots[slotid].friendly_full_description
717         
718         def getNimName(self, slotid):
719                 return self.nim_slots[slotid].description
720
721         def getNimListOfType(self, type, exception = -1):
722                 # returns a list of indexes for NIMs compatible to the given type, except for 'exception'
723                 list = []
724                 for x in self.nim_slots:
725                         if x.isCompatible(type) and x.slot != exception:
726                                 list.append(x.slot)
727                 return list
728
729         def __init__(self):
730                 self.satList = [ ]
731                 self.cablesList = []
732                 self.terrestrialsList = []
733                 self.enumerateNIMs()
734                 self.readTransponders()
735                 InitNimManager(self)    #init config stuff
736
737         # get a list with the friendly full description
738         def nimList(self):
739                 list = [ ]
740                 for slot in self.nim_slots:
741                         list.append(slot.friendly_full_description)
742                 return list
743         
744         def getSlotCount(self):
745                 return len(self.nim_slots)
746         
747         def hasOutputs(self, slotid):
748                 return self.nim_slots[slotid].hasOutputs()
749         
750         def canConnectTo(self, slotid):
751                 slots = []
752                 if self.nim_slots[slotid].internallyConnectableTo() is not None:
753                         slots.append(self.nim_slots[slotid].internallyConnectableTo())
754                 for type in self.nim_slots[slotid].connectableTo(): 
755                         for slot in self.getNimListOfType(type, exception = slotid):
756                                 if self.hasOutputs(slot):
757                                         slots.append(slot)
758                 # remove nims, that have a conntectedTo reference on
759                 for testnim in slots[:]:
760                         for nim in self.getNimListOfType("DVB-S", slotid):
761                                 nimConfig = self.getNimConfig(nim)
762                                 if nimConfig.content.items.has_key("configMode") and nimConfig.configMode.value == "loopthrough" and int(nimConfig.connectedTo.value) == testnim:
763                                         slots.remove(testnim)
764                                         break 
765                 slots.sort()
766                 
767                 return slots
768         
769         def canEqualTo(self, slotid):
770                 type = self.getNimType(slotid)
771                 if type == "DVB-S2":
772                         type = "DVB-S"
773                 nimList = self.getNimListOfType(type, slotid)
774                 for nim in nimList[:]:
775                         mode = self.getNimConfig(nim)
776                         if mode.configMode.value == "loopthrough" or mode.configMode.value == "satposdepends":
777                                 nimList.remove(nim)
778                 return nimList
779
780         def canDependOn(self, slotid):
781                 type = self.getNimType(slotid)
782                 if type == "DVB-S2":
783                         type = "DVB-S"
784                 nimList = self.getNimListOfType(type, slotid)
785                 positionerList = []
786                 for nim in nimList[:]:
787                         mode = self.getNimConfig(nim)
788                         nimHaveRotor = mode.configMode.value == "simple" and mode.diseqcMode.value == "positioner"
789                         if not nimHaveRotor and mode.configMode.value == "advanced":
790                                 for x in range(3601, 3605):
791                                         lnb = int(mode.advanced.sat[x].lnb.value)
792                                         if lnb != 0:
793                                                 nimHaveRotor = True
794                                                 break
795                                 if not nimHaveRotor:
796                                         for sat in mode.advanced.sat.values():
797                                                 lnb_num = int(sat.lnb.value)
798                                                 diseqcmode = lnb_num and mode.advanced.lnb[lnb_num].diseqcMode.value or ""
799                                                 if diseqcmode == "1_2":
800                                                         nimHaveRotor = True
801                                                         break
802                         if nimHaveRotor:
803                                 alreadyConnected = False
804                                 for testnim in nimList:
805                                         testmode = self.getNimConfig(testnim)
806                                         if testmode.configMode.value == "satposdepends" and int(testmode.connectedTo.value) == int(nim):
807                                                 alreadyConnected = True
808                                                 break
809                                 if not alreadyConnected:
810                                         positionerList.append(nim)
811                 return positionerList
812         
813         def getNimConfig(self, slotid):
814                 return config.Nims[slotid]
815         
816         def getSatName(self, pos):
817                 for sat in self.satList:
818                         if sat[0] == pos:
819                                 return sat[1]
820                 return _("N/A")
821
822         def getSatList(self):
823                 return self.satList
824         
825         # returns True if something is configured to be connected to this nim
826         # if slotid == -1, returns if something is connected to ANY nim
827         def somethingConnected(self, slotid = -1):
828                 if (slotid == -1):
829                         connected = False
830                         for id in range(self.getSlotCount()):
831                                 if self.somethingConnected(id):
832                                         connected = True
833                         return connected
834                 else:
835                         nim = config.Nims[slotid]
836                         configMode = nim.configMode.value
837                 
838                         if self.nim_slots[slotid].isCompatible("DVB-S") or self.nim_slots[slotid].isCompatible("DVB-T") or self.nim_slots[slotid].isCompatible("DVB-C"):
839                                 return not (configMode == "nothing")            
840
841         def getSatListForNim(self, slotid):
842                 list = []
843                 if self.nim_slots[slotid].isCompatible("DVB-S"):
844                         nim = config.Nims[slotid]
845                         #print "slotid:", slotid
846
847                         #print "self.satellites:", self.satList[config.Nims[slotid].diseqcA.index]
848                         #print "diseqcA:", config.Nims[slotid].diseqcA.value
849                         configMode = nim.configMode.value
850
851                         if configMode == "equal":
852                                 slotid = int(nim.connectedTo.value)
853                                 nim = config.Nims[slotid]
854                                 configMode = nim.configMode.value
855                         elif configMode == "loopthrough":
856                                 slotid = self.sec.getRoot(slotid, int(nim.connectedTo.value))
857                                 nim = config.Nims[slotid]
858                                 configMode = nim.configMode.value
859
860                         if configMode == "simple":
861                                 dm = nim.diseqcMode.value
862                                 if dm in ("single", "toneburst_a_b", "diseqc_a_b", "diseqc_a_b_c_d"):
863                                         if nim.diseqcA.orbital_position != 3601:
864                                                 list.append(self.satList[nim.diseqcA.index-1])
865                                 if dm in ("toneburst_a_b", "diseqc_a_b", "diseqc_a_b_c_d"):
866                                         if nim.diseqcB.orbital_position != 3601:
867                                                 list.append(self.satList[nim.diseqcB.index-1])
868                                 if dm == "diseqc_a_b_c_d":
869                                         if nim.diseqcC.orbital_position != 3601:
870                                                 list.append(self.satList[nim.diseqcC.index-1])
871                                         if nim.diseqcD.orbital_position != 3601:
872                                                 list.append(self.satList[nim.diseqcD.index-1])
873                                 if dm == "positioner":
874                                         for x in self.satList:
875                                                 list.append(x)
876                         elif configMode == "advanced":
877                                 for x in range(3601, 3605):
878                                         if int(nim.advanced.sat[x].lnb.value) != 0:
879                                                 for x in self.satList:
880                                                         list.append(x)
881                                 if not list:
882                                         for x in self.satList:
883                                                 if int(nim.advanced.sat[x[0]].lnb.value) != 0:
884                                                         list.append(x)
885                 return list
886
887         def getRotorSatListForNim(self, slotid):
888                 list = []
889                 if self.nim_slots[slotid].isCompatible("DVB-S"):
890                         #print "slotid:", slotid
891                         #print "self.satellites:", self.satList[config.Nims[slotid].diseqcA.value]
892                         #print "diseqcA:", config.Nims[slotid].diseqcA.value
893                         configMode = config.Nims[slotid].configMode.value
894                         if configMode == "simple":
895                                 if config.Nims[slotid].diseqcMode.value == "positioner":
896                                         for x in self.satList:
897                                                 list.append(x)
898                         elif configMode == "advanced":
899                                 nim = config.Nims[slotid]
900                                 for x in range(3601, 3605):
901                                         if int(nim.advanced.sat[x].lnb.value) != 0:
902                                                 for x in self.satList:
903                                                         list.append(x)
904                                 if not list:
905                                         for x in self.satList:
906                                                 lnbnum = int(nim.advanced.sat[x[0]].lnb.value)
907                                                 if lnbnum != 0:
908                                                         lnb = nim.advanced.lnb[lnbnum]
909                                                         if lnb.diseqcMode.value == "1_2":
910                                                                 list.append(x)
911                 return list
912
913 def InitSecParams():
914         config.sec = ConfigSubsection()
915
916         x = ConfigInteger(default=25, limits = (0, 9999))
917         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_CONT_TONE_DISABLE_BEFORE_DISEQC, configElement.value))
918         config.sec.delay_after_continuous_tone_disable_before_diseqc = x
919
920         x = ConfigInteger(default=10, limits = (0, 9999))
921         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_FINAL_CONT_TONE_CHANGE, configElement.value))
922         config.sec.delay_after_final_continuous_tone_change = x
923
924         x = ConfigInteger(default=10, limits = (0, 9999))
925         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_FINAL_VOLTAGE_CHANGE, configElement.value))
926         config.sec.delay_after_final_voltage_change = x
927
928         x = ConfigInteger(default=120, limits = (0, 9999))
929         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_BETWEEN_DISEQC_REPEATS, configElement.value))
930         config.sec.delay_between_diseqc_repeats = x
931
932         x = ConfigInteger(default=50, limits = (0, 9999))
933         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_LAST_DISEQC_CMD, configElement.value))
934         config.sec.delay_after_last_diseqc_command = x
935
936         x = ConfigInteger(default=50, limits = (0, 9999))
937         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_TONEBURST, configElement.value))
938         config.sec.delay_after_toneburst = x
939
940         x = ConfigInteger(default=20, limits = (0, 9999))
941         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_SWITCH_CMDS, configElement.value))
942         config.sec.delay_after_change_voltage_before_switch_command = x
943
944         x = ConfigInteger(default=200, limits = (0, 9999))
945         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_ENABLE_VOLTAGE_BEFORE_SWITCH_CMDS, configElement.value))
946         config.sec.delay_after_enable_voltage_before_switch_command = x
947
948         x = ConfigInteger(default=700, limits = (0, 9999))
949         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_BETWEEN_SWITCH_AND_MOTOR_CMD, configElement.value))
950         config.sec.delay_between_switch_and_motor_command = x
951
952         x = ConfigInteger(default=500, limits = (0, 9999))
953         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_MEASURE_IDLE_INPUTPOWER, configElement.value))
954         config.sec.delay_after_voltage_change_before_measure_idle_inputpower = x
955
956         x = ConfigInteger(default=900, limits = (0, 9999))
957         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_ENABLE_VOLTAGE_BEFORE_MOTOR_CMD, configElement.value))
958         config.sec.delay_after_enable_voltage_before_motor_command = x
959
960         x = ConfigInteger(default=500, limits = (0, 9999))
961         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_MOTOR_STOP_CMD, configElement.value))
962         config.sec.delay_after_motor_stop_command = x
963
964         x = ConfigInteger(default=500, limits = (0, 9999))
965         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_MOTOR_CMD, configElement.value))
966         config.sec.delay_after_voltage_change_before_motor_command = x
967
968         x = ConfigInteger(default=70, limits = (0, 9999))
969         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_BEFORE_SEQUENCE_REPEAT, configElement.value))
970         config.sec.delay_before_sequence_repeat = x
971
972         x = ConfigInteger(default=360, limits = (0, 9999))
973         x.addNotifier(lambda configElement: secClass.setParam(secClass.MOTOR_RUNNING_TIMEOUT, configElement.value))
974         config.sec.motor_running_timeout = x
975
976         x = ConfigInteger(default=1, limits = (0, 5))
977         x.addNotifier(lambda configElement: secClass.setParam(secClass.MOTOR_COMMAND_RETRIES, configElement.value))
978         config.sec.motor_command_retries = x
979
980         x = ConfigInteger(default=50, limits = (0, 9999))
981         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_DISEQC_RESET_CMD, configElement.value))
982         config.sec.delay_after_diseqc_reset_cmd = x
983
984         x = ConfigInteger(default=150, limits = (0, 9999))
985         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_DISEQC_PERIPHERIAL_POWERON_CMD, configElement.value))
986         config.sec.delay_after_diseqc_peripherial_poweron_cmd = x
987
988 # TODO add support for satpos depending nims to advanced nim configuration
989 # so a second/third/fourth cable from a motorized lnb can used behind a
990 # diseqc 1.0 / diseqc 1.1 / toneburst switch
991 # the C(++) part should can handle this
992 # the configElement should be only visible when diseqc 1.2 is disabled
993
994 def InitNimManager(nimmgr):
995         hw = HardwareInfo()
996         addNimConfig = False
997         try:
998                 config.Nims
999         except:
1000                 addNimConfig = True
1001
1002         if addNimConfig:
1003                 InitSecParams()
1004                 config.Nims = ConfigSubList()
1005                 for x in range(len(nimmgr.nim_slots)):
1006                         config.Nims.append(ConfigSubsection())
1007
1008         lnb_choices = {
1009                 "universal_lnb": _("Universal LNB"),
1010                 "unicable": _("Unicable"),
1011                 "c_band": _("C-Band"),
1012                 "user_defined": _("User defined")}
1013
1014         lnb_choices_default = "universal_lnb"
1015
1016         unicablelnbproducts = {}
1017         unicablematrixproducts = {}
1018         doc = xml.etree.cElementTree.parse("/usr/share/enigma2/unicable.xml")
1019         root = doc.getroot()
1020
1021         entry = root.find("lnb")
1022         for manufacturer in entry.getchildren():
1023                 m={}
1024                 for product in manufacturer.getchildren():
1025                         scr=[]
1026                         lscr=("scr1","scr2","scr3","scr4","scr5","scr6","scr7","scr8")
1027                         for i in range(len(lscr)):
1028                                 scr.append(product.get(lscr[i],"0"))
1029                         for i in range(len(lscr)):
1030                                 if scr[len(lscr)-i-1] == "0":
1031                                         scr.pop()
1032                                 else:
1033                                         break;
1034                         lof=[]
1035                         lof.append(int(product.get("positions",1)))
1036                         lof.append(int(product.get("lofl",9750)))
1037                         lof.append(int(product.get("lofh",10600)))
1038                         lof.append(int(product.get("threshold",11700)))
1039                         scr.append(tuple(lof))
1040                         m.update({product.get("name"):tuple(scr)})
1041                 unicablelnbproducts.update({manufacturer.get("name"):m})
1042
1043         entry = root.find("matrix")
1044         for manufacturer in entry.getchildren():
1045                 m={}
1046                 for product in manufacturer.getchildren():
1047                         scr=[]
1048                         lscr=("scr1","scr2","scr3","scr4","scr5","scr6","scr7","scr8")
1049                         for i in range(len(lscr)):
1050                                 scr.append(product.get(lscr[i],"0"))
1051                         for i in range(len(lscr)):
1052                                 if scr[len(lscr)-i-1] == "0":
1053                                         scr.pop()
1054                                 else:
1055                                         break;
1056                         lof=[]
1057                         lof.append(int(product.get("positions",1)))
1058                         lof.append(int(product.get("lofl",9750)))
1059                         lof.append(int(product.get("lofh",10600)))
1060                         lof.append(int(product.get("threshold",11700)))
1061                         scr.append(tuple(lof))
1062                         m.update({product.get("name"):tuple(scr)})
1063                 unicablematrixproducts.update({manufacturer.get("name"):m})
1064
1065         UnicableLnbManufacturers = unicablelnbproducts.keys()
1066         UnicableLnbManufacturers.sort()
1067         UnicableMatrixManufacturers = unicablematrixproducts.keys()
1068         UnicableMatrixManufacturers.sort()
1069
1070         unicable_choices = {
1071                 "unicable_lnb": _("Unicable LNB"),
1072                 "unicable_matrix": _("Unicable Martix"),
1073                 "unicable_user": "Unicable "+_("User defined")}
1074         unicable_choices_default = "unicable_lnb"
1075
1076         advanced_lnb_satcruser_choices = [ ("1", "SatCR 1"), ("2", "SatCR 2"), ("3", "SatCR 3"), ("4", "SatCR 4"),
1077                                         ("5", "SatCR 5"), ("6", "SatCR 6"), ("7", "SatCR 7"), ("8", "SatCR 8")]
1078
1079         prio_list = [ ("-1", _("Auto")) ]
1080         prio_list += [(str(prio), str(prio)) for prio in range(65)+range(14000,14065)+range(19000,19065)]
1081
1082         advanced_lnb_csw_choices = [("none", _("None")), ("AA", _("AA")), ("AB", _("AB")), ("BA", _("BA")), ("BB", _("BB"))]
1083         advanced_lnb_csw_choices += [(str(0xF0|y), "Input " + str(y+1)) for y in range(0, 16)]
1084
1085         advanced_lnb_ucsw_choices = [("0", _("None"))] + [(str(y), "Input " + str(y)) for y in range(1, 17)]
1086
1087         diseqc_mode_choices = [
1088                 ("single", _("Single")), ("toneburst_a_b", _("Toneburst A/B")),
1089                 ("diseqc_a_b", _("DiSEqC A/B")), ("diseqc_a_b_c_d", _("DiSEqC A/B/C/D")),
1090                 ("positioner", _("Positioner"))]
1091
1092         positioner_mode_choices = [("usals", _("USALS")), ("manual", _("manual"))]
1093
1094         diseqc_satlist_choices = [(3601, _('nothing connected'), 1)] + nimmgr.satList
1095         
1096         longitude_orientation_choices = [("east", _("East")), ("west", _("West"))]
1097         latitude_orientation_choices = [("north", _("North")), ("south", _("South"))]
1098         turning_speed_choices = [("fast", _("Fast")), ("slow", _("Slow")), ("fast epoch", _("Fast epoch"))]
1099         
1100         advanced_satlist_choices = nimmgr.satList + [
1101                 (3601, _('All Satellites')+' 1', 1), (3602, _('All Satellites')+' 2', 1),
1102                 (3603, _('All Satellites')+' 3', 1), (3604, _('All Satellites')+' 4', 1)]
1103         advanced_lnb_choices = [("0", "not available")] + [(str(y), "LNB " + str(y)) for y in range(1, 33)]
1104         advanced_voltage_choices = [("polarization", _("Polarization")), ("13V", _("13 V")), ("18V", _("18 V"))]
1105         advanced_tonemode_choices = [("band", _("Band")), ("on", _("On")), ("off", _("Off"))]
1106         advanced_lnb_toneburst_choices = [("none", _("None")), ("A", _("A")), ("B", _("B"))]
1107         advanced_lnb_allsat_diseqcmode_choices = [("1_2", _("1.2"))]
1108         advanced_lnb_diseqcmode_choices = [("none", _("None")), ("1_0", _("1.0")), ("1_1", _("1.1")), ("1_2", _("1.2"))]
1109         advanced_lnb_commandOrder1_0_choices = [("ct", "committed, toneburst"), ("tc", "toneburst, committed")]
1110         advanced_lnb_commandOrder_choices = [
1111                 ("ct", "committed, toneburst"), ("tc", "toneburst, committed"),
1112                 ("cut", "committed, uncommitted, toneburst"), ("tcu", "toneburst, committed, uncommitted"),
1113                 ("uct", "uncommitted, committed, toneburst"), ("tuc", "toneburst, uncommitted, commmitted")]
1114         advanced_lnb_diseqc_repeat_choices = [("none", _("None")), ("one", _("One")), ("two", _("Two")), ("three", _("Three"))]
1115         advanced_lnb_fast_turning_btime = mktime(datetime(1970, 1, 1, 7, 0).timetuple());
1116         advanced_lnb_fast_turning_etime = mktime(datetime(1970, 1, 1, 19, 0).timetuple());
1117
1118         def configLOFChanged(configElement):
1119                 if configElement.value == "unicable":
1120                         x = configElement.slot_id
1121                         lnb = configElement.lnb_id
1122                         nim = config.Nims[x]
1123                         lnbs = nim.advanced.lnb
1124                         section = lnbs[lnb]
1125                         if isinstance(section.unicable, ConfigNothing):
1126                                 if lnb == 1:
1127                                         section.unicable = ConfigSelection(unicable_choices, unicable_choices_default)
1128                                 elif lnb == 2:
1129                                         section.unicable = ConfigSelection(choices = {"unicable_matrix": _("Unicable Martix"),"unicable_user": "Unicable "+_("User defined")}, default = "unicable_matrix")
1130                                 else:
1131                                         section.unicable = ConfigSelection(choices = {"unicable_user": _("User defined")}, default = "unicable_user")
1132
1133                                 def fillUnicableConf(sectionDict, unicableproducts, vco_null_check):
1134                                         for y in unicableproducts:
1135                                                 products = unicableproducts[y].keys()
1136                                                 products.sort()
1137                                                 tmp = ConfigSubsection()
1138                                                 tmp.product = ConfigSelection(choices = products, default = products[0])
1139                                                 tmp.scr = ConfigSubDict()
1140                                                 tmp.vco = ConfigSubDict()
1141                                                 tmp.lofl = ConfigSubDict()
1142                                                 tmp.lofh = ConfigSubDict()
1143                                                 tmp.loft = ConfigSubDict()
1144                                                 tmp.positions = ConfigSubDict()
1145                                                 for z in products:
1146                                                         scrlist = []
1147                                                         vcolist = unicableproducts[y][z]
1148                                                         tmp.vco[z] = ConfigSubList()
1149                                                         for cnt in range(1,1+len(vcolist)-1):
1150                                                                 vcofreq = int(vcolist[cnt-1])
1151                                                                 if vcofreq == 0 and vco_null_check:
1152                                                                         scrlist.append(("%d" %cnt,"SCR %d " %cnt +_("not used")))
1153                                                                 else:
1154                                                                         scrlist.append(("%d" %cnt,"SCR %d" %cnt))
1155                                                                 tmp.vco[z].append(ConfigInteger(default=vcofreq, limits = (vcofreq, vcofreq)))
1156                                                                 tmp.scr[z] = ConfigSelection(choices = scrlist, default = scrlist[0][0])
1157
1158                                                                 positions = int(vcolist[len(vcolist)-1][0])
1159                                                                 tmp.positions[z] = ConfigSubList()
1160                                                                 tmp.positions[z].append(ConfigInteger(default=positions, limits = (positions, positions)))
1161
1162                                                                 lofl = vcolist[len(vcolist)-1][1]
1163                                                                 tmp.lofl[z] = ConfigSubList()
1164                                                                 tmp.lofl[z].append(ConfigInteger(default=lofl, limits = (lofl, lofl)))
1165
1166                                                                 lofh = int(vcolist[len(vcolist)-1][2])
1167                                                                 tmp.lofh[z] = ConfigSubList()
1168                                                                 tmp.lofh[z].append(ConfigInteger(default=lofh, limits = (lofh, lofh)))
1169
1170                                                                 loft = int(vcolist[len(vcolist)-1][3])
1171                                                                 tmp.loft[z] = ConfigSubList()
1172                                                                 tmp.loft[z].append(ConfigInteger(default=loft, limits = (loft, loft)))
1173                                                 sectionDict[y] = tmp
1174
1175                                 if lnb < 3:
1176                                         print "MATRIX"
1177                                         section.unicableMatrix = ConfigSubDict()
1178                                         section.unicableMatrixManufacturer = ConfigSelection(UnicableMatrixManufacturers, UnicableMatrixManufacturers[0])
1179                                         fillUnicableConf(section.unicableMatrix, unicablematrixproducts, True)
1180
1181                                 if lnb < 2:
1182                                         print "LNB"
1183                                         section.unicableLnb = ConfigSubDict()
1184                                         section.unicableLnbManufacturer = ConfigSelection(UnicableLnbManufacturers, UnicableLnbManufacturers[0])
1185                                         fillUnicableConf(section.unicableLnb, unicablelnbproducts, False)
1186
1187 #TODO satpositions for satcruser
1188                                 section.satcruser = ConfigSelection(advanced_lnb_satcruser_choices, default="1")
1189                                 tmp = ConfigSubList()
1190                                 tmp.append(ConfigInteger(default=1284, limits = (950, 2150)))
1191                                 tmp.append(ConfigInteger(default=1400, limits = (950, 2150)))
1192                                 tmp.append(ConfigInteger(default=1516, limits = (950, 2150)))
1193                                 tmp.append(ConfigInteger(default=1632, limits = (950, 2150)))
1194                                 tmp.append(ConfigInteger(default=1748, limits = (950, 2150)))
1195                                 tmp.append(ConfigInteger(default=1864, limits = (950, 2150)))
1196                                 tmp.append(ConfigInteger(default=1980, limits = (950, 2150)))
1197                                 tmp.append(ConfigInteger(default=2096, limits = (950, 2150)))
1198                                 section.satcrvcouser = tmp 
1199
1200                                 nim.advanced.unicableconnected = ConfigYesNo(default=False)
1201                                 nim.advanced.unicableconnectedTo = ConfigSelection([(str(id), nimmgr.getNimDescription(id)) for id in nimmgr.getNimListOfType("DVB-S") if id != x])
1202         
1203         def configDiSEqCModeChanged(configElement):
1204                 section = configElement.section
1205                 if configElement.value == "1_2" and isinstance(section.longitude, ConfigNothing):
1206                         section.longitude = ConfigFloat(default = [5,100], limits = [(0,359),(0,999)])
1207                         section.longitudeOrientation = ConfigSelection(longitude_orientation_choices, "east")
1208                         section.latitude = ConfigFloat(default = [50,767], limits = [(0,359),(0,999)])
1209                         section.latitudeOrientation = ConfigSelection(latitude_orientation_choices, "north")
1210                         section.powerMeasurement = ConfigYesNo(default=True)
1211                         section.powerThreshold = ConfigInteger(default=hw.get_device_name() == "dm8000" and 15 or 50, limits=(0, 100))
1212                         section.turningSpeed = ConfigSelection(turning_speed_choices, "fast")
1213                         section.fastTurningBegin = ConfigDateTime(default=advanced_lnb_fast_turning_btime, formatstring = _("%H:%M"), increment = 600)
1214                         section.fastTurningEnd = ConfigDateTime(default=advanced_lnb_fast_turning_etime, formatstring = _("%H:%M"), increment = 600)
1215
1216         def configLNBChanged(configElement):
1217                 x = configElement.slot_id
1218                 nim = config.Nims[x]
1219                 if isinstance(configElement.value, tuple):
1220                         lnb = int(configElement.value[0])
1221                 else:
1222                         lnb = int(configElement.value)
1223                 lnbs = nim.advanced.lnb
1224                 if lnb and lnb not in lnbs:
1225                         section = lnbs[lnb] = ConfigSubsection()
1226                         section.lofl = ConfigInteger(default=9750, limits = (0, 99999))
1227                         section.lofh = ConfigInteger(default=10600, limits = (0, 99999))
1228                         section.threshold = ConfigInteger(default=11700, limits = (0, 99999))
1229 #                       section.output_12v = ConfigSelection(choices = [("0V", _("0 V")), ("12V", _("12 V"))], default="0V")
1230                         section.increased_voltage = ConfigYesNo(False)
1231                         section.toneburst = ConfigSelection(advanced_lnb_toneburst_choices, "none")
1232                         section.longitude = ConfigNothing()
1233                         if lnb > 32:
1234                                 tmp = ConfigSelection(advanced_lnb_allsat_diseqcmode_choices, "1_2")
1235                                 tmp.section = section
1236                                 configDiSEqCModeChanged(tmp)
1237                         else:
1238                                 tmp = ConfigSelection(advanced_lnb_diseqcmode_choices, "none")
1239                                 tmp.section = section
1240                                 tmp.addNotifier(configDiSEqCModeChanged)
1241                         section.diseqcMode = tmp
1242                         section.commitedDiseqcCommand = ConfigSelection(advanced_lnb_csw_choices)
1243                         section.fastDiseqc = ConfigYesNo(False)
1244                         section.sequenceRepeat = ConfigYesNo(False)
1245                         section.commandOrder1_0 = ConfigSelection(advanced_lnb_commandOrder1_0_choices, "ct")
1246                         section.commandOrder = ConfigSelection(advanced_lnb_commandOrder_choices, "ct")
1247                         section.uncommittedDiseqcCommand = ConfigSelection(advanced_lnb_ucsw_choices)
1248                         section.diseqcRepeats = ConfigSelection(advanced_lnb_diseqc_repeat_choices, "none")
1249                         section.prio = ConfigSelection(prio_list, "-1")
1250                         section.unicable = ConfigNothing()
1251                         tmp = ConfigSelection(lnb_choices, lnb_choices_default)
1252                         tmp.slot_id = x
1253                         tmp.lnb_id = lnb
1254                         tmp.addNotifier(configLOFChanged, initial_call = False)
1255                         section.lof = tmp
1256
1257         def configModeChanged(configMode):
1258                 slot_id = configMode.slot_id
1259                 nim = config.Nims[slot_id]
1260                 if configMode.value == "advanced" and isinstance(nim.advanced, ConfigNothing):
1261                         # advanced config:
1262                         nim.advanced = ConfigSubsection()
1263                         nim.advanced.sat = ConfigSubDict()
1264                         nim.advanced.sats = getConfigSatlist(192, advanced_satlist_choices)
1265                         nim.advanced.lnb = ConfigSubDict()
1266                         nim.advanced.lnb[0] = ConfigNothing()
1267                         for x in nimmgr.satList:
1268                                 tmp = ConfigSubsection()
1269                                 tmp.voltage = ConfigSelection(advanced_voltage_choices, "polarization")
1270                                 tmp.tonemode = ConfigSelection(advanced_tonemode_choices, "band")
1271                                 tmp.usals = ConfigYesNo(True)
1272                                 tmp.rotorposition = ConfigInteger(default=1, limits=(1, 255))
1273                                 lnb = ConfigSelection(advanced_lnb_choices, "0")
1274                                 lnb.slot_id = slot_id
1275                                 lnb.addNotifier(configLNBChanged, initial_call = False)
1276                                 tmp.lnb = lnb
1277                                 nim.advanced.sat[x[0]] = tmp
1278                         for x in range(3601, 3605):
1279                                 tmp = ConfigSubsection()
1280                                 tmp.voltage = ConfigSelection(advanced_voltage_choices, "polarization")
1281                                 tmp.tonemode = ConfigSelection(advanced_tonemode_choices, "band")
1282                                 tmp.usals = ConfigYesNo(default=True)
1283                                 tmp.rotorposition = ConfigInteger(default=1, limits=(1, 255))
1284                                 lnbnum = 33+x-3601
1285                                 lnb = ConfigSelection([("0", "not available"), (str(lnbnum), "LNB %d"%(lnbnum))], "0")
1286                                 lnb.slot_id = slot_id
1287                                 lnb.addNotifier(configLNBChanged, initial_call = False)
1288                                 tmp.lnb = lnb
1289                                 nim.advanced.sat[x] = tmp
1290
1291         def toneAmplitudeChanged(configElement):
1292                 fe_id = configElement.fe_id
1293                 slot_id = configElement.slot_id
1294                 if nimmgr.nim_slots[slot_id].description == 'Alps BSBE2':
1295                         open("/proc/stb/frontend/%d/tone_amplitude" %(fe_id), "w").write(configElement.value)
1296                         
1297         def tunerTypeChanged(nimmgr, configElement):
1298                 fe_id = configElement.fe_id
1299                 print "tunerTypeChanged feid %d to mode %s" % (fe_id, configElement.value)
1300                 try:
1301                         oldvalue = open("/sys/module/dvb_core/parameters/dvb_shutdown_timeout", "r").readline()
1302                         open("/sys/module/dvb_core/parameters/dvb_shutdown_timeout", "w").write("0")
1303                 except:
1304                         print "[info] no /sys/module/dvb_core/parameters/dvb_shutdown_timeout available"
1305                 frontend = eDVBResourceManager.getInstance().allocateRawChannel(fe_id).getFrontend()
1306                 frontend.closeFrontend()
1307                 open("/proc/stb/frontend/%d/mode" % (fe_id), "w").write(configElement.value)
1308                 frontend.reopenFrontend()
1309                 try:
1310                         open("/sys/module/dvb_core/parameters/dvb_shutdown_timeout", "w").write(oldvalue)
1311                 except:
1312                         print "[info] no /sys/module/dvb_core/parameters/dvb_shutdown_timeout available"
1313                 nimmgr.enumerateNIMs()
1314         
1315         empty_slots = 0
1316         for slot in nimmgr.nim_slots:
1317                 x = slot.slot
1318                 nim = config.Nims[x]
1319                 addMultiType = False
1320                 try:
1321                         nim.multiType
1322                 except:
1323                         addMultiType = True
1324                 if slot.isMultiType() and addMultiType:
1325                         typeList = []
1326                         for id in slot.getMultiTypeList().keys():
1327                                 type = slot.getMultiTypeList()[id]
1328                                 typeList.append((id, type))
1329                         nim.multiType = ConfigSelection(typeList, "0")
1330                         
1331                         nim.multiType.fe_id = x - empty_slots
1332                         nim.multiType.addNotifier(boundFunction(tunerTypeChanged, nimmgr))
1333                 
1334         empty_slots = 0
1335         for slot in nimmgr.nim_slots:
1336                 x = slot.slot
1337                 nim = config.Nims[x]
1338
1339                 if slot.isCompatible("DVB-S"):
1340                         nim.toneAmplitude = ConfigSelection([("9", "600mV"), ("8", "700mV"), ("7", "800mV"), ("6", "900mV"), ("5", "1100mV")], "7")
1341                         nim.toneAmplitude.fe_id = x - empty_slots
1342                         nim.toneAmplitude.slot_id = x
1343                         nim.toneAmplitude.addNotifier(toneAmplitudeChanged)
1344                         nim.diseqc13V = ConfigYesNo(False)
1345                         nim.diseqcMode = ConfigSelection(diseqc_mode_choices, "diseqc_a_b")
1346                         nim.connectedTo = ConfigSelection([(str(id), nimmgr.getNimDescription(id)) for id in nimmgr.getNimListOfType("DVB-S") if id != x])
1347                         nim.simpleSingleSendDiSEqC = ConfigYesNo(False)
1348                         nim.simpleDiSEqCSetVoltageTone = ConfigYesNo(True)
1349                         nim.simpleDiSEqCOnlyOnSatChange = ConfigYesNo(False)
1350                         nim.diseqcA = getConfigSatlist(192, diseqc_satlist_choices)
1351                         nim.diseqcB = getConfigSatlist(130, diseqc_satlist_choices)
1352                         nim.diseqcC = ConfigSatlist(list = diseqc_satlist_choices)
1353                         nim.diseqcD = ConfigSatlist(list = diseqc_satlist_choices)
1354                         nim.positionerMode = ConfigSelection(positioner_mode_choices, "usals")
1355                         nim.longitude = ConfigFloat(default=[5,100], limits=[(0,359),(0,999)])
1356                         nim.longitudeOrientation = ConfigSelection(longitude_orientation_choices, "east")
1357                         nim.latitude = ConfigFloat(default=[50,767], limits=[(0,359),(0,999)])
1358                         nim.latitudeOrientation = ConfigSelection(latitude_orientation_choices, "north")
1359                         nim.powerMeasurement = ConfigYesNo(True)
1360                         nim.powerThreshold = ConfigInteger(default=hw.get_device_name() == "dm8000" and 15 or 50, limits=(0, 100))
1361                         nim.turningSpeed = ConfigSelection(turning_speed_choices, "fast")
1362                         btime = datetime(1970, 1, 1, 7, 0);
1363                         nim.fastTurningBegin = ConfigDateTime(default = mktime(btime.timetuple()), formatstring = _("%H:%M"), increment = 900)
1364                         etime = datetime(1970, 1, 1, 19, 0);
1365                         nim.fastTurningEnd = ConfigDateTime(default = mktime(etime.timetuple()), formatstring = _("%H:%M"), increment = 900)
1366                         config_mode_choices = [ ("nothing", _("nothing connected")),
1367                                 ("simple", _("simple")), ("advanced", _("advanced"))]
1368                         if len(nimmgr.getNimListOfType(slot.type, exception = x)) > 0:
1369                                 config_mode_choices.append(("equal", _("equal to")))
1370                                 config_mode_choices.append(("satposdepends", _("second cable of motorized LNB")))
1371                         if len(nimmgr.canConnectTo(x)) > 0:
1372                                 config_mode_choices.append(("loopthrough", _("loopthrough to")))
1373                         nim.advanced = ConfigNothing()
1374                         tmp = ConfigSelection(config_mode_choices, "nothing")
1375                         tmp.slot_id = x
1376                         tmp.addNotifier(configModeChanged, initial_call = False)
1377                         nim.configMode = tmp
1378                 elif slot.isCompatible("DVB-C"):
1379                         nim.configMode = ConfigSelection(
1380                                 choices = {
1381                                         "enabled": _("enabled"),
1382                                         "nothing": _("nothing connected"),
1383                                         },
1384                                 default = "enabled")
1385                         list = [ ]
1386                         n = 0
1387                         for x in nimmgr.cablesList:
1388                                 list.append((str(n), x[0]))
1389                                 n += 1
1390                         nim.cable = ConfigSubsection()
1391                         possible_scan_types = [("bands", _("Frequency bands")), ("steps", _("Frequency steps"))]
1392                         if n:
1393                                 possible_scan_types.append(("provider", _("Provider")))
1394                                 nim.cable.scan_provider = ConfigSelection(default = "0", choices = list)
1395                         nim.cable.scan_type = ConfigSelection(default = "bands", choices = possible_scan_types)
1396                         nim.cable.scan_band_EU_VHF_I = ConfigYesNo(default = True)
1397                         nim.cable.scan_band_EU_MID = ConfigYesNo(default = True)
1398                         nim.cable.scan_band_EU_VHF_III = ConfigYesNo(default = True)
1399                         nim.cable.scan_band_EU_UHF_IV = ConfigYesNo(default = True)
1400                         nim.cable.scan_band_EU_UHF_V = ConfigYesNo(default = True)
1401                         nim.cable.scan_band_EU_SUPER = ConfigYesNo(default = True)
1402                         nim.cable.scan_band_EU_HYPER = ConfigYesNo(default = True)
1403                         nim.cable.scan_band_US_LOW = ConfigYesNo(default = False)
1404                         nim.cable.scan_band_US_MID = ConfigYesNo(default = False)
1405                         nim.cable.scan_band_US_HIGH = ConfigYesNo(default = False)
1406                         nim.cable.scan_band_US_SUPER = ConfigYesNo(default = False)
1407                         nim.cable.scan_band_US_HYPER = ConfigYesNo(default = False)
1408                         nim.cable.scan_frequency_steps = ConfigInteger(default = 1000, limits = (1000, 10000))
1409                         nim.cable.scan_mod_qam16 = ConfigYesNo(default = False)
1410                         nim.cable.scan_mod_qam32 = ConfigYesNo(default = False)
1411                         nim.cable.scan_mod_qam64 = ConfigYesNo(default = True)
1412                         nim.cable.scan_mod_qam128 = ConfigYesNo(default = False)
1413                         nim.cable.scan_mod_qam256 = ConfigYesNo(default = True)
1414                         nim.cable.scan_sr_6900 = ConfigYesNo(default = True)
1415                         nim.cable.scan_sr_6875 = ConfigYesNo(default = True)
1416                         nim.cable.scan_sr_ext1 = ConfigInteger(default = 0, limits = (0, 7230))
1417                         nim.cable.scan_sr_ext2 = ConfigInteger(default = 0, limits = (0, 7230))
1418                 elif slot.isCompatible("DVB-T"):
1419                         nim.configMode = ConfigSelection(
1420                                 choices = {
1421                                         "enabled": _("enabled"),
1422                                         "nothing": _("nothing connected"),
1423                                         },
1424                                 default = "enabled")
1425                         list = []
1426                         n = 0
1427                         for x in nimmgr.terrestrialsList:
1428                                 list.append((str(n), x[0]))
1429                                 n += 1
1430                         nim.terrestrial = ConfigSelection(choices = list)
1431                         nim.terrestrial_5V = ConfigOnOff()
1432                 else:
1433                         empty_slots += 1
1434                         nim.configMode = ConfigSelection(choices = { "nothing": _("disabled") }, default="nothing");
1435                         if slot.type is not None:
1436                                 print "pls add support for this frontend type!", slot.type
1437 #                       assert False
1438
1439         nimmgr.sec = SecConfigure(nimmgr)
1440
1441 nimmanager = NimManager()