b92ad92bff83402896d51b5a2b1957e0e7c24815
[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(False)
63                 sec.setRepeats(0)
64                 sec.setFastDiSEqC(fastDiSEqC)
65                 sec.setSeqRepeat(False)
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,69):
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,69):
286                         if len(lnbSat[x]) > 0:
287                                 currLnb = config.Nims[slotid].advanced.lnb[x]
288                                 sec.addLNB()
289
290                                 if x < 65:
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                                                 manufacturer_scr = manufacturer.scr
314                                                 manufacturer_positions_value = manufacturer.positions[product_name][0].value
315                                                 position_idx = (x-1) % manufacturer_positions_value
316                                                 if product_name in manufacturer_scr:
317                                                         diction = manufacturer.diction[product_name].value
318                                                         if x <= manufacturer_positions_value or diction !="EN50607": #for every allowed position
319                                                                 sec.setLNBSatCR(manufacturer_scr[product_name].index)
320
321                                                                 if diction =="EN50607":
322                                                                         sec.setLNBSatCRformat(1)        #JESS
323                                                                 else:
324                                                                         sec.setLNBSatCRformat(0)        #DiSEqC
325                                                                 sec.setLNBSatCRvco(manufacturer.vco[product_name][manufacturer_scr[product_name].index].value*1000)
326                                                                 sec.setLNBSatCRpositions(manufacturer_positions_value)
327                                                                 sec.setLNBLOFL(manufacturer.lofl[product_name][position_idx].value * 1000)
328                                                                 sec.setLNBLOFH(manufacturer.lofh[product_name][position_idx].value * 1000)
329                                                                 sec.setLNBThreshold(manufacturer.loft[product_name][position_idx].value * 1000)
330                                                                 configManufacturer.save_forced = True
331                                                                 manufacturer.product.save_forced = True
332                                                                 manufacturer.vco[product_name][manufacturer_scr[product_name].index].save_forced = True
333                                                         else: #positionnumber out of range
334                                                                 print "positionnumber out of range"
335                                                 else:
336                                                         print "no product in list"
337                                                         
338                                         if currLnb.unicable.value == "unicable_user":
339 #TODO satpositions for satcruser
340                                                 if currLnb.dictionuser.value == "EN50607": 
341                                                         sec.setLNBSatCRformat(1)
342                                                         sec.setLNBSatCR(currLnb.satcruserEN50607.index)
343                                                         sec.setLNBSatCRvco(currLnb.satcrvcouserEN50607[currLnb.satcruserEN50607.index].value*1000)
344                                                 else:
345                                                         sec.setLNBSatCRformat(0)
346                                                         sec.setLNBSatCR(currLnb.satcruserEN50494.index)
347                                                         sec.setLNBSatCRvco(currLnb.satcrvcouserEN50494[currLnb.satcruserEN50494.index].value*1000)
348
349                                                 sec.setLNBLOFL(currLnb.lofl.value * 1000)
350                                                 sec.setLNBLOFH(currLnb.lofh.value * 1000)
351                                                 sec.setLNBThreshold(currLnb.threshold.value * 1000)
352                                                 sec.setLNBSatCRpositions(64)    #HACK
353                                         elif currLnb.unicable.value == "unicable_matrix":
354                                                 setupUnicable(currLnb.unicableMatrixManufacturer, currLnb.unicableMatrix)
355                                         elif currLnb.unicable.value == "unicable_lnb":
356                                                 setupUnicable(currLnb.unicableLnbManufacturer, currLnb.unicableLnb)
357                                 elif currLnb.lof.value == "c_band":
358                                         sec.setLNBLOFL(5150000)
359                                         sec.setLNBLOFH(5150000)
360                                         sec.setLNBThreshold(5150000)
361                                 elif currLnb.lof.value == "user_defined":
362                                         sec.setLNBLOFL(currLnb.lofl.value * 1000)
363                                         sec.setLNBLOFH(currLnb.lofh.value * 1000)
364                                         sec.setLNBThreshold(currLnb.threshold.value * 1000)
365
366 #                               if currLnb.output_12v.value == "0V":
367 #                                       pass # nyi in drivers
368 #                               elif currLnb.output_12v.value == "12V":
369 #                                       pass # nyi in drivers
370
371                                 if currLnb.increased_voltage.value:
372                                         sec.setLNBIncreasedVoltage(True)
373                                 else:
374                                         sec.setLNBIncreasedVoltage(False)
375
376                                 dm = currLnb.diseqcMode.value
377                                 if dm == "none":
378                                         sec.setDiSEqCMode(diseqcParam.NONE)
379                                 elif dm == "1_0":
380                                         sec.setDiSEqCMode(diseqcParam.V1_0)
381                                 elif dm == "1_1":
382                                         sec.setDiSEqCMode(diseqcParam.V1_1)
383                                 elif dm == "1_2":
384                                         sec.setDiSEqCMode(diseqcParam.V1_2)
385
386                                         if self.satposdepends.has_key(slotid):
387                                                 for slot in self.satposdepends[slotid]:
388                                                         tunermask |= (1 << slot)
389
390                                 if dm != "none":
391                                         if currLnb.toneburst.value == "none":
392                                                 sec.setToneburst(diseqcParam.NO)
393                                         elif currLnb.toneburst.value == "A":
394                                                 sec.setToneburst(diseqcParam.A)
395                                         elif currLnb.toneburst.value == "B":
396                                                 sec.setToneburst(diseqcParam.B)
397
398                                         # Committed Diseqc Command
399                                         cdc = currLnb.commitedDiseqcCommand.value
400
401                                         c = { "none": diseqcParam.SENDNO,
402                                                 "AA": diseqcParam.AA,
403                                                 "AB": diseqcParam.AB,
404                                                 "BA": diseqcParam.BA,
405                                                 "BB": diseqcParam.BB }
406
407                                         if c.has_key(cdc):
408                                                 sec.setCommittedCommand(c[cdc])
409                                         else:
410                                                 sec.setCommittedCommand(long(cdc))
411
412                                         sec.setFastDiSEqC(currLnb.fastDiseqc.value)
413
414                                         sec.setSeqRepeat(currLnb.sequenceRepeat.value)
415
416                                         if currLnb.diseqcMode.value == "1_0":
417                                                 currCO = currLnb.commandOrder1_0.value
418                                                 sec.setRepeats(0)
419                                         else:
420                                                 currCO = currLnb.commandOrder.value
421
422                                                 udc = int(currLnb.uncommittedDiseqcCommand.value)
423                                                 if udc > 0:
424                                                         sec.setUncommittedCommand(0xF0|(udc-1))
425                                                 else:
426                                                         sec.setUncommittedCommand(0) # SENDNO
427
428                                                 sec.setRepeats({"none": 0, "one": 1, "two": 2, "three": 3}[currLnb.diseqcRepeats.value])
429
430                                         setCommandOrder = False
431
432                                         # 0 "committed, toneburst",
433                                         # 1 "toneburst, committed",
434                                         # 2 "committed, uncommitted, toneburst",
435                                         # 3 "toneburst, committed, uncommitted",
436                                         # 4 "uncommitted, committed, toneburst"
437                                         # 5 "toneburst, uncommitted, commmitted"
438                                         order_map = {"ct": 0, "tc": 1, "cut": 2, "tcu": 3, "uct": 4, "tuc": 5}
439                                         sec.setCommandOrder(order_map[currCO])
440
441                                 if dm == "1_2":
442                                         latitude = currLnb.latitude.float
443                                         sec.setLatitude(latitude)
444                                         longitude = currLnb.longitude.float
445                                         sec.setLongitude(longitude)
446                                         if currLnb.latitudeOrientation.value == "north":
447                                                 sec.setLaDirection(rotorParam.NORTH)
448                                         else:
449                                                 sec.setLaDirection(rotorParam.SOUTH)
450                                         if currLnb.longitudeOrientation.value == "east":
451                                                 sec.setLoDirection(rotorParam.EAST)
452                                         else:
453                                                 sec.setLoDirection(rotorParam.WEST)
454
455                                         if currLnb.powerMeasurement.value:
456                                                 sec.setUseInputpower(True)
457                                                 sec.setInputpowerDelta(currLnb.powerThreshold.value)
458                                                 turn_speed_dict = { "fast": rotorParam.FAST, "slow": rotorParam.SLOW }
459                                                 if turn_speed_dict.has_key(currLnb.turningSpeed.value):
460                                                         turning_speed = turn_speed_dict[currLnb.turningSpeed.value]
461                                                 else:
462                                                         beg_time = localtime(currLnb.fastTurningBegin.value)
463                                                         end_time = localtime(currLnb.fastTurningEnd.value)
464                                                         turning_speed = ((beg_time.tm_hour + 1) * 60 + beg_time.tm_min + 1) << 16
465                                                         turning_speed |= (end_time.tm_hour + 1) * 60 + end_time.tm_min + 1
466                                                 sec.setRotorTurningSpeed(turning_speed)
467                                         else:
468                                                 sec.setUseInputpower(False)
469
470                                 sec.setLNBSlotMask(tunermask)
471
472                                 sec.setLNBPrio(int(currLnb.prio.value))
473
474                                 # finally add the orbital positions
475                                 for y in lnbSat[x]:
476                                         self.addSatellite(sec, y)
477                                         if x > 64:
478                                                 satpos = x > 64 and (3604-(68 - x)) or y
479                                         else:
480                                                 satpos = y
481                                         currSat = config.Nims[slotid].advanced.sat[satpos]
482                                         if currSat.voltage.value == "polarization":
483                                                 if config.Nims[slotid].diseqc13V.value:
484                                                         sec.setVoltageMode(switchParam.HV_13)
485                                                 else:
486                                                         sec.setVoltageMode(switchParam.HV)
487                                         elif currSat.voltage.value == "13V":
488                                                 sec.setVoltageMode(switchParam._14V)
489                                         elif currSat.voltage.value == "18V":
490                                                 sec.setVoltageMode(switchParam._18V)
491
492                                         if currSat.tonemode.value == "band":
493                                                 sec.setToneMode(switchParam.HILO)
494                                         elif currSat.tonemode.value == "on":
495                                                 sec.setToneMode(switchParam.ON)
496                                         elif currSat.tonemode.value == "off":
497                                                 sec.setToneMode(switchParam.OFF)
498                                                 
499                                         if not currSat.usals.value and x < 66:
500                                                 sec.setRotorPosNum(currSat.rotorposition.value)
501                                         else:
502                                                 sec.setRotorPosNum(0) #USALS
503
504         def __init__(self, nimmgr):
505                 self.NimManager = nimmgr
506                 self.configuredSatellites = set()
507                 self.update()
508
509 class NIM(object):
510         def __init__(self, slot, type, description, has_outputs = True, internally_connectable = None, multi_type = {}, frontend_id = None, i2c = None, is_empty = False):
511                 self.slot = slot
512
513                 if type not in ("DVB-S", "DVB-C", "DVB-T", "DVB-S2", "DVB-T2", None):
514                         print "warning: unknown NIM type %s, not using." % type
515                         type = None
516
517                 self.type = type
518                 self.description = description
519                 self.has_outputs = has_outputs
520                 self.internally_connectable = internally_connectable
521                 self.multi_type = multi_type
522                 self.i2c = i2c
523                 self.frontend_id = frontend_id
524                 self.__is_empty = is_empty
525                 self.compatible = {
526                                 None: (None,),
527                                 "DVB-S": ("DVB-S", None),
528                                 "DVB-C": ("DVB-C", None),
529                                 "DVB-T": ("DVB-T", None),
530                                 "DVB-S2": ("DVB-S", "DVB-S2", None),
531                                 "DVB-T2": ("DVB-T", "DVB-T2", None)
532                         }
533
534         def getType(self):
535                 try:
536                         if self.isMultiType():
537                                 return self.multi_type[self.config.multiType.value]
538                 except:
539                         pass
540                 return self.type
541
542         def isCompatible(self, what):
543                 if not self.isSupported():
544                         return False
545                 return what in self.compatible[self.getType()]
546
547         def canBeCompatible(self, what):
548                 if self.isCompatible(what):
549                         return True
550                 for type in self.getMultiTypeList().values():
551                         if what in self.compatible[type]:
552                                 return True
553                 return False
554         
555         def connectableTo(self):
556                 connectable = {
557                                 "DVB-S": ("DVB-S", "DVB-S2"),
558                                 "DVB-C": ("DVB-C",),
559                                 "DVB-T": ("DVB-T",),
560                                 "DVB-S2": ("DVB-S", "DVB-S2"),
561                                 "DVB-T2": ("DVB-T", "DVB-T2",)
562                         }
563                 return connectable[self.getType()]
564
565         def getSlotName(self):
566                 # get a friendly description for a slot name.
567                 # we name them "Tuner A/B/C/...", because that's what's usually written on the back
568                 # of the device.
569                 return _("Tuner ") + chr(ord('A') + self.slot)
570
571         slot_name = property(getSlotName)
572
573         def getSlotID(self):
574                 return chr(ord('A') + self.slot)
575         
576         def getI2C(self):
577                 return self.i2c
578         
579         def hasOutputs(self):
580                 return self.has_outputs
581         
582         def internallyConnectableTo(self):
583                 return self.internally_connectable
584         
585         def setInternalLink(self):
586                 if self.internally_connectable is not None:
587                         print "setting internal link on frontend id", self.frontend_id
588                         open("/proc/stb/frontend/%d/rf_switch" % self.frontend_id, "w").write("internal")
589                 
590         def removeInternalLink(self):
591                 if self.internally_connectable is not None:
592                         print "removing internal link on frontend id", self.frontend_id
593                         open("/proc/stb/frontend/%d/rf_switch" % self.frontend_id, "w").write("external")
594         
595         def isMultiType(self):
596                 return (len(self.multi_type) > 0)
597         
598         def isEmpty(self):
599                 return self.__is_empty
600         
601         # empty tuners are supported!
602         def isSupported(self):
603                 return (self.frontend_id is not None) or self.__is_empty
604         
605         # returns dict {<slotid>: <type>}
606         def getMultiTypeList(self):
607                 return self.multi_type
608
609         slot_id = property(getSlotID)
610
611         def getFriendlyType(self):
612                 return {
613                         "DVB-S": "DVB-S", 
614                         "DVB-T": "DVB-T",
615                         "DVB-C": "DVB-C",
616                         "DVB-S2": "DVB-S2",
617                         "DVB-T2": "DVB-T2",
618                         None: _("empty")
619                         }[self.getType()]
620
621         friendly_type = property(getFriendlyType)
622
623         def getFriendlyFullDescription(self):
624                 nim_text = self.slot_name + ": "
625                         
626                 if self.empty:
627                         nim_text += _("(empty)")
628                 elif not self.isSupported():
629                         nim_text += self.description + " (" + _("not supported") + ")"
630                 else:
631                         nim_text += self.description + " (" + self.friendly_type + ")"
632                 
633                 return nim_text
634
635         friendly_full_description = property(getFriendlyFullDescription)
636         config_mode = property(lambda self: config.Nims[self.slot].configMode.value)
637         config = property(lambda self: config.Nims[self.slot])
638         empty = property(lambda self: self.getType() is None)
639
640 class NimManager:
641         def getConfiguredSats(self):
642                 return self.sec.getConfiguredSats()
643
644         def getTransponders(self, pos):
645                 if self.transponders.has_key(pos):
646                         return self.transponders[pos]
647                 else:
648                         return []
649
650         def getTranspondersCable(self, nim):
651                 nimConfig = config.Nims[nim]
652                 if nimConfig.configMode.value != "nothing" and nimConfig.cable.scan_type.value == "provider":
653                         return self.transponderscable[self.cablesList[nimConfig.cable.scan_provider.index][0]]
654                 return [ ]
655
656         def getTranspondersTerrestrial(self, region):
657                 return self.transpondersterrestrial[region]
658         
659         def getCableDescription(self, nim):
660                 return self.cablesList[config.Nims[nim].scan_provider.index][0]
661
662         def getCableFlags(self, nim):
663                 return self.cablesList[config.Nims[nim].scan_provider.index][1]
664
665         def getTerrestrialDescription(self, nim):
666                 return self.terrestrialsList[config.Nims[nim].terrestrial.index][0]
667
668         def getTerrestrialFlags(self, nim):
669                 return self.terrestrialsList[config.Nims[nim].terrestrial.index][1]
670
671         def getSatDescription(self, pos):
672                 return self.satellites[pos]
673
674         def sortFunc(self, x):
675                 orbpos = x[0]
676                 if orbpos > 1800:
677                         return orbpos - 3600
678                 else:
679                         return orbpos + 1800
680
681         def readTransponders(self):
682                 # read initial networks from file. we only read files which we are interested in,
683                 # which means only these where a compatible tuner exists.
684                 self.satellites = { }
685                 self.transponders = { }
686                 self.transponderscable = { }
687                 self.transpondersterrestrial = { }
688                 db = eDVBDB.getInstance()
689                 if self.hasNimType("DVB-S"):
690                         print "Reading satellites.xml"
691                         db.readSatellites(self.satList, self.satellites, self.transponders)
692                         self.satList.sort(key = self.sortFunc) # sort by orbpos
693                         #print "SATLIST", self.satList
694                         #print "SATS", self.satellites
695                         #print "TRANSPONDERS", self.transponders
696
697                 if self.hasNimType("DVB-C"):
698                         print "Reading cables.xml"
699                         db.readCables(self.cablesList, self.transponderscable)
700 #                       print "CABLIST", self.cablesList
701 #                       print "TRANSPONDERS", self.transponders
702
703                 if self.hasNimType("DVB-T"):
704                         print "Reading terrestrial.xml"
705                         db.readTerrestrials(self.terrestrialsList, self.transpondersterrestrial)
706 #                       print "TERLIST", self.terrestrialsList
707 #                       print "TRANSPONDERS", self.transpondersterrestrial
708
709         def enumerateNIMs(self):
710                 # enum available NIMs. This is currently very dreambox-centric and uses the /proc/bus/nim_sockets interface.
711                 # the result will be stored into nim_slots.
712                 # the content of /proc/bus/nim_sockets looks like:
713                 # NIM Socket 0:
714                 #          Type: DVB-S
715                 #          Name: BCM4501 DVB-S2 NIM (internal)
716                 # NIM Socket 1:
717                 #          Type: DVB-S
718                 #          Name: BCM4501 DVB-S2 NIM (internal)
719                 # NIM Socket 2:
720                 #          Type: DVB-T
721                 #          Name: Philips TU1216
722                 # NIM Socket 3:
723                 #          Type: DVB-S
724                 #          Name: Alps BSBE1 702A
725                 
726                 #
727                 # Type will be either "DVB-S", "DVB-S2", "DVB-T", "DVB-C" or None.
728
729                 # nim_slots is an array which has exactly one entry for each slot, even for empty ones.
730                 self.nim_slots = [ ]
731
732                 nimfile = tryOpen("/proc/bus/nim_sockets")
733
734                 if nimfile is None:
735                         return
736
737                 current_slot = None
738
739                 entries = {}
740                 for line in nimfile.readlines():
741                         if line == "":
742                                 break
743                         if line.strip().startswith("NIM Socket"):
744                                 parts = line.strip().split(" ")
745                                 current_slot = int(parts[2][:-1])
746                                 entries[current_slot] = {}
747                         elif line.strip().startswith("Type:"):
748                                 entries[current_slot]["type"] = str(line.strip()[6:])
749                                 entries[current_slot]["isempty"] = False
750                         elif line.strip().startswith("Name:"):
751                                 entries[current_slot]["name"] = str(line.strip()[6:])
752                                 entries[current_slot]["isempty"] = False
753                         elif line.strip().startswith("Has_Outputs:"):
754                                 input = str(line.strip()[len("Has_Outputs:") + 1:])
755                                 entries[current_slot]["has_outputs"] = (input == "yes")
756                         elif line.strip().startswith("Internally_Connectable:"):
757                                 input = int(line.strip()[len("Internally_Connectable:") + 1:])
758                                 entries[current_slot]["internally_connectable"] = input
759                         elif line.strip().startswith("Frontend_Device:"):
760                                 input = int(line.strip()[len("Frontend_Device:") + 1:])
761                                 entries[current_slot]["frontend_device"] = input
762                         elif  line.strip().startswith("Mode"):
763                                 # "Mode 0: DVB-T" -> ["Mode 0", " DVB-T"]
764                                 split = line.strip().split(":")
765                                 # "Mode 0" -> ["Mode, "0"]
766                                 split2 = split[0].split(" ")
767                                 modes = entries[current_slot].get("multi_type", {})
768                                 modes[split2[1]] = split[1].strip()
769                                 entries[current_slot]["multi_type"] = modes
770                         elif line.strip().startswith("I2C_Device:"):
771                                 input = int(line.strip()[len("I2C_Device:") + 1:])
772                                 entries[current_slot]["i2c"] = input
773                         elif line.strip().startswith("empty"):
774                                 entries[current_slot]["type"] = None
775                                 entries[current_slot]["name"] = _("N/A")
776                                 entries[current_slot]["isempty"] = True
777                 nimfile.close()
778                 
779                 from os import path
780                 
781                 for id, entry in entries.items():
782                         if not (entry.has_key("name") and entry.has_key("type")):
783                                 entry["name"] =  _("N/A")
784                                 entry["type"] = None
785                         if not (entry.has_key("i2c")):
786                                 entry["i2c"] = None
787                         if not (entry.has_key("has_outputs")):
788                                 entry["has_outputs"] = True
789                         if entry.has_key("frontend_device"): # check if internally connectable
790                                 if path.exists("/proc/stb/frontend/%d/rf_switch" % entry["frontend_device"]):
791                                         entry["internally_connectable"] = entry["frontend_device"] - 1
792                                 else:
793                                         entry["internally_connectable"] = None
794                         else:
795                                 entry["frontend_device"] = entry["internally_connectable"] = None
796                         if not (entry.has_key("multi_type")):
797                                 entry["multi_type"] = {}
798
799                         # get MultiType from DTV_ENUM_DELSYS
800                         if entry["frontend_device"] is not None:
801                                 types = [type for type in ["DVB-C", "DVB-T2", "DVB-T", "DVB-S2", "DVB-S", "ATSC"] if eDVBResourceManager.getInstance().frontendIsCompatible(entry["frontend_device"], type)]
802                                 if "DVB-T2" in types and "DVB-T" in types:
803                                         # DVB-T2 implies DVB-T support
804                                         types.remove("DVB-T")
805                                 if "DVB-S2" in types and "DVB-S" in types:
806                                         # DVB-S2 implies DVB-S support
807                                         types.remove("DVB-S")
808                                 if len(types) > 1:
809                                         entry["multi_type"] = {}
810                                         for type in types:
811                                                 entry["multi_type"][str(types.index(type))] = type
812
813                         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"]))
814
815         def hasNimType(self, chktype):
816                 for slot in self.nim_slots:
817                         if slot.canBeCompatible(chktype):
818                                 return True
819                 return False
820         
821         def getNimType(self, slotid):
822                 return self.nim_slots[slotid].getType()
823         
824         def getNimDescription(self, slotid):
825                 return self.nim_slots[slotid].friendly_full_description
826         
827         def getNimName(self, slotid):
828                 return self.nim_slots[slotid].description
829         
830         def getNim(self, slotid):
831                 return self.nim_slots[slotid]
832         
833         def getI2CDevice(self, slotid):
834                 return self.nim_slots[slotid].getI2C()
835
836         def getNimListOfType(self, type, exception = -1):
837                 # returns a list of indexes for NIMs compatible to the given type, except for 'exception'
838                 list = []
839                 for x in self.nim_slots:
840                         if x.isCompatible(type) and x.slot != exception:
841                                 list.append(x.slot)
842                 return list
843
844         def __init__(self):
845                 self.satList = [ ]
846                 self.cablesList = []
847                 self.terrestrialsList = []
848                 self.enumerateNIMs()
849                 self.readTransponders()
850                 InitNimManager(self)    #init config stuff
851
852         # get a list with the friendly full description
853         def nimList(self):
854                 list = [ ]
855                 for slot in self.nim_slots:
856                         list.append(slot.friendly_full_description)
857                 return list
858         
859         def getSlotCount(self):
860                 return len(self.nim_slots)
861         
862         def hasOutputs(self, slotid):
863                 return self.nim_slots[slotid].hasOutputs()
864         
865         def nimInternallyConnectableTo(self, slotid):
866                 return self.nim_slots[slotid].internallyConnectableTo()
867         
868         def nimRemoveInternalLink(self, slotid):
869                 self.nim_slots[slotid].removeInternalLink()
870         
871         def canConnectTo(self, slotid):
872                 slots = []
873                 if self.nim_slots[slotid].internallyConnectableTo() is not None:
874                         slots.append(self.nim_slots[slotid].internallyConnectableTo())
875                 for type in self.nim_slots[slotid].connectableTo(): 
876                         for slot in self.getNimListOfType(type, exception = slotid):
877                                 if self.hasOutputs(slot):
878                                         slots.append(slot)
879
880                 # remove duplicates from list
881                 slots = list(set(slots))
882
883                 # remove nims, that have a conntectedTo reference on
884                 for testnim in slots[:]:
885                         for nim in self.getNimListOfType("DVB-S", slotid):
886                                 nimConfig = self.getNimConfig(nim)
887                                 if nimConfig.content.items.has_key("configMode") and nimConfig.configMode.value == "loopthrough" and int(nimConfig.connectedTo.value) == testnim:
888                                         slots.remove(testnim)
889                                         break 
890
891                                 if nimConfig.content.items.has_key("configMode") and nimConfig.configMode.value == "advanced":
892                                         try:
893                                                 if (nimConfig.advanced.unicableconnected is not None) and (nimConfig.advanced.unicableconnected.value == True):
894                                                         if int(nimConfig.advanced.unicableconnectedTo.value) == testnim:
895                                                                 slots.remove(testnim)
896                                                                 break
897                                         except:
898                                                 pass
899
900
901                 slots.sort()
902                 
903                 return slots
904         
905         def canEqualTo(self, slotid):
906                 type = self.getNimType(slotid)
907                 if type == "DVB-S2":
908                         type = "DVB-S"
909                 elif type == "DVB-T2":
910                         type = "DVB-T"
911                 nimList = self.getNimListOfType(type, slotid)
912                 for nim in nimList[:]:
913                         mode = self.getNimConfig(nim)
914                         if mode.configMode.value == "loopthrough" or mode.configMode.value == "satposdepends":
915                                 nimList.remove(nim)
916                 return nimList
917
918         def canDependOn(self, slotid):
919                 type = self.getNimType(slotid)
920                 if type == "DVB-S2":
921                         type = "DVB-S"
922                 elif type == "DVB-T2":
923                         type = "DVB-T"
924                 nimList = self.getNimListOfType(type, slotid)
925                 positionerList = []
926                 for nim in nimList[:]:
927                         mode = self.getNimConfig(nim)
928                         nimHaveRotor = mode.configMode.value == "simple" and mode.diseqcMode.value == "positioner"
929                         if not nimHaveRotor and mode.configMode.value == "advanced":
930                                 for x in range(3601, 3605):
931                                         lnb = int(mode.advanced.sat[x].lnb.value)
932                                         if lnb != 0:
933                                                 nimHaveRotor = True
934                                                 break
935                                 if not nimHaveRotor:
936                                         for sat in mode.advanced.sat.values():
937                                                 lnb_num = int(sat.lnb.value)
938                                                 diseqcmode = lnb_num and mode.advanced.lnb[lnb_num].diseqcMode.value or ""
939                                                 if diseqcmode == "1_2":
940                                                         nimHaveRotor = True
941                                                         break
942                         if nimHaveRotor:
943                                 alreadyConnected = False
944                                 for testnim in nimList:
945                                         testmode = self.getNimConfig(testnim)
946                                         if testmode.configMode.value == "satposdepends" and int(testmode.connectedTo.value) == int(nim):
947                                                 alreadyConnected = True
948                                                 break
949                                 if not alreadyConnected:
950                                         positionerList.append(nim)
951                 return positionerList
952         
953         def getNimConfig(self, slotid):
954                 return config.Nims[slotid]
955         
956         def getSatName(self, pos):
957                 for sat in self.satList:
958                         if sat[0] == pos:
959                                 return sat[1]
960                 return _("N/A")
961
962         def getSatList(self):
963                 return self.satList
964         
965         # returns True if something is configured to be connected to this nim
966         # if slotid == -1, returns if something is connected to ANY nim
967         def somethingConnected(self, slotid = -1):
968                 if (slotid == -1):
969                         connected = False
970                         for id in range(self.getSlotCount()):
971                                 if self.somethingConnected(id):
972                                         connected = True
973                         return connected
974                 else:
975                         nim = config.Nims[slotid]
976                         configMode = nim.configMode.value
977                 
978                         if self.nim_slots[slotid].isCompatible("DVB-S") or self.nim_slots[slotid].isCompatible("DVB-T") or self.nim_slots[slotid].isCompatible("DVB-C"):
979                                 return not (configMode == "nothing")            
980
981         def getSatListForNim(self, slotid):
982                 list = []
983                 if self.nim_slots[slotid].isCompatible("DVB-S"):
984                         nim = config.Nims[slotid]
985                         #print "slotid:", slotid
986
987                         #print "self.satellites:", self.satList[config.Nims[slotid].diseqcA.index]
988                         #print "diseqcA:", config.Nims[slotid].diseqcA.value
989                         configMode = nim.configMode.value
990
991                         if configMode == "equal":
992                                 slotid = int(nim.connectedTo.value)
993                                 nim = config.Nims[slotid]
994                                 configMode = nim.configMode.value
995                         elif configMode == "loopthrough":
996                                 slotid = self.sec.getRoot(slotid, int(nim.connectedTo.value))
997                                 nim = config.Nims[slotid]
998                                 configMode = nim.configMode.value
999
1000                         if configMode == "simple":
1001                                 dm = nim.diseqcMode.value
1002                                 if dm in ("single", "toneburst_a_b", "diseqc_a_b", "diseqc_a_b_c_d"):
1003                                         if nim.diseqcA.orbital_position != 3601:
1004                                                 list.append(self.satList[nim.diseqcA.index-1])
1005                                 if dm in ("toneburst_a_b", "diseqc_a_b", "diseqc_a_b_c_d"):
1006                                         if nim.diseqcB.orbital_position != 3601:
1007                                                 list.append(self.satList[nim.diseqcB.index-1])
1008                                 if dm == "diseqc_a_b_c_d":
1009                                         if nim.diseqcC.orbital_position != 3601:
1010                                                 list.append(self.satList[nim.diseqcC.index-1])
1011                                         if nim.diseqcD.orbital_position != 3601:
1012                                                 list.append(self.satList[nim.diseqcD.index-1])
1013                                 if dm == "positioner":
1014                                         for x in self.satList:
1015                                                 list.append(x)
1016                         elif configMode == "advanced":
1017                                 for x in range(3601, 3605):
1018                                         if int(nim.advanced.sat[x].lnb.value) != 0:
1019                                                 for x in self.satList:
1020                                                         list.append(x)
1021                                 if not list:
1022                                         for x in self.satList:
1023                                                 if int(nim.advanced.sat[x[0]].lnb.value) != 0:
1024                                                         list.append(x)
1025                 return list
1026
1027         def getRotorSatListForNim(self, slotid):
1028                 list = []
1029                 if self.nim_slots[slotid].isCompatible("DVB-S"):
1030                         #print "slotid:", slotid
1031                         #print "self.satellites:", self.satList[config.Nims[slotid].diseqcA.value]
1032                         #print "diseqcA:", config.Nims[slotid].diseqcA.value
1033                         configMode = config.Nims[slotid].configMode.value
1034                         if configMode == "simple":
1035                                 if config.Nims[slotid].diseqcMode.value == "positioner":
1036                                         for x in self.satList:
1037                                                 list.append(x)
1038                         elif configMode == "advanced":
1039                                 nim = config.Nims[slotid]
1040                                 for x in range(3601, 3605):
1041                                         if int(nim.advanced.sat[x].lnb.value) != 0:
1042                                                 for x in self.satList:
1043                                                         list.append(x)
1044                                 if not list:
1045                                         for x in self.satList:
1046                                                 lnbnum = int(nim.advanced.sat[x[0]].lnb.value)
1047                                                 if lnbnum != 0:
1048                                                         lnb = nim.advanced.lnb[lnbnum]
1049                                                         if lnb.diseqcMode.value == "1_2":
1050                                                                 list.append(x)
1051                 return list
1052
1053 def InitSecParams():
1054         config.sec = ConfigSubsection()
1055
1056         x = ConfigInteger(default=25, limits = (0, 9999))
1057         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_CONT_TONE_DISABLE_BEFORE_DISEQC, configElement.value))
1058         config.sec.delay_after_continuous_tone_disable_before_diseqc = x
1059
1060         x = ConfigInteger(default=10, limits = (0, 9999))
1061         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_FINAL_CONT_TONE_CHANGE, configElement.value))
1062         config.sec.delay_after_final_continuous_tone_change = x
1063
1064         x = ConfigInteger(default=10, limits = (0, 9999))
1065         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_FINAL_VOLTAGE_CHANGE, configElement.value))
1066         config.sec.delay_after_final_voltage_change = x
1067
1068         x = ConfigInteger(default=120, limits = (0, 9999))
1069         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_BETWEEN_DISEQC_REPEATS, configElement.value))
1070         config.sec.delay_between_diseqc_repeats = x
1071
1072         x = ConfigInteger(default=50, limits = (0, 9999))
1073         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_LAST_DISEQC_CMD, configElement.value))
1074         config.sec.delay_after_last_diseqc_command = x
1075
1076         x = ConfigInteger(default=50, limits = (0, 9999))
1077         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_TONEBURST, configElement.value))
1078         config.sec.delay_after_toneburst = x
1079
1080         x = ConfigInteger(default=20, limits = (0, 9999))
1081         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_SWITCH_CMDS, configElement.value))
1082         config.sec.delay_after_change_voltage_before_switch_command = x
1083
1084         x = ConfigInteger(default=200, limits = (0, 9999))
1085         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_ENABLE_VOLTAGE_BEFORE_SWITCH_CMDS, configElement.value))
1086         config.sec.delay_after_enable_voltage_before_switch_command = x
1087
1088         x = ConfigInteger(default=700, limits = (0, 9999))
1089         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_BETWEEN_SWITCH_AND_MOTOR_CMD, configElement.value))
1090         config.sec.delay_between_switch_and_motor_command = x
1091
1092         x = ConfigInteger(default=500, limits = (0, 9999))
1093         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_MEASURE_IDLE_INPUTPOWER, configElement.value))
1094         config.sec.delay_after_voltage_change_before_measure_idle_inputpower = x
1095
1096         x = ConfigInteger(default=900, limits = (0, 9999))
1097         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_ENABLE_VOLTAGE_BEFORE_MOTOR_CMD, configElement.value))
1098         config.sec.delay_after_enable_voltage_before_motor_command = x
1099
1100         x = ConfigInteger(default=500, limits = (0, 9999))
1101         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_MOTOR_STOP_CMD, configElement.value))
1102         config.sec.delay_after_motor_stop_command = x
1103
1104         x = ConfigInteger(default=500, limits = (0, 9999))
1105         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_MOTOR_CMD, configElement.value))
1106         config.sec.delay_after_voltage_change_before_motor_command = x
1107
1108         x = ConfigInteger(default=70, limits = (0, 9999))
1109         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_BEFORE_SEQUENCE_REPEAT, configElement.value))
1110         config.sec.delay_before_sequence_repeat = x
1111
1112         x = ConfigInteger(default=360, limits = (0, 9999))
1113         x.addNotifier(lambda configElement: secClass.setParam(secClass.MOTOR_RUNNING_TIMEOUT, configElement.value))
1114         config.sec.motor_running_timeout = x
1115
1116         x = ConfigInteger(default=1, limits = (0, 5))
1117         x.addNotifier(lambda configElement: secClass.setParam(secClass.MOTOR_COMMAND_RETRIES, configElement.value))
1118         config.sec.motor_command_retries = x
1119
1120         x = ConfigInteger(default=50, limits = (0, 9999))
1121         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_DISEQC_RESET_CMD, configElement.value))
1122         config.sec.delay_after_diseqc_reset_cmd = x
1123
1124         x = ConfigInteger(default=150, limits = (0, 9999))
1125         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_DISEQC_PERIPHERIAL_POWERON_CMD, configElement.value))
1126         config.sec.delay_after_diseqc_peripherial_poweron_cmd = x
1127
1128 # TODO add support for satpos depending nims to advanced nim configuration
1129 # so a second/third/fourth cable from a motorized lnb can used behind a
1130 # diseqc 1.0 / diseqc 1.1 / toneburst switch
1131 # the C(++) part should can handle this
1132 # the configElement should be only visible when diseqc 1.2 is disabled
1133
1134 def InitNimManager(nimmgr, update_slots = []):
1135         hw = HardwareInfo()
1136         addNimConfig = False
1137         try:
1138                 config.Nims
1139         except:
1140                 addNimConfig = True
1141
1142         if addNimConfig:
1143                 InitSecParams()
1144                 config.Nims = ConfigSubList()
1145                 for x in range(len(nimmgr.nim_slots)):
1146                         config.Nims.append(ConfigSubsection())
1147
1148         lnb_choices = {
1149                 "universal_lnb": _("Universal LNB"),
1150                 "unicable": _("Unicable"),
1151                 "c_band": _("C-Band"),
1152                 "user_defined": _("User defined")}
1153
1154         lnb_choices_default = "universal_lnb"
1155
1156         unicablelnbproducts = {}
1157         unicablematrixproducts = {}
1158         doc = xml.etree.cElementTree.parse(eEnv.resolve("${datadir}/enigma2/unicable.xml"))
1159         root = doc.getroot()
1160
1161         entry = root.find("lnb")
1162         lscr=("scr1","scr2","scr3","scr4","scr5","scr6","scr7","scr8","scr9","scr10",
1163                 "scr11","scr12","scr13","scr14","scr15","scr16","scr17","scr18","scr19","scr20",
1164                 "scr21","scr22","scr23","scr24","scr25","scr26","scr27","scr28","scr29","scr30",
1165                 "scr31","scr32")
1166         for manufacturer in entry.getchildren():
1167                 m={}
1168                 for product in manufacturer.getchildren():
1169                         p={}                                                                                                                                            #new dict empty for new product
1170                         scr=[]
1171                         for i in range(len(lscr)):
1172                                 scr.append(product.get(lscr[i],"0"))
1173                         for i in range(len(lscr)):
1174                                 if scr[len(lscr)-i-1] == "0":
1175                                         scr.pop()
1176                                 else:
1177                                         break;
1178
1179                         p.update({"frequencies":tuple(scr)})                                                                            #add scr frequencies to dict product
1180
1181                         diction = product.get("format","EN50494").upper()
1182                         if diction =="JESS" or diction =="UNICABLE2" or diction =="SCD2" or diction =="EN50607":
1183                                 diction = "EN50607"
1184                         else:
1185                                 diction = "EN50494"
1186                         p.update({"diction":tuple([diction])})                                                                          #add diction to dict product
1187
1188                         positions=[]
1189                         positions.append(int(product.get("positions",1)))
1190                         for cnt in range(positions[0]):
1191                                 lof=[]
1192                                 lof.append(int(product.get("lofl",9750)))
1193                                 lof.append(int(product.get("lofh",10600)))
1194                                 lof.append(int(product.get("threshold",11700)))
1195                                 positions.append(tuple(lof))
1196
1197                         p.update({"positions":tuple(positions)})                                                                        #add positons to dict product.
1198
1199                         m.update({product.get("name"):p})                                                                                       #add dict product to dict manufacturer
1200                 unicablelnbproducts.update({manufacturer.get("name"):m})
1201
1202         entry = root.find("matrix")
1203         for manufacturer in entry.getchildren():
1204                 m={}
1205                 for product in manufacturer.getchildren():
1206                         p={}    #new dict empty for new product
1207                         scr=[]
1208                         for i in range(len(lscr)):
1209                                 scr.append(product.get(lscr[i],"0"))
1210                         for i in range(len(lscr)):
1211                                 if scr[len(lscr)-i-1] == "0":
1212                                         scr.pop()
1213                                 else:
1214                                         break;
1215
1216                         p.update({"frequencies":tuple(scr)})                                                                            #add scr frequencies to dict product
1217
1218                         diction = product.get("format","EN50494").upper()
1219                         if diction =="JESS" or diction =="UNICABLE2" or diction =="SCD2" or diction =="EN50607":
1220                                 diction = "EN50607"
1221                         else:
1222                                 diction = "EN50494"
1223                         p.update({"diction":tuple([diction])})                                                                          #add diction to dict product
1224
1225                         positions=[]
1226                         positions.append(int(product.get("positions",1)))
1227                         for cnt in range(positions[0]):
1228                                 lof=[]
1229                                 lof.append(int(product.get("lofl",9750)))
1230                                 lof.append(int(product.get("lofh",10600)))
1231                                 lof.append(int(product.get("threshold",11700)))
1232                                 positions.append(tuple(lof))
1233
1234                         p.update({"positions":tuple(positions)})                                                                        #add positons to dict product
1235
1236                         m.update({product.get("name"):p})                                                                                       #add dict product to dict manufacturer
1237                 unicablematrixproducts.update({manufacturer.get("name"):m})                                             #add dict manufacturer to dict unicablematrixproducts
1238
1239         UnicableLnbManufacturers = unicablelnbproducts.keys()
1240         UnicableLnbManufacturers.sort()
1241         UnicableMatrixManufacturers = unicablematrixproducts.keys()
1242         UnicableMatrixManufacturers.sort()
1243
1244         unicable_choices = {
1245                 "unicable_lnb": _("Unicable LNB"),
1246                 "unicable_matrix": _("Unicable Martix"),
1247                 "unicable_user": "Unicable "+_("User defined")}
1248         unicable_choices_default = "unicable_lnb"
1249
1250         advanced_lnb_satcr_user_choicesEN50494 = [("1", "SatCR 1"), ("2", "SatCR 2"), ("3", "SatCR 3"), ("4", "SatCR 4"), ("5", "SatCR 5"), ("6", "SatCR 6"), ("7", "SatCR 7"), ("8", "SatCR 8")]
1251
1252         advanced_lnb_satcr_user_choicesEN50607 = [("1", "SatCR 1"), ("2", "SatCR 2"), ("3", "SatCR 3"), ("4", "SatCR 4"), ("5", "SatCR 5"), ("6", "SatCR 6"), ("7", "SatCR 7"), ("8", "SatCR 8"),
1253                                                                    ("9", "SatCR 9"), ("10", "SatCR 10"), ("11", "SatCR 11"), ("12", "SatCR 12"), ("13", "SatCR 13"), ("14", "SatCR 14"), ("15", "SatCR 15"), ("16", "SatCR 16"),
1254                                                                    ("17", "SatCR 17"), ("18", "SatCR 18"), ("19", "SatCR 19"), ("20", "SatCR 20"), ("21", "SatCR 21"), ("22", "SatCR 22"), ("23", "SatCR 23"), ("24", "SatCR 24"),
1255                                                                    ("25", "SatCR 25"), ("26", "SatCR 26"), ("27", "SatCR 27"), ("28", "SatCR 28"), ("29", "SatCR 29"), ("30", "SatCR 30"), ("31", "SatCR 31"), ("32", "SatCR 32")]
1256
1257         advanced_lnb_diction_user_choices = [("EN50494", "Unicable(EN50494)"), ("EN50607", "JESS(EN50607)")]
1258
1259         prio_list = [ ("-1", _("Auto")) ]
1260         prio_list += [(str(prio), str(prio)) for prio in range(65)+range(14000,14065)+range(19000,19065)]
1261
1262         advanced_lnb_csw_choices = [("none", _("None")), ("AA", _("AA")), ("AB", _("AB")), ("BA", _("BA")), ("BB", _("BB"))]
1263         advanced_lnb_csw_choices += [(str(0xF0|y), "Input " + str(y+1)) for y in range(0, 16)]
1264
1265         advanced_lnb_ucsw_choices = [("0", _("None"))] + [(str(y), "Input " + str(y)) for y in range(1, 17)]
1266
1267         diseqc_mode_choices = [
1268                 ("single", _("Single")), ("toneburst_a_b", _("Toneburst A/B")),
1269                 ("diseqc_a_b", _("DiSEqC A/B")), ("diseqc_a_b_c_d", _("DiSEqC A/B/C/D")),
1270                 ("positioner", _("Positioner"))]
1271
1272         positioner_mode_choices = [("usals", _("USALS")), ("manual", _("manual"))]
1273
1274         diseqc_satlist_choices = [(3601, _('nothing connected'), 1)] + nimmgr.satList
1275         
1276         longitude_orientation_choices = [("east", _("East")), ("west", _("West"))]
1277         latitude_orientation_choices = [("north", _("North")), ("south", _("South"))]
1278         turning_speed_choices = [("fast", _("Fast")), ("slow", _("Slow")), ("fast epoch", _("Fast epoch"))]
1279         
1280         advanced_satlist_choices = nimmgr.satList + [
1281                 (3601, _('All Satellites')+' 1', 1), (3602, _('All Satellites')+' 2', 1),
1282                 (3603, _('All Satellites')+' 3', 1), (3604, _('All Satellites')+' 4', 1)]
1283         advanced_lnb_choices = [("0", "not available")] + [(str(y), "LNB " + str(y)) for y in range(1, 65)]
1284         advanced_voltage_choices = [("polarization", _("Polarization")), ("13V", _("13 V")), ("18V", _("18 V"))]
1285         advanced_tonemode_choices = [("band", _("Band")), ("on", _("On")), ("off", _("Off"))]
1286         advanced_lnb_toneburst_choices = [("none", _("None")), ("A", _("A")), ("B", _("B"))]
1287         advanced_lnb_allsat_diseqcmode_choices = [("1_2", _("1.2"))]
1288         advanced_lnb_diseqcmode_choices = [("none", _("None")), ("1_0", _("1.0")), ("1_1", _("1.1")), ("1_2", _("1.2"))]
1289         advanced_lnb_commandOrder1_0_choices = [("ct", "committed, toneburst"), ("tc", "toneburst, committed")]
1290         advanced_lnb_commandOrder_choices = [
1291                 ("ct", "committed, toneburst"), ("tc", "toneburst, committed"),
1292                 ("cut", "committed, uncommitted, toneburst"), ("tcu", "toneburst, committed, uncommitted"),
1293                 ("uct", "uncommitted, committed, toneburst"), ("tuc", "toneburst, uncommitted, commmitted")]
1294         advanced_lnb_diseqc_repeat_choices = [("none", _("None")), ("one", _("One")), ("two", _("Two")), ("three", _("Three"))]
1295         advanced_lnb_fast_turning_btime = mktime(datetime(1970, 1, 1, 7, 0).timetuple());
1296         advanced_lnb_fast_turning_etime = mktime(datetime(1970, 1, 1, 19, 0).timetuple());
1297
1298         def configLOFChanged(configElement):
1299                 if configElement.value == "unicable":
1300                         x = configElement.slot_id
1301                         lnb = configElement.lnb_id
1302                         nim = config.Nims[x]
1303                         lnbs = nim.advanced.lnb
1304                         section = lnbs[lnb]
1305                         if isinstance(section.unicable, ConfigNothing):
1306                                 if lnb == 1:
1307                                         section.unicable = ConfigSelection(unicable_choices, unicable_choices_default)
1308 #                               elif lnb == 2:
1309                                 else:
1310                                         section.unicable = ConfigSelection(choices = {"unicable_matrix": _("Unicable Martix"),"unicable_user": "Unicable "+_("User defined")}, default = "unicable_matrix")
1311 #                                       section.unicable = ConfigSelection(choices = {"unicable_user": _("User defined")}, default = "unicable_user")
1312                         def fillUnicableConf(sectionDict, unicableproducts, vco_null_check):
1313                                 for manufacturer in unicableproducts:
1314                                         products = unicableproducts[manufacturer].keys()
1315                                         products.sort()
1316                                         products_valide = []
1317                                         products_valide_append = products_valide.append
1318                                         tmp = ConfigSubsection()
1319                                         tmp.scr = ConfigSubDict()
1320                                         tmp.vco = ConfigSubDict()
1321                                         tmp.lofl = ConfigSubDict()
1322                                         tmp.lofh = ConfigSubDict()
1323                                         tmp.loft = ConfigSubDict()
1324                                         tmp.positions = ConfigSubDict()
1325                                         tmp.diction = ConfigSubDict()
1326                                         for article in products:
1327                                                 positionslist = unicableproducts[manufacturer][article].get("positions")
1328                                                 positions = int(positionslist[0])
1329                                                 dictionlist = [unicableproducts[manufacturer][article].get("diction")]
1330                                                 if lnb <= positions or dictionlist[0][0] !="EN50607":
1331                                                         tmp.positions[article] = ConfigSubList()
1332                                                         tmp.positions[article].append(ConfigInteger(default=positions, limits = (positions, positions)))
1333                                                         tmp.diction[article] = ConfigSelection(choices = dictionlist, default = dictionlist[0][0])
1334
1335                                                         scrlist = []
1336                                                         scrlist_append = scrlist.append
1337                                                         vcolist=unicableproducts[manufacturer][article].get("frequencies")
1338                                                         tmp.vco[article] = ConfigSubList()
1339                                                         for cnt in range(1,len(vcolist)+1):
1340                                                                 vcofreq = int(vcolist[cnt-1])
1341                                                                 if vcofreq == 0 and vco_null_check:
1342                                                                         scrlist_append(("%d" %cnt,"SCR %d " %cnt +_("not used")))
1343                                                                 else:
1344                                                                         scrlist_append(("%d" %cnt,"SCR %d" %cnt))
1345                                                                 tmp.vco[article].append(ConfigInteger(default=vcofreq, limits = (vcofreq, vcofreq)))
1346
1347                                                         tmp.scr[article] = ConfigSelection(choices = scrlist, default = scrlist[0][0])
1348
1349                                                         tmp.lofl[article] = ConfigSubList()
1350                                                         tmp.lofh[article] = ConfigSubList()
1351                                                         tmp.loft[article] = ConfigSubList()
1352
1353                                                         tmp_lofl_article_append = tmp.lofl[article].append
1354                                                         tmp_lofh_article_append = tmp.lofh[article].append
1355                                                         tmp_loft_article_append = tmp.loft[article].append
1356                                                         
1357                                                         for cnt in range(1,positions+1):
1358                                                                 lofl = int(positionslist[cnt][0])
1359                                                                 lofh = int(positionslist[cnt][1])
1360                                                                 loft = int(positionslist[cnt][2])
1361                                                                 tmp_lofl_article_append(ConfigInteger(default=lofl, limits = (lofl, lofl)))
1362                                                                 tmp_lofh_article_append(ConfigInteger(default=lofh, limits = (lofh, lofh)))
1363                                                                 tmp_loft_article_append(ConfigInteger(default=loft, limits = (loft, loft)))
1364                                                         products_valide_append(article)
1365
1366                                         if len(products_valide)==0:
1367                                                 products_valide_append("None")
1368                                         tmp.product = ConfigSelection(choices = products_valide, default = products_valide[0])
1369                                         sectionDict[manufacturer] = tmp
1370
1371                         if lnb < 65:
1372                                 print "MATRIX"
1373                                 section.unicableMatrix = ConfigSubDict()
1374                                 section.unicableMatrixManufacturer = ConfigSelection(UnicableMatrixManufacturers, UnicableMatrixManufacturers[0])
1375                                 fillUnicableConf(section.unicableMatrix, unicablematrixproducts, True)
1376
1377                         if lnb < 2: #Konfiguration nur fuer LNB1 zulassen
1378                                 print "LNB"
1379                                 section.unicableLnb = ConfigSubDict()
1380                                 section.unicableLnbManufacturer = ConfigSelection(UnicableLnbManufacturers, UnicableLnbManufacturers[0])
1381                                 fillUnicableConf(section.unicableLnb, unicablelnbproducts, False)
1382
1383 #TODO satpositions for satcruser
1384
1385                         section.dictionuser = ConfigSelection(advanced_lnb_diction_user_choices, default="EN50494")
1386                         section.satcruserEN50494 = ConfigSelection(advanced_lnb_satcr_user_choicesEN50494, default="1")
1387                         section.satcruserEN50607 = ConfigSelection(advanced_lnb_satcr_user_choicesEN50607, default="1")
1388
1389                         tmp = ConfigSubList()
1390                         tmp.append(ConfigInteger(default=1284, limits = (950, 2150)))
1391                         tmp.append(ConfigInteger(default=1400, limits = (950, 2150)))
1392                         tmp.append(ConfigInteger(default=1516, limits = (950, 2150)))
1393                         tmp.append(ConfigInteger(default=1632, limits = (950, 2150)))
1394                         tmp.append(ConfigInteger(default=1748, limits = (950, 2150)))
1395                         tmp.append(ConfigInteger(default=1864, limits = (950, 2150)))
1396                         tmp.append(ConfigInteger(default=1980, limits = (950, 2150)))
1397                         tmp.append(ConfigInteger(default=2096, limits = (950, 2150)))
1398                         section.satcrvcouserEN50494 = tmp 
1399
1400                         tmp.append(ConfigInteger(default=1284, limits = (950, 2150)))
1401                         tmp.append(ConfigInteger(default=1400, limits = (950, 2150)))
1402                         tmp.append(ConfigInteger(default=1516, limits = (950, 2150)))
1403                         tmp.append(ConfigInteger(default=1632, limits = (950, 2150)))
1404                         tmp.append(ConfigInteger(default=1748, limits = (950, 2150)))
1405                         tmp.append(ConfigInteger(default=1864, limits = (950, 2150)))
1406                         tmp.append(ConfigInteger(default=1980, limits = (950, 2150)))
1407                         tmp.append(ConfigInteger(default=2096, limits = (950, 2150)))
1408                         tmp.append(ConfigInteger(default=1284, limits = (950, 2150)))
1409                         tmp.append(ConfigInteger(default=1400, limits = (950, 2150)))
1410                         tmp.append(ConfigInteger(default=1516, limits = (950, 2150)))
1411                         tmp.append(ConfigInteger(default=1632, limits = (950, 2150)))
1412                         tmp.append(ConfigInteger(default=1748, limits = (950, 2150)))
1413                         tmp.append(ConfigInteger(default=1864, limits = (950, 2150)))
1414                         tmp.append(ConfigInteger(default=1980, limits = (950, 2150)))
1415                         tmp.append(ConfigInteger(default=2096, limits = (950, 2150)))
1416                         tmp.append(ConfigInteger(default=1284, limits = (950, 2150)))
1417                         tmp.append(ConfigInteger(default=1400, limits = (950, 2150)))
1418                         tmp.append(ConfigInteger(default=1516, limits = (950, 2150)))
1419                         tmp.append(ConfigInteger(default=1632, limits = (950, 2150)))
1420                         tmp.append(ConfigInteger(default=1748, limits = (950, 2150)))
1421                         tmp.append(ConfigInteger(default=1864, limits = (950, 2150)))
1422                         tmp.append(ConfigInteger(default=1980, limits = (950, 2150)))
1423                         tmp.append(ConfigInteger(default=2096, limits = (950, 2150)))
1424                         section.satcrvcouserEN50607 = tmp 
1425
1426                         nim.advanced.unicableconnected = ConfigYesNo(default=False)
1427                         nim.advanced.unicableconnectedTo = ConfigSelection([(str(id), nimmgr.getNimDescription(id)) for id in nimmgr.getNimListOfType("DVB-S") if id != x])
1428
1429         def configDiSEqCModeChanged(configElement):
1430                 section = configElement.section
1431                 if configElement.value == "1_2" and isinstance(section.longitude, ConfigNothing):
1432                         section.longitude = ConfigFloat(default = [5,100], limits = [(0,359),(0,999)])
1433                         section.longitudeOrientation = ConfigSelection(longitude_orientation_choices, "east")
1434                         section.latitude = ConfigFloat(default = [50,767], limits = [(0,359),(0,999)])
1435                         section.latitudeOrientation = ConfigSelection(latitude_orientation_choices, "north")
1436                         section.powerMeasurement = ConfigYesNo(default=True)
1437                         section.powerThreshold = ConfigInteger(default=hw.get_device_name() == "dm7025" and 50 or 15, limits=(0, 100))
1438                         section.turningSpeed = ConfigSelection(turning_speed_choices, "fast")
1439                         section.fastTurningBegin = ConfigDateTime(default=advanced_lnb_fast_turning_btime, formatstring = _("%H:%M"), increment = 600)
1440                         section.fastTurningEnd = ConfigDateTime(default=advanced_lnb_fast_turning_etime, formatstring = _("%H:%M"), increment = 600)
1441
1442         def configLNBChanged(configElement):
1443                 x = configElement.slot_id
1444                 nim = config.Nims[x]
1445                 if isinstance(configElement.value, tuple):
1446                         lnb = int(configElement.value[0])
1447                 else:
1448                         lnb = int(configElement.value)
1449                 lnbs = nim.advanced.lnb
1450                 if lnb and lnb not in lnbs:
1451                         section = lnbs[lnb] = ConfigSubsection()
1452                         section.lofl = ConfigInteger(default=9750, limits = (0, 99999))
1453                         section.lofh = ConfigInteger(default=10600, limits = (0, 99999))
1454                         section.threshold = ConfigInteger(default=11700, limits = (0, 99999))
1455 #                       section.output_12v = ConfigSelection(choices = [("0V", _("0 V")), ("12V", _("12 V"))], default="0V")
1456                         section.increased_voltage = ConfigYesNo(False)
1457                         section.toneburst = ConfigSelection(advanced_lnb_toneburst_choices, "none")
1458                         section.longitude = ConfigNothing()
1459                         if lnb > 64:
1460                                 tmp = ConfigSelection(advanced_lnb_allsat_diseqcmode_choices, "1_2")
1461                                 tmp.section = section
1462                                 configDiSEqCModeChanged(tmp)
1463                         else:
1464                                 tmp = ConfigSelection(advanced_lnb_diseqcmode_choices, "none")
1465                                 tmp.section = section
1466                                 tmp.addNotifier(configDiSEqCModeChanged)
1467                         section.diseqcMode = tmp
1468                         section.commitedDiseqcCommand = ConfigSelection(advanced_lnb_csw_choices)
1469                         section.fastDiseqc = ConfigYesNo(False)
1470                         section.sequenceRepeat = ConfigYesNo(False)
1471                         section.commandOrder1_0 = ConfigSelection(advanced_lnb_commandOrder1_0_choices, "ct")
1472                         section.commandOrder = ConfigSelection(advanced_lnb_commandOrder_choices, "ct")
1473                         section.uncommittedDiseqcCommand = ConfigSelection(advanced_lnb_ucsw_choices)
1474                         section.diseqcRepeats = ConfigSelection(advanced_lnb_diseqc_repeat_choices, "none")
1475                         section.prio = ConfigSelection(prio_list, "-1")
1476                         section.unicable = ConfigNothing()
1477                         tmp = ConfigSelection(lnb_choices, lnb_choices_default)
1478                         tmp.slot_id = x
1479                         tmp.lnb_id = lnb
1480                         tmp.addNotifier(configLOFChanged, initial_call = False)
1481                         section.lof = tmp
1482
1483         def configModeChanged(configMode):
1484                 slot_id = configMode.slot_id
1485                 nim = config.Nims[slot_id]
1486                 if configMode.value == "advanced" and isinstance(nim.advanced, ConfigNothing):
1487                         # advanced config:
1488                         nim.advanced = ConfigSubsection()
1489                         nim.advanced.sat = ConfigSubDict()
1490                         nim.advanced.sats = getConfigSatlist(192, advanced_satlist_choices)
1491                         nim.advanced.lnb = ConfigSubDict()
1492                         nim.advanced.lnb[0] = ConfigNothing()
1493                         for x in nimmgr.satList:
1494                                 tmp = ConfigSubsection()
1495                                 tmp.voltage = ConfigSelection(advanced_voltage_choices, "polarization")
1496                                 tmp.tonemode = ConfigSelection(advanced_tonemode_choices, "band")
1497                                 tmp.usals = ConfigYesNo(True)
1498                                 tmp.rotorposition = ConfigInteger(default=1, limits=(1, 255))
1499                                 lnb = ConfigSelection(advanced_lnb_choices, "0")
1500                                 lnb.slot_id = slot_id
1501                                 lnb.addNotifier(configLNBChanged, initial_call = False)
1502                                 tmp.lnb = lnb
1503                                 nim.advanced.sat[x[0]] = tmp
1504                         for x in range(3601, 3605):
1505                                 tmp = ConfigSubsection()
1506                                 tmp.voltage = ConfigSelection(advanced_voltage_choices, "polarization")
1507                                 tmp.tonemode = ConfigSelection(advanced_tonemode_choices, "band")
1508                                 tmp.usals = ConfigYesNo(default=True)
1509                                 tmp.rotorposition = ConfigInteger(default=1, limits=(1, 255))
1510                                 lnbnum = 65+x-3601
1511                                 lnb = ConfigSelection([("0", "not available"), (str(lnbnum), "LNB %d"%(lnbnum))], "0")
1512                                 lnb.slot_id = slot_id
1513                                 lnb.addNotifier(configLNBChanged, initial_call = False)
1514                                 tmp.lnb = lnb
1515                                 nim.advanced.sat[x] = tmp
1516
1517         def toneAmplitudeChanged(configElement):
1518                 fe_id = configElement.fe_id
1519                 slot_id = configElement.slot_id
1520                 if nimmgr.nim_slots[slot_id].description == 'Alps BSBE2':
1521                         open("/proc/stb/frontend/%d/tone_amplitude" %(fe_id), "w").write(configElement.value)
1522
1523         def createSatConfig(nim, x, empty_slots):
1524                 print "[Nimmanager] slot %d create config satellite.." % slot.slot
1525                 try:
1526                         nim.toneAmplitude
1527                 except:
1528                         nim.toneAmplitude = ConfigSelection([("11", "340mV"), ("10", "360mV"), ("9", "600mV"), ("8", "700mV"), ("7", "800mV"), ("6", "900mV"), ("5", "1100mV")], "7")
1529                         nim.toneAmplitude.fe_id = x - empty_slots
1530                         nim.toneAmplitude.slot_id = x
1531                         nim.toneAmplitude.addNotifier(toneAmplitudeChanged)
1532                         nim.diseqc13V = ConfigYesNo(False)
1533                         nim.diseqcMode = ConfigSelection(diseqc_mode_choices, "diseqc_a_b")
1534                         nim.connectedTo = ConfigSelection([(str(id), nimmgr.getNimDescription(id)) for id in nimmgr.getNimListOfType("DVB-S") if id != x])
1535                         nim.simpleSingleSendDiSEqC = ConfigYesNo(False)
1536                         nim.simpleDiSEqCSetVoltageTone = ConfigYesNo(True)
1537                         nim.simpleDiSEqCOnlyOnSatChange = ConfigYesNo(False)
1538                         nim.diseqcA = getConfigSatlist(192, diseqc_satlist_choices)
1539                         nim.diseqcB = getConfigSatlist(130, diseqc_satlist_choices)
1540                         nim.diseqcC = ConfigSatlist(list = diseqc_satlist_choices)
1541                         nim.diseqcD = ConfigSatlist(list = diseqc_satlist_choices)
1542                         nim.positionerMode = ConfigSelection(positioner_mode_choices, "usals")
1543                         nim.longitude = ConfigFloat(default=[5,100], limits=[(0,359),(0,999)])
1544                         nim.longitudeOrientation = ConfigSelection(longitude_orientation_choices, "east")
1545                         nim.latitude = ConfigFloat(default=[50,767], limits=[(0,359),(0,999)])
1546                         nim.latitudeOrientation = ConfigSelection(latitude_orientation_choices, "north")
1547                         nim.powerMeasurement = ConfigYesNo(True)
1548                         nim.powerThreshold = ConfigInteger(default=hw.get_device_name() == "dm8000" and 15 or 50, limits=(0, 100))
1549                         nim.turningSpeed = ConfigSelection(turning_speed_choices, "fast")
1550                         btime = datetime(1970, 1, 1, 7, 0);
1551                         nim.fastTurningBegin = ConfigDateTime(default = mktime(btime.timetuple()), formatstring = _("%H:%M"), increment = 900)
1552                         etime = datetime(1970, 1, 1, 19, 0);
1553                         nim.fastTurningEnd = ConfigDateTime(default = mktime(etime.timetuple()), formatstring = _("%H:%M"), increment = 900)
1554
1555         def createCableConfig(nim, x):
1556                 print "[Nimmanager] slot %d create config cable.." % slot.slot
1557                 try:
1558                         nim.cable
1559                 except:
1560                         list = [ ]
1561                         n = 0
1562                         for x in nimmgr.cablesList:
1563                                 list.append((str(n), x[0]))
1564                                 n += 1
1565                         nim.cable = ConfigSubsection()
1566                         possible_scan_types = [("bands", _("Frequency bands")), ("steps", _("Frequency steps"))]
1567                         if n:
1568                                 possible_scan_types.append(("provider", _("Provider")))
1569                                 nim.cable.scan_provider = ConfigSelection(default = "0", choices = list)
1570                         nim.cable.scan_type = ConfigSelection(default = "bands", choices = possible_scan_types)
1571                         nim.cable.scan_band_EU_VHF_I = ConfigYesNo(default = True)
1572                         nim.cable.scan_band_EU_MID = ConfigYesNo(default = True)
1573                         nim.cable.scan_band_EU_VHF_III = ConfigYesNo(default = True)
1574                         nim.cable.scan_band_EU_UHF_IV = ConfigYesNo(default = True)
1575                         nim.cable.scan_band_EU_UHF_V = ConfigYesNo(default = True)
1576                         nim.cable.scan_band_EU_SUPER = ConfigYesNo(default = True)
1577                         nim.cable.scan_band_EU_HYPER = ConfigYesNo(default = True)
1578                         nim.cable.scan_band_US_LOW = ConfigYesNo(default = False)
1579                         nim.cable.scan_band_US_MID = ConfigYesNo(default = False)
1580                         nim.cable.scan_band_US_HIGH = ConfigYesNo(default = False)
1581                         nim.cable.scan_band_US_SUPER = ConfigYesNo(default = False)
1582                         nim.cable.scan_band_US_HYPER = ConfigYesNo(default = False)
1583                         nim.cable.scan_frequency_steps = ConfigInteger(default = 1000, limits = (1000, 10000))
1584                         nim.cable.scan_mod_qam16 = ConfigYesNo(default = False)
1585                         nim.cable.scan_mod_qam32 = ConfigYesNo(default = False)
1586                         nim.cable.scan_mod_qam64 = ConfigYesNo(default = True)
1587                         nim.cable.scan_mod_qam128 = ConfigYesNo(default = False)
1588                         nim.cable.scan_mod_qam256 = ConfigYesNo(default = True)
1589                         nim.cable.scan_sr_6900 = ConfigYesNo(default = True)
1590                         nim.cable.scan_sr_6875 = ConfigYesNo(default = True)
1591                         nim.cable.scan_sr_ext1 = ConfigInteger(default = 0, limits = (0, 7230))
1592                         nim.cable.scan_sr_ext2 = ConfigInteger(default = 0, limits = (0, 7230))
1593
1594         def createTerrestrialConfig(nim, x):
1595                 print "[Nimmanager] slot %d create config terrestrial.." % slot.slot
1596                 try:
1597                         nim.terrestrial
1598                 except:
1599                         list = []
1600                         n = 0
1601                         for x in nimmgr.terrestrialsList:
1602                                 list.append((str(n), x[0]))
1603                                 n += 1
1604                         nim.terrestrial = ConfigSelection(choices = list)
1605                         nim.terrestrial_5V = ConfigOnOff()
1606
1607         def tunerTypeChanged(nimmgr, configElement):
1608                 fe_id = configElement.fe_id
1609                 eDVBResourceManager.getInstance().setFrontendType(nimmgr.nim_slots[fe_id].frontend_id, nimmgr.nim_slots[fe_id].getType())
1610                 import os
1611                 if os.path.exists("/proc/stb/frontend/%d/mode" % fe_id):
1612                         cur_type = int(open("/proc/stb/frontend/%d/mode" % (fe_id), "r").read())
1613                         if cur_type == int(configElement.value):
1614                                 print "tuner type is already already %d" %cur_type
1615                                 return
1616                                 print "tunerTypeChanged feid %d from %d to mode %d" % (fe_id, cur_type, int(configElement.value))
1617
1618                 print "tunerTypeChanged feid %d, mode %d" % (fe_id, int(configElement.value))
1619         
1620                 try:
1621                         oldvalue = open("/sys/module/dvb_core/parameters/dvb_shutdown_timeout", "r").readline()
1622                         open("/sys/module/dvb_core/parameters/dvb_shutdown_timeout", "w").write("0")
1623                 except:
1624                         print "[info] no /sys/module/dvb_core/parameters/dvb_shutdown_timeout available"
1625
1626                 frontend = eDVBResourceManager.getInstance().allocateRawChannel(fe_id).getFrontend()
1627                 frontend.closeFrontend()
1628
1629                 if os.path.exists("/proc/stb/frontend/%d/mode" % fe_id):
1630                         open("/proc/stb/frontend/%d/mode" % (fe_id), "w").write(configElement.value)
1631                 
1632                 frontend.reopenFrontend()
1633                 try:
1634                         open("/sys/module/dvb_core/parameters/dvb_shutdown_timeout", "w").write(oldvalue)
1635                 except:
1636                         print "[info] no /sys/module/dvb_core/parameters/dvb_shutdown_timeout available"
1637                 nimmgr.enumerateNIMs()
1638
1639         empty_slots = 0
1640         for slot in nimmgr.nim_slots:
1641                 print "[InitNimManager] check multi type slot %d" % slot.slot
1642                 x = slot.slot
1643                 nim = config.Nims[x]
1644                 addMultiType = False
1645                 try:
1646                         nim.multiType
1647                 except:
1648                         addMultiType = True
1649                 if slot.isMultiType() and addMultiType:
1650                         print "[InitNimManager] slot %d is multi type : " % slot.slot, slot.getMultiTypeList()
1651                         typeList = []
1652                         for id in slot.getMultiTypeList().keys():
1653                                 type = slot.getMultiTypeList()[id]
1654                                 typeList.append((id, type))
1655                         nim.multiType = ConfigSelection(typeList, "0")
1656                         nim.multiType.fe_id = x - empty_slots
1657                         nim.multiType.addNotifier(boundFunction(tunerTypeChanged, nimmgr))
1658
1659         empty_slots = 0
1660         for slot in nimmgr.nim_slots:
1661                 x = slot.slot
1662                 nim = config.Nims[x]
1663
1664                 if update_slots and (x not in update_slots):
1665                         continue
1666
1667                 if slot.isCompatible("DVB-S"):
1668                         createSatConfig(nim, x, empty_slots)
1669                         config_mode_choices = [ ("nothing", _("nothing connected")),
1670                                 ("simple", _("simple")), ("advanced", _("advanced"))]
1671                         if len(nimmgr.getNimListOfType(slot.getType(), exception = x)) > 0:
1672                                 config_mode_choices.append(("equal", _("equal to")))
1673                                 config_mode_choices.append(("satposdepends", _("second cable of motorized LNB")))
1674                         if len(nimmgr.canConnectTo(x)) > 0:
1675                                 config_mode_choices.append(("loopthrough", _("loopthrough to")))
1676                         nim.advanced = ConfigNothing()
1677                         tmp = ConfigSelection(config_mode_choices, "nothing")
1678                         tmp.slot_id = x
1679                         tmp.addNotifier(configModeChanged, initial_call = False)
1680                         nim.configMode = tmp
1681                 elif slot.isCompatible("DVB-C"):
1682                         nim.configMode = ConfigSelection(
1683                                 choices = {
1684                                         "enabled": _("enabled"),
1685                                         "nothing": _("nothing connected"),
1686                                         },
1687                                 default = "enabled")
1688                         createCableConfig(nim, x)
1689                 elif slot.isCompatible("DVB-T"):
1690                         nim.configMode = ConfigSelection(
1691                                 choices = {
1692                                         "enabled": _("enabled"),
1693                                         "nothing": _("nothing connected"),
1694                                         },
1695                                 default = "enabled")
1696                         createTerrestrialConfig(nim, x)
1697                 else:
1698                         print "[Nimmanager] slot %d create config nothing.." % slot.slot
1699                         empty_slots += 1
1700                         nim.configMode = ConfigSelection(choices = { "nothing": _("disabled") }, default="nothing");
1701                         if slot.getType() is not None:
1702                                 print "pls add support for this frontend type!", slot.getType()
1703 #                       assert False
1704
1705         nimmgr.sec = SecConfigure(nimmgr)
1706
1707 nimmanager = NimManager()