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