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