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