update dvbapp.
[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                 # remove nims, that have a conntectedTo reference on
880                 for testnim in slots[:]:
881                         for nim in self.getNimListOfType("DVB-S", slotid):
882                                 nimConfig = self.getNimConfig(nim)
883                                 if nimConfig.content.items.has_key("configMode") and nimConfig.configMode.value == "loopthrough" and int(nimConfig.connectedTo.value) == testnim:
884                                         slots.remove(testnim)
885                                         break 
886                 slots.sort()
887                 
888                 return slots
889         
890         def canEqualTo(self, slotid):
891                 type = self.getNimType(slotid)
892                 if type == "DVB-S2":
893                         type = "DVB-S"
894                 elif type == "DVB-T2":
895                         type = "DVB-T"
896                 nimList = self.getNimListOfType(type, slotid)
897                 for nim in nimList[:]:
898                         mode = self.getNimConfig(nim)
899                         if mode.configMode.value == "loopthrough" or mode.configMode.value == "satposdepends":
900                                 nimList.remove(nim)
901                 return nimList
902
903         def canDependOn(self, slotid):
904                 type = self.getNimType(slotid)
905                 if type == "DVB-S2":
906                         type = "DVB-S"
907                 elif type == "DVB-T2":
908                         type = "DVB-T"
909                 nimList = self.getNimListOfType(type, slotid)
910                 positionerList = []
911                 for nim in nimList[:]:
912                         mode = self.getNimConfig(nim)
913                         nimHaveRotor = mode.configMode.value == "simple" and mode.diseqcMode.value == "positioner"
914                         if not nimHaveRotor and mode.configMode.value == "advanced":
915                                 for x in range(3601, 3605):
916                                         lnb = int(mode.advanced.sat[x].lnb.value)
917                                         if lnb != 0:
918                                                 nimHaveRotor = True
919                                                 break
920                                 if not nimHaveRotor:
921                                         for sat in mode.advanced.sat.values():
922                                                 lnb_num = int(sat.lnb.value)
923                                                 diseqcmode = lnb_num and mode.advanced.lnb[lnb_num].diseqcMode.value or ""
924                                                 if diseqcmode == "1_2":
925                                                         nimHaveRotor = True
926                                                         break
927                         if nimHaveRotor:
928                                 alreadyConnected = False
929                                 for testnim in nimList:
930                                         testmode = self.getNimConfig(testnim)
931                                         if testmode.configMode.value == "satposdepends" and int(testmode.connectedTo.value) == int(nim):
932                                                 alreadyConnected = True
933                                                 break
934                                 if not alreadyConnected:
935                                         positionerList.append(nim)
936                 return positionerList
937         
938         def getNimConfig(self, slotid):
939                 return config.Nims[slotid]
940         
941         def getSatName(self, pos):
942                 for sat in self.satList:
943                         if sat[0] == pos:
944                                 return sat[1]
945                 return _("N/A")
946
947         def getSatList(self):
948                 return self.satList
949         
950         # returns True if something is configured to be connected to this nim
951         # if slotid == -1, returns if something is connected to ANY nim
952         def somethingConnected(self, slotid = -1):
953                 if (slotid == -1):
954                         connected = False
955                         for id in range(self.getSlotCount()):
956                                 if self.somethingConnected(id):
957                                         connected = True
958                         return connected
959                 else:
960                         nim = config.Nims[slotid]
961                         configMode = nim.configMode.value
962                 
963                         if self.nim_slots[slotid].isCompatible("DVB-S") or self.nim_slots[slotid].isCompatible("DVB-T") or self.nim_slots[slotid].isCompatible("DVB-C"):
964                                 return not (configMode == "nothing")            
965
966         def getSatListForNim(self, slotid):
967                 list = []
968                 if self.nim_slots[slotid].isCompatible("DVB-S"):
969                         nim = config.Nims[slotid]
970                         #print "slotid:", slotid
971
972                         #print "self.satellites:", self.satList[config.Nims[slotid].diseqcA.index]
973                         #print "diseqcA:", config.Nims[slotid].diseqcA.value
974                         configMode = nim.configMode.value
975
976                         if configMode == "equal":
977                                 slotid = int(nim.connectedTo.value)
978                                 nim = config.Nims[slotid]
979                                 configMode = nim.configMode.value
980                         elif configMode == "loopthrough":
981                                 slotid = self.sec.getRoot(slotid, int(nim.connectedTo.value))
982                                 nim = config.Nims[slotid]
983                                 configMode = nim.configMode.value
984
985                         if configMode == "simple":
986                                 dm = nim.diseqcMode.value
987                                 if dm in ("single", "toneburst_a_b", "diseqc_a_b", "diseqc_a_b_c_d"):
988                                         if nim.diseqcA.orbital_position != 3601:
989                                                 list.append(self.satList[nim.diseqcA.index-1])
990                                 if dm in ("toneburst_a_b", "diseqc_a_b", "diseqc_a_b_c_d"):
991                                         if nim.diseqcB.orbital_position != 3601:
992                                                 list.append(self.satList[nim.diseqcB.index-1])
993                                 if dm == "diseqc_a_b_c_d":
994                                         if nim.diseqcC.orbital_position != 3601:
995                                                 list.append(self.satList[nim.diseqcC.index-1])
996                                         if nim.diseqcD.orbital_position != 3601:
997                                                 list.append(self.satList[nim.diseqcD.index-1])
998                                 if dm == "positioner":
999                                         for x in self.satList:
1000                                                 list.append(x)
1001                         elif configMode == "advanced":
1002                                 for x in range(3601, 3605):
1003                                         if int(nim.advanced.sat[x].lnb.value) != 0:
1004                                                 for x in self.satList:
1005                                                         list.append(x)
1006                                 if not list:
1007                                         for x in self.satList:
1008                                                 if int(nim.advanced.sat[x[0]].lnb.value) != 0:
1009                                                         list.append(x)
1010                 return list
1011
1012         def getRotorSatListForNim(self, slotid):
1013                 list = []
1014                 if self.nim_slots[slotid].isCompatible("DVB-S"):
1015                         #print "slotid:", slotid
1016                         #print "self.satellites:", self.satList[config.Nims[slotid].diseqcA.value]
1017                         #print "diseqcA:", config.Nims[slotid].diseqcA.value
1018                         configMode = config.Nims[slotid].configMode.value
1019                         if configMode == "simple":
1020                                 if config.Nims[slotid].diseqcMode.value == "positioner":
1021                                         for x in self.satList:
1022                                                 list.append(x)
1023                         elif configMode == "advanced":
1024                                 nim = config.Nims[slotid]
1025                                 for x in range(3601, 3605):
1026                                         if int(nim.advanced.sat[x].lnb.value) != 0:
1027                                                 for x in self.satList:
1028                                                         list.append(x)
1029                                 if not list:
1030                                         for x in self.satList:
1031                                                 lnbnum = int(nim.advanced.sat[x[0]].lnb.value)
1032                                                 if lnbnum != 0:
1033                                                         lnb = nim.advanced.lnb[lnbnum]
1034                                                         if lnb.diseqcMode.value == "1_2":
1035                                                                 list.append(x)
1036                 return list
1037
1038 def InitSecParams():
1039         config.sec = ConfigSubsection()
1040
1041         x = ConfigInteger(default=25, limits = (0, 9999))
1042         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_CONT_TONE_DISABLE_BEFORE_DISEQC, configElement.value))
1043         config.sec.delay_after_continuous_tone_disable_before_diseqc = x
1044
1045         x = ConfigInteger(default=10, limits = (0, 9999))
1046         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_FINAL_CONT_TONE_CHANGE, configElement.value))
1047         config.sec.delay_after_final_continuous_tone_change = x
1048
1049         x = ConfigInteger(default=10, limits = (0, 9999))
1050         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_FINAL_VOLTAGE_CHANGE, configElement.value))
1051         config.sec.delay_after_final_voltage_change = x
1052
1053         x = ConfigInteger(default=120, limits = (0, 9999))
1054         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_BETWEEN_DISEQC_REPEATS, configElement.value))
1055         config.sec.delay_between_diseqc_repeats = x
1056
1057         x = ConfigInteger(default=50, limits = (0, 9999))
1058         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_LAST_DISEQC_CMD, configElement.value))
1059         config.sec.delay_after_last_diseqc_command = x
1060
1061         x = ConfigInteger(default=50, limits = (0, 9999))
1062         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_TONEBURST, configElement.value))
1063         config.sec.delay_after_toneburst = x
1064
1065         x = ConfigInteger(default=20, limits = (0, 9999))
1066         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_SWITCH_CMDS, configElement.value))
1067         config.sec.delay_after_change_voltage_before_switch_command = x
1068
1069         x = ConfigInteger(default=200, limits = (0, 9999))
1070         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_ENABLE_VOLTAGE_BEFORE_SWITCH_CMDS, configElement.value))
1071         config.sec.delay_after_enable_voltage_before_switch_command = x
1072
1073         x = ConfigInteger(default=700, limits = (0, 9999))
1074         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_BETWEEN_SWITCH_AND_MOTOR_CMD, configElement.value))
1075         config.sec.delay_between_switch_and_motor_command = x
1076
1077         x = ConfigInteger(default=500, limits = (0, 9999))
1078         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_MEASURE_IDLE_INPUTPOWER, configElement.value))
1079         config.sec.delay_after_voltage_change_before_measure_idle_inputpower = x
1080
1081         x = ConfigInteger(default=900, limits = (0, 9999))
1082         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_ENABLE_VOLTAGE_BEFORE_MOTOR_CMD, configElement.value))
1083         config.sec.delay_after_enable_voltage_before_motor_command = x
1084
1085         x = ConfigInteger(default=500, limits = (0, 9999))
1086         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_MOTOR_STOP_CMD, configElement.value))
1087         config.sec.delay_after_motor_stop_command = x
1088
1089         x = ConfigInteger(default=500, limits = (0, 9999))
1090         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_MOTOR_CMD, configElement.value))
1091         config.sec.delay_after_voltage_change_before_motor_command = x
1092
1093         x = ConfigInteger(default=70, limits = (0, 9999))
1094         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_BEFORE_SEQUENCE_REPEAT, configElement.value))
1095         config.sec.delay_before_sequence_repeat = x
1096
1097         x = ConfigInteger(default=360, limits = (0, 9999))
1098         x.addNotifier(lambda configElement: secClass.setParam(secClass.MOTOR_RUNNING_TIMEOUT, configElement.value))
1099         config.sec.motor_running_timeout = x
1100
1101         x = ConfigInteger(default=1, limits = (0, 5))
1102         x.addNotifier(lambda configElement: secClass.setParam(secClass.MOTOR_COMMAND_RETRIES, configElement.value))
1103         config.sec.motor_command_retries = x
1104
1105         x = ConfigInteger(default=50, limits = (0, 9999))
1106         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_DISEQC_RESET_CMD, configElement.value))
1107         config.sec.delay_after_diseqc_reset_cmd = x
1108
1109         x = ConfigInteger(default=150, limits = (0, 9999))
1110         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_DISEQC_PERIPHERIAL_POWERON_CMD, configElement.value))
1111         config.sec.delay_after_diseqc_peripherial_poweron_cmd = x
1112
1113 # TODO add support for satpos depending nims to advanced nim configuration
1114 # so a second/third/fourth cable from a motorized lnb can used behind a
1115 # diseqc 1.0 / diseqc 1.1 / toneburst switch
1116 # the C(++) part should can handle this
1117 # the configElement should be only visible when diseqc 1.2 is disabled
1118
1119 def InitNimManager(nimmgr, update_slots = []):
1120         hw = HardwareInfo()
1121         addNimConfig = False
1122         try:
1123                 config.Nims
1124         except:
1125                 addNimConfig = True
1126
1127         if addNimConfig:
1128                 InitSecParams()
1129                 config.Nims = ConfigSubList()
1130                 for x in range(len(nimmgr.nim_slots)):
1131                         config.Nims.append(ConfigSubsection())
1132
1133         lnb_choices = {
1134                 "universal_lnb": _("Universal LNB"),
1135                 "unicable": _("Unicable"),
1136                 "c_band": _("C-Band"),
1137                 "user_defined": _("User defined")}
1138
1139         lnb_choices_default = "universal_lnb"
1140
1141         unicablelnbproducts = {}
1142         unicablematrixproducts = {}
1143         doc = xml.etree.cElementTree.parse(eEnv.resolve("${datadir}/enigma2/unicable.xml"))
1144         root = doc.getroot()
1145
1146         entry = root.find("lnb")
1147         lscr=("scr1","scr2","scr3","scr4","scr5","scr6","scr7","scr8","scr9","scr10",
1148                 "scr11","scr12","scr13","scr14","scr15","scr16","scr17","scr18","scr19","scr20",
1149                 "scr21","scr22","scr23","scr24","scr25","scr26","scr27","scr28","scr29","scr30",
1150                 "scr31","scr32")
1151         for manufacturer in entry.getchildren():
1152                 m={}
1153                 for product in manufacturer.getchildren():
1154                         p={}                                                                                                                                            #new dict empty for new product
1155                         scr=[]
1156                         for i in range(len(lscr)):
1157                                 scr.append(product.get(lscr[i],"0"))
1158                         for i in range(len(lscr)):
1159                                 if scr[len(lscr)-i-1] == "0":
1160                                         scr.pop()
1161                                 else:
1162                                         break;
1163
1164                         p.update({"frequencies":tuple(scr)})                                                                            #add scr frequencies to dict product
1165
1166                         diction = product.get("format","EN50494").upper()
1167                         if diction =="JESS" or diction =="UNICABLE2" or diction =="SCD2" or diction =="EN50607":
1168                                 diction = "EN50607"
1169                         else:
1170                                 diction = "EN50494"
1171                         p.update({"diction":tuple([diction])})                                                                          #add diction to dict product
1172
1173                         positions=[]
1174                         positions.append(int(product.get("positions",1)))
1175                         for cnt in range(positions[0]):
1176                                 lof=[]
1177                                 lof.append(int(product.get("lofl",9750)))
1178                                 lof.append(int(product.get("lofh",10600)))
1179                                 lof.append(int(product.get("threshold",11700)))
1180                                 positions.append(tuple(lof))
1181
1182                         p.update({"positions":tuple(positions)})                                                                        #add positons to dict product.
1183
1184                         m.update({product.get("name"):p})                                                                                       #add dict product to dict manufacturer
1185                 unicablelnbproducts.update({manufacturer.get("name"):m})
1186
1187         entry = root.find("matrix")
1188         for manufacturer in entry.getchildren():
1189                 m={}
1190                 for product in manufacturer.getchildren():
1191                         p={}    #new dict empty for new product
1192                         scr=[]
1193                         for i in range(len(lscr)):
1194                                 scr.append(product.get(lscr[i],"0"))
1195                         for i in range(len(lscr)):
1196                                 if scr[len(lscr)-i-1] == "0":
1197                                         scr.pop()
1198                                 else:
1199                                         break;
1200
1201                         p.update({"frequencies":tuple(scr)})                                                                            #add scr frequencies to dict product
1202
1203                         diction = product.get("format","EN50494").upper()
1204                         if diction =="JESS" or diction =="UNICABLE2" or diction =="SCD2" or diction =="EN50607":
1205                                 diction = "EN50607"
1206                         else:
1207                                 diction = "EN50494"
1208                         p.update({"diction":tuple([diction])})                                                                          #add diction to dict product
1209
1210                         positions=[]
1211                         positions.append(int(product.get("positions",1)))
1212                         for cnt in range(positions[0]):
1213                                 lof=[]
1214                                 lof.append(int(product.get("lofl",9750)))
1215                                 lof.append(int(product.get("lofh",10600)))
1216                                 lof.append(int(product.get("threshold",11700)))
1217                                 positions.append(tuple(lof))
1218
1219                         p.update({"positions":tuple(positions)})                                                                        #add positons to dict product
1220
1221                         m.update({product.get("name"):p})                                                                                       #add dict product to dict manufacturer
1222                 unicablematrixproducts.update({manufacturer.get("name"):m})                                             #add dict manufacturer to dict unicablematrixproducts
1223
1224         UnicableLnbManufacturers = unicablelnbproducts.keys()
1225         UnicableLnbManufacturers.sort()
1226         UnicableMatrixManufacturers = unicablematrixproducts.keys()
1227         UnicableMatrixManufacturers.sort()
1228
1229         unicable_choices = {
1230                 "unicable_lnb": _("Unicable LNB"),
1231                 "unicable_matrix": _("Unicable Martix"),
1232                 "unicable_user": "Unicable "+_("User defined")}
1233         unicable_choices_default = "unicable_lnb"
1234
1235         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")]
1236
1237         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"),
1238                                                                    ("9", "SatCR 9"), ("10", "SatCR 10"), ("11", "SatCR 11"), ("12", "SatCR 12"), ("13", "SatCR 13"), ("14", "SatCR 14"), ("15", "SatCR 15"), ("16", "SatCR 16"),
1239                                                                    ("17", "SatCR 17"), ("18", "SatCR 18"), ("19", "SatCR 19"), ("20", "SatCR 20"), ("21", "SatCR 21"), ("22", "SatCR 22"), ("23", "SatCR 23"), ("24", "SatCR 24"),
1240                                                                    ("25", "SatCR 25"), ("26", "SatCR 26"), ("27", "SatCR 27"), ("28", "SatCR 28"), ("29", "SatCR 29"), ("30", "SatCR 30"), ("31", "SatCR 31"), ("32", "SatCR 32")]
1241
1242         advanced_lnb_diction_user_choices = [("EN50494", "Unicable(EN50494)"), ("EN50607", "JESS(EN50607)")]
1243
1244         prio_list = [ ("-1", _("Auto")) ]
1245         prio_list += [(str(prio), str(prio)) for prio in range(65)+range(14000,14065)+range(19000,19065)]
1246
1247         advanced_lnb_csw_choices = [("none", _("None")), ("AA", _("AA")), ("AB", _("AB")), ("BA", _("BA")), ("BB", _("BB"))]
1248         advanced_lnb_csw_choices += [(str(0xF0|y), "Input " + str(y+1)) for y in range(0, 16)]
1249
1250         advanced_lnb_ucsw_choices = [("0", _("None"))] + [(str(y), "Input " + str(y)) for y in range(1, 17)]
1251
1252         diseqc_mode_choices = [
1253                 ("single", _("Single")), ("toneburst_a_b", _("Toneburst A/B")),
1254                 ("diseqc_a_b", _("DiSEqC A/B")), ("diseqc_a_b_c_d", _("DiSEqC A/B/C/D")),
1255                 ("positioner", _("Positioner"))]
1256
1257         positioner_mode_choices = [("usals", _("USALS")), ("manual", _("manual"))]
1258
1259         diseqc_satlist_choices = [(3601, _('nothing connected'), 1)] + nimmgr.satList
1260         
1261         longitude_orientation_choices = [("east", _("East")), ("west", _("West"))]
1262         latitude_orientation_choices = [("north", _("North")), ("south", _("South"))]
1263         turning_speed_choices = [("fast", _("Fast")), ("slow", _("Slow")), ("fast epoch", _("Fast epoch"))]
1264         
1265         advanced_satlist_choices = nimmgr.satList + [
1266                 (3601, _('All Satellites')+' 1', 1), (3602, _('All Satellites')+' 2', 1),
1267                 (3603, _('All Satellites')+' 3', 1), (3604, _('All Satellites')+' 4', 1)]
1268         advanced_lnb_choices = [("0", "not available")] + [(str(y), "LNB " + str(y)) for y in range(1, 65)]
1269         advanced_voltage_choices = [("polarization", _("Polarization")), ("13V", _("13 V")), ("18V", _("18 V"))]
1270         advanced_tonemode_choices = [("band", _("Band")), ("on", _("On")), ("off", _("Off"))]
1271         advanced_lnb_toneburst_choices = [("none", _("None")), ("A", _("A")), ("B", _("B"))]
1272         advanced_lnb_allsat_diseqcmode_choices = [("1_2", _("1.2"))]
1273         advanced_lnb_diseqcmode_choices = [("none", _("None")), ("1_0", _("1.0")), ("1_1", _("1.1")), ("1_2", _("1.2"))]
1274         advanced_lnb_commandOrder1_0_choices = [("ct", "committed, toneburst"), ("tc", "toneburst, committed")]
1275         advanced_lnb_commandOrder_choices = [
1276                 ("ct", "committed, toneburst"), ("tc", "toneburst, committed"),
1277                 ("cut", "committed, uncommitted, toneburst"), ("tcu", "toneburst, committed, uncommitted"),
1278                 ("uct", "uncommitted, committed, toneburst"), ("tuc", "toneburst, uncommitted, commmitted")]
1279         advanced_lnb_diseqc_repeat_choices = [("none", _("None")), ("one", _("One")), ("two", _("Two")), ("three", _("Three"))]
1280         advanced_lnb_fast_turning_btime = mktime(datetime(1970, 1, 1, 7, 0).timetuple());
1281         advanced_lnb_fast_turning_etime = mktime(datetime(1970, 1, 1, 19, 0).timetuple());
1282
1283         def configLOFChanged(configElement):
1284                 if configElement.value == "unicable":
1285                         x = configElement.slot_id
1286                         lnb = configElement.lnb_id
1287                         nim = config.Nims[x]
1288                         lnbs = nim.advanced.lnb
1289                         section = lnbs[lnb]
1290                         if isinstance(section.unicable, ConfigNothing):
1291                                 if lnb == 1:
1292                                         section.unicable = ConfigSelection(unicable_choices, unicable_choices_default)
1293 #                               elif lnb == 2:
1294                                 else:
1295                                         section.unicable = ConfigSelection(choices = {"unicable_matrix": _("Unicable Martix"),"unicable_user": "Unicable "+_("User defined")}, default = "unicable_matrix")
1296 #                                       section.unicable = ConfigSelection(choices = {"unicable_user": _("User defined")}, default = "unicable_user")
1297                         def fillUnicableConf(sectionDict, unicableproducts, vco_null_check):
1298                                 for manufacturer in unicableproducts:
1299                                         products = unicableproducts[manufacturer].keys()
1300                                         products.sort()
1301                                         products_valide = []
1302                                         products_valide_append = products_valide.append
1303                                         tmp = ConfigSubsection()
1304                                         tmp.scr = ConfigSubDict()
1305                                         tmp.vco = ConfigSubDict()
1306                                         tmp.lofl = ConfigSubDict()
1307                                         tmp.lofh = ConfigSubDict()
1308                                         tmp.loft = ConfigSubDict()
1309                                         tmp.positions = ConfigSubDict()
1310                                         tmp.diction = ConfigSubDict()
1311                                         for article in products:
1312                                                 positionslist = unicableproducts[manufacturer][article].get("positions")
1313                                                 positions = int(positionslist[0])
1314                                                 dictionlist = [unicableproducts[manufacturer][article].get("diction")]
1315                                                 if lnb <= positions or dictionlist[0][0] !="EN50607":
1316                                                         tmp.positions[article] = ConfigSubList()
1317                                                         tmp.positions[article].append(ConfigInteger(default=positions, limits = (positions, positions)))
1318                                                         tmp.diction[article] = ConfigSelection(choices = dictionlist, default = dictionlist[0][0])
1319
1320                                                         scrlist = []
1321                                                         scrlist_append = scrlist.append
1322                                                         vcolist=unicableproducts[manufacturer][article].get("frequencies")
1323                                                         tmp.vco[article] = ConfigSubList()
1324                                                         for cnt in range(1,len(vcolist)+1):
1325                                                                 vcofreq = int(vcolist[cnt-1])
1326                                                                 if vcofreq == 0 and vco_null_check:
1327                                                                         scrlist_append(("%d" %cnt,"SCR %d " %cnt +_("not used")))
1328                                                                 else:
1329                                                                         scrlist_append(("%d" %cnt,"SCR %d" %cnt))
1330                                                                 tmp.vco[article].append(ConfigInteger(default=vcofreq, limits = (vcofreq, vcofreq)))
1331
1332                                                         tmp.scr[article] = ConfigSelection(choices = scrlist, default = scrlist[0][0])
1333
1334                                                         tmp.lofl[article] = ConfigSubList()
1335                                                         tmp.lofh[article] = ConfigSubList()
1336                                                         tmp.loft[article] = ConfigSubList()
1337
1338                                                         tmp_lofl_article_append = tmp.lofl[article].append
1339                                                         tmp_lofh_article_append = tmp.lofh[article].append
1340                                                         tmp_loft_article_append = tmp.loft[article].append
1341                                                         
1342                                                         for cnt in range(1,positions+1):
1343                                                                 lofl = int(positionslist[cnt][0])
1344                                                                 lofh = int(positionslist[cnt][1])
1345                                                                 loft = int(positionslist[cnt][2])
1346                                                                 tmp_lofl_article_append(ConfigInteger(default=lofl, limits = (lofl, lofl)))
1347                                                                 tmp_lofh_article_append(ConfigInteger(default=lofh, limits = (lofh, lofh)))
1348                                                                 tmp_loft_article_append(ConfigInteger(default=loft, limits = (loft, loft)))
1349                                                         products_valide_append(article)
1350
1351                                         if len(products_valide)==0:
1352                                                 products_valide_append("None")
1353                                         tmp.product = ConfigSelection(choices = products_valide, default = products_valide[0])
1354                                         sectionDict[manufacturer] = tmp
1355
1356                         if lnb < 65:
1357                                 print "MATRIX"
1358                                 section.unicableMatrix = ConfigSubDict()
1359                                 section.unicableMatrixManufacturer = ConfigSelection(UnicableMatrixManufacturers, UnicableMatrixManufacturers[0])
1360                                 fillUnicableConf(section.unicableMatrix, unicablematrixproducts, True)
1361
1362                         if lnb < 2: #Konfiguration nur fuer LNB1 zulassen
1363                                 print "LNB"
1364                                 section.unicableLnb = ConfigSubDict()
1365                                 section.unicableLnbManufacturer = ConfigSelection(UnicableLnbManufacturers, UnicableLnbManufacturers[0])
1366                                 fillUnicableConf(section.unicableLnb, unicablelnbproducts, False)
1367
1368 #TODO satpositions for satcruser
1369
1370                         section.dictionuser = ConfigSelection(advanced_lnb_diction_user_choices, default="EN50494")
1371                         section.satcruserEN50494 = ConfigSelection(advanced_lnb_satcr_user_choicesEN50494, default="1")
1372                         section.satcruserEN50607 = ConfigSelection(advanced_lnb_satcr_user_choicesEN50607, default="1")
1373
1374                         tmp = ConfigSubList()
1375                         tmp.append(ConfigInteger(default=1284, limits = (950, 2150)))
1376                         tmp.append(ConfigInteger(default=1400, limits = (950, 2150)))
1377                         tmp.append(ConfigInteger(default=1516, limits = (950, 2150)))
1378                         tmp.append(ConfigInteger(default=1632, limits = (950, 2150)))
1379                         tmp.append(ConfigInteger(default=1748, limits = (950, 2150)))
1380                         tmp.append(ConfigInteger(default=1864, limits = (950, 2150)))
1381                         tmp.append(ConfigInteger(default=1980, limits = (950, 2150)))
1382                         tmp.append(ConfigInteger(default=2096, limits = (950, 2150)))
1383                         section.satcrvcouserEN50494 = tmp 
1384
1385                         tmp.append(ConfigInteger(default=1284, limits = (950, 2150)))
1386                         tmp.append(ConfigInteger(default=1400, limits = (950, 2150)))
1387                         tmp.append(ConfigInteger(default=1516, limits = (950, 2150)))
1388                         tmp.append(ConfigInteger(default=1632, limits = (950, 2150)))
1389                         tmp.append(ConfigInteger(default=1748, limits = (950, 2150)))
1390                         tmp.append(ConfigInteger(default=1864, limits = (950, 2150)))
1391                         tmp.append(ConfigInteger(default=1980, limits = (950, 2150)))
1392                         tmp.append(ConfigInteger(default=2096, limits = (950, 2150)))
1393                         tmp.append(ConfigInteger(default=1284, limits = (950, 2150)))
1394                         tmp.append(ConfigInteger(default=1400, limits = (950, 2150)))
1395                         tmp.append(ConfigInteger(default=1516, limits = (950, 2150)))
1396                         tmp.append(ConfigInteger(default=1632, limits = (950, 2150)))
1397                         tmp.append(ConfigInteger(default=1748, limits = (950, 2150)))
1398                         tmp.append(ConfigInteger(default=1864, limits = (950, 2150)))
1399                         tmp.append(ConfigInteger(default=1980, limits = (950, 2150)))
1400                         tmp.append(ConfigInteger(default=2096, limits = (950, 2150)))
1401                         tmp.append(ConfigInteger(default=1284, limits = (950, 2150)))
1402                         tmp.append(ConfigInteger(default=1400, limits = (950, 2150)))
1403                         tmp.append(ConfigInteger(default=1516, limits = (950, 2150)))
1404                         tmp.append(ConfigInteger(default=1632, limits = (950, 2150)))
1405                         tmp.append(ConfigInteger(default=1748, limits = (950, 2150)))
1406                         tmp.append(ConfigInteger(default=1864, limits = (950, 2150)))
1407                         tmp.append(ConfigInteger(default=1980, limits = (950, 2150)))
1408                         tmp.append(ConfigInteger(default=2096, limits = (950, 2150)))
1409                         section.satcrvcouserEN50607 = tmp 
1410
1411                         nim.advanced.unicableconnected = ConfigYesNo(default=False)
1412                         nim.advanced.unicableconnectedTo = ConfigSelection([(str(id), nimmgr.getNimDescription(id)) for id in nimmgr.getNimListOfType("DVB-S") if id != x])
1413
1414         def configDiSEqCModeChanged(configElement):
1415                 section = configElement.section
1416                 if configElement.value == "1_2" and isinstance(section.longitude, ConfigNothing):
1417                         section.longitude = ConfigFloat(default = [5,100], limits = [(0,359),(0,999)])
1418                         section.longitudeOrientation = ConfigSelection(longitude_orientation_choices, "east")
1419                         section.latitude = ConfigFloat(default = [50,767], limits = [(0,359),(0,999)])
1420                         section.latitudeOrientation = ConfigSelection(latitude_orientation_choices, "north")
1421                         section.powerMeasurement = ConfigYesNo(default=True)
1422                         section.powerThreshold = ConfigInteger(default=hw.get_device_name() == "dm7025" and 50 or 15, limits=(0, 100))
1423                         section.turningSpeed = ConfigSelection(turning_speed_choices, "fast")
1424                         section.fastTurningBegin = ConfigDateTime(default=advanced_lnb_fast_turning_btime, formatstring = _("%H:%M"), increment = 600)
1425                         section.fastTurningEnd = ConfigDateTime(default=advanced_lnb_fast_turning_etime, formatstring = _("%H:%M"), increment = 600)
1426
1427         def configLNBChanged(configElement):
1428                 x = configElement.slot_id
1429                 nim = config.Nims[x]
1430                 if isinstance(configElement.value, tuple):
1431                         lnb = int(configElement.value[0])
1432                 else:
1433                         lnb = int(configElement.value)
1434                 lnbs = nim.advanced.lnb
1435                 if lnb and lnb not in lnbs:
1436                         section = lnbs[lnb] = ConfigSubsection()
1437                         section.lofl = ConfigInteger(default=9750, limits = (0, 99999))
1438                         section.lofh = ConfigInteger(default=10600, limits = (0, 99999))
1439                         section.threshold = ConfigInteger(default=11700, limits = (0, 99999))
1440 #                       section.output_12v = ConfigSelection(choices = [("0V", _("0 V")), ("12V", _("12 V"))], default="0V")
1441                         section.increased_voltage = ConfigYesNo(False)
1442                         section.toneburst = ConfigSelection(advanced_lnb_toneburst_choices, "none")
1443                         section.longitude = ConfigNothing()
1444                         if lnb > 64:
1445                                 tmp = ConfigSelection(advanced_lnb_allsat_diseqcmode_choices, "1_2")
1446                                 tmp.section = section
1447                                 configDiSEqCModeChanged(tmp)
1448                         else:
1449                                 tmp = ConfigSelection(advanced_lnb_diseqcmode_choices, "none")
1450                                 tmp.section = section
1451                                 tmp.addNotifier(configDiSEqCModeChanged)
1452                         section.diseqcMode = tmp
1453                         section.commitedDiseqcCommand = ConfigSelection(advanced_lnb_csw_choices)
1454                         section.fastDiseqc = ConfigYesNo(False)
1455                         section.sequenceRepeat = ConfigYesNo(False)
1456                         section.commandOrder1_0 = ConfigSelection(advanced_lnb_commandOrder1_0_choices, "ct")
1457                         section.commandOrder = ConfigSelection(advanced_lnb_commandOrder_choices, "ct")
1458                         section.uncommittedDiseqcCommand = ConfigSelection(advanced_lnb_ucsw_choices)
1459                         section.diseqcRepeats = ConfigSelection(advanced_lnb_diseqc_repeat_choices, "none")
1460                         section.prio = ConfigSelection(prio_list, "-1")
1461                         section.unicable = ConfigNothing()
1462                         tmp = ConfigSelection(lnb_choices, lnb_choices_default)
1463                         tmp.slot_id = x
1464                         tmp.lnb_id = lnb
1465                         tmp.addNotifier(configLOFChanged, initial_call = False)
1466                         section.lof = tmp
1467
1468         def configModeChanged(configMode):
1469                 slot_id = configMode.slot_id
1470                 nim = config.Nims[slot_id]
1471                 if configMode.value == "advanced" and isinstance(nim.advanced, ConfigNothing):
1472                         # advanced config:
1473                         nim.advanced = ConfigSubsection()
1474                         nim.advanced.sat = ConfigSubDict()
1475                         nim.advanced.sats = getConfigSatlist(192, advanced_satlist_choices)
1476                         nim.advanced.lnb = ConfigSubDict()
1477                         nim.advanced.lnb[0] = ConfigNothing()
1478                         for x in nimmgr.satList:
1479                                 tmp = ConfigSubsection()
1480                                 tmp.voltage = ConfigSelection(advanced_voltage_choices, "polarization")
1481                                 tmp.tonemode = ConfigSelection(advanced_tonemode_choices, "band")
1482                                 tmp.usals = ConfigYesNo(True)
1483                                 tmp.rotorposition = ConfigInteger(default=1, limits=(1, 255))
1484                                 lnb = ConfigSelection(advanced_lnb_choices, "0")
1485                                 lnb.slot_id = slot_id
1486                                 lnb.addNotifier(configLNBChanged, initial_call = False)
1487                                 tmp.lnb = lnb
1488                                 nim.advanced.sat[x[0]] = tmp
1489                         for x in range(3601, 3605):
1490                                 tmp = ConfigSubsection()
1491                                 tmp.voltage = ConfigSelection(advanced_voltage_choices, "polarization")
1492                                 tmp.tonemode = ConfigSelection(advanced_tonemode_choices, "band")
1493                                 tmp.usals = ConfigYesNo(default=True)
1494                                 tmp.rotorposition = ConfigInteger(default=1, limits=(1, 255))
1495                                 lnbnum = 65+x-3601
1496                                 lnb = ConfigSelection([("0", "not available"), (str(lnbnum), "LNB %d"%(lnbnum))], "0")
1497                                 lnb.slot_id = slot_id
1498                                 lnb.addNotifier(configLNBChanged, initial_call = False)
1499                                 tmp.lnb = lnb
1500                                 nim.advanced.sat[x] = tmp
1501
1502         def toneAmplitudeChanged(configElement):
1503                 fe_id = configElement.fe_id
1504                 slot_id = configElement.slot_id
1505                 if nimmgr.nim_slots[slot_id].description == 'Alps BSBE2':
1506                         open("/proc/stb/frontend/%d/tone_amplitude" %(fe_id), "w").write(configElement.value)
1507
1508         def createSatConfig(nim, x, empty_slots):
1509                 print "[Nimmanager] slot %d create config satellite.." % slot.slot
1510                 try:
1511                         nim.toneAmplitude
1512                 except:
1513                         nim.toneAmplitude = ConfigSelection([("11", "340mV"), ("10", "360mV"), ("9", "600mV"), ("8", "700mV"), ("7", "800mV"), ("6", "900mV"), ("5", "1100mV")], "7")
1514                         nim.toneAmplitude.fe_id = x - empty_slots
1515                         nim.toneAmplitude.slot_id = x
1516                         nim.toneAmplitude.addNotifier(toneAmplitudeChanged)
1517                         nim.diseqc13V = ConfigYesNo(False)
1518                         nim.diseqcMode = ConfigSelection(diseqc_mode_choices, "diseqc_a_b")
1519                         nim.connectedTo = ConfigSelection([(str(id), nimmgr.getNimDescription(id)) for id in nimmgr.getNimListOfType("DVB-S") if id != x])
1520                         nim.simpleSingleSendDiSEqC = ConfigYesNo(False)
1521                         nim.simpleDiSEqCSetVoltageTone = ConfigYesNo(True)
1522                         nim.simpleDiSEqCOnlyOnSatChange = ConfigYesNo(False)
1523                         nim.diseqcA = getConfigSatlist(192, diseqc_satlist_choices)
1524                         nim.diseqcB = getConfigSatlist(130, diseqc_satlist_choices)
1525                         nim.diseqcC = ConfigSatlist(list = diseqc_satlist_choices)
1526                         nim.diseqcD = ConfigSatlist(list = diseqc_satlist_choices)
1527                         nim.positionerMode = ConfigSelection(positioner_mode_choices, "usals")
1528                         nim.longitude = ConfigFloat(default=[5,100], limits=[(0,359),(0,999)])
1529                         nim.longitudeOrientation = ConfigSelection(longitude_orientation_choices, "east")
1530                         nim.latitude = ConfigFloat(default=[50,767], limits=[(0,359),(0,999)])
1531                         nim.latitudeOrientation = ConfigSelection(latitude_orientation_choices, "north")
1532                         nim.powerMeasurement = ConfigYesNo(True)
1533                         nim.powerThreshold = ConfigInteger(default=hw.get_device_name() == "dm8000" and 15 or 50, limits=(0, 100))
1534                         nim.turningSpeed = ConfigSelection(turning_speed_choices, "fast")
1535                         btime = datetime(1970, 1, 1, 7, 0);
1536                         nim.fastTurningBegin = ConfigDateTime(default = mktime(btime.timetuple()), formatstring = _("%H:%M"), increment = 900)
1537                         etime = datetime(1970, 1, 1, 19, 0);
1538                         nim.fastTurningEnd = ConfigDateTime(default = mktime(etime.timetuple()), formatstring = _("%H:%M"), increment = 900)
1539
1540         def createCableConfig(nim, x):
1541                 print "[Nimmanager] slot %d create config cable.." % slot.slot
1542                 try:
1543                         nim.cable
1544                 except:
1545                         list = [ ]
1546                         n = 0
1547                         for x in nimmgr.cablesList:
1548                                 list.append((str(n), x[0]))
1549                                 n += 1
1550                         nim.cable = ConfigSubsection()
1551                         possible_scan_types = [("bands", _("Frequency bands")), ("steps", _("Frequency steps"))]
1552                         if n:
1553                                 possible_scan_types.append(("provider", _("Provider")))
1554                                 nim.cable.scan_provider = ConfigSelection(default = "0", choices = list)
1555                         nim.cable.scan_type = ConfigSelection(default = "bands", choices = possible_scan_types)
1556                         nim.cable.scan_band_EU_VHF_I = ConfigYesNo(default = True)
1557                         nim.cable.scan_band_EU_MID = ConfigYesNo(default = True)
1558                         nim.cable.scan_band_EU_VHF_III = ConfigYesNo(default = True)
1559                         nim.cable.scan_band_EU_UHF_IV = ConfigYesNo(default = True)
1560                         nim.cable.scan_band_EU_UHF_V = ConfigYesNo(default = True)
1561                         nim.cable.scan_band_EU_SUPER = ConfigYesNo(default = True)
1562                         nim.cable.scan_band_EU_HYPER = ConfigYesNo(default = True)
1563                         nim.cable.scan_band_US_LOW = ConfigYesNo(default = False)
1564                         nim.cable.scan_band_US_MID = ConfigYesNo(default = False)
1565                         nim.cable.scan_band_US_HIGH = ConfigYesNo(default = False)
1566                         nim.cable.scan_band_US_SUPER = ConfigYesNo(default = False)
1567                         nim.cable.scan_band_US_HYPER = ConfigYesNo(default = False)
1568                         nim.cable.scan_frequency_steps = ConfigInteger(default = 1000, limits = (1000, 10000))
1569                         nim.cable.scan_mod_qam16 = ConfigYesNo(default = False)
1570                         nim.cable.scan_mod_qam32 = ConfigYesNo(default = False)
1571                         nim.cable.scan_mod_qam64 = ConfigYesNo(default = True)
1572                         nim.cable.scan_mod_qam128 = ConfigYesNo(default = False)
1573                         nim.cable.scan_mod_qam256 = ConfigYesNo(default = True)
1574                         nim.cable.scan_sr_6900 = ConfigYesNo(default = True)
1575                         nim.cable.scan_sr_6875 = ConfigYesNo(default = True)
1576                         nim.cable.scan_sr_ext1 = ConfigInteger(default = 0, limits = (0, 7230))
1577                         nim.cable.scan_sr_ext2 = ConfigInteger(default = 0, limits = (0, 7230))
1578
1579         def createTerrestrialConfig(nim, x):
1580                 print "[Nimmanager] slot %d create config terrestrial.." % slot.slot
1581                 try:
1582                         nim.terrestrial
1583                 except:
1584                         list = []
1585                         n = 0
1586                         for x in nimmgr.terrestrialsList:
1587                                 list.append((str(n), x[0]))
1588                                 n += 1
1589                         nim.terrestrial = ConfigSelection(choices = list)
1590                         nim.terrestrial_5V = ConfigOnOff()
1591
1592         def tunerTypeChanged(nimmgr, configElement):
1593                 fe_id = configElement.fe_id
1594                 eDVBResourceManager.getInstance().setFrontendType(nimmgr.nim_slots[fe_id].frontend_id, nimmgr.nim_slots[fe_id].getType())
1595                 import os
1596                 if os.path.exists("/proc/stb/frontend/%d/mode" % fe_id):
1597                         cur_type = int(open("/proc/stb/frontend/%d/mode" % (fe_id), "r").read())
1598                         if cur_type == int(configElement.value):
1599                                 print "tuner type is already already %d" %cur_type
1600                                 return
1601                                 print "tunerTypeChanged feid %d from %d to mode %d" % (fe_id, cur_type, int(configElement.value))
1602
1603                 print "tunerTypeChanged feid %d, mode %d" % (fe_id, int(configElement.value))
1604         
1605                 try:
1606                         oldvalue = open("/sys/module/dvb_core/parameters/dvb_shutdown_timeout", "r").readline()
1607                         open("/sys/module/dvb_core/parameters/dvb_shutdown_timeout", "w").write("0")
1608                 except:
1609                         print "[info] no /sys/module/dvb_core/parameters/dvb_shutdown_timeout available"
1610
1611                 frontend = eDVBResourceManager.getInstance().allocateRawChannel(fe_id).getFrontend()
1612                 frontend.closeFrontend()
1613
1614                 if os.path.exists("/proc/stb/frontend/%d/mode" % fe_id):
1615                         open("/proc/stb/frontend/%d/mode" % (fe_id), "w").write(configElement.value)
1616                 
1617                 frontend.reopenFrontend()
1618                 try:
1619                         open("/sys/module/dvb_core/parameters/dvb_shutdown_timeout", "w").write(oldvalue)
1620                 except:
1621                         print "[info] no /sys/module/dvb_core/parameters/dvb_shutdown_timeout available"
1622                 nimmgr.enumerateNIMs()
1623
1624         empty_slots = 0
1625         for slot in nimmgr.nim_slots:
1626                 print "[InitNimManager] check multi type slot %d" % slot.slot
1627                 x = slot.slot
1628                 nim = config.Nims[x]
1629                 addMultiType = False
1630                 try:
1631                         nim.multiType
1632                 except:
1633                         addMultiType = True
1634                 if slot.isMultiType() and addMultiType:
1635                         print "[InitNimManager] slot %d is multi type : " % slot.slot, slot.getMultiTypeList()
1636                         typeList = []
1637                         for id in slot.getMultiTypeList().keys():
1638                                 type = slot.getMultiTypeList()[id]
1639                                 typeList.append((id, type))
1640                         nim.multiType = ConfigSelection(typeList, "0")
1641                         nim.multiType.fe_id = x - empty_slots
1642                         nim.multiType.addNotifier(boundFunction(tunerTypeChanged, nimmgr))
1643
1644         empty_slots = 0
1645         for slot in nimmgr.nim_slots:
1646                 x = slot.slot
1647                 nim = config.Nims[x]
1648
1649                 if update_slots and (x not in update_slots):
1650                         continue
1651
1652                 if slot.isCompatible("DVB-S"):
1653                         createSatConfig(nim, x, empty_slots)
1654                         config_mode_choices = [ ("nothing", _("nothing connected")),
1655                                 ("simple", _("simple")), ("advanced", _("advanced"))]
1656                         if len(nimmgr.getNimListOfType(slot.getType(), exception = x)) > 0:
1657                                 config_mode_choices.append(("equal", _("equal to")))
1658                                 config_mode_choices.append(("satposdepends", _("second cable of motorized LNB")))
1659                         if len(nimmgr.canConnectTo(x)) > 0:
1660                                 config_mode_choices.append(("loopthrough", _("loopthrough to")))
1661                         nim.advanced = ConfigNothing()
1662                         tmp = ConfigSelection(config_mode_choices, "nothing")
1663                         tmp.slot_id = x
1664                         tmp.addNotifier(configModeChanged, initial_call = False)
1665                         nim.configMode = tmp
1666                 elif slot.isCompatible("DVB-C"):
1667                         nim.configMode = ConfigSelection(
1668                                 choices = {
1669                                         "enabled": _("enabled"),
1670                                         "nothing": _("nothing connected"),
1671                                         },
1672                                 default = "enabled")
1673                         createCableConfig(nim, x)
1674                 elif slot.isCompatible("DVB-T"):
1675                         nim.configMode = ConfigSelection(
1676                                 choices = {
1677                                         "enabled": _("enabled"),
1678                                         "nothing": _("nothing connected"),
1679                                         },
1680                                 default = "enabled")
1681                         createTerrestrialConfig(nim, x)
1682                 else:
1683                         print "[Nimmanager] slot %d create config nothing.." % slot.slot
1684                         empty_slots += 1
1685                         nim.configMode = ConfigSelection(choices = { "nothing": _("disabled") }, default="nothing");
1686                         if slot.getType() is not None:
1687                                 print "pls add support for this frontend type!", slot.getType()
1688 #                       assert False
1689
1690         nimmgr.sec = SecConfigure(nimmgr)
1691
1692 nimmanager = NimManager()