Merge branch 'bug_587_new_internally_connectable_and_unsupported_tuner_management...
[vuplus_dvbapp] / 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, i2c = None):
485
486                 self.slot = slot
487
488                 if type not in ("DVB-S", "DVB-C", "DVB-T", "DVB-S2", None):
489                         print "warning: unknown NIM type %s, not using." % type
490                         type = None
491
492                 self.type = type
493                 self.description = description
494                 self.has_outputs = has_outputs
495                 self.internally_connectable = internally_connectable
496                 self.multi_type = multi_type
497                 self.i2c = i2c
498                 self.frontend_id = frontend_id
499
500         def isCompatible(self, what):
501                 if not self.isSupported():
502                         return False
503                 compatible = {
504                                 None: (None,),
505                                 "DVB-S": ("DVB-S", None),
506                                 "DVB-C": ("DVB-C", None),
507                                 "DVB-T": ("DVB-T", None),
508                                 "DVB-S2": ("DVB-S", "DVB-S2", None)
509                         }
510                 return what in compatible[self.type]
511         
512         def getType(self):
513                 return self.type
514         
515         def connectableTo(self):
516                 connectable = {
517                                 "DVB-S": ("DVB-S", "DVB-S2"),
518                                 "DVB-C": ("DVB-C",),
519                                 "DVB-T": ("DVB-T",),
520                                 "DVB-S2": ("DVB-S", "DVB-S2")
521                         }
522                 return connectable[self.type]
523
524         def getSlotName(self):
525                 # get a friendly description for a slot name.
526                 # we name them "Tuner A/B/C/...", because that's what's usually written on the back
527                 # of the device.
528                 return _("Tuner ") + chr(ord('A') + self.slot)
529
530         slot_name = property(getSlotName)
531
532         def getSlotID(self):
533                 return chr(ord('A') + self.slot)
534         
535         def getI2C(self):
536                 return self.i2c
537         
538         def hasOutputs(self):
539                 return self.has_outputs
540         
541         def internallyConnectableTo(self):
542                 return self.internally_connectable
543         
544         def setInternalLink(self):
545                 if self.internally_connectable is not None:
546                         print "setting internal link on frontend id", self.frontend_id
547                         open("/proc/stb/frontend/%d/rf_switch" % self.frontend_id, "w").write("internal")
548                 
549         def removeInternalLink(self):
550                 if self.internally_connectable is not None:
551                         print "removing internal link on frontend id", self.frontend_id
552                         open("/proc/stb/frontend/%d/rf_switch" % self.frontend_id, "w").write("external")
553         
554         def isMultiType(self):
555                 return (len(self.multi_type) > 0)
556         
557         def isSupported(self):
558                 return (self.frontend_id is not None)
559         
560         # returns dict {<slotid>: <type>}
561         def getMultiTypeList(self):
562                 return self.multi_type
563
564         slot_id = property(getSlotID)
565
566         def getFriendlyType(self):
567                 return {
568                         "DVB-S": "DVB-S", 
569                         "DVB-T": "DVB-T",
570                         "DVB-S2": "DVB-S2",
571                         "DVB-C": "DVB-C",
572                         None: _("empty")
573                         }[self.type]
574
575         friendly_type = property(getFriendlyType)
576
577         def getFriendlyFullDescription(self):
578                 nim_text = self.slot_name + ": "
579                         
580                 if self.empty:
581                         nim_text += _("(empty)")
582                 elif not self.isSupported():
583                         nim_text += self.description + " (" + _("not supported") + ")"
584                 else:
585                         nim_text += self.description + " (" + self.friendly_type + ")"
586                 
587                 return nim_text
588
589         friendly_full_description = property(getFriendlyFullDescription)
590         config_mode = property(lambda self: config.Nims[self.slot].configMode.value)
591         config = property(lambda self: config.Nims[self.slot])
592         empty = property(lambda self: self.type is None)
593
594 class NimManager:
595         def getConfiguredSats(self):
596                 return self.sec.getConfiguredSats()
597
598         def getTransponders(self, pos):
599                 if self.transponders.has_key(pos):
600                         return self.transponders[pos]
601                 else:
602                         return []
603
604         def getTranspondersCable(self, nim):
605                 nimConfig = config.Nims[nim]
606                 if nimConfig.configMode.value != "nothing" and nimConfig.cable.scan_type.value == "provider":
607                         return self.transponderscable[self.cablesList[nimConfig.cable.scan_provider.index][0]]
608                 return [ ]
609
610         def getTranspondersTerrestrial(self, region):
611                 return self.transpondersterrestrial[region]
612         
613         def getCableDescription(self, nim):
614                 return self.cablesList[config.Nims[nim].scan_provider.index][0]
615
616         def getCableFlags(self, nim):
617                 return self.cablesList[config.Nims[nim].scan_provider.index][1]
618
619         def getTerrestrialDescription(self, nim):
620                 return self.terrestrialsList[config.Nims[nim].terrestrial.index][0]
621
622         def getTerrestrialFlags(self, nim):
623                 return self.terrestrialsList[config.Nims[nim].terrestrial.index][1]
624
625         def getSatDescription(self, pos):
626                 return self.satellites[pos]
627
628         def sortFunc(self, x):
629                 orbpos = x[0]
630                 if orbpos > 1800:
631                         return orbpos - 3600
632                 else:
633                         return orbpos + 1800
634
635         def readTransponders(self):
636                 # read initial networks from file. we only read files which we are interested in,
637                 # which means only these where a compatible tuner exists.
638                 self.satellites = { }
639                 self.transponders = { }
640                 self.transponderscable = { }
641                 self.transpondersterrestrial = { }
642                 db = eDVBDB.getInstance()
643                 if self.hasNimType("DVB-S"):
644                         print "Reading satellites.xml"
645                         db.readSatellites(self.satList, self.satellites, self.transponders)
646                         self.satList.sort(key = self.sortFunc) # sort by orbpos
647                         #print "SATLIST", self.satList
648                         #print "SATS", self.satellites
649                         #print "TRANSPONDERS", self.transponders
650
651                 if self.hasNimType("DVB-C"):
652                         print "Reading cables.xml"
653                         db.readCables(self.cablesList, self.transponderscable)
654 #                       print "CABLIST", self.cablesList
655 #                       print "TRANSPONDERS", self.transponders
656
657                 if self.hasNimType("DVB-T"):
658                         print "Reading terrestrial.xml"
659                         db.readTerrestrials(self.terrestrialsList, self.transpondersterrestrial)
660 #                       print "TERLIST", self.terrestrialsList
661 #                       print "TRANSPONDERS", self.transpondersterrestrial
662
663         def enumerateNIMs(self):
664                 # enum available NIMs. This is currently very dreambox-centric and uses the /proc/bus/nim_sockets interface.
665                 # the result will be stored into nim_slots.
666                 # the content of /proc/bus/nim_sockets looks like:
667                 # NIM Socket 0:
668                 #          Type: DVB-S
669                 #          Name: BCM4501 DVB-S2 NIM (internal)
670                 # NIM Socket 1:
671                 #          Type: DVB-S
672                 #          Name: BCM4501 DVB-S2 NIM (internal)
673                 # NIM Socket 2:
674                 #          Type: DVB-T
675                 #          Name: Philips TU1216
676                 # NIM Socket 3:
677                 #          Type: DVB-S
678                 #          Name: Alps BSBE1 702A
679                 
680                 #
681                 # Type will be either "DVB-S", "DVB-S2", "DVB-T", "DVB-C" or None.
682
683                 # nim_slots is an array which has exactly one entry for each slot, even for empty ones.
684                 self.nim_slots = [ ]
685
686                 nimfile = tryOpen("/proc/bus/nim_sockets")
687
688                 if nimfile is None:
689                         return
690
691                 current_slot = None
692
693                 entries = {}
694                 for line in nimfile.readlines():
695                         if line == "":
696                                 break
697                         if line.strip().startswith("NIM Socket"):
698                                 parts = line.strip().split(" ")
699                                 current_slot = int(parts[2][:-1])
700                                 entries[current_slot] = {}
701                         elif line.strip().startswith("Type:"):
702                                 entries[current_slot]["type"] = str(line.strip()[6:])
703                         elif line.strip().startswith("Name:"):
704                                 entries[current_slot]["name"] = str(line.strip()[6:])
705                         elif line.strip().startswith("Has_Outputs:"):
706                                 input = str(line.strip()[len("Has_Outputs:") + 1:])
707                                 entries[current_slot]["has_outputs"] = (input == "yes")
708                         elif line.strip().startswith("Internally_Connectable:"):
709                                 input = int(line.strip()[len("Internally_Connectable:") + 1:])
710                                 entries[current_slot]["internally_connectable"] = input
711                         elif line.strip().startswith("Frontend_Device:"):
712                                 input = int(line.strip()[len("Frontend_Device:") + 1:])
713                                 entries[current_slot]["frontend_device"] = input
714                         elif  line.strip().startswith("Mode"):
715                                 # "Mode 0: DVB-T" -> ["Mode 0", " DVB-T"]
716                                 split = line.strip().split(":")
717                                 # "Mode 0" -> ["Mode, "0"]
718                                 split2 = split[0].split(" ")
719                                 modes = entries[current_slot].get("multi_type", {})
720                                 modes[split2[1]] = split[1].strip()
721                                 entries[current_slot]["multi_type"] = modes
722                         elif line.strip().startswith("I2C_Device:"):
723                                 input = int(line.strip()[len("I2C_Device:") + 1:])
724                                 entries[current_slot]["i2c"] = input
725                         elif line.strip().startswith("empty"):
726                                 entries[current_slot]["type"] = None
727                                 entries[current_slot]["name"] = _("N/A")
728                 nimfile.close()
729                 
730                 from os import path
731                 
732                 for id, entry in entries.items():
733                         if not (entry.has_key("name") and entry.has_key("type")):
734                                 entry["name"] =  _("N/A")
735                                 entry["type"] = None
736                         if not (entry.has_key("i2c")):
737                                 entry["i2c"] = None
738                         if not (entry.has_key("has_outputs")):
739                                 entry["has_outputs"] = True
740                         if entry.has_key("frontend_device"): # check if internally connectable
741                                 if path.exists("/proc/stb/frontend/%d/rf_switch" % entry["frontend_device"]):
742                                         entry["internally_connectable"] = entry["frontend_device"] - 1
743                                 else:
744                                         entry["internally_connectable"] = None
745                         else:
746                                 entry["frontend_device"] = entry["internally_connectable"] = None
747                         if not (entry.has_key("multi_type")):
748                                 entry["multi_type"] = {}
749                         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"], i2c = entry["i2c"]))
750
751
752         def hasNimType(self, chktype):
753                 for slot in self.nim_slots:
754                         if slot.isCompatible(chktype):
755                                 return True
756                         for type in slot.getMultiTypeList().values():
757                                 if chktype == type:
758                                         return True
759                 return False
760         
761         def getNimType(self, slotid):
762                 return self.nim_slots[slotid].type
763         
764         def getNimDescription(self, slotid):
765                 return self.nim_slots[slotid].friendly_full_description
766         
767         def getNimName(self, slotid):
768                 return self.nim_slots[slotid].description
769         
770         def getNim(self, slotid):
771                 return self.nim_slots[slotid]
772
773         def getNimListOfType(self, type, exception = -1):
774                 # returns a list of indexes for NIMs compatible to the given type, except for 'exception'
775                 list = []
776                 for x in self.nim_slots:
777                         if x.isCompatible(type) and x.slot != exception:
778                                 list.append(x.slot)
779                 return list
780
781         def __init__(self):
782                 self.satList = [ ]
783                 self.cablesList = []
784                 self.terrestrialsList = []
785                 self.enumerateNIMs()
786                 self.readTransponders()
787                 InitNimManager(self)    #init config stuff
788
789         # get a list with the friendly full description
790         def nimList(self):
791                 list = [ ]
792                 for slot in self.nim_slots:
793                         list.append(slot.friendly_full_description)
794                 return list
795         
796         def getSlotCount(self):
797                 return len(self.nim_slots)
798         
799         def hasOutputs(self, slotid):
800                 return self.nim_slots[slotid].hasOutputs()
801         
802         def nimInternallyConnectableTo(self, slotid):
803                 return self.nim_slots[slotid].internallyConnectableTo()
804         
805         def nimRemoveInternalLink(self, slotid):
806                 self.nim_slots[slotid].removeInternalLink()
807         
808         def canConnectTo(self, slotid):
809                 slots = []
810                 if self.nim_slots[slotid].internallyConnectableTo() is not None:
811                         slots.append(self.nim_slots[slotid].internallyConnectableTo())
812                 for type in self.nim_slots[slotid].connectableTo(): 
813                         for slot in self.getNimListOfType(type, exception = slotid):
814                                 if self.hasOutputs(slot):
815                                         slots.append(slot)
816                 # remove nims, that have a conntectedTo reference on
817                 for testnim in slots[:]:
818                         for nim in self.getNimListOfType("DVB-S", slotid):
819                                 nimConfig = self.getNimConfig(nim)
820                                 if nimConfig.content.items.has_key("configMode") and nimConfig.configMode.value == "loopthrough" and int(nimConfig.connectedTo.value) == testnim:
821                                         slots.remove(testnim)
822                                         break 
823                 slots.sort()
824                 
825                 return slots
826         
827         def canEqualTo(self, slotid):
828                 type = self.getNimType(slotid)
829                 if type == "DVB-S2":
830                         type = "DVB-S"
831                 nimList = self.getNimListOfType(type, slotid)
832                 for nim in nimList[:]:
833                         mode = self.getNimConfig(nim)
834                         if mode.configMode.value == "loopthrough" or mode.configMode.value == "satposdepends":
835                                 nimList.remove(nim)
836                 return nimList
837
838         def canDependOn(self, slotid):
839                 type = self.getNimType(slotid)
840                 if type == "DVB-S2":
841                         type = "DVB-S"
842                 nimList = self.getNimListOfType(type, slotid)
843                 positionerList = []
844                 for nim in nimList[:]:
845                         mode = self.getNimConfig(nim)
846                         nimHaveRotor = mode.configMode.value == "simple" and mode.diseqcMode.value == "positioner"
847                         if not nimHaveRotor and mode.configMode.value == "advanced":
848                                 for x in range(3601, 3605):
849                                         lnb = int(mode.advanced.sat[x].lnb.value)
850                                         if lnb != 0:
851                                                 nimHaveRotor = True
852                                                 break
853                                 if not nimHaveRotor:
854                                         for sat in mode.advanced.sat.values():
855                                                 lnb_num = int(sat.lnb.value)
856                                                 diseqcmode = lnb_num and mode.advanced.lnb[lnb_num].diseqcMode.value or ""
857                                                 if diseqcmode == "1_2":
858                                                         nimHaveRotor = True
859                                                         break
860                         if nimHaveRotor:
861                                 alreadyConnected = False
862                                 for testnim in nimList:
863                                         testmode = self.getNimConfig(testnim)
864                                         if testmode.configMode.value == "satposdepends" and int(testmode.connectedTo.value) == int(nim):
865                                                 alreadyConnected = True
866                                                 break
867                                 if not alreadyConnected:
868                                         positionerList.append(nim)
869                 return positionerList
870         
871         def getNimConfig(self, slotid):
872                 return config.Nims[slotid]
873         
874         def getSatName(self, pos):
875                 for sat in self.satList:
876                         if sat[0] == pos:
877                                 return sat[1]
878                 return _("N/A")
879
880         def getSatList(self):
881                 return self.satList
882         
883         # returns True if something is configured to be connected to this nim
884         # if slotid == -1, returns if something is connected to ANY nim
885         def somethingConnected(self, slotid = -1):
886                 if (slotid == -1):
887                         connected = False
888                         for id in range(self.getSlotCount()):
889                                 if self.somethingConnected(id):
890                                         connected = True
891                         return connected
892                 else:
893                         nim = config.Nims[slotid]
894                         configMode = nim.configMode.value
895                 
896                         if self.nim_slots[slotid].isCompatible("DVB-S") or self.nim_slots[slotid].isCompatible("DVB-T") or self.nim_slots[slotid].isCompatible("DVB-C"):
897                                 return not (configMode == "nothing")            
898
899         def getSatListForNim(self, slotid):
900                 list = []
901                 if self.nim_slots[slotid].isCompatible("DVB-S"):
902                         nim = config.Nims[slotid]
903                         #print "slotid:", slotid
904
905                         #print "self.satellites:", self.satList[config.Nims[slotid].diseqcA.index]
906                         #print "diseqcA:", config.Nims[slotid].diseqcA.value
907                         configMode = nim.configMode.value
908
909                         if configMode == "equal":
910                                 slotid = int(nim.connectedTo.value)
911                                 nim = config.Nims[slotid]
912                                 configMode = nim.configMode.value
913                         elif configMode == "loopthrough":
914                                 slotid = self.sec.getRoot(slotid, int(nim.connectedTo.value))
915                                 nim = config.Nims[slotid]
916                                 configMode = nim.configMode.value
917
918                         if configMode == "simple":
919                                 dm = nim.diseqcMode.value
920                                 if dm in ("single", "toneburst_a_b", "diseqc_a_b", "diseqc_a_b_c_d"):
921                                         if nim.diseqcA.orbital_position != 3601:
922                                                 list.append(self.satList[nim.diseqcA.index-1])
923                                 if dm in ("toneburst_a_b", "diseqc_a_b", "diseqc_a_b_c_d"):
924                                         if nim.diseqcB.orbital_position != 3601:
925                                                 list.append(self.satList[nim.diseqcB.index-1])
926                                 if dm == "diseqc_a_b_c_d":
927                                         if nim.diseqcC.orbital_position != 3601:
928                                                 list.append(self.satList[nim.diseqcC.index-1])
929                                         if nim.diseqcD.orbital_position != 3601:
930                                                 list.append(self.satList[nim.diseqcD.index-1])
931                                 if dm == "positioner":
932                                         for x in self.satList:
933                                                 list.append(x)
934                         elif configMode == "advanced":
935                                 for x in range(3601, 3605):
936                                         if int(nim.advanced.sat[x].lnb.value) != 0:
937                                                 for x in self.satList:
938                                                         list.append(x)
939                                 if not list:
940                                         for x in self.satList:
941                                                 if int(nim.advanced.sat[x[0]].lnb.value) != 0:
942                                                         list.append(x)
943                 return list
944
945         def getRotorSatListForNim(self, slotid):
946                 list = []
947                 if self.nim_slots[slotid].isCompatible("DVB-S"):
948                         #print "slotid:", slotid
949                         #print "self.satellites:", self.satList[config.Nims[slotid].diseqcA.value]
950                         #print "diseqcA:", config.Nims[slotid].diseqcA.value
951                         configMode = config.Nims[slotid].configMode.value
952                         if configMode == "simple":
953                                 if config.Nims[slotid].diseqcMode.value == "positioner":
954                                         for x in self.satList:
955                                                 list.append(x)
956                         elif configMode == "advanced":
957                                 nim = config.Nims[slotid]
958                                 for x in range(3601, 3605):
959                                         if int(nim.advanced.sat[x].lnb.value) != 0:
960                                                 for x in self.satList:
961                                                         list.append(x)
962                                 if not list:
963                                         for x in self.satList:
964                                                 lnbnum = int(nim.advanced.sat[x[0]].lnb.value)
965                                                 if lnbnum != 0:
966                                                         lnb = nim.advanced.lnb[lnbnum]
967                                                         if lnb.diseqcMode.value == "1_2":
968                                                                 list.append(x)
969                 return list
970
971 def InitSecParams():
972         config.sec = ConfigSubsection()
973
974         x = ConfigInteger(default=25, limits = (0, 9999))
975         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_CONT_TONE_DISABLE_BEFORE_DISEQC, configElement.value))
976         config.sec.delay_after_continuous_tone_disable_before_diseqc = x
977
978         x = ConfigInteger(default=10, limits = (0, 9999))
979         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_FINAL_CONT_TONE_CHANGE, configElement.value))
980         config.sec.delay_after_final_continuous_tone_change = x
981
982         x = ConfigInteger(default=10, limits = (0, 9999))
983         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_FINAL_VOLTAGE_CHANGE, configElement.value))
984         config.sec.delay_after_final_voltage_change = x
985
986         x = ConfigInteger(default=120, limits = (0, 9999))
987         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_BETWEEN_DISEQC_REPEATS, configElement.value))
988         config.sec.delay_between_diseqc_repeats = x
989
990         x = ConfigInteger(default=50, limits = (0, 9999))
991         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_LAST_DISEQC_CMD, configElement.value))
992         config.sec.delay_after_last_diseqc_command = x
993
994         x = ConfigInteger(default=50, limits = (0, 9999))
995         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_TONEBURST, configElement.value))
996         config.sec.delay_after_toneburst = x
997
998         x = ConfigInteger(default=20, limits = (0, 9999))
999         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_SWITCH_CMDS, configElement.value))
1000         config.sec.delay_after_change_voltage_before_switch_command = x
1001
1002         x = ConfigInteger(default=200, limits = (0, 9999))
1003         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_ENABLE_VOLTAGE_BEFORE_SWITCH_CMDS, configElement.value))
1004         config.sec.delay_after_enable_voltage_before_switch_command = x
1005
1006         x = ConfigInteger(default=700, limits = (0, 9999))
1007         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_BETWEEN_SWITCH_AND_MOTOR_CMD, configElement.value))
1008         config.sec.delay_between_switch_and_motor_command = x
1009
1010         x = ConfigInteger(default=500, limits = (0, 9999))
1011         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_MEASURE_IDLE_INPUTPOWER, configElement.value))
1012         config.sec.delay_after_voltage_change_before_measure_idle_inputpower = x
1013
1014         x = ConfigInteger(default=900, limits = (0, 9999))
1015         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_ENABLE_VOLTAGE_BEFORE_MOTOR_CMD, configElement.value))
1016         config.sec.delay_after_enable_voltage_before_motor_command = x
1017
1018         x = ConfigInteger(default=500, limits = (0, 9999))
1019         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_MOTOR_STOP_CMD, configElement.value))
1020         config.sec.delay_after_motor_stop_command = x
1021
1022         x = ConfigInteger(default=500, limits = (0, 9999))
1023         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_MOTOR_CMD, configElement.value))
1024         config.sec.delay_after_voltage_change_before_motor_command = x
1025
1026         x = ConfigInteger(default=70, limits = (0, 9999))
1027         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_BEFORE_SEQUENCE_REPEAT, configElement.value))
1028         config.sec.delay_before_sequence_repeat = x
1029
1030         x = ConfigInteger(default=360, limits = (0, 9999))
1031         x.addNotifier(lambda configElement: secClass.setParam(secClass.MOTOR_RUNNING_TIMEOUT, configElement.value))
1032         config.sec.motor_running_timeout = x
1033
1034         x = ConfigInteger(default=1, limits = (0, 5))
1035         x.addNotifier(lambda configElement: secClass.setParam(secClass.MOTOR_COMMAND_RETRIES, configElement.value))
1036         config.sec.motor_command_retries = x
1037
1038         x = ConfigInteger(default=50, limits = (0, 9999))
1039         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_DISEQC_RESET_CMD, configElement.value))
1040         config.sec.delay_after_diseqc_reset_cmd = x
1041
1042         x = ConfigInteger(default=150, limits = (0, 9999))
1043         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_DISEQC_PERIPHERIAL_POWERON_CMD, configElement.value))
1044         config.sec.delay_after_diseqc_peripherial_poweron_cmd = x
1045
1046 # TODO add support for satpos depending nims to advanced nim configuration
1047 # so a second/third/fourth cable from a motorized lnb can used behind a
1048 # diseqc 1.0 / diseqc 1.1 / toneburst switch
1049 # the C(++) part should can handle this
1050 # the configElement should be only visible when diseqc 1.2 is disabled
1051
1052 def InitNimManager(nimmgr):
1053         hw = HardwareInfo()
1054         addNimConfig = False
1055         try:
1056                 config.Nims
1057         except:
1058                 addNimConfig = True
1059
1060         if addNimConfig:
1061                 InitSecParams()
1062                 config.Nims = ConfigSubList()
1063                 for x in range(len(nimmgr.nim_slots)):
1064                         config.Nims.append(ConfigSubsection())
1065
1066         lnb_choices = {
1067                 "universal_lnb": _("Universal LNB"),
1068                 "unicable": _("Unicable"),
1069                 "c_band": _("C-Band"),
1070                 "user_defined": _("User defined")}
1071
1072         lnb_choices_default = "universal_lnb"
1073
1074         unicablelnbproducts = {}
1075         unicablematrixproducts = {}
1076         doc = xml.etree.cElementTree.parse("/usr/share/enigma2/unicable.xml")
1077         root = doc.getroot()
1078
1079         entry = root.find("lnb")
1080         for manufacturer in entry.getchildren():
1081                 m={}
1082                 for product in manufacturer.getchildren():
1083                         scr=[]
1084                         lscr=("scr1","scr2","scr3","scr4","scr5","scr6","scr7","scr8")
1085                         for i in range(len(lscr)):
1086                                 scr.append(product.get(lscr[i],"0"))
1087                         for i in range(len(lscr)):
1088                                 if scr[len(lscr)-i-1] == "0":
1089                                         scr.pop()
1090                                 else:
1091                                         break;
1092                         lof=[]
1093                         lof.append(int(product.get("positions",1)))
1094                         lof.append(int(product.get("lofl",9750)))
1095                         lof.append(int(product.get("lofh",10600)))
1096                         lof.append(int(product.get("threshold",11700)))
1097                         scr.append(tuple(lof))
1098                         m.update({product.get("name"):tuple(scr)})
1099                 unicablelnbproducts.update({manufacturer.get("name"):m})
1100
1101         entry = root.find("matrix")
1102         for manufacturer in entry.getchildren():
1103                 m={}
1104                 for product in manufacturer.getchildren():
1105                         scr=[]
1106                         lscr=("scr1","scr2","scr3","scr4","scr5","scr6","scr7","scr8")
1107                         for i in range(len(lscr)):
1108                                 scr.append(product.get(lscr[i],"0"))
1109                         for i in range(len(lscr)):
1110                                 if scr[len(lscr)-i-1] == "0":
1111                                         scr.pop()
1112                                 else:
1113                                         break;
1114                         lof=[]
1115                         lof.append(int(product.get("positions",1)))
1116                         lof.append(int(product.get("lofl",9750)))
1117                         lof.append(int(product.get("lofh",10600)))
1118                         lof.append(int(product.get("threshold",11700)))
1119                         scr.append(tuple(lof))
1120                         m.update({product.get("name"):tuple(scr)})
1121                 unicablematrixproducts.update({manufacturer.get("name"):m})
1122
1123         UnicableLnbManufacturers = unicablelnbproducts.keys()
1124         UnicableLnbManufacturers.sort()
1125         UnicableMatrixManufacturers = unicablematrixproducts.keys()
1126         UnicableMatrixManufacturers.sort()
1127
1128         unicable_choices = {
1129                 "unicable_lnb": _("Unicable LNB"),
1130                 "unicable_matrix": _("Unicable Martix"),
1131                 "unicable_user": "Unicable "+_("User defined")}
1132         unicable_choices_default = "unicable_lnb"
1133
1134         advanced_lnb_satcruser_choices = [ ("1", "SatCR 1"), ("2", "SatCR 2"), ("3", "SatCR 3"), ("4", "SatCR 4"),
1135                                         ("5", "SatCR 5"), ("6", "SatCR 6"), ("7", "SatCR 7"), ("8", "SatCR 8")]
1136
1137         prio_list = [ ("-1", _("Auto")) ]
1138         prio_list += [(str(prio), str(prio)) for prio in range(65)+range(14000,14065)+range(19000,19065)]
1139
1140         advanced_lnb_csw_choices = [("none", _("None")), ("AA", _("AA")), ("AB", _("AB")), ("BA", _("BA")), ("BB", _("BB"))]
1141         advanced_lnb_csw_choices += [(str(0xF0|y), "Input " + str(y+1)) for y in range(0, 16)]
1142
1143         advanced_lnb_ucsw_choices = [("0", _("None"))] + [(str(y), "Input " + str(y)) for y in range(1, 17)]
1144
1145         diseqc_mode_choices = [
1146                 ("single", _("Single")), ("toneburst_a_b", _("Toneburst A/B")),
1147                 ("diseqc_a_b", _("DiSEqC A/B")), ("diseqc_a_b_c_d", _("DiSEqC A/B/C/D")),
1148                 ("positioner", _("Positioner"))]
1149
1150         positioner_mode_choices = [("usals", _("USALS")), ("manual", _("manual"))]
1151
1152         diseqc_satlist_choices = [(3601, _('nothing connected'), 1)] + nimmgr.satList
1153         
1154         longitude_orientation_choices = [("east", _("East")), ("west", _("West"))]
1155         latitude_orientation_choices = [("north", _("North")), ("south", _("South"))]
1156         turning_speed_choices = [("fast", _("Fast")), ("slow", _("Slow")), ("fast epoch", _("Fast epoch"))]
1157         
1158         advanced_satlist_choices = nimmgr.satList + [
1159                 (3601, _('All Satellites')+' 1', 1), (3602, _('All Satellites')+' 2', 1),
1160                 (3603, _('All Satellites')+' 3', 1), (3604, _('All Satellites')+' 4', 1)]
1161         advanced_lnb_choices = [("0", "not available")] + [(str(y), "LNB " + str(y)) for y in range(1, 33)]
1162         advanced_voltage_choices = [("polarization", _("Polarization")), ("13V", _("13 V")), ("18V", _("18 V"))]
1163         advanced_tonemode_choices = [("band", _("Band")), ("on", _("On")), ("off", _("Off"))]
1164         advanced_lnb_toneburst_choices = [("none", _("None")), ("A", _("A")), ("B", _("B"))]
1165         advanced_lnb_allsat_diseqcmode_choices = [("1_2", _("1.2"))]
1166         advanced_lnb_diseqcmode_choices = [("none", _("None")), ("1_0", _("1.0")), ("1_1", _("1.1")), ("1_2", _("1.2"))]
1167         advanced_lnb_commandOrder1_0_choices = [("ct", "committed, toneburst"), ("tc", "toneburst, committed")]
1168         advanced_lnb_commandOrder_choices = [
1169                 ("ct", "committed, toneburst"), ("tc", "toneburst, committed"),
1170                 ("cut", "committed, uncommitted, toneburst"), ("tcu", "toneburst, committed, uncommitted"),
1171                 ("uct", "uncommitted, committed, toneburst"), ("tuc", "toneburst, uncommitted, commmitted")]
1172         advanced_lnb_diseqc_repeat_choices = [("none", _("None")), ("one", _("One")), ("two", _("Two")), ("three", _("Three"))]
1173         advanced_lnb_fast_turning_btime = mktime(datetime(1970, 1, 1, 7, 0).timetuple());
1174         advanced_lnb_fast_turning_etime = mktime(datetime(1970, 1, 1, 19, 0).timetuple());
1175
1176         def configLOFChanged(configElement):
1177                 if configElement.value == "unicable":
1178                         x = configElement.slot_id
1179                         lnb = configElement.lnb_id
1180                         nim = config.Nims[x]
1181                         lnbs = nim.advanced.lnb
1182                         section = lnbs[lnb]
1183                         if isinstance(section.unicable, ConfigNothing):
1184                                 if lnb == 1:
1185                                         section.unicable = ConfigSelection(unicable_choices, unicable_choices_default)
1186                                 elif lnb == 2:
1187                                         section.unicable = ConfigSelection(choices = {"unicable_matrix": _("Unicable Martix"),"unicable_user": "Unicable "+_("User defined")}, default = "unicable_matrix")
1188                                 else:
1189                                         section.unicable = ConfigSelection(choices = {"unicable_user": _("User defined")}, default = "unicable_user")
1190
1191                                 def fillUnicableConf(sectionDict, unicableproducts, vco_null_check):
1192                                         for y in unicableproducts:
1193                                                 products = unicableproducts[y].keys()
1194                                                 products.sort()
1195                                                 tmp = ConfigSubsection()
1196                                                 tmp.product = ConfigSelection(choices = products, default = products[0])
1197                                                 tmp.scr = ConfigSubDict()
1198                                                 tmp.vco = ConfigSubDict()
1199                                                 tmp.lofl = ConfigSubDict()
1200                                                 tmp.lofh = ConfigSubDict()
1201                                                 tmp.loft = ConfigSubDict()
1202                                                 tmp.positions = ConfigSubDict()
1203                                                 for z in products:
1204                                                         scrlist = []
1205                                                         vcolist = unicableproducts[y][z]
1206                                                         tmp.vco[z] = ConfigSubList()
1207                                                         for cnt in range(1,1+len(vcolist)-1):
1208                                                                 vcofreq = int(vcolist[cnt-1])
1209                                                                 if vcofreq == 0 and vco_null_check:
1210                                                                         scrlist.append(("%d" %cnt,"SCR %d " %cnt +_("not used")))
1211                                                                 else:
1212                                                                         scrlist.append(("%d" %cnt,"SCR %d" %cnt))
1213                                                                 tmp.vco[z].append(ConfigInteger(default=vcofreq, limits = (vcofreq, vcofreq)))
1214                                                                 tmp.scr[z] = ConfigSelection(choices = scrlist, default = scrlist[0][0])
1215
1216                                                                 positions = int(vcolist[len(vcolist)-1][0])
1217                                                                 tmp.positions[z] = ConfigSubList()
1218                                                                 tmp.positions[z].append(ConfigInteger(default=positions, limits = (positions, positions)))
1219
1220                                                                 lofl = vcolist[len(vcolist)-1][1]
1221                                                                 tmp.lofl[z] = ConfigSubList()
1222                                                                 tmp.lofl[z].append(ConfigInteger(default=lofl, limits = (lofl, lofl)))
1223
1224                                                                 lofh = int(vcolist[len(vcolist)-1][2])
1225                                                                 tmp.lofh[z] = ConfigSubList()
1226                                                                 tmp.lofh[z].append(ConfigInteger(default=lofh, limits = (lofh, lofh)))
1227
1228                                                                 loft = int(vcolist[len(vcolist)-1][3])
1229                                                                 tmp.loft[z] = ConfigSubList()
1230                                                                 tmp.loft[z].append(ConfigInteger(default=loft, limits = (loft, loft)))
1231                                                 sectionDict[y] = tmp
1232
1233                                 if lnb < 3:
1234                                         print "MATRIX"
1235                                         section.unicableMatrix = ConfigSubDict()
1236                                         section.unicableMatrixManufacturer = ConfigSelection(UnicableMatrixManufacturers, UnicableMatrixManufacturers[0])
1237                                         fillUnicableConf(section.unicableMatrix, unicablematrixproducts, True)
1238
1239                                 if lnb < 2:
1240                                         print "LNB"
1241                                         section.unicableLnb = ConfigSubDict()
1242                                         section.unicableLnbManufacturer = ConfigSelection(UnicableLnbManufacturers, UnicableLnbManufacturers[0])
1243                                         fillUnicableConf(section.unicableLnb, unicablelnbproducts, False)
1244
1245 #TODO satpositions for satcruser
1246                                 section.satcruser = ConfigSelection(advanced_lnb_satcruser_choices, default="1")
1247                                 tmp = ConfigSubList()
1248                                 tmp.append(ConfigInteger(default=1284, limits = (950, 2150)))
1249                                 tmp.append(ConfigInteger(default=1400, limits = (950, 2150)))
1250                                 tmp.append(ConfigInteger(default=1516, limits = (950, 2150)))
1251                                 tmp.append(ConfigInteger(default=1632, limits = (950, 2150)))
1252                                 tmp.append(ConfigInteger(default=1748, limits = (950, 2150)))
1253                                 tmp.append(ConfigInteger(default=1864, limits = (950, 2150)))
1254                                 tmp.append(ConfigInteger(default=1980, limits = (950, 2150)))
1255                                 tmp.append(ConfigInteger(default=2096, limits = (950, 2150)))
1256                                 section.satcrvcouser = tmp 
1257
1258                                 nim.advanced.unicableconnected = ConfigYesNo(default=False)
1259                                 nim.advanced.unicableconnectedTo = ConfigSelection([(str(id), nimmgr.getNimDescription(id)) for id in nimmgr.getNimListOfType("DVB-S") if id != x])
1260         
1261         def configDiSEqCModeChanged(configElement):
1262                 section = configElement.section
1263                 if configElement.value == "1_2" and isinstance(section.longitude, ConfigNothing):
1264                         section.longitude = ConfigFloat(default = [5,100], limits = [(0,359),(0,999)])
1265                         section.longitudeOrientation = ConfigSelection(longitude_orientation_choices, "east")
1266                         section.latitude = ConfigFloat(default = [50,767], limits = [(0,359),(0,999)])
1267                         section.latitudeOrientation = ConfigSelection(latitude_orientation_choices, "north")
1268                         section.powerMeasurement = ConfigYesNo(default=True)
1269                         section.powerThreshold = ConfigInteger(default=hw.get_device_name() == "dm7025" and 50 or 15, limits=(0, 100))
1270                         section.turningSpeed = ConfigSelection(turning_speed_choices, "fast")
1271                         section.fastTurningBegin = ConfigDateTime(default=advanced_lnb_fast_turning_btime, formatstring = _("%H:%M"), increment = 600)
1272                         section.fastTurningEnd = ConfigDateTime(default=advanced_lnb_fast_turning_etime, formatstring = _("%H:%M"), increment = 600)
1273
1274         def configLNBChanged(configElement):
1275                 x = configElement.slot_id
1276                 nim = config.Nims[x]
1277                 if isinstance(configElement.value, tuple):
1278                         lnb = int(configElement.value[0])
1279                 else:
1280                         lnb = int(configElement.value)
1281                 lnbs = nim.advanced.lnb
1282                 if lnb and lnb not in lnbs:
1283                         section = lnbs[lnb] = ConfigSubsection()
1284                         section.lofl = ConfigInteger(default=9750, limits = (0, 99999))
1285                         section.lofh = ConfigInteger(default=10600, limits = (0, 99999))
1286                         section.threshold = ConfigInteger(default=11700, limits = (0, 99999))
1287 #                       section.output_12v = ConfigSelection(choices = [("0V", _("0 V")), ("12V", _("12 V"))], default="0V")
1288                         section.increased_voltage = ConfigYesNo(False)
1289                         section.toneburst = ConfigSelection(advanced_lnb_toneburst_choices, "none")
1290                         section.longitude = ConfigNothing()
1291                         if lnb > 32:
1292                                 tmp = ConfigSelection(advanced_lnb_allsat_diseqcmode_choices, "1_2")
1293                                 tmp.section = section
1294                                 configDiSEqCModeChanged(tmp)
1295                         else:
1296                                 tmp = ConfigSelection(advanced_lnb_diseqcmode_choices, "none")
1297                                 tmp.section = section
1298                                 tmp.addNotifier(configDiSEqCModeChanged)
1299                         section.diseqcMode = tmp
1300                         section.commitedDiseqcCommand = ConfigSelection(advanced_lnb_csw_choices)
1301                         section.fastDiseqc = ConfigYesNo(False)
1302                         section.sequenceRepeat = ConfigYesNo(False)
1303                         section.commandOrder1_0 = ConfigSelection(advanced_lnb_commandOrder1_0_choices, "ct")
1304                         section.commandOrder = ConfigSelection(advanced_lnb_commandOrder_choices, "ct")
1305                         section.uncommittedDiseqcCommand = ConfigSelection(advanced_lnb_ucsw_choices)
1306                         section.diseqcRepeats = ConfigSelection(advanced_lnb_diseqc_repeat_choices, "none")
1307                         section.prio = ConfigSelection(prio_list, "-1")
1308                         section.unicable = ConfigNothing()
1309                         tmp = ConfigSelection(lnb_choices, lnb_choices_default)
1310                         tmp.slot_id = x
1311                         tmp.lnb_id = lnb
1312                         tmp.addNotifier(configLOFChanged, initial_call = False)
1313                         section.lof = tmp
1314
1315         def configModeChanged(configMode):
1316                 slot_id = configMode.slot_id
1317                 nim = config.Nims[slot_id]
1318                 if configMode.value == "advanced" and isinstance(nim.advanced, ConfigNothing):
1319                         # advanced config:
1320                         nim.advanced = ConfigSubsection()
1321                         nim.advanced.sat = ConfigSubDict()
1322                         nim.advanced.sats = getConfigSatlist(192, advanced_satlist_choices)
1323                         nim.advanced.lnb = ConfigSubDict()
1324                         nim.advanced.lnb[0] = ConfigNothing()
1325                         for x in nimmgr.satList:
1326                                 tmp = ConfigSubsection()
1327                                 tmp.voltage = ConfigSelection(advanced_voltage_choices, "polarization")
1328                                 tmp.tonemode = ConfigSelection(advanced_tonemode_choices, "band")
1329                                 tmp.usals = ConfigYesNo(True)
1330                                 tmp.rotorposition = ConfigInteger(default=1, limits=(1, 255))
1331                                 lnb = ConfigSelection(advanced_lnb_choices, "0")
1332                                 lnb.slot_id = slot_id
1333                                 lnb.addNotifier(configLNBChanged, initial_call = False)
1334                                 tmp.lnb = lnb
1335                                 nim.advanced.sat[x[0]] = tmp
1336                         for x in range(3601, 3605):
1337                                 tmp = ConfigSubsection()
1338                                 tmp.voltage = ConfigSelection(advanced_voltage_choices, "polarization")
1339                                 tmp.tonemode = ConfigSelection(advanced_tonemode_choices, "band")
1340                                 tmp.usals = ConfigYesNo(default=True)
1341                                 tmp.rotorposition = ConfigInteger(default=1, limits=(1, 255))
1342                                 lnbnum = 33+x-3601
1343                                 lnb = ConfigSelection([("0", "not available"), (str(lnbnum), "LNB %d"%(lnbnum))], "0")
1344                                 lnb.slot_id = slot_id
1345                                 lnb.addNotifier(configLNBChanged, initial_call = False)
1346                                 tmp.lnb = lnb
1347                                 nim.advanced.sat[x] = tmp
1348
1349         def toneAmplitudeChanged(configElement):
1350                 fe_id = configElement.fe_id
1351                 slot_id = configElement.slot_id
1352                 if nimmgr.nim_slots[slot_id].description == 'Alps BSBE2':
1353                         open("/proc/stb/frontend/%d/tone_amplitude" %(fe_id), "w").write(configElement.value)
1354                         
1355         def tunerTypeChanged(nimmgr, configElement):
1356                 fe_id = configElement.fe_id
1357                 print "tunerTypeChanged feid %d to mode %s" % (fe_id, configElement.value)
1358                 try:
1359                         oldvalue = open("/sys/module/dvb_core/parameters/dvb_shutdown_timeout", "r").readline()
1360                         open("/sys/module/dvb_core/parameters/dvb_shutdown_timeout", "w").write("0")
1361                 except:
1362                         print "[info] no /sys/module/dvb_core/parameters/dvb_shutdown_timeout available"
1363                 frontend = eDVBResourceManager.getInstance().allocateRawChannel(fe_id).getFrontend()
1364                 frontend.closeFrontend()
1365                 open("/proc/stb/frontend/%d/mode" % (fe_id), "w").write(configElement.value)
1366                 frontend.reopenFrontend()
1367                 try:
1368                         open("/sys/module/dvb_core/parameters/dvb_shutdown_timeout", "w").write(oldvalue)
1369                 except:
1370                         print "[info] no /sys/module/dvb_core/parameters/dvb_shutdown_timeout available"
1371                 nimmgr.enumerateNIMs()
1372         
1373         empty_slots = 0
1374         for slot in nimmgr.nim_slots:
1375                 x = slot.slot
1376                 nim = config.Nims[x]
1377                 addMultiType = False
1378                 try:
1379                         nim.multiType
1380                 except:
1381                         addMultiType = True
1382                 if slot.isMultiType() and addMultiType:
1383                         typeList = []
1384                         for id in slot.getMultiTypeList().keys():
1385                                 type = slot.getMultiTypeList()[id]
1386                                 typeList.append((id, type))
1387                         nim.multiType = ConfigSelection(typeList, "0")
1388                         
1389                         nim.multiType.fe_id = x - empty_slots
1390                         nim.multiType.addNotifier(boundFunction(tunerTypeChanged, nimmgr))
1391                 
1392         empty_slots = 0
1393         for slot in nimmgr.nim_slots:
1394                 x = slot.slot
1395                 nim = config.Nims[x]
1396
1397                 if slot.isCompatible("DVB-S"):
1398                         nim.toneAmplitude = ConfigSelection([("9", "600mV"), ("8", "700mV"), ("7", "800mV"), ("6", "900mV"), ("5", "1100mV")], "7")
1399                         nim.toneAmplitude.fe_id = x - empty_slots
1400                         nim.toneAmplitude.slot_id = x
1401                         nim.toneAmplitude.addNotifier(toneAmplitudeChanged)
1402                         nim.diseqc13V = ConfigYesNo(False)
1403                         nim.diseqcMode = ConfigSelection(diseqc_mode_choices, "diseqc_a_b")
1404                         nim.connectedTo = ConfigSelection([(str(id), nimmgr.getNimDescription(id)) for id in nimmgr.getNimListOfType("DVB-S") if id != x])
1405                         nim.simpleSingleSendDiSEqC = ConfigYesNo(False)
1406                         nim.simpleDiSEqCSetVoltageTone = ConfigYesNo(True)
1407                         nim.simpleDiSEqCOnlyOnSatChange = ConfigYesNo(False)
1408                         nim.diseqcA = getConfigSatlist(192, diseqc_satlist_choices)
1409                         nim.diseqcB = getConfigSatlist(130, diseqc_satlist_choices)
1410                         nim.diseqcC = ConfigSatlist(list = diseqc_satlist_choices)
1411                         nim.diseqcD = ConfigSatlist(list = diseqc_satlist_choices)
1412                         nim.positionerMode = ConfigSelection(positioner_mode_choices, "usals")
1413                         nim.longitude = ConfigFloat(default=[5,100], limits=[(0,359),(0,999)])
1414                         nim.longitudeOrientation = ConfigSelection(longitude_orientation_choices, "east")
1415                         nim.latitude = ConfigFloat(default=[50,767], limits=[(0,359),(0,999)])
1416                         nim.latitudeOrientation = ConfigSelection(latitude_orientation_choices, "north")
1417                         nim.powerMeasurement = ConfigYesNo(True)
1418                         nim.powerThreshold = ConfigInteger(default=hw.get_device_name() == "dm8000" and 15 or 50, limits=(0, 100))
1419                         nim.turningSpeed = ConfigSelection(turning_speed_choices, "fast")
1420                         btime = datetime(1970, 1, 1, 7, 0);
1421                         nim.fastTurningBegin = ConfigDateTime(default = mktime(btime.timetuple()), formatstring = _("%H:%M"), increment = 900)
1422                         etime = datetime(1970, 1, 1, 19, 0);
1423                         nim.fastTurningEnd = ConfigDateTime(default = mktime(etime.timetuple()), formatstring = _("%H:%M"), increment = 900)
1424                         config_mode_choices = [ ("nothing", _("nothing connected")),
1425                                 ("simple", _("simple")), ("advanced", _("advanced"))]
1426                         if len(nimmgr.getNimListOfType(slot.type, exception = x)) > 0:
1427                                 config_mode_choices.append(("equal", _("equal to")))
1428                                 config_mode_choices.append(("satposdepends", _("second cable of motorized LNB")))
1429                         if len(nimmgr.canConnectTo(x)) > 0:
1430                                 config_mode_choices.append(("loopthrough", _("loopthrough to")))
1431                         nim.advanced = ConfigNothing()
1432                         tmp = ConfigSelection(config_mode_choices, "nothing")
1433                         tmp.slot_id = x
1434                         tmp.addNotifier(configModeChanged, initial_call = False)
1435                         nim.configMode = tmp
1436                 elif slot.isCompatible("DVB-C"):
1437                         nim.configMode = ConfigSelection(
1438                                 choices = {
1439                                         "enabled": _("enabled"),
1440                                         "nothing": _("nothing connected"),
1441                                         },
1442                                 default = "enabled")
1443                         list = [ ]
1444                         n = 0
1445                         for x in nimmgr.cablesList:
1446                                 list.append((str(n), x[0]))
1447                                 n += 1
1448                         nim.cable = ConfigSubsection()
1449                         possible_scan_types = [("bands", _("Frequency bands")), ("steps", _("Frequency steps"))]
1450                         if n:
1451                                 possible_scan_types.append(("provider", _("Provider")))
1452                                 nim.cable.scan_provider = ConfigSelection(default = "0", choices = list)
1453                         nim.cable.scan_type = ConfigSelection(default = "bands", choices = possible_scan_types)
1454                         nim.cable.scan_band_EU_VHF_I = ConfigYesNo(default = True)
1455                         nim.cable.scan_band_EU_MID = ConfigYesNo(default = True)
1456                         nim.cable.scan_band_EU_VHF_III = ConfigYesNo(default = True)
1457                         nim.cable.scan_band_EU_UHF_IV = ConfigYesNo(default = True)
1458                         nim.cable.scan_band_EU_UHF_V = ConfigYesNo(default = True)
1459                         nim.cable.scan_band_EU_SUPER = ConfigYesNo(default = True)
1460                         nim.cable.scan_band_EU_HYPER = ConfigYesNo(default = True)
1461                         nim.cable.scan_band_US_LOW = ConfigYesNo(default = False)
1462                         nim.cable.scan_band_US_MID = ConfigYesNo(default = False)
1463                         nim.cable.scan_band_US_HIGH = ConfigYesNo(default = False)
1464                         nim.cable.scan_band_US_SUPER = ConfigYesNo(default = False)
1465                         nim.cable.scan_band_US_HYPER = ConfigYesNo(default = False)
1466                         nim.cable.scan_frequency_steps = ConfigInteger(default = 1000, limits = (1000, 10000))
1467                         nim.cable.scan_mod_qam16 = ConfigYesNo(default = False)
1468                         nim.cable.scan_mod_qam32 = ConfigYesNo(default = False)
1469                         nim.cable.scan_mod_qam64 = ConfigYesNo(default = True)
1470                         nim.cable.scan_mod_qam128 = ConfigYesNo(default = False)
1471                         nim.cable.scan_mod_qam256 = ConfigYesNo(default = True)
1472                         nim.cable.scan_sr_6900 = ConfigYesNo(default = True)
1473                         nim.cable.scan_sr_6875 = ConfigYesNo(default = True)
1474                         nim.cable.scan_sr_ext1 = ConfigInteger(default = 0, limits = (0, 7230))
1475                         nim.cable.scan_sr_ext2 = ConfigInteger(default = 0, limits = (0, 7230))
1476                 elif slot.isCompatible("DVB-T"):
1477                         nim.configMode = ConfigSelection(
1478                                 choices = {
1479                                         "enabled": _("enabled"),
1480                                         "nothing": _("nothing connected"),
1481                                         },
1482                                 default = "enabled")
1483                         list = []
1484                         n = 0
1485                         for x in nimmgr.terrestrialsList:
1486                                 list.append((str(n), x[0]))
1487                                 n += 1
1488                         nim.terrestrial = ConfigSelection(choices = list)
1489                         nim.terrestrial_5V = ConfigOnOff()
1490                 else:
1491                         empty_slots += 1
1492                         nim.configMode = ConfigSelection(choices = { "nothing": _("disabled") }, default="nothing");
1493                         if slot.type is not None:
1494                                 print "pls add support for this frontend type!", slot.type
1495 #                       assert False
1496
1497         nimmgr.sec = SecConfigure(nimmgr)
1498
1499 nimmanager = NimManager()