fix syntax error,
[vuplus_dvbapp] / lib / python / Plugins / SystemPlugins / PositionerSetup / plugin.py
1 from enigma import eTimer, eDVBSatelliteEquipmentControl, eDVBResourceManager, \
2         eDVBDiseqcCommand, eDVBFrontendParametersSatellite, eDVBFrontendParameters
3
4 from Screens.Screen import Screen
5 from Screens.ScanSetup import ScanSetup
6 from Screens.MessageBox import MessageBox
7 from Plugins.Plugin import PluginDescriptor
8
9 from Components.Label import Label
10 from Components.ConfigList import ConfigList
11 from Components.TunerInfo import TunerInfo
12 from Components.ActionMap import ActionMap
13 from Components.NimManager import nimmanager
14 from Components.MenuList import MenuList
15 from Components.config import ConfigSatlist, ConfigNothing, ConfigSelection, ConfigSubsection, KEY_LEFT, KEY_RIGHT, getConfigListEntry
16
17 from time import sleep
18
19 class PositionerSetup(Screen):
20         skin = """
21                 <screen position="100,100" size="560,400" title="Positioner setup..." >
22                         <widget name="list" position="100,0" size="350,155" />
23
24                         <widget name="red" position="0,155" size="140,80" backgroundColor="red" halign="center" valign="center" font="Regular;21" />
25                         <widget name="green" position="140,155" size="140,80" backgroundColor="green" halign="center" valign="center" font="Regular;21" />
26                         <widget name="yellow" position="280,155" size="140,80" backgroundColor="yellow" halign="center" valign="center" font="Regular;21" />
27                         <widget name="blue" position="420,155" size="140,80" backgroundColor="blue" halign="center" valign="center" font="Regular;21" />
28                         
29                         <widget name="snr" text="SNR:" position="0,245" size="60,22" font="Regular;21" />
30                         <widget name="agc" text="AGC:" position="0,270" size="60,22" font="Regular;21" />
31                         <widget name="ber" text="BER:" position="0,295" size="60,22" font="Regular;21" />
32                         <widget name="lock" text="Lock:" position="0,320" size="60,22" font="Regular;21" />
33                         <widget name="snr_percentage" position="220,245" size="60,22" font="Regular;21" />
34                         <widget name="agc_percentage" position="220,270" size="60,22" font="Regular;21" />
35                         <widget name="ber_value" position="220,295" size="60,22" font="Regular;21" />
36                         <widget name="lock_state" position="60,320" size="150,22" font="Regular;21" />
37                         <widget name="snr_bar" position="60,245" size="150,22" />
38                         <widget name="agc_bar" position="60,270" size="150,22" />
39                         <widget name="ber_bar" position="60,295" size="150,22" />
40
41                         <widget name="frequency" text="Frequency:" position="300,245" size="120,22" font="Regular;21" />
42                         <widget name="symbolrate" text="Symbolrate:" position="300,270" size="120,22" font="Regular;21" />
43                         <widget name="fec" text="FEC:" position="300,295" size="120,22" font="Regular;21" />
44                         <widget name="frequency_value" position="420,245" size="120,22" font="Regular;21" />
45                         <widget name="symbolrate_value" position="420,270" size="120,22" font="Regular;21" />
46                         <widget name="fec_value" position="420,295" size="120,22" font="Regular;21" />
47                 </screen>"""
48         def __init__(self, session, feid):
49                 self.skin = PositionerSetup.skin
50                 Screen.__init__(self, session)
51                 self.feid = feid
52                 self.oldref = None
53                 
54                 if not self.openFrontend():
55                         self.oldref = session.nav.getCurrentlyPlayingServiceReference()
56                         session.nav.stopService() # try to disable foreground service
57                         if not self.openFrontend():
58                                 if session.pipshown: # try to disable pip
59                                         session.pipshown = False
60                                         del session.pip
61                                         if not self.openFrontend():
62                                                 self.frontend = None # in normal case this should not happen
63                                                 self.getFrontend = None
64                 
65                 self.diseqc = Diseqc(self.frontend)
66                 self.tuner = Tuner(self.frontend)
67                 self.tuner.tune((0,0,0,0,0,0))
68                 
69                 self.createConfig()
70                 
71                 self.isMoving = False
72                 self.stopOnLock = False
73                 
74                 self.red = Label("")
75                 self["red"] = self.red
76                 self.green = Label("")
77                 self["green"] = self.green
78                 self.yellow = Label("")
79                 self["yellow"] = self.yellow
80                 self.blue = Label("")
81                 self["blue"] = self.blue
82                 
83                 self.list = []
84                 self["list"] = ConfigList(self.list)
85                 self.createSetup()
86                 
87                 self["snr"] = Label()
88                 self["agc"] = Label()
89                 self["ber"] = Label()
90                 self["lock"] = Label()
91                 self["snr_percentage"] = TunerInfo(TunerInfo.SNR_PERCENTAGE, frontendfkt = self.getFrontend)
92                 self["agc_percentage"] = TunerInfo(TunerInfo.AGC_PERCENTAGE, frontendfkt = self.getFrontend)
93                 self["ber_value"] = TunerInfo(TunerInfo.BER_VALUE, frontendfkt = self.getFrontend)
94                 self["snr_bar"] = TunerInfo(TunerInfo.SNR_BAR, frontendfkt = self.getFrontend)
95                 self["agc_bar"] = TunerInfo(TunerInfo.AGC_BAR, frontendfkt = self.getFrontend)
96                 self["ber_bar"] = TunerInfo(TunerInfo.BER_BAR, frontendfkt = self.getFrontend)
97                 self["lock_state"] = TunerInfo(TunerInfo.LOCK_STATE, frontendfkt = self.getFrontend)
98
99                 self["frequency"] = Label()
100                 self["symbolrate"] = Label()
101                 self["fec"] = Label()
102
103                 self["frequency_value"] = Label("")
104                 self["symbolrate_value"] = Label("")
105                 self["fec_value"] = Label("")
106                 
107                 self["actions"] = ActionMap(["DirectionActions", "OkCancelActions", "ColorActions"],
108                 {
109                         "ok": self.go,
110                         "cancel": self.keyCancel,
111                         "up": self.up,
112                         "down": self.down,
113                         "left": self.left,
114                         "right": self.right,
115                         "red": self.redKey,
116                         "green": self.greenKey,
117                         "yellow": self.yellowKey,
118                         "blue": self.blueKey,
119                 }, -1)
120                 
121                 self.updateColors("tune")
122                 
123                 self.statusTimer = eTimer()
124                 self.statusTimer.timeout.get().append(self.updateStatus)
125                 self.statusTimer.start(50, False)
126
127         def restartPrevService(self, yesno):
128                 if yesno:
129                         if self.frontend:
130                                 self.frontend = None
131                                 del self.raw_channel
132                         self.session.nav.playService(self.oldref)
133                 self.close(None)
134         
135         def keyCancel(self):
136                 if self.oldref:
137                         self.session.openWithCallback(self.restartPrevService, MessageBox, _("Zap back to service before positioner setup?"), MessageBox.TYPE_YESNO)
138                 else:
139                         self.restartPrevService(False)
140
141         def getFrontend(self):
142                 return self.frontend
143
144         def openFrontend(self):
145                 res_mgr = eDVBResourceManager.getInstance()
146                 if res_mgr:
147                         self.raw_channel = res_mgr.allocateRawChannel(self.feid)
148                         if self.raw_channel:
149                                 self.frontend = self.raw_channel.getFrontend()
150                                 if self.frontend:
151                                         return True
152                                 else:
153                                         print "getFrontend failed"
154                         else:
155                                 print "getRawChannel failed"
156                 else:
157                         print "getResourceManager instance failed"
158                 return False
159
160         def createConfig(self):
161                 self.positioner_tune = ConfigNothing()
162                 self.positioner_move = ConfigNothing()
163                 self.positioner_finemove = ConfigNothing()
164                 self.positioner_limits = ConfigNothing()
165                 self.positioner_goto0 = ConfigNothing()
166                 storepos = []
167                 for x in range(1,255):
168                         storepos.append(str(x))
169                 self.positioner_storage = ConfigSelection(choices = storepos)
170
171         def createSetup(self):
172                 self.list.append((_("Tune"), self.positioner_tune, "tune"))
173                 self.list.append((_("Positioner movement"), self.positioner_move, "move"))
174                 self.list.append((_("Positioner fine movement"), self.positioner_finemove, "finemove"))
175                 self.list.append((_("Set limits"), self.positioner_limits, "limits"))
176                 self.list.append((_("Positioner storage"), self.positioner_storage, "storage"))
177                 self.list.append((_("Goto 0"), self.positioner_goto0, "goto0"))
178                 self["list"].l.setList(self.list)
179
180         def go(self):
181                 pass
182
183         def getCurrentConfigPath(self):
184                 return self["list"].getCurrent()[2]
185
186         def up(self):
187                 if not self.isMoving:
188                         self["list"].instance.moveSelection(self["list"].instance.moveUp)
189                         self.updateColors(self.getCurrentConfigPath())
190
191         def down(self):
192                 if not self.isMoving:
193                         self["list"].instance.moveSelection(self["list"].instance.moveDown)
194                         self.updateColors(self.getCurrentConfigPath())
195
196         def left(self):
197                 self["list"].handleKey(KEY_LEFT)
198
199         def right(self):
200                 self["list"].handleKey(KEY_RIGHT)
201
202         def updateColors(self, entry):
203                 if entry == "tune":
204                         self.red.setText(_("Tune"))
205                         self.green.setText("")
206                         self.yellow.setText("")
207                         self.blue.setText("")
208                 elif entry == "move":
209                         if self.isMoving:
210                                 self.red.setText(_("Stop"))
211                                 self.green.setText(_("Stop"))
212                                 self.yellow.setText(_("Stop"))
213                                 self.blue.setText(_("Stop"))
214                         else:
215                                 self.red.setText(_("Move west"))
216                                 self.green.setText(_("Search west"))
217                                 self.yellow.setText(_("Search east"))
218                                 self.blue.setText(_("Move east"))
219                 elif entry == "finemove":
220                         self.red.setText("")
221                         self.green.setText(_("Step west"))
222                         self.yellow.setText(_("Step east"))
223                         self.blue.setText("")
224                 elif entry == "limits":
225                         self.red.setText(_("Limits off"))
226                         self.green.setText(_("Limit west"))
227                         self.yellow.setText(_("Limit east"))
228                         self.blue.setText(_("Limits on"))
229                 elif entry == "storage":
230                         self.red.setText("")
231                         self.green.setText(_("Store position"))
232                         self.yellow.setText(_("Goto position"))
233                         self.blue.setText("")
234                 elif entry == "goto0":
235                         self.red.setText(_("Goto 0"))
236                         self.green.setText("")
237                         self.yellow.setText("")
238                         self.blue.setText("")
239                 else:
240                         self.red.setText("")
241                         self.green.setText("")
242                         self.yellow.setText("")
243                         self.blue.setText("")
244
245         def redKey(self):
246                 entry = self.getCurrentConfigPath()
247                 if entry == "move":
248                         if self.isMoving:
249                                 self.diseqccommand("stop")
250                                 self.isMoving = False
251                                 self.stopOnLock = False
252                         else:
253                                 self.diseqccommand("moveWest", 0)
254                                 self.isMoving = True
255                         self.updateColors("move")
256                 elif entry == "limits":
257                         self.diseqccommand("limitOff")
258                 elif entry == "tune":
259                         self.session.openWithCallback(self.tune, TunerScreen, self.feid)
260                 elif entry == "goto0":
261                         print "move to position 0"
262                         self.diseqccommand("moveTo", 0)
263
264         def greenKey(self):
265                 entry = self.getCurrentConfigPath()
266                 if entry == "move":
267                         if self.isMoving:
268                                 self.diseqccommand("stop")
269                                 self.isMoving = False
270                                 self.stopOnLock = False
271                         else:
272                                 self.isMoving = True
273                                 self.stopOnLock = True
274                                 self.diseqccommand("moveWest", 0)
275                         self.updateColors("move")
276                 elif entry == "finemove":
277                         print "stepping west"
278                         self.diseqccommand("moveWest", 0xFF) # one step
279                 elif entry == "storage":
280                         print "store at position", int(self.positioner_storage.value)
281                         self.diseqccommand("store", int(self.positioner_storage.value))
282                 elif entry == "limits":
283                         self.diseqccommand("limitWest")
284
285         def yellowKey(self):
286                 entry = self.getCurrentConfigPath()
287                 if entry == "move":
288                         if self.isMoving:
289                                 self.diseqccommand("stop")
290                                 self.isMoving = False
291                                 self.stopOnLock = False
292                         else:
293                                 self.isMoving = True
294                                 self.stopOnLock = True
295                                 self.diseqccommand("moveEast", 0)
296                         self.updateColors("move")
297                 elif entry == "finemove":
298                         print "stepping east"
299                         self.diseqccommand("moveEast", 0xFF) # one step
300                 elif entry == "storage":
301                         print "move to position", int(self.positioner_storage.value)
302                         self.diseqccommand("moveTo", int(self.positioner_storage.value))
303                 elif entry == "limits":
304                         self.diseqccommand("limitEast")
305
306         def blueKey(self):
307                 entry = self.getCurrentConfigPath()
308                 if entry == "move":
309                         if self.isMoving:
310                                 self.diseqccommand("stop")
311                                 self.isMoving = False
312                                 self.stopOnLock = False
313                         else:
314                                 self.diseqccommand("moveEast", 0)
315                                 self.isMoving = True
316                         self.updateColors("move")
317                         print "moving east"
318                 elif entry == "limits":
319                         self.diseqccommand("limitOn")
320
321         def diseqccommand(self, cmd, param = 0):
322                 self.diseqc.command(cmd, param)
323                 self.tuner.retune()
324
325         def updateStatus(self):
326                 self["snr_percentage"].update()
327                 self["agc_percentage"].update()
328                 self["ber_value"].update()
329                 self["snr_bar"].update()
330                 self["agc_bar"].update()
331                 self["ber_bar"].update()
332                 self["lock_state"].update()
333                 transponderdata = self.tuner.getTransponderData()
334                 self["frequency_value"].setText(str(transponderdata["frequency"]))
335                 self["symbolrate_value"].setText(str(transponderdata["symbol_rate"]))
336                 self["fec_value"].setText(str(transponderdata["fec_inner"]))
337                 if transponderdata["tuner_locked"] == 1 and self.isMoving and self.stopOnLock:
338                         self.diseqccommand("stop")
339                         self.isMoving = False
340                         self.stopOnLock = False
341                         self.updateColors(self.getCurrentConfigPath())
342
343         def tune(self, transponder):
344                 if transponder is not None:
345                         self.tuner.tune(transponder)
346
347 class Diseqc:
348         def __init__(self, frontend):
349                 self.frontend = frontend
350
351         def command(self, what, param = 0):
352                 if self.frontend:
353                         cmd = eDVBDiseqcCommand()
354                         if what == "moveWest":
355                                 string = 'e03169' + ("%02x" % param)
356                         elif what == "moveEast":
357                                 string = 'e03168' + ("%02x" % param)
358                         elif what == "moveTo":
359                                 string = 'e0316b' + ("%02x" % param)
360                         elif what == "store":
361                                 string = 'e0316a' + ("%02x" % param)
362                         elif what == "limitOn":
363                                 string = 'e0316a00'
364                         elif what == "limitOff":
365                                 string = 'e03163'
366                         elif what == "limitEast":
367                                 string = 'e03166'
368                         elif what == "limitWest":
369                                 string = 'e03167'
370                         else:
371                                 string = 'e03160' #positioner stop
372                         
373                         print "diseqc command:",
374                         print string
375                         cmd.setCommandString(string)
376                         self.frontend.sendDiseqc(cmd)
377                         if string == 'e03160': #positioner stop
378                                 sleep(0.05)
379                                 self.frontend.sendDiseqc(cmd) # send 2nd time
380
381 class Tuner:
382         def __init__(self, frontend):
383                 self.frontend = frontend
384
385         def tune(self, transponder):
386                 print "tuning to transponder with data", transponder
387                 parm = eDVBFrontendParametersSatellite()
388                 parm.frequency = transponder[0] * 1000
389                 parm.symbol_rate = transponder[1] * 1000
390                 parm.polarisation = transponder[2]
391                 parm.fec = transponder[3]
392                 parm.inversion = transponder[4]
393                 parm.orbital_position = transponder[5]
394                 parm.system = 0  # FIXMEE !! HARDCODED DVB-S (add support for DVB-S2)
395                 parm.modulation = 1 # FIXMEE !! HARDCODED QPSK
396                 feparm = eDVBFrontendParameters()
397                 feparm.setDVBS(parm, True)
398                 self.lastparm = feparm
399                 if self.frontend:
400                         self.frontend.tune(feparm)
401
402         def retune(self):
403                 if self.frontend:
404                         self.frontend.tune(self.lastparm)
405
406         def getTransponderData(self):
407                 if self.frontend:
408                         return self.frontend.readTransponderData(True)
409                 return None
410
411 tuning = None
412
413 class TunerScreen(ScanSetup):
414         skin = """
415                 <screen position="90,100" size="520,400" title="Tune">
416                         <widget name="config" position="20,10" size="460,350" scrollbarMode="showOnDemand" />
417                         <widget name="introduction" position="20,360" size="350,30" font="Regular;23" />
418                 </screen>"""
419
420         def __init__(self, session, feid):
421                 self.feid = feid
422                 ScanSetup.__init__(self, session)
423                 self["introduction"].setText("")
424
425         def createSetup(self):
426                 self.typeOfTuningEntry = None
427                 self.satEntry = None
428                 self.list = []
429                 self.typeOfTuningEntry = getConfigListEntry(_('Tune'), tuning.type)
430                 self.list.append(self.typeOfTuningEntry)
431                 self.satEntry = getConfigListEntry(_('Satellite'), tuning.sat)
432                 self.list.append(self.satEntry)
433                 if tuning.type.value == "manual_transponder":
434                         self.list.append(getConfigListEntry(_('Frequency'), self.scan_sat.frequency))
435                         self.list.append(getConfigListEntry(_('Inversion'), self.scan_sat.inversion))
436                         self.list.append(getConfigListEntry(_('Symbol Rate'), self.scan_sat.symbolrate))
437                         self.list.append(getConfigListEntry(_("Polarity"), self.scan_sat.polarization))
438                         self.list.append(getConfigListEntry(_("FEC"), self.scan_sat.fec))
439                 elif tuning.type.value == "predefined_transponder":
440                         self.list.append(getConfigListEntry(_("Transponder"), tuning.transponder))
441                 self["config"].list = self.list
442                 self["config"].l.setList(self.list)
443
444         def newConfig(self):
445                 if self["config"].getCurrent() == self.typeOfTuningEntry:
446                         self.createSetup()
447                 elif self["config"].getCurrent() == self.satEntry:
448                         self.createSetup()
449
450         def createConfig(self, foo):
451                 global tuning
452                 if not tuning:
453                         tuning = ConfigSubsection()
454                         tuning.type = ConfigSelection(
455                                 default = "manual_transponder",
456                                 choices = { "manual_transponder" : _("Manual transponder"),
457                                                         "predefined_transponder" : _("Predefined transponder") } )
458                         tuning.sat = ConfigSatlist(list=nimmanager.getRotorSatListForNim(self.feid))
459                         tuning.sat.addNotifier(self.tuningSatChanged)
460                         self.updateTransponders()
461                         TunerScreenConfigCreated = True
462                 ScanSetup.createConfig(self, None)
463
464         def tuningSatChanged(self, *parm):
465                 self.updateTransponders()
466
467         def updateTransponders(self):
468                 if len(tuning.sat.choices):
469                         transponderlist = nimmanager.getTransponders(int(tuning.sat.value))
470                         tps = []
471                         cnt=0
472                         for x in transponderlist:
473                                 if x[3] == 0:
474                                         pol = "H"
475                                 elif x[3] == 1:
476                                         pol = "V"
477                                 elif x[3] == 2:
478                                         pol = "CL"
479                                 elif x[3] == 3:
480                                         pol = "CR"
481                                 if x[4] == 0:
482                                         fec = "FEC_AUTO"
483                                 elif x[4] == 1:
484                                         fec = "FEC_1_2"
485                                 elif x[4] == 2:
486                                         fec = "FEC_2_3"
487                                 elif x[4] == 3:
488                                         fec = "FEC_3_4"
489                                 elif x[4] == 4:
490                                         fec = "FEC_5_6"
491                                 elif x[4] == 5:
492                                         fec = "FEC_7_8"
493                                 elif x[4] == 5:
494                                         fec = "FEC_8_9"
495                                 elif x[4] == 6:
496                                         fec = "FEC_None"
497                                 tps.append(str(x[1]) + "," + str(x[2]) + "," + pol + "," + fec)
498                         tuning.transponder = ConfigSelection(choices=tps)
499
500         def keyGo(self):
501                 returnvalue = (0, 0, 0, 0, 0, 0)
502                 satpos = int(tuning.sat.value)
503                 if tuning.type.value == "manual_transponder":
504                         returnvalue = (
505                                 self.scan_sat.frequency.value,
506                                 self.scan_sat.symbolrate.value,
507                                 self.scan_sat.polarization.index,
508                                 self.scan_sat.fec.index,
509                                 self.scan_sat.inversion.index,
510                                 satpos)
511                 elif tuning.type.value == "predefined_transponder":
512                         transponder = nimmanager.getTransponders(satpos)[tuning.transponder.index]
513                         returnvalue = (int(transponder[1] / 1000), int(transponder[2] / 1000), transponder[3], transponder[4], 2, satpos)
514                 self.close(returnvalue)
515
516         def keyCancel(self):
517                 self.close(None)
518
519 class NimSelection(Screen):
520         skin = """
521                 <screen position="140,165" size="400,100" title="select Slot">
522                         <widget name="nimlist" position="20,10" size="360,75" />
523                 </screen>"""
524
525         def __init__(self, session):
526                 Screen.__init__(self, session)
527
528                 nimlist = nimmanager.getNimListOfType(nimmanager.nimType["DVB-S"])
529                 nimMenuList = []
530                 for x in nimlist:
531                         nimMenuList.append((_("NIM ") + (["A", "B", "C", "D"][x]) + ": " + nimmanager.getNimName(x) + " (" + nimmanager.getNimTypeName(x) + ")", x))
532                 
533                 self["nimlist"] = MenuList(nimMenuList)
534
535                 self["actions"] = ActionMap(["OkCancelActions"],
536                 {
537                         "ok": self.okbuttonClick ,
538                         "cancel": self.close
539                 }, -1)
540
541         def okbuttonClick(self):
542                 selection = self["nimlist"].getCurrent()
543                 self.session.open(PositionerSetup, selection[1])
544
545 def PositionerMain(session, **kwargs):
546         nimList = nimmanager.getNimListOfType(nimmanager.nimType["DVB-S"])
547         if len(nimList) == 0:
548                 session.open(MessageBox, _("No positioner capable frontend found."), MessageBox.TYPE_ERROR)
549         else:
550                 if session.nav.RecordTimer.isRecording():
551                         session.open(MessageBox, _("A recording is currently running. Please stop the recording before trying to configure the positioner."), MessageBox.TYPE_ERROR)
552                 else:
553                         usableNims = []
554                         for x in nimList:
555                                 configured_rotor_sats = nimmanager.getRotorSatListForNim(x)
556                                 if len(configured_rotor_sats) != 0:
557                                         usableNims.append(x)
558                         if len(usableNims) == 1:
559                                 session.open(PositionerSetup, usableNims[0])
560                         elif len(usableNims) > 1:
561                                 session.open(NimSelection)
562                         else:
563                                 session.open(MessageBox, _("No tuner is configured for use with a diseqc positioner!"), MessageBox.TYPE_ERROR)
564
565 def PositionerSetupStart(menuid):
566         if menuid == "scan":
567                 return [(_("Positioner setup"), PositionerMain)]
568         else:
569                 return []
570
571 def Plugins(**kwargs):
572         return PluginDescriptor(name=_("Positioner setup"), description="Setup your positioner", where = PluginDescriptor.WHERE_SETUP, fnc=PositionerSetupStart)