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