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