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