class PositionerSetup(Screen): skin = """ <screen position="100,100" size="560,400" title="Positioner setup..." > <widget name="list" position="100,0" size="350,155" /> <widget name="red" position="0,155" size="140,80" backgroundColor="red" halign="center" valign="center" font="Regular;21" /> <widget name="green" position="140,155" size="140,80" backgroundColor="green" halign="center" valign="center" font="Regular;21" /> <widget name="yellow" position="280,155" size="140,80" backgroundColor="yellow" halign="center" valign="center" font="Regular;21" /> <widget name="blue" position="420,155" size="140,80" backgroundColor="blue" halign="center" valign="center" font="Regular;21" /> <widget name="snr_db" position="60,245" size="150,22" halign="center" valign="center" font="Regular;21" /> <eLabel text="SNR:" position="0,270" size="60,22" font="Regular;21" /> <eLabel text="BER:" position="0,295" size="60,22" font="Regular;21" /> <eLabel text="Lock:" position="0,320" size="60,22" font="Regular;21" /> <widget name="snr_percentage" position="220,270" size="60,22" font="Regular;21" /> <widget name="ber_value" position="220,295" size="60,22" font="Regular;21" /> <widget name="lock_state" position="60,320" size="150,22" font="Regular;21" /> <widget name="snr_bar" position="60,270" size="150,22" /> <widget name="ber_bar" position="60,295" size="150,22" /> <eLabel text="Frequency:" position="300,245" size="120,22" font="Regular;21" /> <eLabel text="Symbolrate:" position="300,270" size="120,22" font="Regular;21" /> <eLabel text="FEC:" position="300,295" size="120,22" font="Regular;21" /> <widget name="frequency_value" position="420,245" size="120,22" font="Regular;21" /> <widget name="symbolrate_value" position="420,270" size="120,22" font="Regular;21" /> <widget name="fec_value" position="420,295" size="120,22" font="Regular;21" /> </screen>""" def __init__(self, session, feid): self.skin = PositionerSetup.skin Screen.__init__(self, session) self.feid = feid self.oldref = None cur = {} if not self.openFrontend(): self.oldref = session.nav.getCurrentlyPlayingServiceReference() service = session.nav.getCurrentService() feInfo = service and service.frontendInfo() if feInfo: cur = feInfo.getTransponderData(True) del feInfo del service session.nav.stopService() # try to disable foreground service if not self.openFrontend(): if session.pipshown: # try to disable pip service = self.session.pip.pipservice feInfo = service and service.frontendInfo() if feInfo: cur = feInfo.getTransponderData() del feInfo del service session.pipshown = False del session.pip if not self.openFrontend(): self.frontend = None # in normal case this should not happen self.frontendStatus = {} self.diseqc = Diseqc(self.frontend) self.tuner = Tuner(self.frontend) tp = (cur.get("frequency", 0) / 1000, cur.get("symbol_rate", 0) / 1000, cur.get("polarization", eDVBFrontendParametersSatellite.Polarisation_Horizontal), cur.get("fec_inner", eDVBFrontendParametersSatellite.FEC_Auto), cur.get("inversion", eDVBFrontendParametersSatellite.Inversion_Unknown), cur.get("orbital_position", 0), cur.get("system", eDVBFrontendParametersSatellite.System_DVB_S), cur.get("modulation", eDVBFrontendParametersSatellite.Modulation_QPSK), cur.get("rolloff", eDVBFrontendParametersSatellite.RollOff_alpha_0_35), cur.get("pilot", eDVBFrontendParametersSatellite.Pilot_Unknown)) self.tuner.tune(tp) self.createConfig() self.isMoving = False self.stopOnLock = False self.red = Label("") self["red"] = self.red self.green = Label("") self["green"] = self.green self.yellow = Label("") self["yellow"] = self.yellow self.blue = Label("") self["blue"] = self.blue self.list = [] self["list"] = ConfigList(self.list) self.createSetup() self["snr_db"] = TunerInfo(TunerInfo.SNR_DB, statusDict=self.frontendStatus) self["snr_percentage"] = TunerInfo(TunerInfo.SNR_PERCENTAGE, statusDict=self.frontendStatus) self["ber_value"] = TunerInfo(TunerInfo.BER_VALUE, statusDict=self.frontendStatus) self["snr_bar"] = TunerInfo(TunerInfo.SNR_BAR, statusDict=self.frontendStatus) self["ber_bar"] = TunerInfo(TunerInfo.BER_BAR, statusDict=self.frontendStatus) self["lock_state"] = TunerInfo(TunerInfo.LOCK_STATE, statusDict=self.frontendStatus) self["frequency_value"] = Label("") self["symbolrate_value"] = Label("") self["fec_value"] = Label("") self["actions"] = ActionMap( ["DirectionActions", "OkCancelActions", "ColorActions"], { "ok": self.go, "cancel": self.keyCancel, "up": self.up, "down": self.down, "left": self.left, "right": self.right, "red": self.redKey, "green": self.greenKey, "yellow": self.yellowKey, "blue": self.blueKey, }, -1) self.updateColors("tune") self.statusTimer = eTimer() self.statusTimer.callback.append(self.updateStatus) self.statusTimer.start(50, True) self.onClose.append(self.__onClose) def __onClose(self): self.session.nav.playService(self.oldref) def restartPrevService(self, yesno): if yesno: if self.frontend: self.frontend = None del self.raw_channel else: self.oldref = None self.close(None) def keyCancel(self): if self.oldref: self.session.openWithCallback( self.restartPrevService, MessageBox, _("Zap back to service before positioner setup?"), MessageBox.TYPE_YESNO) else: self.restartPrevService(False) def openFrontend(self): res_mgr = eDVBResourceManager.getInstance() if res_mgr: self.raw_channel = res_mgr.allocateRawChannel(self.feid) if self.raw_channel: self.frontend = self.raw_channel.getFrontend() if self.frontend: return True else: print "getFrontend failed" else: print "getRawChannel failed" else: print "getResourceManager instance failed" return False def createConfig(self): self.positioner_tune = ConfigNothing() self.positioner_move = ConfigNothing() self.positioner_finemove = ConfigNothing() self.positioner_limits = ConfigNothing() self.positioner_goto0 = ConfigNothing() storepos = [] for x in range(1, 255): storepos.append(str(x)) self.positioner_storage = ConfigSelection(choices=storepos) def createSetup(self): self.list.append((_("Tune"), self.positioner_tune, "tune")) self.list.append( (_("Positioner movement"), self.positioner_move, "move")) self.list.append((_("Positioner fine movement"), self.positioner_finemove, "finemove")) self.list.append((_("Set limits"), self.positioner_limits, "limits")) self.list.append( (_("Positioner storage"), self.positioner_storage, "storage")) self.list.append((_("Goto 0"), self.positioner_goto0, "goto0")) self["list"].l.setList(self.list) def go(self): pass def getCurrentConfigPath(self): return self["list"].getCurrent()[2] def up(self): if not self.isMoving: self["list"].instance.moveSelection(self["list"].instance.moveUp) self.updateColors(self.getCurrentConfigPath()) def down(self): if not self.isMoving: self["list"].instance.moveSelection(self["list"].instance.moveDown) self.updateColors(self.getCurrentConfigPath()) def left(self): self["list"].handleKey(KEY_LEFT) def right(self): self["list"].handleKey(KEY_RIGHT) def updateColors(self, entry): if entry == "tune": self.red.setText(_("Tune")) self.green.setText("") self.yellow.setText("") self.blue.setText("") elif entry == "move": if self.isMoving: self.red.setText(_("Stop")) self.green.setText(_("Stop")) self.yellow.setText(_("Stop")) self.blue.setText(_("Stop")) else: self.red.setText(_("Move west")) self.green.setText(_("Search west")) self.yellow.setText(_("Search east")) self.blue.setText(_("Move east")) elif entry == "finemove": self.red.setText("") self.green.setText(_("Step west")) self.yellow.setText(_("Step east")) self.blue.setText("") elif entry == "limits": self.red.setText(_("Limits off")) self.green.setText(_("Limit west")) self.yellow.setText(_("Limit east")) self.blue.setText(_("Limits on")) elif entry == "storage": self.red.setText("") self.green.setText(_("Store position")) self.yellow.setText(_("Goto position")) self.blue.setText("") elif entry == "goto0": self.red.setText(_("Goto 0")) self.green.setText("") self.yellow.setText("") self.blue.setText("") else: self.red.setText("") self.green.setText("") self.yellow.setText("") self.blue.setText("") def redKey(self): entry = self.getCurrentConfigPath() if entry == "move": if self.isMoving: self.diseqccommand("stop") self.isMoving = False self.stopOnLock = False else: self.diseqccommand("moveWest", 0) self.isMoving = True self.updateColors("move") elif entry == "limits": self.diseqccommand("limitOff") elif entry == "tune": fe_data = {} self.frontend.getFrontendData(fe_data) self.frontend.getTransponderData(fe_data, True) feparm = self.tuner.lastparm.getDVBS() fe_data["orbital_position"] = feparm.orbital_position self.session.openWithCallback(self.tune, TunerScreen, self.feid, fe_data) elif entry == "goto0": print "move to position 0" self.diseqccommand("moveTo", 0) def greenKey(self): entry = self.getCurrentConfigPath() if entry == "move": if self.isMoving: self.diseqccommand("stop") self.isMoving = False self.stopOnLock = False else: self.isMoving = True self.stopOnLock = True self.diseqccommand("moveWest", 0) self.updateColors("move") elif entry == "finemove": print "stepping west" self.diseqccommand("moveWest", 0xFF) # one step elif entry == "storage": print "store at position", int(self.positioner_storage.value) self.diseqccommand("store", int(self.positioner_storage.value)) elif entry == "limits": self.diseqccommand("limitWest") def yellowKey(self): entry = self.getCurrentConfigPath() if entry == "move": if self.isMoving: self.diseqccommand("stop") self.isMoving = False self.stopOnLock = False else: self.isMoving = True self.stopOnLock = True self.diseqccommand("moveEast", 0) self.updateColors("move") elif entry == "finemove": print "stepping east" self.diseqccommand("moveEast", 0xFF) # one step elif entry == "storage": print "move to position", int(self.positioner_storage.value) self.diseqccommand("moveTo", int(self.positioner_storage.value)) elif entry == "limits": self.diseqccommand("limitEast") def blueKey(self): entry = self.getCurrentConfigPath() if entry == "move": if self.isMoving: self.diseqccommand("stop") self.isMoving = False self.stopOnLock = False else: self.diseqccommand("moveEast", 0) self.isMoving = True self.updateColors("move") print "moving east" elif entry == "limits": self.diseqccommand("limitOn") def diseqccommand(self, cmd, param=0): self.diseqc.command(cmd, param) self.tuner.retune() def updateStatus(self): if self.frontend: self.frontend.getFrontendStatus(self.frontendStatus) self["snr_db"].update() self["snr_percentage"].update() self["ber_value"].update() self["snr_bar"].update() self["ber_bar"].update() self["lock_state"].update() transponderdata = ConvertToHumanReadable( self.tuner.getTransponderData(), "DVB-S") self["frequency_value"].setText(str(transponderdata.get("frequency"))) self["symbolrate_value"].setText( str(transponderdata.get("symbol_rate"))) self["fec_value"].setText(str(transponderdata.get("fec_inner"))) if self.frontendStatus.get( "tuner_locked", 0) == 1 and self.isMoving and self.stopOnLock: self.diseqccommand("stop") self.isMoving = False self.stopOnLock = False self.updateColors(self.getCurrentConfigPath()) self.statusTimer.start(50, True) def tune(self, transponder): if transponder is not None: self.tuner.tune(transponder)
class PositionerSetup(Screen): @staticmethod def satposition2metric(position): if position > 1800: position = 3600 - position orientation = "west" else: orientation = "east" return position, orientation @staticmethod def orbital2metric(position, orientation): if orientation == "west": position = 360 - position if orientation == "south": position = - position return position @staticmethod def longitude2orbital(position): if position >= 180: return 360 - position, "west" else: return position, "east" @staticmethod def latitude2orbital(position): if position >= 0: return position, "north" else: return -position, "south" UPDATE_INTERVAL = 50 # milliseconds STATUS_MSG_TIMEOUT = 2 # seconds LOG_SIZE = 16 * 1024 # log buffer size def __init__(self, session, feid): self.session = session Screen.__init__(self, session) self.feid = feid self.oldref = None log.open(self.LOG_SIZE) if config.Nims[self.feid].configMode.value == 'advanced': self.advanced = True self.advancedconfig = config.Nims[self.feid].advanced self.advancedsats = self.advancedconfig.sat self.availablesats = map(lambda x: x[0], nimmanager.getRotorSatListForNim(self.feid)) else: self.advanced = False cur = { } if not self.openFrontend(): self.oldref = session.nav.getCurrentlyPlayingServiceReference() service = session.nav.getCurrentService() feInfo = service and service.frontendInfo() if feInfo: cur = feInfo.getTransponderData(True) del feInfo del service session.nav.stopService() # try to disable foreground service if not self.openFrontend(): if session.pipshown: # try to disable pip service = self.session.pip.pipservice feInfo = service and service.frontendInfo() if feInfo: cur = feInfo.getTransponderData(True) del feInfo del service from Screens.InfoBar import InfoBar InfoBar.instance and hasattr(InfoBar.instance, "showPiP") and InfoBar.instance.showPiP() if not self.openFrontend(): self.frontend = None # in normal case this should not happen if hasattr(self, 'raw_channel'): del self.raw_channel self.frontendStatus = { } self.diseqc = Diseqc(self.frontend) # True means we dont like that the normal sec stuff sends commands to the rotor! self.tuner = Tuner(self.frontend, ignore_rotor = True) tp = ( cur.get("frequency", 0) / 1000, cur.get("symbol_rate", 0) / 1000, cur.get("polarization", eDVBFrontendParametersSatellite.Polarisation_Horizontal), cur.get("fec_inner", eDVBFrontendParametersSatellite.FEC_Auto), cur.get("inversion", eDVBFrontendParametersSatellite.Inversion_Unknown), cur.get("orbital_position", 0), cur.get("system", eDVBFrontendParametersSatellite.System_DVB_S), cur.get("modulation", eDVBFrontendParametersSatellite.Modulation_QPSK), cur.get("rolloff", eDVBFrontendParametersSatellite.RollOff_alpha_0_35), cur.get("pilot", eDVBFrontendParametersSatellite.Pilot_Unknown)) self.tuner.tune(tp) self.isMoving = False self.stopOnLock = False self.red = Button("") self["key_red"] = self.red self.green = Button("") self["key_green"] = self.green self.yellow = Button("") self["key_yellow"] = self.yellow self.blue = Button("") self["key_blue"] = self.blue self.list = [] self["list"] = ConfigList(self.list) self["snr_db"] = TunerInfo(TunerInfo.SNR_DB, statusDict = self.frontendStatus) self["snr_percentage"] = TunerInfo(TunerInfo.SNR_PERCENTAGE, statusDict = self.frontendStatus) self["ber_value"] = TunerInfo(TunerInfo.BER_VALUE, statusDict = self.frontendStatus) self["snr_bar"] = TunerInfo(TunerInfo.SNR_BAR, statusDict = self.frontendStatus) self["ber_bar"] = TunerInfo(TunerInfo.BER_BAR, statusDict = self.frontendStatus) self["lock_state"] = TunerInfo(TunerInfo.LOCK_STATE, statusDict = self.frontendStatus) self["frequency_value"] = Label("") self["symbolrate_value"] = Label("") self["fec_value"] = Label("") self["polarisation"] = Label("") self["status_bar"] = Label("") self.statusMsgTimeoutTicks = 0 self.statusMsgBlinking = False self.statusMsgBlinkCount = 0 self.statusMsgBlinkRate = 500 / self.UPDATE_INTERVAL # milliseconds self.tuningChangedTo(tp) self["actions"] = NumberActionMap(["DirectionActions", "OkCancelActions", "ColorActions", "TimerEditActions", "InputActions"], { "ok": self.keyOK, "cancel": self.keyCancel, "up": self.keyUp, "down": self.keyDown, "left": self.keyLeft, "right": self.keyRight, "red": self.redKey, "green": self.greenKey, "yellow": self.yellowKey, "blue": self.blueKey, "log": self.showLog, "1": self.keyNumberGlobal, "2": self.keyNumberGlobal, "3": self.keyNumberGlobal, "4": self.keyNumberGlobal, "5": self.keyNumberGlobal, "6": self.keyNumberGlobal, "7": self.keyNumberGlobal, "8": self.keyNumberGlobal, "9": self.keyNumberGlobal, "0": self.keyNumberGlobal }, -1) self.updateColors("tune") self.statusTimer = eTimer() self.statusTimer.callback.append(self.updateStatus) self.collectingStatistics = False self.statusTimer.start(self.UPDATE_INTERVAL, True) self.dataAvailable = Event() self.onClose.append(self.__onClose) self.createConfig() self.createSetup() def __onClose(self): self.statusTimer.stop() log.close() self.session.nav.playService(self.oldref) def restartPrevService(self, yesno): if yesno: if self.frontend: self.frontend = None del self.raw_channel else: self.oldref=None self.close(None) def keyCancel(self): if self.oldref: self.session.openWithCallback(self.restartPrevService, MessageBox, _("Zap back to service before positioner setup?"), MessageBox.TYPE_YESNO) else: self.restartPrevService(False) def openFrontend(self): res_mgr = eDVBResourceManager.getInstance() if res_mgr: self.raw_channel = res_mgr.allocateRawChannel(self.feid) if self.raw_channel: self.frontend = self.raw_channel.getFrontend() if self.frontend: return True else: print "getFrontend failed" else: print "getRawChannel failed" else: print "getResourceManager instance failed" return False def setLNB(self, lnb): try: self.sitelon = lnb.longitude.float self.longitudeOrientation = lnb.longitudeOrientation.value self.sitelat = lnb.latitude.float self.latitudeOrientation = lnb.latitudeOrientation.value self.tuningstepsize = lnb.tuningstepsize.float self.rotorPositions = lnb.rotorPositions.value self.turningspeedH = lnb.turningspeedH.float self.turningspeedV = lnb.turningspeedV.float except: # some reasonable defaults from NimManager self.sitelon = 5.1 self.longitudeOrientation = 'east' self.sitelat = 50.767 self.latitudeOrientation = 'north' self.tuningstepsize = 0.36 self.rotorPositions = 99 self.turningspeedH = 2.3 self.turningspeedV = 1.7 self.sitelat = PositionerSetup.orbital2metric(self.sitelat, self.latitudeOrientation) self.sitelon = PositionerSetup.orbital2metric(self.sitelon, self.longitudeOrientation) def getLNBfromConfig(self, orb_pos): lnb = None if orb_pos in self.availablesats: lnbnum = int(self.advancedsats[orb_pos].lnb.value) if not lnbnum: for allsats in range(3601, 3607): lnbnum = int(self.advancedsats[allsats].lnb.value) if lnbnum: break if lnbnum: self.printMsg(_("Using LNB %d") % lnbnum) lnb = self.advancedconfig.lnb[lnbnum] if not lnb: self.logMsg(_("Warning: no LNB; using factory defaults."), timeout = 4) return lnb def createConfig(self): rotorposition = 1 orb_pos = 0 self.printMsg(_("Using tuner %s") % chr(0x41 + self.feid)) if not self.advanced: self.printMsg(_("Configuration mode: %s") % _("simple")) nim = config.Nims[self.feid] self.sitelon = nim.longitude.float self.longitudeOrientation = nim.longitudeOrientation.value self.sitelat = nim.latitude.float self.latitudeOrientation = nim.latitudeOrientation.value self.sitelat = PositionerSetup.orbital2metric(self.sitelat, self.latitudeOrientation) self.sitelon = PositionerSetup.orbital2metric(self.sitelon, self.longitudeOrientation) self.tuningstepsize = nim.tuningstepsize.float self.rotorPositions = nim.rotorPositions.value self.turningspeedH = nim.turningspeedH.float self.turningspeedV = nim.turningspeedV.float else: # it is advanced self.printMsg(_("Configuration mode: %s") % _("advanced")) fe_data = { } self.frontend.getFrontendData(fe_data) self.frontend.getTransponderData(fe_data, True) orb_pos = fe_data.get("orbital_position", None) if orb_pos in self.availablesats: rotorposition = int(self.advancedsats[orb_pos].rotorposition.value) self.setLNB(self.getLNBfromConfig(orb_pos)) self.positioner_tune = ConfigNothing() self.positioner_move = ConfigNothing() self.positioner_finemove = ConfigNothing() self.positioner_limits = ConfigNothing() self.positioner_storage = ConfigInteger(default = rotorposition, limits = (1, self.rotorPositions)) self.allocatedIndices = [] m = PositionerSetup.satposition2metric(orb_pos) self.orbitalposition = ConfigFloat(default = [int(m[0] / 10), m[0] % 10], limits = [(0,180),(0,9)]) self.orientation = ConfigSelection([("east", _("East")), ("west", _("West"))], m[1]) def createSetup(self): self.list.append((_("Tune and focus"), self.positioner_tune, "tune")) self.list.append((_("Movement"), self.positioner_move, "move")) self.list.append((_("Fine movement"), self.positioner_finemove, "finemove")) self.list.append((_("Set limits"), self.positioner_limits, "limits")) self.list.append((_("Memory index"), self.positioner_storage, "storage")) self.list.append((_("Goto"), self.orbitalposition, "goto")) self.list.append((" ", self.orientation, "goto")) self["list"].l.setList(self.list) def keyOK(self): pass def getCurrentConfigPath(self): return self["list"].getCurrent()[2] def keyUp(self): if not self.isMoving: self["list"].instance.moveSelection(self["list"].instance.moveUp) self.updateColors(self.getCurrentConfigPath()) def keyDown(self): if not self.isMoving: self["list"].instance.moveSelection(self["list"].instance.moveDown) self.updateColors(self.getCurrentConfigPath()) def keyNumberGlobal(self, number): self["list"].handleKey(KEY_0 + number) def keyLeft(self): self["list"].handleKey(KEY_LEFT) def keyRight(self): self["list"].handleKey(KEY_RIGHT) def updateColors(self, entry): if entry == "tune": self.red.setText(_("Tune")) self.green.setText(_("Auto focus")) self.yellow.setText(_("Calibrate")) self.blue.setText(_("Calculate")) elif entry == "move": if self.isMoving: self.red.setText(_("Stop")) self.green.setText(_("Stop")) self.yellow.setText(_("Stop")) self.blue.setText(_("Stop")) else: self.red.setText(_("Move west")) self.green.setText(_("Search west")) self.yellow.setText(_("Search east")) self.blue.setText(_("Move east")) elif entry == "finemove": self.red.setText("") self.green.setText(_("Step west")) self.yellow.setText(_("Step east")) self.blue.setText("") elif entry == "limits": self.red.setText(_("Limits off")) self.green.setText(_("Limit west")) self.yellow.setText(_("Limit east")) self.blue.setText(_("Limits on")) elif entry == "storage": self.red.setText("") self.green.setText(_("Store position")) self.yellow.setText(_("Goto position")) if self.advanced: self.blue.setText(_("Allocate")) else: self.blue.setText("") elif entry == "goto": self.red.setText("") self.green.setText(_("Goto 0")) self.yellow.setText(_("Goto X")) self.blue.setText("") else: self.red.setText("") self.green.setText("") self.yellow.setText("") self.blue.setText("") def printMsg(self, msg): print msg print>>log, msg def stopMoving(self): self.printMsg(_("Stop")) self.diseqccommand("stop") self.isMoving = False self.stopOnLock = False self.statusMsg(_("Stopped"), timeout = self.STATUS_MSG_TIMEOUT) def redKey(self): entry = self.getCurrentConfigPath() if entry == "move": if self.isMoving: self.stopMoving() else: self.printMsg(_("Move west")) self.diseqccommand("moveWest", 0) self.isMoving = True self.statusMsg(_("Moving west ..."), blinking = True) self.updateColors("move") elif entry == "limits": self.printMsg(_("Limits off")) self.diseqccommand("limitOff") self.statusMsg(_("Limits cancelled"), timeout = self.STATUS_MSG_TIMEOUT) elif entry == "tune": fe_data = { } self.frontend.getFrontendData(fe_data) self.frontend.getTransponderData(fe_data, True) feparm = self.tuner.lastparm.getDVBS() fe_data["orbital_position"] = feparm.orbital_position self.statusTimer.stop() self.session.openWithCallback(self.tune, TunerScreen, self.feid, fe_data) def greenKey(self): entry = self.getCurrentConfigPath() if entry == "tune": # Auto focus self.printMsg(_("Auto focus")) print>>log, (_("Site latitude") + " : %5.1f %s") % PositionerSetup.latitude2orbital(self.sitelat) print>>log, (_("Site longitude") + " : %5.1f %s") % PositionerSetup.longitude2orbital(self.sitelon) Thread(target = self.autofocus).start() elif entry == "move": if self.isMoving: self.stopMoving() else: self.printMsg(_("Search west")) self.isMoving = True self.stopOnLock = True self.diseqccommand("moveWest", 0) self.statusMsg(_("Searching west ..."), blinking = True) self.updateColors("move") elif entry == "finemove": self.printMsg(_("Step west")) self.diseqccommand("moveWest", 0xFF) # one step self.statusMsg(_("Stepped west"), timeout = self.STATUS_MSG_TIMEOUT) elif entry == "storage": self.printMsg(_("Store at index")) index = int(self.positioner_storage.value) self.diseqccommand("store", index) self.statusMsg((_("Position stored at index") + " %2d") % index, timeout = self.STATUS_MSG_TIMEOUT) elif entry == "limits": self.printMsg(_("Limit west")) self.diseqccommand("limitWest") self.statusMsg(_("West limit set"), timeout = self.STATUS_MSG_TIMEOUT) elif entry == "goto": self.printMsg(_("Goto 0")) self.diseqccommand("moveTo", 0) self.statusMsg(_("Moved to position 0"), timeout = self.STATUS_MSG_TIMEOUT) def yellowKey(self): entry = self.getCurrentConfigPath() if entry == "move": if self.isMoving: self.stopMoving() else: self.printMsg(_("Move east")) self.isMoving = True self.stopOnLock = True self.diseqccommand("moveEast", 0) self.statusMsg(_("Searching east ..."), blinking = True) self.updateColors("move") elif entry == "finemove": self.printMsg(_("Step east")) self.diseqccommand("moveEast", 0xFF) # one step self.statusMsg(_("Stepped east"), timeout = self.STATUS_MSG_TIMEOUT) elif entry == "storage": self.printMsg(_("Goto index position")) index = int(self.positioner_storage.value) self.diseqccommand("moveTo", index) self.statusMsg((_("Moved to position at index") + " %2d") % index, timeout = self.STATUS_MSG_TIMEOUT) elif entry == "limits": self.printMsg(_("Limit east")) self.diseqccommand("limitEast") self.statusMsg(_("East limit set"), timeout = self.STATUS_MSG_TIMEOUT) elif entry == "goto": self.printMsg(_("Move to position X")) satlon = self.orbitalposition.float position = "%5.1f %s" % (satlon, self.orientation.value) print>>log, (_("Satellite longitude:") + " %s") % position satlon = PositionerSetup.orbital2metric(satlon, self.orientation.value) self.statusMsg((_("Moving to position") + " %s") % position, timeout = self.STATUS_MSG_TIMEOUT) self.gotoX(satlon) elif entry == "tune": # Start USALS calibration self.printMsg(_("USALS calibration")) print>>log, (_("Site latitude") + " : %5.1f %s") % PositionerSetup.latitude2orbital(self.sitelat) print>>log, (_("Site longitude") + " : %5.1f %s") % PositionerSetup.longitude2orbital(self.sitelon) Thread(target = self.gotoXcalibration).start() def blueKey(self): entry = self.getCurrentConfigPath() if entry == "move": if self.isMoving: self.stopMoving() else: self.printMsg(_("Move east")) self.diseqccommand("moveEast", 0) self.isMoving = True self.statusMsg(_("Moving east ..."), blinking = True) self.updateColors("move") elif entry == "limits": self.printMsg(_("Limits on")) self.diseqccommand("limitOn") self.statusMsg(_("Limits enabled"), timeout = self.STATUS_MSG_TIMEOUT) elif entry == "tune": # Start (re-)calculate self.session.openWithCallback(self.recalcConfirmed, MessageBox, _("This will (re-)calculate all positions of your rotor and may remove previously memorised positions and fine-tuning!\nAre you sure?"), MessageBox.TYPE_YESNO, default = False, timeout = 10) elif entry == "storage": if self.advanced: self.printMsg(_("Allocate unused memory index")) while True: if not len(self.allocatedIndices): for sat in self.availablesats: current_index = int(self.advancedsats[sat].rotorposition.value) if current_index not in self.allocatedIndices: self.allocatedIndices.append(current_index) if len(self.allocatedIndices) == self.rotorPositions: self.statusMsg(_("No free index available"), timeout = self.STATUS_MSG_TIMEOUT) break index = 1 if len(self.allocatedIndices): for i in sorted(self.allocatedIndices): if i != index: break index += 1 if index <= self.rotorPositions: self.positioner_storage.value = index self["list"].invalidateCurrent() self.allocatedIndices.append(index) self.statusMsg((_("Index allocated:") + " %2d") % index, timeout = self.STATUS_MSG_TIMEOUT) break else: self.allocatedIndices = [] def recalcConfirmed(self, yesno): if yesno: self.printMsg(_("Calculate all positions")) print>>log, (_("Site latitude") + " : %5.1f %s") % PositionerSetup.latitude2orbital(self.sitelat) print>>log, (_("Site longitude") + " : %5.1f %s") % PositionerSetup.longitude2orbital(self.sitelon) lon = self.sitelon if lon >= 180: lon -= 360 if lon < -30: # americas, make unsigned binary west positive polarity lon = -lon lon = int(round(lon)) & 0xFF lat = int(round(self.sitelat)) & 0xFF index = int(self.positioner_storage.value) & 0xFF self.diseqccommand("calc", (((index << 8) | lon) << 8) | lat) self.statusMsg(_("Calculation complete"), timeout = self.STATUS_MSG_TIMEOUT) def showLog(self): self.session.open(PositionerSetupLog) def diseqccommand(self, cmd, param = 0): print>>log, "Diseqc(%s, %X)" % (cmd, param) self.diseqc.command(cmd, param) self.tuner.retune() def tune(self, transponder): # re-start the update timer self.statusTimer.start(self.UPDATE_INTERVAL, True) if transponder is not None: self.tuner.tune(transponder) self.tuningChangedTo(transponder) feparm = self.tuner.lastparm.getDVBS() orb_pos = feparm.orbital_position m = PositionerSetup.satposition2metric(orb_pos) self.orbitalposition.value = [int(m[0] / 10), m[0] % 10] self.orientation.value = m[1] if self.advanced: if orb_pos in self.availablesats: rotorposition = int(self.advancedsats[orb_pos].rotorposition.value) self.positioner_storage.value = rotorposition self.allocatedIndices = [] self.setLNB(self.getLNBfromConfig(orb_pos)) def isLocked(self): return self.frontendStatus.get("tuner_locked", 0) == 1 def statusMsg(self, msg, blinking = False, timeout = 0): # timeout in seconds self.statusMsgBlinking = blinking if not blinking: self["status_bar"].visible = True self["status_bar"].setText(msg) self.statusMsgTimeoutTicks = (timeout * 1000 + self.UPDATE_INTERVAL / 2) / self.UPDATE_INTERVAL def updateStatus(self): self.statusTimer.start(self.UPDATE_INTERVAL, True) if self.frontend: self.frontend.getFrontendStatus(self.frontendStatus) self["snr_db"].update() self["snr_percentage"].update() self["ber_value"].update() self["snr_bar"].update() self["ber_bar"].update() self["lock_state"].update() if self.statusMsgBlinking: self.statusMsgBlinkCount += 1 if self.statusMsgBlinkCount == self.statusMsgBlinkRate: self.statusMsgBlinkCount = 0 self["status_bar"].visible = not self["status_bar"].visible if self.statusMsgTimeoutTicks > 0: self.statusMsgTimeoutTicks -= 1 if self.statusMsgTimeoutTicks == 0: self["status_bar"].setText("") self.statusMsgBlinking = False self["status_bar"].visible = True if self.isLocked() and self.isMoving and self.stopOnLock: self.stopMoving() self.updateColors(self.getCurrentConfigPath()) if self.collectingStatistics: self.low_rate_adapter_count += 1 if self.low_rate_adapter_count == self.MAX_LOW_RATE_ADAPTER_COUNT: self.low_rate_adapter_count = 0 self.snr_percentage += self["snr_percentage"].getValue(TunerInfo.SNR) self.lock_count += self["lock_state"].getValue(TunerInfo.LOCK) self.stat_count += 1 if self.stat_count == self.max_count: self.collectingStatistics = False count = float(self.stat_count) self.lock_count /= count self.snr_percentage *= 100.0 / 0x10000 / count self.dataAvailable.set() def tuningChangedTo(self, tp): def setLowRateAdapterCount(symbolrate): # change the measurement time and update interval in case of low symbol rate, # since more time is needed for the front end in that case. # It is an heuristic determination without any pretence. For symbol rates # of 5000 the interval is multiplied by 3 until 15000 which is seen # as a high symbol rate. Linear interpolation elsewhere. return max(int(round((3 - 1) * (symbolrate - 15000) / (5000 - 15000) + 1)), 1) self.symbolrate = tp[1] self.polarisation = tp[2] self.MAX_LOW_RATE_ADAPTER_COUNT = setLowRateAdapterCount(self.symbolrate) transponderdata = ConvertToHumanReadable(self.tuner.getTransponderData(), "DVB-S") self["frequency_value"].setText(str(transponderdata.get("frequency"))) self["symbolrate_value"].setText(str(transponderdata.get("symbol_rate"))) self["fec_value"].setText(str(transponderdata.get("fec_inner"))) self["polarisation"].setText(str(transponderdata.get("polarization"))) @staticmethod def rotorCmd2Step(rotorCmd, stepsize): return round(float(rotorCmd & 0xFFF) / 0x10 / stepsize) * (1 - ((rotorCmd & 0x1000) >> 11)) @staticmethod def gotoXcalc(satlon, sitelat, sitelon): def azimuth2Rotorcode(angle): gotoXtable = (0x00, 0x02, 0x03, 0x05, 0x06, 0x08, 0x0A, 0x0B, 0x0D, 0x0E) a = int(round(abs(angle) * 10.0)) return ((a / 10) << 4) + gotoXtable[a % 10] satHourAngle = rotor_calc.calcSatHourangle(satlon, sitelat, sitelon) if sitelat >= 0: # Northern Hemisphere rotorCmd = azimuth2Rotorcode(180 - satHourAngle) if satHourAngle <= 180: # the east rotorCmd |= 0xE000 else: # west rotorCmd |= 0xD000 else: # Southern Hemisphere if satHourAngle <= 180: # the east rotorCmd = azimuth2Rotorcode(satHourAngle) | 0xD000 else: # west rotorCmd = azimuth2Rotorcode(360 - satHourAngle) | 0xE000 return rotorCmd def gotoX(self, satlon): rotorCmd = PositionerSetup.gotoXcalc(satlon, self.sitelat, self.sitelon) self.diseqccommand("gotoX", rotorCmd) x = PositionerSetup.rotorCmd2Step(rotorCmd, self.tuningstepsize) print>>log, (_("Rotor step position:") + " %4d") % x return x def getTurningspeed(self): if self.polarisation == eDVBFrontendParametersSatellite.Polarisation_Horizontal: turningspeed = self.turningspeedH else: turningspeed = self.turningspeedV return max(turningspeed, 0.1) TURNING_START_STOP_DELAY = 1.600 # seconds MAX_SEARCH_ANGLE = 12.0 # degrees MAX_FOCUS_ANGLE = 6.0 # degrees LOCK_LIMIT = 0.1 # ratio MEASURING_TIME = 2.500 # seconds def measure(self, time = MEASURING_TIME): # time in seconds self.snr_percentage = 0.0 self.lock_count = 0.0 self.stat_count = 0 self.low_rate_adapter_count = 0 self.max_count = max(int((time * 1000 + self.UPDATE_INTERVAL / 2)/ self.UPDATE_INTERVAL), 1) self.collectingStatistics = True self.dataAvailable.clear() self.dataAvailable.wait() def logMsg(self, msg, timeout = 0): self.statusMsg(msg, timeout = timeout) self.printMsg(msg) def sync(self): self.lock_count = 0.0 n = 0 while self.lock_count < (1 - self.LOCK_LIMIT) and n < 5: self.measure(time = 0.500) n += 1 if self.lock_count < (1 - self.LOCK_LIMIT): return False return True randomGenerator = None def randomBool(self): if self.randomGenerator is None: self.randomGenerator = SystemRandom() return self.randomGenerator.random() >= 0.5 def gotoXcalibration(self): def move(x): z = self.gotoX(x + satlon) time = int(abs(x - prev_pos) / turningspeed + 2 * self.TURNING_START_STOP_DELAY) sleep(time * self.MAX_LOW_RATE_ADAPTER_COUNT) return z def reportlevels(pos, level, lock): print>>log, (_("Signal quality") + " %5.1f" + chr(176) + " : %6.2f") % (pos, level) print>>log, (_("Lock ratio") + " %5.1f" + chr(176) + " : %6.2f") % (pos, lock) def optimise(readings): xi = readings.keys() yi = map(lambda (x, y) : x, readings.values()) x0 = sum(map(mul, xi, yi)) / sum(yi) xm = xi[yi.index(max(yi))] return x0, xm def toGeopos(x): if x < 0: return _("W") else: return _("E") def toGeoposEx(x): if x < 0: return _("west") else: return _("east") self.logMsg(_("GotoX calibration")) satlon = self.orbitalposition.float print>>log, (_("Satellite longitude:") + " %5.1f" + chr(176) + " %s") % (satlon, self.orientation.value) satlon = PositionerSetup.orbital2metric(satlon, self.orientation.value) prev_pos = 0.0 # previous relative position w.r.t. satlon turningspeed = self.getTurningspeed() x = 0.0 # relative position w.r.t. satlon dir = 1 if self.randomBool(): dir = -dir while abs(x) < self.MAX_SEARCH_ANGLE: if self.sync(): break x += (1.0 * dir) # one degree east/west self.statusMsg((_("Searching") + " " + toGeoposEx(dir) + " %2d" + chr(176)) % abs(x), blinking = True) move(x) prev_pos = x else: x = 0.0 dir = -dir while abs(x) < self.MAX_SEARCH_ANGLE: x += (1.0 * dir) # one degree east/west self.statusMsg((_("Searching") + " " + toGeoposEx(dir) + " %2d" + chr(176)) % abs(x), blinking = True) move(x) prev_pos = x if self.sync(): break else: msg = _("Cannot find any signal ..., aborting !") self.printMsg(msg) self.statusMsg("") self.session.open(MessageBox, msg, MessageBox.TYPE_ERROR, timeout = 5) return x = round(x / self.tuningstepsize) * self.tuningstepsize move(x) prev_pos = x measurements = {} self.measure() print>>log, (_("Initial signal quality") + " %5.1f" + chr(176) + ": %6.2f") % (x, self.snr_percentage) print>>log, (_("Initial lock ratio") + " %5.1f" + chr(176) + ": %6.2f") % (x, self.lock_count) measurements[x] = (self.snr_percentage, self.lock_count) start_pos = x x = 0.0 dir = 1 if self.randomBool(): dir = -dir while x < self.MAX_FOCUS_ANGLE: x += self.tuningstepsize * dir # one step east/west self.statusMsg((_("Moving") + " " + toGeoposEx(dir) + " %5.1f" + chr(176)) % abs(x + start_pos), blinking = True) move(x + start_pos) prev_pos = x + start_pos self.measure() measurements[x + start_pos] = (self.snr_percentage, self.lock_count) reportlevels(x + start_pos, self.snr_percentage, self.lock_count) if self.lock_count < self.LOCK_LIMIT: break else: msg = _("Cannot determine") + " " + toGeoposEx(dir) + " " + _("limit ..., aborting !") self.printMsg(msg) self.statusMsg("") self.session.open(MessageBox, msg, MessageBox.TYPE_ERROR, timeout = 5) return x = 0.0 dir = -dir self.statusMsg((_("Moving") + " " + toGeoposEx(dir) + " %5.1f" + chr(176)) % abs(start_pos), blinking = True) move(start_pos) prev_pos = start_pos if not self.sync(): msg = _("Sync failure moving back to origin !") self.printMsg(msg) self.statusMsg("") self.session.open(MessageBox, msg, MessageBox.TYPE_ERROR, timeout = 5) return while abs(x) < self.MAX_FOCUS_ANGLE: x += self.tuningstepsize * dir # one step west/east self.statusMsg((_("Moving") + " " + toGeoposEx(dir) + " %5.1f" + chr(176)) % abs(x + start_pos), blinking = True) move(x + start_pos) prev_pos = x + start_pos self.measure() measurements[x + start_pos] = (self.snr_percentage, self.lock_count) reportlevels(x + start_pos, self.snr_percentage, self.lock_count) if self.lock_count < self.LOCK_LIMIT: break else: msg = _("Cannot determine") + " " + toGeoposEx(dir) + " " + _("limit ..., aborting !") self.printMsg(msg) self.statusMsg("") self.session.open(MessageBox, msg, MessageBox.TYPE_ERROR, timeout = 5) return (x0, xm) = optimise(measurements) x = move(x0) if satlon > 180: satlon -= 360 x0 += satlon xm += satlon print>>log, (_("Weighted position") + " : %5.1f" + chr(176) + " %s") % (abs(x0), toGeopos(x0)) print>>log, (_("Strongest position") + " : %5.1f" + chr(176) + " %s") % (abs(xm), toGeopos(xm)) self.logMsg((_("Final position at") + " %5.1f" + chr(176) + " %s / %d; " + _("offset is") + " %4.1f" + chr(176)) % (abs(x0), toGeopos(x0), x, x0 - satlon), timeout = 10) def autofocus(self): def move(x): if x > 0: self.diseqccommand("moveEast", (-x) & 0xFF) elif x < 0: self.diseqccommand("moveWest", x & 0xFF) if x != 0: time = int(abs(x) * self.tuningstepsize / turningspeed + 2 * self.TURNING_START_STOP_DELAY) sleep(time * self.MAX_LOW_RATE_ADAPTER_COUNT) def reportlevels(pos, level, lock): print>>log, (_("Signal quality") + " [%2d] : %6.2f") % (pos, level) print>>log, (_("Lock ratio") + " [%2d] : %6.2f") % (pos, lock) def optimise(readings): xi = readings.keys() yi = map(lambda (x, y) : x, readings.values()) x0 = int(round(sum(map(mul, xi, yi)) / sum(yi))) xm = xi[yi.index(max(yi))] return x0, xm def toGeoposEx(x): if x < 0: return _("west") else: return _("east") self.logMsg(_("Auto focus commencing ...")) turningspeed = self.getTurningspeed() measurements = {} maxsteps = max(min(round(self.MAX_FOCUS_ANGLE / self.tuningstepsize), 0x1F), 3) self.measure() print>>log, (_("Initial signal quality:") + " %6.2f") % self.snr_percentage print>>log, (_("Initial lock ratio") + " : %6.2f") % self.lock_count if self.lock_count < 1 - self.LOCK_LIMIT: msg = _("There is no signal to lock on !") self.printMsg(msg) self.statusMsg("") self.session.open(MessageBox, msg, MessageBox.TYPE_ERROR, timeout = 5) return print>>log, _("Signal OK, proceeding") x = 0 dir = 1 if self.randomBool(): dir = -dir measurements[x] = (self.snr_percentage, self.lock_count) nsteps = 0 while nsteps < maxsteps: x += dir self.statusMsg((_("Moving") + " " + toGeoposEx(dir) + " %2d") % abs(x), blinking = True) move(dir) # one step self.measure() measurements[x] = (self.snr_percentage, self.lock_count) reportlevels(x, self.snr_percentage, self.lock_count) if self.lock_count < self.LOCK_LIMIT: break nsteps += 1 else: msg = _("Cannot determine") + " " + toGeoposEx(dir) + " " + _("limit ..., aborting !") self.printMsg(msg) self.statusMsg("") self.session.open(MessageBox, msg, MessageBox.TYPE_ERROR, timeout = 5) return dir = -dir self.statusMsg(_("Moving") + " " + toGeoposEx(dir) + " 0", blinking = True) move(-x) if not self.sync(): msg = _("Sync failure moving back to origin !") self.printMsg(msg) self.statusMsg("") self.session.open(MessageBox, msg, MessageBox.TYPE_ERROR, timeout = 5) return x = 0 nsteps = 0 while nsteps < maxsteps: x += dir self.statusMsg((_("Moving") + " " + toGeoposEx(dir) + " %2d") % abs(x), blinking = True) move(dir) # one step self.measure() measurements[x] = (self.snr_percentage, self.lock_count) reportlevels(x, self.snr_percentage, self.lock_count) if self.lock_count < self.LOCK_LIMIT: break nsteps += 1 else: msg = _("Cannot determine") + " " + toGeoposEx(dir) + " " + _("limit ..., aborting !") self.printMsg(msg) self.statusMsg("") self.session.open(MessageBox, msg, MessageBox.TYPE_ERROR, timeout = 5) return (x0, xm) = optimise(measurements) print>>log, (_("Weighted position") + " : %2d") % x0 print>>log, (_("Strongest position") + " : %2d") % xm self.logMsg((_("Final position at index") + " %2d (%5.1f" + chr(176) + ")") % (x0, x0 * self.tuningstepsize), timeout = 6) move(x0 - x)
class PositionerSetup(Screen): skin = """ <screen position="100,100" size="560,400" title="Positioner setup..." > <widget name="list" position="100,0" size="350,155" /> <widget name="red" position="0,155" size="140,80" backgroundColor="red" halign="center" valign="center" font="Regular;21" /> <widget name="green" position="140,155" size="140,80" backgroundColor="green" halign="center" valign="center" font="Regular;21" /> <widget name="yellow" position="280,155" size="140,80" backgroundColor="yellow" halign="center" valign="center" font="Regular;21" /> <widget name="blue" position="420,155" size="140,80" backgroundColor="blue" halign="center" valign="center" font="Regular;21" /> <widget name="snr_db" position="60,245" size="150,22" halign="center" valign="center" font="Regular;21" /> <eLabel text="SNR:" position="0,270" size="60,22" font="Regular;21" /> <eLabel text="BER:" position="0,295" size="60,22" font="Regular;21" /> <eLabel text="Lock:" position="0,320" size="60,22" font="Regular;21" /> <widget name="snr_percentage" position="220,270" size="60,22" font="Regular;21" /> <widget name="ber_value" position="220,295" size="60,22" font="Regular;21" /> <widget name="lock_state" position="60,320" size="150,22" font="Regular;21" /> <widget name="snr_bar" position="60,270" size="150,22" /> <widget name="ber_bar" position="60,295" size="150,22" /> <eLabel text="Frequency:" position="300,245" size="120,22" font="Regular;21" /> <eLabel text="Symbolrate:" position="300,270" size="120,22" font="Regular;21" /> <eLabel text="FEC:" position="300,295" size="120,22" font="Regular;21" /> <widget name="frequency_value" position="420,245" size="120,22" font="Regular;21" /> <widget name="symbolrate_value" position="420,270" size="120,22" font="Regular;21" /> <widget name="fec_value" position="420,295" size="120,22" font="Regular;21" /> </screen>""" def __init__(self, session, feid): self.skin = PositionerSetup.skin Screen.__init__(self, session) self.feid = feid self.oldref = None cur = { } if not self.openFrontend(): self.oldref = session.nav.getCurrentlyPlayingServiceReference() service = session.nav.getCurrentService() feInfo = service and service.frontendInfo() if feInfo: cur = feInfo.getTransponderData(True) del feInfo del service session.nav.stopService() # try to disable foreground service if not self.openFrontend(): if session.pipshown: # try to disable pip service = self.session.pip.pipservice feInfo = service and service.frontendInfo() if feInfo: cur = feInfo.getTransponderData() del feInfo del service session.pipshown = False session.deleteDialog(session.pip) del session.pip if not self.openFrontend(): self.frontend = None # in normal case this should not happen self.frontendStatus = { } self.diseqc = Diseqc(self.frontend) self.tuner = Tuner(self.frontend, True) #True means we dont like that the normal sec stuff sends commands to the rotor! tp = ( cur.get("frequency", 0) / 1000, cur.get("symbol_rate", 0) / 1000, cur.get("polarization", eDVBFrontendParametersSatellite.Polarisation_Horizontal), cur.get("fec_inner", eDVBFrontendParametersSatellite.FEC_Auto), cur.get("inversion", eDVBFrontendParametersSatellite.Inversion_Unknown), cur.get("orbital_position", 0), cur.get("system", eDVBFrontendParametersSatellite.System_DVB_S), cur.get("modulation", eDVBFrontendParametersSatellite.Modulation_QPSK), cur.get("rolloff", eDVBFrontendParametersSatellite.RollOff_alpha_0_35), cur.get("pilot", eDVBFrontendParametersSatellite.Pilot_Unknown)) self.tuner.tune(tp) self.createConfig() self.isMoving = False self.stopOnLock = False self.red = Label("") self["red"] = self.red self.green = Label("") self["green"] = self.green self.yellow = Label("") self["yellow"] = self.yellow self.blue = Label("") self["blue"] = self.blue self.list = [] self["list"] = ConfigList(self.list) self.createSetup() self["snr_db"] = TunerInfo(TunerInfo.SNR_DB, statusDict = self.frontendStatus) self["snr_percentage"] = TunerInfo(TunerInfo.SNR_PERCENTAGE, statusDict = self.frontendStatus) self["ber_value"] = TunerInfo(TunerInfo.BER_VALUE, statusDict = self.frontendStatus) self["snr_bar"] = TunerInfo(TunerInfo.SNR_BAR, statusDict = self.frontendStatus) self["ber_bar"] = TunerInfo(TunerInfo.BER_BAR, statusDict = self.frontendStatus) self["lock_state"] = TunerInfo(TunerInfo.LOCK_STATE, statusDict = self.frontendStatus) self["frequency_value"] = Label("") self["symbolrate_value"] = Label("") self["fec_value"] = Label("") self["actions"] = ActionMap(["DirectionActions", "OkCancelActions", "ColorActions"], { "ok": self.go, "cancel": self.keyCancel, "up": self.up, "down": self.down, "left": self.left, "right": self.right, "red": self.redKey, "green": self.greenKey, "yellow": self.yellowKey, "blue": self.blueKey, }, -1) self.updateColors("tune") self.statusTimer = eTimer() self.statusTimer_conn = self.statusTimer.timeout.connect(self.updateStatus) self.statusTimer.start(50, True) self.onClose.append(self.__onClose) def __onClose(self): self.session.nav.playService(self.oldref) def restartPrevService(self, yesno): if yesno: if self.frontend: self.frontend = None del self.raw_channel else: self.oldref=None self.close(None) def keyCancel(self): if self.oldref: self.session.openWithCallback(self.restartPrevService, MessageBox, _("Zap back to service before positioner setup?"), MessageBox.TYPE_YESNO) else: self.restartPrevService(False) def openFrontend(self): res_mgr = eDVBResourceManager.getInstance() if res_mgr: self.raw_channel = res_mgr.allocateRawChannel(self.feid) if self.raw_channel: self.frontend = self.raw_channel.getFrontend() if self.frontend: return True else: print "getFrontend failed" else: print "getRawChannel failed" else: print "getResourceManager instance failed" return False def createConfig(self): self.positioner_tune = ConfigNothing() self.positioner_move = ConfigNothing() self.positioner_finemove = ConfigNothing() self.positioner_limits = ConfigNothing() self.positioner_goto0 = ConfigNothing() storepos = [] for x in range(1,255): storepos.append(str(x)) self.positioner_storage = ConfigSelection(choices = storepos) def createSetup(self): self.list.append((_("Tune"), self.positioner_tune, "tune")) self.list.append((_("Positioner movement"), self.positioner_move, "move")) self.list.append((_("Positioner fine movement"), self.positioner_finemove, "finemove")) self.list.append((_("Set limits"), self.positioner_limits, "limits")) self.list.append((_("Positioner storage"), self.positioner_storage, "storage")) self.list.append((_("Goto 0"), self.positioner_goto0, "goto0")) self["list"].l.setList(self.list) def go(self): pass def getCurrentConfigPath(self): return self["list"].getCurrent()[2] def up(self): if not self.isMoving: self["list"].instance.moveSelection(self["list"].instance.moveUp) self.updateColors(self.getCurrentConfigPath()) def down(self): if not self.isMoving: self["list"].instance.moveSelection(self["list"].instance.moveDown) self.updateColors(self.getCurrentConfigPath()) def left(self): self["list"].handleKey(KEY_LEFT) def right(self): self["list"].handleKey(KEY_RIGHT) def updateColors(self, entry): if entry == "tune": self.red.setText(_("Tune")) self.green.setText("") self.yellow.setText("") self.blue.setText("") elif entry == "move": if self.isMoving: self.red.setText(_("Stop")) self.green.setText(_("Stop")) self.yellow.setText(_("Stop")) self.blue.setText(_("Stop")) else: self.red.setText(_("Move west")) self.green.setText(_("Search west")) self.yellow.setText(_("Search east")) self.blue.setText(_("Move east")) elif entry == "finemove": self.red.setText("") self.green.setText(_("Step west")) self.yellow.setText(_("Step east")) self.blue.setText("") elif entry == "limits": self.red.setText(_("Limits off")) self.green.setText(_("Limit west")) self.yellow.setText(_("Limit east")) self.blue.setText(_("Limits on")) elif entry == "storage": self.red.setText("") self.green.setText(_("Store position")) self.yellow.setText(_("Goto position")) self.blue.setText("") elif entry == "goto0": self.red.setText(_("Goto 0")) self.green.setText("") self.yellow.setText("") self.blue.setText("") else: self.red.setText("") self.green.setText("") self.yellow.setText("") self.blue.setText("") def redKey(self): entry = self.getCurrentConfigPath() if entry == "move": if self.isMoving: self.diseqccommand("stop") self.isMoving = False self.stopOnLock = False else: self.diseqccommand("moveWest", 0) self.isMoving = True self.updateColors("move") elif entry == "limits": self.diseqccommand("limitOff") elif entry == "tune": fe_data = { } self.frontend.getFrontendData(fe_data) self.frontend.getTransponderData(fe_data, True) feparm = self.tuner.lastparm.getDVBS() fe_data["orbital_position"] = feparm.orbital_position self.session.openWithCallback(self.tune, TunerScreen, self.feid, fe_data) elif entry == "goto0": print "move to position 0" self.diseqccommand("moveTo", 0) def greenKey(self): entry = self.getCurrentConfigPath() if entry == "move": if self.isMoving: self.diseqccommand("stop") self.isMoving = False self.stopOnLock = False else: self.isMoving = True self.stopOnLock = True self.diseqccommand("moveWest", 0) self.updateColors("move") elif entry == "finemove": print "stepping west" self.diseqccommand("moveWest", 0xFF) # one step elif entry == "storage": print "store at position", int(self.positioner_storage.value) self.diseqccommand("store", int(self.positioner_storage.value)) elif entry == "limits": self.diseqccommand("limitWest") def yellowKey(self): entry = self.getCurrentConfigPath() if entry == "move": if self.isMoving: self.diseqccommand("stop") self.isMoving = False self.stopOnLock = False else: self.isMoving = True self.stopOnLock = True self.diseqccommand("moveEast", 0) self.updateColors("move") elif entry == "finemove": print "stepping east" self.diseqccommand("moveEast", 0xFF) # one step elif entry == "storage": print "move to position", int(self.positioner_storage.value) self.diseqccommand("moveTo", int(self.positioner_storage.value)) elif entry == "limits": self.diseqccommand("limitEast") def blueKey(self): entry = self.getCurrentConfigPath() if entry == "move": if self.isMoving: self.diseqccommand("stop") self.isMoving = False self.stopOnLock = False else: self.diseqccommand("moveEast", 0) self.isMoving = True self.updateColors("move") print "moving east" elif entry == "limits": self.diseqccommand("limitOn") def diseqccommand(self, cmd, param = 0): self.diseqc.command(cmd, param) self.tuner.retune() def updateStatus(self): if self.frontend: self.frontendStatus.clear() self.frontend.getFrontendStatus(self.frontendStatus) self["snr_db"].update() self["snr_percentage"].update() self["ber_value"].update() self["snr_bar"].update() self["ber_bar"].update() self["lock_state"].update() transponderdata = ConvertToHumanReadable(self.tuner.getTransponderData(), "DVB-S") self["frequency_value"].setText(str(transponderdata.get("frequency"))) self["symbolrate_value"].setText(str(transponderdata.get("symbol_rate"))) self["fec_value"].setText(str(transponderdata.get("fec_inner"))) if self.frontendStatus.get("tuner_locked", 0) == 1 and self.isMoving and self.stopOnLock: self.diseqccommand("stop") self.isMoving = False self.stopOnLock = False self.updateColors(self.getCurrentConfigPath()) self.statusTimer.start(50, True) def tune(self, transponder): if transponder is not None: self.tuner.tune(transponder)