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