df9ab5268d438995c893470b1adcd436244d4c20
[openblackhole/openblackhole-enigma2.git] / 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, ConfigText
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 class SecConfigure:
31         def getConfiguredSats(self):
32                 return self.configuredSatellites
33
34         def addSatellite(self, sec, orbpos):
35                 sec.addSatellite(orbpos)
36                 self.configuredSatellites.add(orbpos)
37
38         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, CircularLNB = False):
39                 if orbpos is None or orbpos == 3600 or orbpos == 3601:
40                         return
41                 #simple defaults
42                 sec.addLNB()
43                 tunermask = 1 << slotid
44                 if self.equal.has_key(slotid):
45                         for slot in self.equal[slotid]:
46                                 tunermask |= (1 << slot)
47                 if self.linked.has_key(slotid):
48                         for slot in self.linked[slotid]:
49                                 tunermask |= (1 << slot)
50                 sec.setLNBSatCR(-1)
51                 sec.setLNBNum(1)
52                 sec.setLNBLOFL(CircularLNB and 10750000 or 9750000)
53                 sec.setLNBLOFH(CircularLNB and 10750000 or 10600000)
54                 sec.setLNBThreshold(CircularLNB and 10750000 or 11700000)
55                 sec.setLNBIncreasedVoltage(False)
56                 sec.setRepeats(0)
57                 sec.setFastDiSEqC(fastDiSEqC)
58                 sec.setSeqRepeat(False)
59                 sec.setCommandOrder(0)
60
61                 #user values
62
63                 sec.setDiSEqCMode(3 if diseqcmode == 4 else diseqcmode)
64                 sec.setToneburst(toneburstmode)
65                 sec.setCommittedCommand(diseqcpos)
66                 sec.setUncommittedCommand(0) # SENDNO
67
68                 if 0 <= diseqcmode < 3:
69                         self.addSatellite(sec, orbpos)
70                         if setVoltageTone:
71                                 if diseqc13V:
72                                         sec.setVoltageMode(switchParam.HV_13)
73                                 else:
74                                         sec.setVoltageMode(switchParam.HV)
75                                 sec.setToneMode(switchParam.HILO)
76                         else:
77                                 sec.setVoltageMode(switchParam._14V)
78                                 sec.setToneMode(switchParam.OFF)
79                 elif 3 <= diseqcmode < 5: # diseqc 1.2
80                         if self.satposdepends.has_key(slotid):
81                                 for slot in self.satposdepends[slotid]:
82                                         tunermask |= (1 << slot)
83                         sec.setLatitude(latitude)
84                         sec.setLaDirection(laDirection)
85                         sec.setLongitude(longitude)
86                         sec.setLoDirection(loDirection)
87                         sec.setUseInputpower(useInputPower)
88                         sec.setInputpowerDelta(inputPowerDelta)
89                         sec.setRotorTurningSpeed(turningSpeed)
90                         user_satList = self.NimManager.satList
91                         if diseqcmode == 4:
92                                 user_satList = []
93                                 if orbpos and isinstance(orbpos, str):
94                                         for user_sat in self.NimManager.satList:
95                                                 if str(user_sat[0]) in orbpos:
96                                                         user_satList.append(user_sat)
97                         for x in user_satList:
98                                 print "Add sat " + str(x[0])
99                                 self.addSatellite(sec, int(x[0]))
100                                 if diseqc13V:
101                                         sec.setVoltageMode(switchParam.HV_13)
102                                 else:
103                                         sec.setVoltageMode(switchParam.HV)
104                                 sec.setToneMode(switchParam.HILO)
105                                 sec.setRotorPosNum(0) # USALS
106
107                 sec.setLNBSlotMask(tunermask)
108
109         def setSatposDepends(self, sec, nim1, nim2):
110                 print "tuner", nim1, "depends on satpos of", nim2
111                 sec.setTunerDepends(nim1, nim2)
112
113         def linkInternally(self, slotid):
114                 nim = self.NimManager.getNim(slotid)
115                 if nim.internallyConnectableTo is not None:
116                         nim.setInternalLink()
117
118         def linkNIMs(self, sec, nim1, nim2):
119                 print "link tuner", nim1, "to tuner", nim2
120                 if nim2 == (nim1 - 1):
121                         self.linkInternally(nim1)
122                 sec.setTunerLinked(nim1, nim2)
123
124         def getRoot(self, slotid, connto):
125                 visited = []
126                 while (self.NimManager.getNimConfig(connto).configMode.value in ("satposdepends", "equal", "loopthrough")):
127                         connto = int(self.NimManager.getNimConfig(connto).connectedTo.value)
128                         if connto in visited: # prevent endless loop
129                                 return slotid
130                         visited.append(connto)
131                 return connto
132
133         def update(self):
134                 sec = secClass.getInstance()
135                 self.configuredSatellites = set()
136                 for slotid in self.NimManager.getNimListOfType("DVB-S"):
137                         if self.NimManager.nimInternallyConnectableTo(slotid) is not None:
138                                 self.NimManager.nimRemoveInternalLink(slotid)
139                 sec.clear() ## this do unlinking NIMs too !!
140                 print "sec config cleared"
141
142                 self.linked = { }
143                 self.satposdepends = { }
144                 self.equal = { }
145
146                 nim_slots = self.NimManager.nim_slots
147
148                 used_nim_slots = [ ]
149
150                 for slot in nim_slots:
151                         if slot.type is not None:
152                                 used_nim_slots.append((slot.slot, slot.description, slot.config.configMode.value != "nothing" and True or False, slot.isCompatible("DVB-S2"), slot.frontend_id is None and -1 or slot.frontend_id))
153                 eDVBResourceManager.getInstance().setFrontendSlotInformations(used_nim_slots)
154
155                 for slot in nim_slots:
156                         if slot.frontend_id is not None:
157                                 types = [type for type in ["DVB-T2", "DVB-T", "DVB-C", "DVB-S2", "DVB-S", "ATSC"] if eDVBResourceManager.getInstance().frontendIsCompatible(slot.frontend_id, type)]
158                                 if "DVB-T2" in types and "DVB-T" in types:
159                                         # DVB-T2 implies DVB-T support
160                                         types.remove("DVB-T")
161                                 if "DVB-S2" in types and "DVB-S" in types:
162                                         # DVB-S2 implies DVB-S support
163                                         types.remove("DVB-S")
164                                 if len(types) > 1:
165                                         slot.multi_type = {}
166                                         for type in types:
167                                                 slot.multi_type[str(types.index(type))] = type
168
169                 for slot in nim_slots:
170                         x = slot.slot
171                         nim = slot.config
172                         if slot.isCompatible("DVB-S"):
173                                 # save what nim we link to/are equal to/satposdepends to.
174                                 # this is stored in the *value* (not index!) of the config list
175                                 if nim.configMode.value == "equal":
176                                         connto = self.getRoot(x, int(nim.connectedTo.value))
177                                         if not self.equal.has_key(connto):
178                                                 self.equal[connto] = []
179                                         self.equal[connto].append(x)
180                                 elif nim.configMode.value == "loopthrough":
181                                         self.linkNIMs(sec, x, int(nim.connectedTo.value))
182                                         connto = self.getRoot(x, int(nim.connectedTo.value))
183                                         if not self.linked.has_key(connto):
184                                                 self.linked[connto] = []
185                                         self.linked[connto].append(x)
186                                 elif nim.configMode.value == "satposdepends":
187                                         self.setSatposDepends(sec, x, int(nim.connectedTo.value))
188                                         connto = self.getRoot(x, int(nim.connectedTo.value))
189                                         if not self.satposdepends.has_key(connto):
190                                                 self.satposdepends[connto] = []
191                                         self.satposdepends[connto].append(x)
192
193                 for slot in nim_slots:
194                         x = slot.slot
195                         nim = slot.config
196                         hw = HardwareInfo()
197                         if slot.isCompatible("DVB-S"):
198                                 print "slot: " + str(x) + " configmode: " + str(nim.configMode.value)
199                                 if nim.configMode.value in ( "loopthrough", "satposdepends", "nothing" ):
200                                         pass
201                                 else:
202                                         sec.setSlotNotLinked(x)
203                                         if nim.configMode.value == "equal":
204                                                 pass
205                                         elif nim.configMode.value == "simple":          #simple config
206                                                 print "diseqcmode: ", nim.diseqcMode.value
207                                                 if nim.diseqcMode.value == "single":                    #single
208                                                         currentCircular = False
209                                                         if nim.diseqcA.value in ("360", "560"): 
210                                                                 currentCircular = nim.simpleDiSEqCSetCircularLNB.value
211                                                         if nim.simpleSingleSendDiSEqC.value:
212                                                                 self.addLNBSimple(sec, slotid = x, orbpos = nim.diseqcA.orbital_position, toneburstmode = diseqcParam.NO, diseqcmode = diseqcParam.V1_0, diseqcpos = diseqcParam.AA, diseqc13V = nim.diseqc13V.value, CircularLNB = currentCircular)
213                                                         else:
214                                                                 self.addLNBSimple(sec, slotid = x, orbpos = nim.diseqcA.orbital_position, toneburstmode = diseqcParam.NO, diseqcmode = diseqcParam.NONE, diseqcpos = diseqcParam.SENDNO, diseqc13V = nim.diseqc13V.value, CircularLNB = currentCircular)
215                                                 elif nim.diseqcMode.value == "toneburst_a_b":           #Toneburst A/B
216                                                         self.addLNBSimple(sec, slotid = x, orbpos = nim.diseqcA.orbital_position, toneburstmode = diseqcParam.A, diseqcmode = diseqcParam.V1_0, diseqcpos = diseqcParam.SENDNO, diseqc13V = nim.diseqc13V.value)
217                                                         self.addLNBSimple(sec, slotid = x, orbpos = nim.diseqcB.orbital_position, toneburstmode = diseqcParam.B, diseqcmode = diseqcParam.V1_0, diseqcpos = diseqcParam.SENDNO, diseqc13V = nim.diseqc13V.value)
218                                                 elif nim.diseqcMode.value == "diseqc_a_b":              #DiSEqC A/B
219                                                         fastDiSEqC = nim.simpleDiSEqCOnlyOnSatChange.value
220                                                         setVoltageTone = nim.simpleDiSEqCSetVoltageTone.value
221                                                         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)
222                                                         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)
223                                                 elif nim.diseqcMode.value == "diseqc_a_b_c_d":          #DiSEqC A/B/C/D
224                                                         fastDiSEqC = nim.simpleDiSEqCOnlyOnSatChange.value
225                                                         setVoltageTone = nim.simpleDiSEqCSetVoltageTone.value
226                                                         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)
227                                                         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)
228                                                         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)
229                                                         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)
230                                                 elif nim.diseqcMode.value in ("positioner", "positioner_select"):               #Positioner
231                                                         current_mode = 3
232                                                         sat = 0
233                                                         if nim.diseqcMode.value == "positioner_select":
234                                                                 current_mode = 4
235                                                                 sat = nim.userSatellitesList.value
236                                                         if nim.latitudeOrientation.value == "north":
237                                                                 laValue = rotorParam.NORTH
238                                                         else:
239                                                                 laValue = rotorParam.SOUTH
240                                                         if nim.longitudeOrientation.value == "east":
241                                                                 loValue = rotorParam.EAST
242                                                         else:
243                                                                 loValue = rotorParam.WEST
244                                                         inputPowerDelta=nim.powerThreshold.value
245                                                         useInputPower=False
246                                                         turning_speed=0
247                                                         if nim.powerMeasurement.value:
248                                                                 useInputPower=True
249                                                                 turn_speed_dict = { "fast": rotorParam.FAST, "slow": rotorParam.SLOW }
250                                                                 if turn_speed_dict.has_key(nim.turningSpeed.value):
251                                                                         turning_speed = turn_speed_dict[nim.turningSpeed.value]
252                                                                 else:
253                                                                         beg_time = localtime(nim.fastTurningBegin.value)
254                                                                         end_time = localtime(nim.fastTurningEnd.value)
255                                                                         turning_speed = ((beg_time.tm_hour+1) * 60 + beg_time.tm_min + 1) << 16
256                                                                         turning_speed |= (end_time.tm_hour+1) * 60 + end_time.tm_min + 1
257                                                         self.addLNBSimple(sec, slotid = x, diseqcmode = current_mode,
258                                                                 orbpos = sat,
259                                                                 longitude = nim.longitude.float,
260                                                                 loDirection = loValue,
261                                                                 latitude = nim.latitude.float,
262                                                                 laDirection = laValue,
263                                                                 turningSpeed = turning_speed,
264                                                                 useInputPower = useInputPower,
265                                                                 inputPowerDelta = inputPowerDelta,
266                                                                 diseqc13V = nim.diseqc13V.value)
267                                         elif nim.configMode.value == "advanced": #advanced config
268                                                 self.updateAdvanced(sec, x)
269                 print "sec config completed"
270
271         def updateAdvanced(self, sec, slotid):
272                 try:
273                         if config.Nims[slotid].advanced.unicableconnected is not None:
274                                 if config.Nims[slotid].advanced.unicableconnected.value == True:
275                                         config.Nims[slotid].advanced.unicableconnectedTo.save_forced = True
276                                         self.linkNIMs(sec, slotid, int(config.Nims[slotid].advanced.unicableconnectedTo.value))
277                                         connto = self.getRoot(slotid, int(config.Nims[slotid].advanced.unicableconnectedTo.value))
278                                         if not self.linked.has_key(connto):
279                                                 self.linked[connto] = []
280                                         self.linked[connto].append(slotid)
281                                 else:
282                                         config.Nims[slotid].advanced.unicableconnectedTo.save_forced = False
283                 except:
284                         pass
285
286                 lnbSat = {}
287                 for x in range(1, 71):
288                         lnbSat[x] = []
289
290                 #wildcard for all satellites ( for rotor )
291                 for x in range(3601, 3605):
292                         lnb = int(config.Nims[slotid].advanced.sat[x].lnb.value)
293                         if lnb != 0:
294                                 for x in self.NimManager.satList:
295                                         print "add", x[0], "to", lnb
296                                         lnbSat[lnb].append(x[0])
297
298                 #wildcard for user satellites ( for rotor )
299                 for x in range(3605, 3607):
300                         lnb = int(config.Nims[slotid].advanced.sat[x].lnb.value)
301                         if lnb != 0:
302                                 for user_sat in self.NimManager.satList:
303                                         if str(user_sat[0]) in config.Nims[slotid].advanced.sat[x].userSatellitesList.value:
304                                                 print "add", user_sat[0], "to", lnb
305                                                 lnbSat[lnb].append(user_sat[0])
306
307                 for x in self.NimManager.satList:
308                         lnb = int(config.Nims[slotid].advanced.sat[x[0]].lnb.value)
309                         if lnb != 0:
310                                 print "add", x[0], "to", lnb
311                                 lnbSat[lnb].append(x[0])
312
313                 for x in range(1, 71):
314                         if len(lnbSat[x]) > 0:
315                                 currLnb = config.Nims[slotid].advanced.lnb[x]
316                                 sec.addLNB()
317
318                                 if x < 65:
319                                         sec.setLNBNum(x)
320
321                                 tunermask = 1 << slotid
322                                 if self.equal.has_key(slotid):
323                                         for slot in self.equal[slotid]:
324                                                 tunermask |= (1 << slot)
325                                 if self.linked.has_key(slotid):
326                                         for slot in self.linked[slotid]:
327                                                 tunermask |= (1 << slot)
328
329                                 if currLnb.lof.value != "unicable":
330                                         sec.setLNBSatCR(-1)
331
332                                 if currLnb.lof.value == "universal_lnb":
333                                         sec.setLNBLOFL(9750000)
334                                         sec.setLNBLOFH(10600000)
335                                         sec.setLNBThreshold(11700000)
336                                 elif currLnb.lof.value == "unicable":
337                                         def setupUnicable(configManufacturer, ProductDict):
338                                                 manufacturer_name = configManufacturer.value
339                                                 manufacturer = ProductDict[manufacturer_name]
340                                                 product_name = manufacturer.product.value
341                                                 sec.setLNBSatCR(manufacturer.scr[product_name].index)
342                                                 sec.setLNBSatCRvco(manufacturer.vco[product_name][manufacturer.scr[product_name].index].value*1000)
343                                                 sec.setLNBSatCRpositions(manufacturer.positions[product_name][0].value)
344                                                 sec.setLNBLOFL(manufacturer.lofl[product_name][0].value * 1000)
345                                                 sec.setLNBLOFH(manufacturer.lofh[product_name][0].value * 1000)
346                                                 sec.setLNBThreshold(manufacturer.loft[product_name][0].value * 1000)
347                                                 configManufacturer.save_forced = True
348                                                 manufacturer.product.save_forced = True
349                                                 manufacturer.vco[product_name][manufacturer.scr[product_name].index].save_forced = True
350
351                                         if currLnb.unicable.value == "unicable_user":
352 #TODO satpositions for satcruser
353                                                 sec.setLNBLOFL(currLnb.lofl.value * 1000)
354                                                 sec.setLNBLOFH(currLnb.lofh.value * 1000)
355                                                 sec.setLNBThreshold(currLnb.threshold.value * 1000)
356                                                 sec.setLNBSatCR(currLnb.satcruser.index)
357                                                 sec.setLNBSatCRvco(currLnb.satcrvcouser[currLnb.satcruser.index].value*1000)
358                                                 sec.setLNBSatCRpositions(1)     #HACK
359                                         elif currLnb.unicable.value == "unicable_matrix":
360                                                 setupUnicable(currLnb.unicableMatrixManufacturer, currLnb.unicableMatrix)
361                                         elif currLnb.unicable.value == "unicable_lnb":
362                                                 setupUnicable(currLnb.unicableLnbManufacturer, currLnb.unicableLnb)
363                                 elif currLnb.lof.value == "c_band":
364                                         sec.setLNBLOFL(5150000)
365                                         sec.setLNBLOFH(5150000)
366                                         sec.setLNBThreshold(5150000)
367                                 elif currLnb.lof.value == "user_defined":
368                                         sec.setLNBLOFL(currLnb.lofl.value * 1000)
369                                         sec.setLNBLOFH(currLnb.lofh.value * 1000)
370                                         sec.setLNBThreshold(currLnb.threshold.value * 1000)
371                                 elif currLnb.lof.value == "circular_lnb":
372                                         sec.setLNBLOFL(10750000)
373                                         sec.setLNBLOFH(10750000)
374                                         sec.setLNBThreshold(10750000)
375
376                                 if currLnb.increased_voltage.value:
377                                         sec.setLNBIncreasedVoltage(True)
378                                 else:
379                                         sec.setLNBIncreasedVoltage(False)
380
381                                 dm = currLnb.diseqcMode.value
382                                 if dm == "none":
383                                         sec.setDiSEqCMode(diseqcParam.NONE)
384                                 elif dm == "1_0":
385                                         sec.setDiSEqCMode(diseqcParam.V1_0)
386                                 elif dm == "1_1":
387                                         sec.setDiSEqCMode(diseqcParam.V1_1)
388                                 elif dm == "1_2":
389                                         sec.setDiSEqCMode(diseqcParam.V1_2)
390
391                                         if self.satposdepends.has_key(slotid):
392                                                 for slot in self.satposdepends[slotid]:
393                                                         tunermask |= (1 << slot)
394
395                                 if dm != "none":
396                                         if currLnb.toneburst.value == "none":
397                                                 sec.setToneburst(diseqcParam.NO)
398                                         elif currLnb.toneburst.value == "A":
399                                                 sec.setToneburst(diseqcParam.A)
400                                         elif currLnb.toneburst.value == "B":
401                                                 sec.setToneburst(diseqcParam.B)
402
403                                         # Committed Diseqc Command
404                                         cdc = currLnb.commitedDiseqcCommand.value
405
406                                         c = { "none": diseqcParam.SENDNO,
407                                                 "AA": diseqcParam.AA,
408                                                 "AB": diseqcParam.AB,
409                                                 "BA": diseqcParam.BA,
410                                                 "BB": diseqcParam.BB }
411
412                                         if c.has_key(cdc):
413                                                 sec.setCommittedCommand(c[cdc])
414                                         else:
415                                                 sec.setCommittedCommand(long(cdc))
416
417                                         sec.setFastDiSEqC(currLnb.fastDiseqc.value)
418
419                                         sec.setSeqRepeat(currLnb.sequenceRepeat.value)
420
421                                         if currLnb.diseqcMode.value == "1_0":
422                                                 currCO = currLnb.commandOrder1_0.value
423                                                 sec.setRepeats(0)
424                                         else:
425                                                 currCO = currLnb.commandOrder.value
426
427                                                 udc = int(currLnb.uncommittedDiseqcCommand.value)
428                                                 if udc > 0:
429                                                         sec.setUncommittedCommand(0xF0|(udc-1))
430                                                 else:
431                                                         sec.setUncommittedCommand(0) # SENDNO
432
433                                                 sec.setRepeats({"none": 0, "one": 1, "two": 2, "three": 3}[currLnb.diseqcRepeats.value])
434
435                                         setCommandOrder = False
436
437                                         # 0 "committed, toneburst",
438                                         # 1 "toneburst, committed",
439                                         # 2 "committed, uncommitted, toneburst",
440                                         # 3 "toneburst, committed, uncommitted",
441                                         # 4 "uncommitted, committed, toneburst"
442                                         # 5 "toneburst, uncommitted, commmitted"
443                                         order_map = {"ct": 0, "tc": 1, "cut": 2, "tcu": 3, "uct": 4, "tuc": 5}
444                                         sec.setCommandOrder(order_map[currCO])
445
446                                 if dm == "1_2":
447                                         latitude = currLnb.latitude.float
448                                         sec.setLatitude(latitude)
449                                         longitude = currLnb.longitude.float
450                                         sec.setLongitude(longitude)
451                                         if currLnb.latitudeOrientation.value == "north":
452                                                 sec.setLaDirection(rotorParam.NORTH)
453                                         else:
454                                                 sec.setLaDirection(rotorParam.SOUTH)
455                                         if currLnb.longitudeOrientation.value == "east":
456                                                 sec.setLoDirection(rotorParam.EAST)
457                                         else:
458                                                 sec.setLoDirection(rotorParam.WEST)
459
460                                         if currLnb.powerMeasurement.value:
461                                                 sec.setUseInputpower(True)
462                                                 sec.setInputpowerDelta(currLnb.powerThreshold.value)
463                                                 turn_speed_dict = { "fast": rotorParam.FAST, "slow": rotorParam.SLOW }
464                                                 if turn_speed_dict.has_key(currLnb.turningSpeed.value):
465                                                         turning_speed = turn_speed_dict[currLnb.turningSpeed.value]
466                                                 else:
467                                                         beg_time = localtime(currLnb.fastTurningBegin.value)
468                                                         end_time = localtime(currLnb.fastTurningEnd.value)
469                                                         turning_speed = ((beg_time.tm_hour + 1) * 60 + beg_time.tm_min + 1) << 16
470                                                         turning_speed |= (end_time.tm_hour + 1) * 60 + end_time.tm_min + 1
471                                                 sec.setRotorTurningSpeed(turning_speed)
472                                         else:
473                                                 sec.setUseInputpower(False)
474
475                                 sec.setLNBSlotMask(tunermask)
476
477                                 sec.setLNBPrio(int(currLnb.prio.value))
478
479                                 # finally add the orbital positions
480                                 for y in lnbSat[x]:
481                                         self.addSatellite(sec, y)
482                                         if x > 64:
483                                                 satpos = x > 64 and (3606-(70 - x)) or y
484                                         else:
485                                                 satpos = y
486                                         currSat = config.Nims[slotid].advanced.sat[satpos]
487                                         if currSat.voltage.value == "polarization":
488                                                 if config.Nims[slotid].diseqc13V.value:
489                                                         sec.setVoltageMode(switchParam.HV_13)
490                                                 else:
491                                                         sec.setVoltageMode(switchParam.HV)
492                                         elif currSat.voltage.value == "13V":
493                                                 sec.setVoltageMode(switchParam._14V)
494                                         elif currSat.voltage.value == "18V":
495                                                 sec.setVoltageMode(switchParam._18V)
496
497                                         if currSat.tonemode.value == "band":
498                                                 sec.setToneMode(switchParam.HILO)
499                                         elif currSat.tonemode.value == "on":
500                                                 sec.setToneMode(switchParam.ON)
501                                         elif currSat.tonemode.value == "off":
502                                                 sec.setToneMode(switchParam.OFF)
503                                         if not currSat.usals.value and x < 65:
504                                                 sec.setRotorPosNum(currSat.rotorposition.value)
505                                         else:
506                                                 sec.setRotorPosNum(0) #USALS
507
508         def __init__(self, nimmgr):
509                 self.NimManager = nimmgr
510                 self.configuredSatellites = set()
511                 self.update()
512
513 class NIM(object):
514         def __init__(self, slot, type, description, has_outputs = True, internally_connectable = None, multi_type = {}, frontend_id = None, i2c = None, is_empty = False):
515                 self.slot = slot
516
517                 if type not in ("DVB-S", "DVB-C", "DVB-T", "DVB-S2", "DVB-T2", "DVB-C2", "ATSC", None):
518                         print "warning: unknown NIM type %s, not using." % type
519                         type = None
520
521                 self.type = type
522                 self.description = description
523                 self.has_outputs = has_outputs
524                 self.internally_connectable = internally_connectable
525                 self.multi_type = multi_type
526                 self.i2c = i2c
527                 self.frontend_id = frontend_id
528                 self.__is_empty = is_empty
529
530                 self.compatible = {
531                                 None: (None,),
532                                 "DVB-S": ("DVB-S", None),
533                                 "DVB-C": ("DVB-C", None),
534                                 "DVB-T": ("DVB-T", None),
535                                 "DVB-S2": ("DVB-S", "DVB-S2", None),
536                                 "DVB-C2": ("DVB-C", "DVB-C2", None),
537                                 "DVB-T2": ("DVB-T", "DVB-T2", None),
538                                 "ATSC": ("ATSC", None),
539                         }
540
541         def isCompatible(self, what):
542                 if not self.isSupported():
543                         return False
544                 return what in self.compatible[self.getType()]
545
546         def canBeCompatible(self, what):
547                 if not self.isSupported():
548                         return False
549                 if self.isCompatible(what):
550                         return True
551                 for type in self.multi_type.values():
552                         if what in self.compatible[type]:
553                                 return True
554                 return False
555
556         def getType(self):
557                 try:
558                         if self.isMultiType():
559                                 return self.multi_type[self.config.multiType.value]
560                 except:
561                         pass
562                 return self.type
563
564         def connectableTo(self):
565                 connectable = {
566                                 "DVB-S": ("DVB-S", "DVB-S2"),
567                                 "DVB-C": ("DVB-C", "DVB-C2"),
568                                 "DVB-T": ("DVB-T","DVB-T2"),
569                                 "DVB-S2": ("DVB-S", "DVB-S2"),
570                                 "DVB-C2": ("DVB-C", "DVB-C2"),
571                                 "DVB-T2": ("DVB-T", "DVB-T2"),
572                                 "ATSC": ("ATSC"),
573                         }
574                 return connectable[self.getType()]
575
576         def getSlotName(self):
577                 # get a friendly description for a slot name.
578                 # we name them "Tuner A/B/C/...", because that's what's usually written on the back
579                 # of the device.
580                 return _("Tuner") + " " + chr(ord('A') + self.slot)
581
582         slot_name = property(getSlotName)
583
584         def getSlotID(self):
585                 return chr(ord('A') + self.slot)
586
587         def getI2C(self):
588                 return self.i2c
589
590         def hasOutputs(self):
591                 return self.has_outputs
592
593         def internallyConnectableTo(self):
594                 return self.internally_connectable
595
596         def setInternalLink(self):
597                 if self.internally_connectable is not None:
598                         print "setting internal link on frontend id", self.frontend_id
599                         open("/proc/stb/frontend/%d/rf_switch" % self.frontend_id, "w").write("internal")
600
601         def removeInternalLink(self):
602                 if self.internally_connectable is not None:
603                         print "removing internal link on frontend id", self.frontend_id
604                         open("/proc/stb/frontend/%d/rf_switch" % self.frontend_id, "w").write("external")
605
606         def isMultiType(self):
607                 return (len(self.multi_type) > 0)
608
609         def isEmpty(self):
610                 return self.__is_empty
611
612         # empty tuners are supported!
613         def isSupported(self):
614                 return (self.frontend_id is not None) or self.__is_empty
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-C2": "DVB-C2",
630                         "ATSC": "ATSC",
631                         None: _("empty")
632                         }[self.getType()]
633
634         friendly_type = property(getFriendlyType)
635
636         def getFriendlyFullDescription(self):
637                 nim_text = self.slot_name + ": "
638
639                 if self.empty:
640                         nim_text += _("(empty)")
641                 elif not self.isSupported():
642                         nim_text += self.description + " (" + _("not supported") + ")"
643                 else:
644                         nim_text += self.description + " (" + self.friendly_type + ")"
645
646                 return nim_text
647
648         friendly_full_description = property(getFriendlyFullDescription)
649         config_mode = property(lambda self: config.Nims[self.slot].configMode.value)
650         config = property(lambda self: config.Nims[self.slot])
651         empty = property(lambda self: self.getType is None)
652
653 class NimManager:
654         def getConfiguredSats(self):
655                 return self.sec.getConfiguredSats()
656
657         def getTransponders(self, pos):
658                 if self.transponders.has_key(pos):
659                         return self.transponders[pos]
660                 else:
661                         return []
662
663         def getTranspondersCable(self, nim):
664                 nimConfig = config.Nims[nim]
665                 if nimConfig.configMode.value != "nothing" and nimConfig.cable.scan_type.value == "provider":
666                         return self.transponderscable[self.cablesList[nimConfig.cable.scan_provider.index][0]]
667                 return [ ]
668
669         def getTranspondersTerrestrial(self, region):
670                 return self.transpondersterrestrial[region]
671
672         def getCableDescription(self, nim):
673                 return self.cablesList[config.Nims[nim].scan_provider.index][0]
674
675         def getCableFlags(self, nim):
676                 return self.cablesList[config.Nims[nim].scan_provider.index][1]
677
678         def getTerrestrialDescription(self, nim):
679                 return self.terrestrialsList[config.Nims[nim].terrestrial.index][0]
680
681         def getTerrestrialFlags(self, nim):
682                 return self.terrestrialsList[config.Nims[nim].terrestrial.index][1]
683
684         def getSatDescription(self, pos):
685                 return self.satellites[pos]
686
687         def sortFunc(self, x):
688                 orbpos = x[0]
689                 if orbpos > 1800:
690                         return orbpos - 3600
691                 else:
692                         return orbpos + 1800
693
694         def readTransponders(self):
695                 self.satellites = { }
696                 self.transponders = { }
697                 self.transponderscable = { }
698                 self.transpondersterrestrial = { }
699                 self.transpondersatsc = { }
700                 db = eDVBDB.getInstance()
701
702                 if self.hasNimType("DVB-S"):
703                         print "Reading satellites.xml"
704                         db.readSatellites(self.satList, self.satellites, self.transponders)
705                         self.satList.sort() # sort by orbpos
706
707                 if self.hasNimType("DVB-C") or self.hasNimType("DVB-T"):
708                         print "Reading cables.xml"
709                         db.readCables(self.cablesList, self.transponderscable)
710                         print "Reading terrestrial.xml"
711                         db.readTerrestrials(self.terrestrialsList, self.transpondersterrestrial)
712
713         def enumerateNIMs(self):
714                 # enum available NIMs. This is currently very dreambox-centric and uses the /proc/bus/nim_sockets interface.
715                 # the result will be stored into nim_slots.
716                 # the content of /proc/bus/nim_sockets looks like:
717                 # NIM Socket 0:
718                 #          Type: DVB-S
719                 #          Name: BCM4501 DVB-S2 NIM (internal)
720                 # NIM Socket 1:
721                 #          Type: DVB-S
722                 #          Name: BCM4501 DVB-S2 NIM (internal)
723                 # NIM Socket 2:
724                 #          Type: DVB-T
725                 #          Name: Philips TU1216
726                 # NIM Socket 3:
727                 #          Type: DVB-S
728                 #          Name: Alps BSBE1 702A
729
730                 #
731                 # Type will be either "DVB-S", "DVB-S2", "DVB-T", "DVB-C" or None.
732
733                 # nim_slots is an array which has exactly one entry for each slot, even for empty ones.
734                 self.nim_slots = [ ]
735
736                 try:
737                         nimfile = open("/proc/bus/nim_sockets")
738                 except IOError:
739                         return
740
741                 current_slot = None
742
743                 entries = {}
744                 for line in nimfile:
745                         if not line:
746                                 break
747                         line = line.strip()
748                         if line.startswith("NIM Socket"):
749                                 parts = line.split(" ")
750                                 current_slot = int(parts[2][:-1])
751                                 entries[current_slot] = {}
752                         elif line.startswith("Type:"):
753                                 entries[current_slot]["type"] = str(line[6:])
754                                 entries[current_slot]["isempty"] = False
755                         elif line.startswith("Name:"):
756                                 entries[current_slot]["name"] = str(line[6:])
757                                 entries[current_slot]["isempty"] = False
758                         elif line.startswith("Has_Outputs:"):
759                                 input = str(line[len("Has_Outputs:") + 1:])
760                                 entries[current_slot]["has_outputs"] = (input == "yes")
761                         elif line.startswith("Internally_Connectable:"):
762                                 input = int(line[len("Internally_Connectable:") + 1:])
763                                 entries[current_slot]["internally_connectable"] = input
764                         elif line.startswith("Frontend_Device:"):
765                                 input = int(line[len("Frontend_Device:") + 1:])
766                                 entries[current_slot]["frontend_device"] = input
767                         elif  line.startswith("Mode"):
768                                 # "Mode 0: DVB-T" -> ["Mode 0", "DVB-T"]
769                                 split = line.split(": ")
770                                 if len(split) > 1 and split[1]:
771                                         # "Mode 0" -> ["Mode", "0"]
772                                         split2 = split[0].split(" ")
773                                         modes = entries[current_slot].get("multi_type", {})
774                                         modes[split2[1]] = split[1].strip()
775                                         entries[current_slot]["multi_type"] = modes
776                         elif line.startswith("I2C_Device:"):
777                                 input = int(line[len("I2C_Device:") + 1:])
778                                 entries[current_slot]["i2c"] = input
779                         elif line.startswith("empty"):
780                                 entries[current_slot]["type"] = None
781                                 entries[current_slot]["name"] = _("N/A")
782                                 entries[current_slot]["isempty"] = True
783                 nimfile.close()
784
785                 from os import path
786
787                 for id, entry in entries.items():
788                         if not (entry.has_key("name") and entry.has_key("type")):
789                                 entry["name"] =  _("N/A")
790                                 entry["type"] = None
791                         if not (entry.has_key("i2c")):
792                                 entry["i2c"] = None
793                         if not (entry.has_key("has_outputs")):
794                                 entry["has_outputs"] = True
795                         if entry.has_key("frontend_device"): # check if internally connectable
796                                 if path.exists("/proc/stb/frontend/%d/rf_switch" % entry["frontend_device"]):
797                                         entry["internally_connectable"] = entry["frontend_device"] - 1
798                                 else:
799                                         entry["internally_connectable"] = None
800                         else:
801                                 entry["frontend_device"] = entry["internally_connectable"] = None
802                         if not (entry.has_key("multi_type")):
803                                 entry["multi_type"] = {}
804                         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"]))
805
806         def hasNimType(self, chktype):
807                 for slot in self.nim_slots:
808                         if slot.isCompatible(chktype):
809                                 return True
810                         for type in slot.getMultiTypeList().values():
811                                 if chktype == type:
812                                         return True
813                 return False
814
815         def getNimType(self, slotid):
816                 return self.nim_slots[slotid].type
817
818         def getNimDescription(self, slotid):
819                 return self.nim_slots[slotid].friendly_full_description
820
821         def getNimName(self, slotid):
822                 return self.nim_slots[slotid].description
823
824         def getNim(self, slotid):
825                 return self.nim_slots[slotid]
826
827         def getI2CDevice(self, slotid):
828                 return self.nim_slots[slotid].getI2C()
829
830         def getNimListOfType(self, type, exception = -1):
831                 # returns a list of indexes for NIMs compatible to the given type, except for 'exception'
832                 list = []
833                 for x in self.nim_slots:
834                         if x.isCompatible(type) and x.slot != exception:
835                                 list.append(x.slot)
836                 return list
837
838         def __init__(self):
839                 self.satList = [ ]
840                 self.cablesList = []
841                 self.terrestrialsList = []
842                 self.atscList = []
843                 self.enumerateNIMs()
844                 self.readTransponders()
845                 InitNimManager(self)    #init config stuff
846
847         # get a list with the friendly full description
848         def nimList(self):
849                 list = [ ]
850                 for slot in self.nim_slots:
851                         list.append(slot.friendly_full_description)
852                 return list
853
854         def getSlotCount(self):
855                 return len(self.nim_slots)
856
857         def hasOutputs(self, slotid):
858                 return self.nim_slots[slotid].hasOutputs()
859
860         def nimInternallyConnectableTo(self, slotid):
861                 return self.nim_slots[slotid].internallyConnectableTo()
862
863         def nimRemoveInternalLink(self, slotid):
864                 self.nim_slots[slotid].removeInternalLink()
865
866         def canConnectTo(self, slotid):
867                 slots = []
868                 if self.nim_slots[slotid].internallyConnectableTo() is not None:
869                         slots.append(self.nim_slots[slotid].internallyConnectableTo())
870                 for type in self.nim_slots[slotid].connectableTo():
871                         for slot in self.getNimListOfType(type, exception = slotid):
872                                 if self.hasOutputs(slot):
873                                         slots.append(slot)
874                 # remove nims, that have a conntectedTo reference on
875                 for testnim in slots[:]:
876                         for nim in self.getNimListOfType("DVB-S", slotid):
877                                 nimConfig = self.getNimConfig(nim)
878                                 if nimConfig.content.items.has_key("configMode") and nimConfig.configMode.value == "loopthrough" and int(nimConfig.connectedTo.value) == testnim:
879                                         slots.remove(testnim)
880                                         break
881                 slots.sort()
882                 return slots
883
884         def canEqualTo(self, slotid):
885                 type = self.getNimType(slotid)
886                 type = type[:5] # DVB-S2 --> DVB-S, DVB-T2 --> DVB-T, DVB-C2 --> DVB-C
887                 nimList = self.getNimListOfType(type, slotid)
888                 for nim in nimList[:]:
889                         mode = self.getNimConfig(nim)
890                         if mode.configMode.value == "loopthrough" or mode.configMode.value == "satposdepends":
891                                 nimList.remove(nim)
892                 return nimList
893
894         def canDependOn(self, slotid):
895                 type = self.getNimType(slotid)
896                 type = type[:5] # DVB-S2 --> DVB-S, DVB-T2 --> DVB-T, DVB-C2 --> DVB-C
897                 nimList = self.getNimListOfType(type, slotid)
898                 positionerList = []
899                 for nim in nimList[:]:
900                         mode = self.getNimConfig(nim)
901                         nimHaveRotor = mode.configMode.value == "simple" and mode.diseqcMode.value  in ("positioner", "positioner_select")
902                         if not nimHaveRotor and mode.configMode.value == "advanced":
903                                 for x in range(3601, 3607):
904                                         lnb = int(mode.advanced.sat[x].lnb.value)
905                                         if lnb != 0:
906                                                 nimHaveRotor = True
907                                                 break
908                                 if not nimHaveRotor:
909                                         for sat in mode.advanced.sat.values():
910                                                 lnb_num = int(sat.lnb.value)
911                                                 diseqcmode = lnb_num and mode.advanced.lnb[lnb_num].diseqcMode.value or ""
912                                                 if diseqcmode == "1_2":
913                                                         nimHaveRotor = True
914                                                         break
915                         if nimHaveRotor:
916                                 alreadyConnected = False
917                                 for testnim in nimList:
918                                         testmode = self.getNimConfig(testnim)
919                                         if testmode.configMode.value == "satposdepends" and int(testmode.connectedTo.value) == int(nim):
920                                                 alreadyConnected = True
921                                                 break
922                                 if not alreadyConnected:
923                                         positionerList.append(nim)
924                 return positionerList
925
926         def getNimConfig(self, slotid):
927                 return config.Nims[slotid]
928
929         def getSatName(self, pos):
930                 for sat in self.satList:
931                         if sat[0] == pos:
932                                 return sat[1]
933                 return _("N/A")
934
935         def getSatList(self):
936                 return self.satList
937
938         # returns True if something is configured to be connected to this nim
939         # if slotid == -1, returns if something is connected to ANY nim
940         def somethingConnected(self, slotid = -1):
941                 if (slotid == -1):
942                         connected = False
943                         for id in range(self.getSlotCount()):
944                                 if self.somethingConnected(id):
945                                         connected = True
946                         return connected
947                 else:
948                         nim = config.Nims[slotid]
949                         configMode = nim.configMode.value
950
951                         if self.nim_slots[slotid].isCompatible("DVB-S") or self.nim_slots[slotid].isCompatible("DVB-T") or self.nim_slots[slotid].isCompatible("DVB-C"):
952                                 return not (configMode == "nothing")
953
954         def getSatListForNim(self, slotid):
955                 list = []
956                 if self.nim_slots[slotid].isCompatible("DVB-S"):
957                         nim = config.Nims[slotid]
958                         #print "slotid:", slotid
959
960                         #print "self.satellites:", self.satList[config.Nims[slotid].diseqcA.index]
961                         #print "diseqcA:", config.Nims[slotid].diseqcA.value
962                         configMode = nim.configMode.value
963
964                         if configMode == "equal":
965                                 slotid = int(nim.connectedTo.value)
966                                 nim = config.Nims[slotid]
967                                 configMode = nim.configMode.value
968                         elif configMode == "loopthrough":
969                                 slotid = self.sec.getRoot(slotid, int(nim.connectedTo.value))
970                                 nim = config.Nims[slotid]
971                                 configMode = nim.configMode.value
972
973                         if configMode == "simple":
974                                 dm = nim.diseqcMode.value
975                                 if dm in ("single", "toneburst_a_b", "diseqc_a_b", "diseqc_a_b_c_d"):
976                                         if nim.diseqcA.orbital_position < 3600:
977                                                 list.append(self.satList[nim.diseqcA.index - 2])
978                                 if dm in ("toneburst_a_b", "diseqc_a_b", "diseqc_a_b_c_d"):
979                                         if nim.diseqcB.orbital_position < 3600:
980                                                 list.append(self.satList[nim.diseqcB.index - 2])
981                                 if dm == "diseqc_a_b_c_d":
982                                         if nim.diseqcC.orbital_position < 3600:
983                                                 list.append(self.satList[nim.diseqcC.index - 2])
984                                         if nim.diseqcD.orbital_position < 3600:
985                                                 list.append(self.satList[nim.diseqcD.index - 2])
986                                 if dm == "positioner":
987                                         for x in self.satList:
988                                                 list.append(x)
989                                 if dm == "positioner_select":
990                                         for x in self.satList:
991                                                 if str(x[0]) in nim.userSatellitesList.value:
992                                                         list.append(x)
993                         elif configMode == "advanced":
994                                 for x in range(3601, 3605):
995                                         if int(nim.advanced.sat[x].lnb.value) != 0:
996                                                 for x in self.satList:
997                                                         list.append(x)
998                                 if not list:
999                                         for x in self.satList:
1000                                                 if int(nim.advanced.sat[x[0]].lnb.value) != 0:
1001                                                         list.append(x)
1002                                 for x in range(3605, 3607):
1003                                         if int(nim.advanced.sat[x].lnb.value) != 0:
1004                                                 for user_sat in self.satList:
1005                                                         if str(user_sat[0]) in nim.advanced.sat[x].userSatellitesList.value and user_sat not in list:
1006                                                                 list.append(user_sat)
1007                 return list
1008
1009         def getRotorSatListForNim(self, slotid):
1010                 list = []
1011                 if self.nim_slots[slotid].isCompatible("DVB-S"):
1012                         nim = config.Nims[slotid]
1013                         configMode = nim.configMode.value
1014                         if configMode == "simple":
1015                                 if nim.diseqcMode.value == "positioner":
1016                                         for x in self.satList:
1017                                                 list.append(x)
1018                                 elif nim.diseqcMode.value == "positioner_select":
1019                                         for x in self.satList:
1020                                                 if str(x[0]) in nim.userSatellitesList.value:
1021                                                         list.append(x)
1022                         elif configMode == "advanced":
1023                                 for x in range(3601, 3605):
1024                                         if int(nim.advanced.sat[x].lnb.value) != 0:
1025                                                 for x in self.satList:
1026                                                         list.append(x)
1027                                 if not list:
1028                                         for x in self.satList:
1029                                                 lnbnum = int(nim.advanced.sat[x[0]].lnb.value)
1030                                                 if lnbnum != 0:
1031                                                         lnb = nim.advanced.lnb[lnbnum]
1032                                                         if lnb.diseqcMode.value == "1_2":
1033                                                                 list.append(x)
1034                                 for x in range(3605, 3607):
1035                                         if int(nim.advanced.sat[x].lnb.value) != 0:
1036                                                 for user_sat in self.satList:
1037                                                         if str(user_sat[0]) in nim.advanced.sat[x].userSatellitesList.value and user_sat not in list:
1038                                                                 list.append(user_sat)
1039                 return list
1040
1041 def InitSecParams():
1042         config.sec = ConfigSubsection()
1043
1044         x = ConfigInteger(default=25, limits = (0, 9999))
1045         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_CONT_TONE_DISABLE_BEFORE_DISEQC, configElement.value))
1046         config.sec.delay_after_continuous_tone_disable_before_diseqc = x
1047
1048         x = ConfigInteger(default=10, limits = (0, 9999))
1049         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_FINAL_CONT_TONE_CHANGE, configElement.value))
1050         config.sec.delay_after_final_continuous_tone_change = x
1051
1052         x = ConfigInteger(default=10, limits = (0, 9999))
1053         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_FINAL_VOLTAGE_CHANGE, configElement.value))
1054         config.sec.delay_after_final_voltage_change = x
1055
1056         x = ConfigInteger(default=120, limits = (0, 9999))
1057         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_BETWEEN_DISEQC_REPEATS, configElement.value))
1058         config.sec.delay_between_diseqc_repeats = x
1059
1060         x = ConfigInteger(default=50, limits = (0, 9999))
1061         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_LAST_DISEQC_CMD, configElement.value))
1062         config.sec.delay_after_last_diseqc_command = x
1063
1064         x = ConfigInteger(default=50, limits = (0, 9999))
1065         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_TONEBURST, configElement.value))
1066         config.sec.delay_after_toneburst = x
1067
1068         x = ConfigInteger(default=20, limits = (0, 9999))
1069         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_SWITCH_CMDS, configElement.value))
1070         config.sec.delay_after_change_voltage_before_switch_command = x
1071
1072         x = ConfigInteger(default=200, limits = (0, 9999))
1073         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_ENABLE_VOLTAGE_BEFORE_SWITCH_CMDS, configElement.value))
1074         config.sec.delay_after_enable_voltage_before_switch_command = x
1075
1076         x = ConfigInteger(default=700, limits = (0, 9999))
1077         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_BETWEEN_SWITCH_AND_MOTOR_CMD, configElement.value))
1078         config.sec.delay_between_switch_and_motor_command = x
1079
1080         x = ConfigInteger(default=500, limits = (0, 9999))
1081         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_MEASURE_IDLE_INPUTPOWER, configElement.value))
1082         config.sec.delay_after_voltage_change_before_measure_idle_inputpower = x
1083
1084         x = ConfigInteger(default=900, limits = (0, 9999))
1085         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_ENABLE_VOLTAGE_BEFORE_MOTOR_CMD, configElement.value))
1086         config.sec.delay_after_enable_voltage_before_motor_command = x
1087
1088         x = ConfigInteger(default=500, limits = (0, 9999))
1089         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_MOTOR_STOP_CMD, configElement.value))
1090         config.sec.delay_after_motor_stop_command = x
1091
1092         x = ConfigInteger(default=500, limits = (0, 9999))
1093         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_MOTOR_CMD, configElement.value))
1094         config.sec.delay_after_voltage_change_before_motor_command = x
1095
1096         x = ConfigInteger(default=70, limits = (0, 9999))
1097         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_BEFORE_SEQUENCE_REPEAT, configElement.value))
1098         config.sec.delay_before_sequence_repeat = x
1099
1100         x = ConfigInteger(default=360, limits = (0, 9999))
1101         x.addNotifier(lambda configElement: secClass.setParam(secClass.MOTOR_RUNNING_TIMEOUT, configElement.value))
1102         config.sec.motor_running_timeout = x
1103
1104         x = ConfigInteger(default=1, limits = (0, 5))
1105         x.addNotifier(lambda configElement: secClass.setParam(secClass.MOTOR_COMMAND_RETRIES, configElement.value))
1106         config.sec.motor_command_retries = x
1107
1108         x = ConfigInteger(default=50, limits = (0, 9999))
1109         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_DISEQC_RESET_CMD, configElement.value))
1110         config.sec.delay_after_diseqc_reset_cmd = x
1111
1112         x = ConfigInteger(default=150, limits = (0, 9999))
1113         x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_DISEQC_PERIPHERIAL_POWERON_CMD, configElement.value))
1114         config.sec.delay_after_diseqc_peripherial_poweron_cmd = x
1115
1116 # TODO add support for satpos depending nims to advanced nim configuration
1117 # so a second/third/fourth cable from a motorized lnb can used behind a
1118 # diseqc 1.0 / diseqc 1.1 / toneburst switch
1119 # the C(++) part should can handle this
1120 # the configElement should be only visible when diseqc 1.2 is disabled
1121
1122 def InitNimManager(nimmgr):
1123         hw = HardwareInfo()
1124         addNimConfig = False
1125         try:
1126                 config.Nims
1127         except:
1128                 addNimConfig = True
1129
1130         if addNimConfig:
1131                 InitSecParams()
1132                 config.Nims = ConfigSubList()
1133                 for x in range(len(nimmgr.nim_slots)):
1134                         config.Nims.append(ConfigSubsection())
1135
1136         lnb_choices = {
1137                 "universal_lnb": _("Universal LNB"),
1138                 "unicable": _("Unicable"),
1139                 "c_band": _("C-Band"),
1140                 "circular_lnb": _("Circular LNB"),
1141                 "user_defined": _("User defined")}
1142
1143         lnb_choices_default = "universal_lnb"
1144
1145         unicablelnbproducts = {}
1146         unicablematrixproducts = {}
1147         doc = xml.etree.cElementTree.parse(eEnv.resolve("${datadir}/enigma2/unicable.xml"))
1148         root = doc.getroot()
1149
1150         entry = root.find("lnb")
1151         for manufacturer in entry.getchildren():
1152                 m={}
1153                 for product in manufacturer.getchildren():
1154                         scr=[]
1155                         lscr=("scr1","scr2","scr3","scr4","scr5","scr6","scr7","scr8")
1156                         for i in range(len(lscr)):
1157                                 scr.append(product.get(lscr[i],"0"))
1158                         for i in range(len(lscr)):
1159                                 if scr[len(lscr)-i-1] == "0":
1160                                         scr.pop()
1161                                 else:
1162                                         break;
1163                         lof=[]
1164                         lof.append(int(product.get("positions",1)))
1165                         lof.append(int(product.get("lofl",9750)))
1166                         lof.append(int(product.get("lofh",10600)))
1167                         lof.append(int(product.get("threshold",11700)))
1168                         scr.append(tuple(lof))
1169                         m.update({product.get("name"):tuple(scr)})
1170                 unicablelnbproducts.update({manufacturer.get("name"):m})
1171
1172         entry = root.find("matrix")
1173         for manufacturer in entry.getchildren():
1174                 m={}
1175                 for product in manufacturer.getchildren():
1176                         scr=[]
1177                         lscr=("scr1","scr2","scr3","scr4","scr5","scr6","scr7","scr8")
1178                         for i in range(len(lscr)):
1179                                 scr.append(product.get(lscr[i],"0"))
1180                         for i in range(len(lscr)):
1181                                 if scr[len(lscr)-i-1] == "0":
1182                                         scr.pop()
1183                                 else:
1184                                         break;
1185                         lof=[]
1186                         lof.append(int(product.get("positions",1)))
1187                         lof.append(int(product.get("lofl",9750)))
1188                         lof.append(int(product.get("lofh",10600)))
1189                         lof.append(int(product.get("threshold",11700)))
1190                         scr.append(tuple(lof))
1191                         m.update({product.get("name"):tuple(scr)})
1192                 unicablematrixproducts.update({manufacturer.get("name"):m})
1193
1194         UnicableLnbManufacturers = unicablelnbproducts.keys()
1195         UnicableLnbManufacturers.sort()
1196         UnicableMatrixManufacturers = unicablematrixproducts.keys()
1197         UnicableMatrixManufacturers.sort()
1198
1199         unicable_choices = {
1200                 "unicable_lnb": _("Unicable LNB"),
1201                 "unicable_matrix": _("Unicable Martix"),
1202                 "unicable_user": "Unicable "+_("User defined")}
1203         unicable_choices_default = "unicable_lnb"
1204
1205         advanced_lnb_satcruser_choices = [ ("1", "SatCR 1"), ("2", "SatCR 2"), ("3", "SatCR 3"), ("4", "SatCR 4"),
1206                                         ("5", "SatCR 5"), ("6", "SatCR 6"), ("7", "SatCR 7"), ("8", "SatCR 8")]
1207
1208         prio_list = [ ("-1", _("Auto")) ]
1209         for prio in range(65)+range(14000,14065)+range(19000,19065):
1210                 description = ""
1211                 if prio == 0:
1212                         description = _(" (disabled)")
1213                 elif 0 < prio < 65:
1214                         description = _(" (lower than any auto)")
1215                 elif 13999 < prio < 14066:
1216                         description = _(" (higher than rotor any auto)")
1217                 elif 18999 < prio < 19066:
1218                         description = _(" (higher than any auto)")
1219                 prio_list.append((str(prio), str(prio) + description))
1220
1221         advanced_lnb_csw_choices = [("none", _("None")), ("AA", _("Port A")), ("AB", _("Port B")), ("BA", _("Port C")), ("BB", _("Port D"))]
1222
1223         advanced_lnb_ucsw_choices = [("0", _("None"))] + [(str(y), "Input " + str(y)) for y in range(1, 17)]
1224
1225         diseqc_mode_choices = [
1226                 ("single", _("Single")), ("toneburst_a_b", _("Toneburst A/B")),
1227                 ("diseqc_a_b", "DiSEqC A/B"), ("diseqc_a_b_c_d", "DiSEqC A/B/C/D"),
1228                 ("positioner", _("Positioner")), ("positioner_select", _("Positioner (selecting satellites)"))]
1229
1230         positioner_mode_choices = [("usals", _("USALS")), ("manual", _("manual"))]
1231
1232         diseqc_satlist_choices = [(3600, _('automatic'), 1), (3601, _('nothing connected'), 1)] + nimmgr.satList
1233
1234         longitude_orientation_choices = [("east", _("East")), ("west", _("West"))]
1235         latitude_orientation_choices = [("north", _("North")), ("south", _("South"))]
1236         turning_speed_choices = [("fast", _("Fast")), ("slow", _("Slow")), ("fast epoch", _("Fast epoch"))]
1237
1238         advanced_satlist_choices = nimmgr.satList + [
1239                 (3601, _('All satellites 1 (USALS)'), 1), (3602, _('All satellites 2 (USALS)'), 1),
1240                 (3603, _('All satellites 3 (USALS)'), 1), (3604, _('All satellites 4 (USALS)'), 1), (3605, _('Selecting satellites 1 (USALS)'), 1), (3606, _('Selecting satellites 2 (USALS)'), 1)]
1241         advanced_lnb_choices = [("0", _("not configured"))] + [(str(y), "LNB " + str(y)) for y in range(1, 65)]
1242         advanced_voltage_choices = [("polarization", _("Polarization")), ("13V", _("13 V")), ("18V", _("18 V"))]
1243         advanced_tonemode_choices = [("band", _("Band")), ("on", _("On")), ("off", _("Off"))]
1244         advanced_lnb_toneburst_choices = [("none", _("None")), ("A", _("A")), ("B", _("B"))]
1245         advanced_lnb_allsat_diseqcmode_choices = [("1_2", _("1.2"))]
1246         advanced_lnb_diseqcmode_choices = [("none", _("None")), ("1_0", _("1.0")), ("1_1", _("1.1")), ("1_2", _("1.2"))]
1247         advanced_lnb_commandOrder1_0_choices = [("ct", "DiSEqC 1.0, toneburst"), ("tc", "toneburst, DiSEqC 1.0")]
1248         advanced_lnb_commandOrder_choices = [
1249                 ("ct", "DiSEqC 1.0, toneburst"), ("tc", "toneburst, DiSEqC 1.0"),
1250                 ("cut", "DiSEqC 1.0, DiSEqC 1.1, toneburst"), ("tcu", "toneburst, DiSEqC 1.0, DiSEqC 1.1"),
1251                 ("uct", "DiSEqC 1.1, DiSEqC 1.0, toneburst"), ("tuc", "toneburst, DiSEqC 1.1, DiSEqC 1.0")]
1252         advanced_lnb_diseqc_repeat_choices = [("none", _("None")), ("one", _("One")), ("two", _("Two")), ("three", _("Three"))]
1253         advanced_lnb_fast_turning_btime = mktime(datetime(1970, 1, 1, 7, 0).timetuple());
1254         advanced_lnb_fast_turning_etime = mktime(datetime(1970, 1, 1, 19, 0).timetuple());
1255
1256         def configLOFChanged(configElement):
1257                 if configElement.value == "unicable":
1258                         x = configElement.slot_id
1259                         lnb = configElement.lnb_id
1260                         nim = config.Nims[x]
1261                         lnbs = nim.advanced.lnb
1262                         section = lnbs[lnb]
1263                         if isinstance(section.unicable, ConfigNothing):
1264                                 if lnb == 1:
1265                                         section.unicable = ConfigSelection(unicable_choices, unicable_choices_default)
1266                                 elif lnb == 2:
1267                                         section.unicable = ConfigSelection(choices = {"unicable_matrix": _("Unicable Martix"),"unicable_user": "Unicable "+_("User defined")}, default = "unicable_matrix")
1268                                 else:
1269                                         section.unicable = ConfigSelection(choices = {"unicable_user": _("User defined")}, default = "unicable_user")
1270
1271                                 def fillUnicableConf(sectionDict, unicableproducts, vco_null_check):
1272                                         for y in unicableproducts:
1273                                                 products = unicableproducts[y].keys()
1274                                                 products.sort()
1275                                                 tmp = ConfigSubsection()
1276                                                 tmp.product = ConfigSelection(choices = products, default = products[0])
1277                                                 tmp.scr = ConfigSubDict()
1278                                                 tmp.vco = ConfigSubDict()
1279                                                 tmp.lofl = ConfigSubDict()
1280                                                 tmp.lofh = ConfigSubDict()
1281                                                 tmp.loft = ConfigSubDict()
1282                                                 tmp.positions = ConfigSubDict()
1283                                                 for z in products:
1284                                                         scrlist = []
1285                                                         vcolist = unicableproducts[y][z]
1286                                                         tmp.vco[z] = ConfigSubList()
1287                                                         for cnt in range(1,1+len(vcolist)-1):
1288                                                                 vcofreq = int(vcolist[cnt-1])
1289                                                                 if vcofreq == 0 and vco_null_check:
1290                                                                         scrlist.append(("%d" %cnt,"SCR %d " %cnt +_("not used")))
1291                                                                 else:
1292                                                                         scrlist.append(("%d" %cnt,"SCR %d" %cnt))
1293                                                                 tmp.vco[z].append(ConfigInteger(default=vcofreq, limits = (vcofreq, vcofreq)))
1294                                                                 tmp.scr[z] = ConfigSelection(choices = scrlist, default = scrlist[0][0])
1295
1296                                                                 positions = int(vcolist[len(vcolist)-1][0])
1297                                                                 tmp.positions[z] = ConfigSubList()
1298                                                                 tmp.positions[z].append(ConfigInteger(default=positions, limits = (positions, positions)))
1299
1300                                                                 lofl = vcolist[len(vcolist)-1][1]
1301                                                                 tmp.lofl[z] = ConfigSubList()
1302                                                                 tmp.lofl[z].append(ConfigInteger(default=lofl, limits = (lofl, lofl)))
1303
1304                                                                 lofh = int(vcolist[len(vcolist)-1][2])
1305                                                                 tmp.lofh[z] = ConfigSubList()
1306                                                                 tmp.lofh[z].append(ConfigInteger(default=lofh, limits = (lofh, lofh)))
1307
1308                                                                 loft = int(vcolist[len(vcolist)-1][3])
1309                                                                 tmp.loft[z] = ConfigSubList()
1310                                                                 tmp.loft[z].append(ConfigInteger(default=loft, limits = (loft, loft)))
1311                                                 sectionDict[y] = tmp
1312
1313                                 if lnb < 3:
1314                                         print "MATRIX"
1315                                         section.unicableMatrix = ConfigSubDict()
1316                                         section.unicableMatrixManufacturer = ConfigSelection(UnicableMatrixManufacturers, UnicableMatrixManufacturers[0])
1317                                         fillUnicableConf(section.unicableMatrix, unicablematrixproducts, True)
1318
1319                                 if lnb < 2:
1320                                         print "LNB"
1321                                         section.unicableLnb = ConfigSubDict()
1322                                         section.unicableLnbManufacturer = ConfigSelection(UnicableLnbManufacturers, UnicableLnbManufacturers[0])
1323                                         fillUnicableConf(section.unicableLnb, unicablelnbproducts, False)
1324
1325 #TODO satpositions for satcruser
1326                                 section.satcruser = ConfigSelection(advanced_lnb_satcruser_choices, default="1")
1327                                 tmp = ConfigSubList()
1328                                 tmp.append(ConfigInteger(default=1284, limits = (950, 2150)))
1329                                 tmp.append(ConfigInteger(default=1400, limits = (950, 2150)))
1330                                 tmp.append(ConfigInteger(default=1516, limits = (950, 2150)))
1331                                 tmp.append(ConfigInteger(default=1632, limits = (950, 2150)))
1332                                 tmp.append(ConfigInteger(default=1748, limits = (950, 2150)))
1333                                 tmp.append(ConfigInteger(default=1864, limits = (950, 2150)))
1334                                 tmp.append(ConfigInteger(default=1980, limits = (950, 2150)))
1335                                 tmp.append(ConfigInteger(default=2096, limits = (950, 2150)))
1336                                 section.satcrvcouser = tmp
1337
1338                                 nim.advanced.unicableconnected = ConfigYesNo(default=False)
1339                                 nim.advanced.unicableconnectedTo = ConfigSelection([(str(id), nimmgr.getNimDescription(id)) for id in nimmgr.getNimListOfType("DVB-S") if id != x])
1340
1341         def configDiSEqCModeChanged(configElement):
1342                 section = configElement.section
1343                 if configElement.value == "1_2" and isinstance(section.longitude, ConfigNothing):
1344                         section.longitude = ConfigFloat(default = [5,100], limits = [(0,359),(0,999)])
1345                         section.longitudeOrientation = ConfigSelection(longitude_orientation_choices, "east")
1346                         section.latitude = ConfigFloat(default = [50,767], limits = [(0,359),(0,999)])
1347                         section.latitudeOrientation = ConfigSelection(latitude_orientation_choices, "north")
1348                         section.tuningstepsize = ConfigFloat(default = [0,360], limits = [(0,9),(0,999)])
1349                         section.rotorPositions = ConfigInteger(default = 99, limits = [1,999])
1350                         section.turningspeedH = ConfigFloat(default = [2,3], limits = [(0,9),(0,9)])
1351                         section.turningspeedV = ConfigFloat(default = [1,7], limits = [(0,9),(0,9)])
1352                         section.powerMeasurement = ConfigYesNo(default=True)
1353                         section.powerThreshold = ConfigInteger(default=hw.get_device_name() == "dm7025" and 50 or 15, limits=(0, 100))
1354                         section.turningSpeed = ConfigSelection(turning_speed_choices, "fast")
1355                         section.fastTurningBegin = ConfigDateTime(default=advanced_lnb_fast_turning_btime, formatstring = _("%H:%M"), increment = 600)
1356                         section.fastTurningEnd = ConfigDateTime(default=advanced_lnb_fast_turning_etime, formatstring = _("%H:%M"), increment = 600)
1357
1358         def configLNBChanged(configElement):
1359                 x = configElement.slot_id
1360                 nim = config.Nims[x]
1361                 if isinstance(configElement.value, tuple):
1362                         lnb = int(configElement.value[0])
1363                 else:
1364                         lnb = int(configElement.value)
1365                 lnbs = nim.advanced.lnb
1366                 if lnb and lnb not in lnbs:
1367                         section = lnbs[lnb] = ConfigSubsection()
1368                         section.lofl = ConfigInteger(default=9750, limits = (0, 99999))
1369                         section.lofh = ConfigInteger(default=10600, limits = (0, 99999))
1370                         section.threshold = ConfigInteger(default=11700, limits = (0, 99999))
1371                         section.increased_voltage = ConfigYesNo(False)
1372                         section.toneburst = ConfigSelection(advanced_lnb_toneburst_choices, "none")
1373                         section.longitude = ConfigNothing()
1374                         if lnb > 64:
1375                                 tmp = ConfigSelection(advanced_lnb_allsat_diseqcmode_choices, "1_2")
1376                                 tmp.section = section
1377                                 configDiSEqCModeChanged(tmp)
1378                         else:
1379                                 tmp = ConfigSelection(advanced_lnb_diseqcmode_choices, "none")
1380                                 tmp.section = section
1381                                 tmp.addNotifier(configDiSEqCModeChanged)
1382                         section.diseqcMode = tmp
1383                         section.commitedDiseqcCommand = ConfigSelection(advanced_lnb_csw_choices)
1384                         section.fastDiseqc = ConfigYesNo(False)
1385                         section.sequenceRepeat = ConfigYesNo(False)
1386                         section.commandOrder1_0 = ConfigSelection(advanced_lnb_commandOrder1_0_choices, "ct")
1387                         section.commandOrder = ConfigSelection(advanced_lnb_commandOrder_choices, "ct")
1388                         section.uncommittedDiseqcCommand = ConfigSelection(advanced_lnb_ucsw_choices)
1389                         section.diseqcRepeats = ConfigSelection(advanced_lnb_diseqc_repeat_choices, "none")
1390                         section.prio = ConfigSelection(prio_list, "-1")
1391                         section.unicable = ConfigNothing()
1392                         tmp = ConfigSelection(lnb_choices, lnb_choices_default)
1393                         tmp.slot_id = x
1394                         tmp.lnb_id = lnb
1395                         tmp.addNotifier(configLOFChanged, initial_call = False)
1396                         section.lof = tmp
1397
1398         def configModeChanged(configMode):
1399                 slot_id = configMode.slot_id
1400                 nim = config.Nims[slot_id]
1401                 if configMode.value == "advanced" and isinstance(nim.advanced, ConfigNothing):
1402                         # advanced config:
1403                         nim.advanced = ConfigSubsection()
1404                         nim.advanced.sat = ConfigSubDict()
1405                         nim.advanced.sats = getConfigSatlist(192, advanced_satlist_choices)
1406                         nim.advanced.lnb = ConfigSubDict()
1407                         nim.advanced.lnb[0] = ConfigNothing()
1408                         for x in nimmgr.satList:
1409                                 tmp = ConfigSubsection()
1410                                 tmp.voltage = ConfigSelection(advanced_voltage_choices, "polarization")
1411                                 tmp.tonemode = ConfigSelection(advanced_tonemode_choices, "band")
1412                                 tmp.usals = ConfigYesNo(True)
1413                                 tmp.rotorposition = ConfigInteger(default=1, limits=(1, 255))
1414                                 lnb = ConfigSelection(advanced_lnb_choices, "0")
1415                                 lnb.slot_id = slot_id
1416                                 lnb.addNotifier(configLNBChanged, initial_call = False)
1417                                 tmp.lnb = lnb
1418                                 nim.advanced.sat[x[0]] = tmp
1419                         for x in range(3601, 3607):
1420                                 tmp = ConfigSubsection()
1421                                 tmp.voltage = ConfigSelection(advanced_voltage_choices, "polarization")
1422                                 tmp.tonemode = ConfigSelection(advanced_tonemode_choices, "band")
1423                                 tmp.usals = ConfigYesNo(default=True)
1424                                 tmp.userSatellitesList = ConfigText('[]')
1425                                 tmp.rotorposition = ConfigInteger(default=1, limits=(1, 255))
1426                                 lnbnum = 65+x-3601
1427                                 lnb = ConfigSelection([("0", _("not configured")), (str(lnbnum), "LNB %d"%(lnbnum))], "0")
1428                                 lnb.slot_id = slot_id
1429                                 lnb.addNotifier(configLNBChanged, initial_call = False)
1430                                 tmp.lnb = lnb
1431                                 nim.advanced.sat[x] = tmp
1432
1433         def toneAmplitudeChanged(configElement):
1434                 fe_id = configElement.fe_id
1435                 slot_id = configElement.slot_id
1436                 if nimmgr.nim_slots[slot_id].description == 'Alps BSBE2':
1437                         open("/proc/stb/frontend/%d/tone_amplitude" %(fe_id), "w").write(configElement.value)
1438
1439         def createSatConfig(nim, x, empty_slots):
1440                 try:
1441                         nim.toneAmplitude
1442                 except:
1443                         nim.toneAmplitude = ConfigSelection([("11", "340mV"), ("10", "360mV"), ("9", "600mV"), ("8", "700mV"), ("7", "800mV"), ("6", "900mV"), ("5", "1100mV")], "7")
1444                         nim.toneAmplitude.fe_id = x - empty_slots
1445                         nim.toneAmplitude.slot_id = x
1446                         nim.toneAmplitude.addNotifier(toneAmplitudeChanged)
1447                         nim.diseqc13V = ConfigYesNo(False)
1448                         nim.diseqcMode = ConfigSelection(diseqc_mode_choices, "diseqc_a_b")
1449                         nim.connectedTo = ConfigSelection([(str(id), nimmgr.getNimDescription(id)) for id in nimmgr.getNimListOfType("DVB-S") if id != x])
1450                         nim.simpleSingleSendDiSEqC = ConfigYesNo(False)
1451                         nim.simpleDiSEqCSetVoltageTone = ConfigYesNo(True)
1452                         nim.simpleDiSEqCOnlyOnSatChange = ConfigYesNo(False)
1453                         nim.simpleDiSEqCSetCircularLNB = ConfigYesNo(True)
1454                         nim.diseqcA = ConfigSatlist(list = diseqc_satlist_choices)
1455                         nim.diseqcB = ConfigSatlist(list = diseqc_satlist_choices)
1456                         nim.diseqcC = ConfigSatlist(list = diseqc_satlist_choices)
1457                         nim.diseqcD = ConfigSatlist(list = diseqc_satlist_choices)
1458                         nim.positionerMode = ConfigSelection(positioner_mode_choices, "usals")
1459                         nim.userSatellitesList = ConfigText('[]')
1460                         nim.pressOKtoList = ConfigNothing()
1461                         nim.longitude = ConfigFloat(default=[5,100], limits=[(0,359),(0,999)])
1462                         nim.longitudeOrientation = ConfigSelection(longitude_orientation_choices, "east")
1463                         nim.latitude = ConfigFloat(default=[50,767], limits=[(0,359),(0,999)])
1464                         nim.latitudeOrientation = ConfigSelection(latitude_orientation_choices, "north")
1465                         nim.tuningstepsize = ConfigFloat(default = [0,360], limits = [(0,9),(0,999)])
1466                         nim.rotorPositions = ConfigInteger(default = 99, limits = [1,999])
1467                         nim.turningspeedH = ConfigFloat(default = [2,3], limits = [(0,9),(0,9)])
1468                         nim.turningspeedV = ConfigFloat(default = [1,7], limits = [(0,9),(0,9)])
1469                         nim.powerMeasurement = ConfigYesNo(True)
1470                         nim.powerThreshold = ConfigInteger(default=hw.get_device_name() == "dm8000" and 15 or 50, limits=(0, 100))
1471                         nim.turningSpeed = ConfigSelection(turning_speed_choices, "fast")
1472                         btime = datetime(1970, 1, 1, 7, 0);
1473                         nim.fastTurningBegin = ConfigDateTime(default = mktime(btime.timetuple()), formatstring = _("%H:%M"), increment = 900)
1474                         etime = datetime(1970, 1, 1, 19, 0);
1475                         nim.fastTurningEnd = ConfigDateTime(default = mktime(etime.timetuple()), formatstring = _("%H:%M"), increment = 900)
1476
1477         def createCableConfig(nim, x):
1478                 try:
1479                         nim.cable
1480                 except:
1481                         list = [ ]
1482                         n = 0
1483                         for x in nimmgr.cablesList:
1484                                 list.append((str(n), x[0]))
1485                                 n += 1
1486                         nim.cable = ConfigSubsection()
1487                         nim.cable.scan_networkid = ConfigInteger(default = 0, limits = (0, 99999))
1488                         possible_scan_types = [("bands", _("Frequency bands")), ("steps", _("Frequency steps"))]
1489                         if n:
1490                                 possible_scan_types.append(("provider", _("Provider")))
1491                                 nim.cable.scan_provider = ConfigSelection(default = "0", choices = list)
1492                         nim.cable.scan_type = ConfigSelection(default = "bands", choices = possible_scan_types)
1493                         nim.cable.scan_band_EU_VHF_I = ConfigYesNo(default = True)
1494                         nim.cable.scan_band_EU_MID = ConfigYesNo(default = True)
1495                         nim.cable.scan_band_EU_VHF_III = ConfigYesNo(default = True)
1496                         nim.cable.scan_band_EU_UHF_IV = ConfigYesNo(default = True)
1497                         nim.cable.scan_band_EU_UHF_V = ConfigYesNo(default = True)
1498                         nim.cable.scan_band_EU_SUPER = ConfigYesNo(default = True)
1499                         nim.cable.scan_band_EU_HYPER = ConfigYesNo(default = True)
1500                         nim.cable.scan_band_US_LOW = ConfigYesNo(default = False)
1501                         nim.cable.scan_band_US_MID = ConfigYesNo(default = False)
1502                         nim.cable.scan_band_US_HIGH = ConfigYesNo(default = False)
1503                         nim.cable.scan_band_US_SUPER = ConfigYesNo(default = False)
1504                         nim.cable.scan_band_US_HYPER = ConfigYesNo(default = False)
1505                         nim.cable.scan_frequency_steps = ConfigInteger(default = 1000, limits = (1000, 10000))
1506                         nim.cable.scan_mod_qam16 = ConfigYesNo(default = False)
1507                         nim.cable.scan_mod_qam32 = ConfigYesNo(default = False)
1508                         nim.cable.scan_mod_qam64 = ConfigYesNo(default = True)
1509                         nim.cable.scan_mod_qam128 = ConfigYesNo(default = False)
1510                         nim.cable.scan_mod_qam256 = ConfigYesNo(default = True)
1511                         nim.cable.scan_sr_6900 = ConfigYesNo(default = True)
1512                         nim.cable.scan_sr_6875 = ConfigYesNo(default = True)
1513                         nim.cable.scan_sr_ext1 = ConfigInteger(default = 0, limits = (0, 7230))
1514                         nim.cable.scan_sr_ext2 = ConfigInteger(default = 0, limits = (0, 7230))
1515
1516         def createTerrestrialConfig(nim, x):
1517                 try:
1518                         nim.terrestrial
1519                 except:
1520                         list = []
1521                         n = 0
1522                         for x in nimmgr.terrestrialsList:
1523                                 list.append((str(n), x[0]))
1524                                 n += 1
1525                         nim.terrestrial = ConfigSelection(choices = list)
1526                         nim.terrestrial_5V = ConfigOnOff()
1527
1528         empty_slots = 0
1529         for slot in nimmgr.nim_slots:
1530                 x = slot.slot
1531                 nim = config.Nims[x]
1532
1533                 if slot.isCompatible("DVB-S"):
1534                         createSatConfig(nim, x, empty_slots)
1535                         config_mode_choices = [("nothing", _("nothing connected")),
1536                                 ("simple", _("simple")), ("advanced", _("advanced"))]
1537                         if len(nimmgr.getNimListOfType(slot.type, exception = x)) > 0:
1538                                 config_mode_choices.append(("equal", _("equal to")))
1539                                 config_mode_choices.append(("satposdepends", _("second cable of motorized LNB")))
1540                         if len(nimmgr.canConnectTo(x)) > 0:
1541                                 config_mode_choices.append(("loopthrough", _("loopthrough to")))
1542                         nim.advanced = ConfigNothing()
1543                         tmp = ConfigSelection(config_mode_choices, "simple")
1544                         tmp.slot_id = x
1545                         tmp.addNotifier(configModeChanged, initial_call = False)
1546                         nim.configMode = tmp
1547                 elif slot.isCompatible("DVB-C"):
1548                         nim.configMode = ConfigSelection(
1549                                 choices = {
1550                                         "enabled": _("enabled"),
1551                                         "nothing": _("nothing connected"),
1552                                         },
1553                                 default = "enabled")
1554                         createCableConfig(nim, x)
1555                 elif slot.isCompatible("DVB-T"):
1556                         nim.configMode = ConfigSelection(
1557                                 choices = {
1558                                         "enabled": _("enabled"),
1559                                         "nothing": _("nothing connected"),
1560                                         },
1561                                 default = "enabled")
1562                         createTerrestrialConfig(nim, x)
1563                 else:
1564                         empty_slots += 1
1565                         nim.configMode = ConfigSelection(choices = { "nothing": _("disabled") }, default="nothing");
1566                         if slot.type is not None:
1567                                 print "pls add support for this frontend type!", slot.type
1568
1569         nimmgr.sec = SecConfigure(nimmgr)
1570
1571         def tunerTypeChanged(nimmgr, configElement):
1572                 fe_id = configElement.fe_id
1573                 eDVBResourceManager.getInstance().setFrontendType(nimmgr.nim_slots[fe_id].frontend_id, nimmgr.nim_slots[fe_id].getType())
1574                 import os
1575                 if os.path.exists("/proc/stb/frontend/%d/mode" % fe_id):
1576                         cur_type = int(open("/proc/stb/frontend/%d/mode" % (fe_id), "r").read())
1577                         if cur_type != int(configElement.value):
1578                                 print "tunerTypeChanged feid %d from %d to mode %d" % (fe_id, cur_type, int(configElement.value))
1579
1580                                 try:
1581                                         oldvalue = open("/sys/module/dvb_core/parameters/dvb_shutdown_timeout", "r").readline()
1582                                         open("/sys/module/dvb_core/parameters/dvb_shutdown_timeout", "w").write("0")
1583                                 except:
1584                                         print "[info] no /sys/module/dvb_core/parameters/dvb_shutdown_timeout available"
1585
1586                                 frontend = eDVBResourceManager.getInstance().allocateRawChannel(fe_id).getFrontend()
1587                                 frontend.closeFrontend()
1588                                 open("/proc/stb/frontend/%d/mode" % (fe_id), "w").write(configElement.value)
1589                                 frontend.reopenFrontend()
1590                                 try:
1591                                         open("/sys/module/dvb_core/parameters/dvb_shutdown_timeout", "w").write(oldvalue)
1592                                 except:
1593                                         print "[info] no /sys/module/dvb_core/parameters/dvb_shutdown_timeout available"
1594                                 nimmgr.enumerateNIMs()
1595                         else:
1596                                 print "tuner type is already already %d" %cur_type
1597
1598         empty_slots = 0
1599         for slot in nimmgr.nim_slots:
1600                 x = slot.slot
1601                 nim = config.Nims[x]
1602                 addMultiType = False
1603                 try:
1604                         nim.multiType
1605                 except:
1606                         addMultiType = True
1607                 if slot.isMultiType() and addMultiType:
1608                         typeList = []
1609                         for id in slot.getMultiTypeList().keys():
1610                                 type = slot.getMultiTypeList()[id]
1611                                 typeList.append((id, type))
1612                         nim.multiType = ConfigSelection(typeList, "0")
1613
1614                         nim.multiType.fe_id = x - empty_slots
1615                         nim.multiType.addNotifier(boundFunction(tunerTypeChanged, nimmgr))
1616
1617         empty_slots = 0
1618         for slot in nimmgr.nim_slots:
1619                 x = slot.slot
1620                 nim = config.Nims[x]
1621                 empty = True
1622
1623                 if slot.canBeCompatible("DVB-S"):
1624                         createSatConfig(nim, x, empty_slots)
1625                         empty = False
1626                 if slot.canBeCompatible("DVB-C"):
1627                         createCableConfig(nim, x)
1628                         empty = False
1629                 if slot.canBeCompatible("DVB-T"):
1630                         createTerrestrialConfig(nim, x)
1631                         empty = False
1632                 if empty:
1633                         empty_slots += 1
1634
1635 nimmanager = NimManager()