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