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