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