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