Example #1
0
    def run(self):
        self.setName(self.getThreadPrefix())
        builtInDir = self.getStringParam('builtinDir')
        systemDir = AVNConfig.getDirWithDefault(self.param,
                                                'systemDir',
                                                defaultSub=os.path.join(
                                                    '..', 'plugins'),
                                                belowData=False)
        userDir = AVNConfig.getDirWithDefault(self.param, 'userDir', 'plugins')
        directories = {
            'builtin': {
                'dir': builtInDir,
                'prefix': 'builtin'
            },
            'system': {
                'dir': systemDir,
                'prefix': 'system'
            },
            'user': {
                'dir': userDir,
                'prefix': 'user'
            }
        }

        for basedir in ['builtin', 'system', 'user']:
            dircfg = directories[basedir]
            if not os.path.isdir(dircfg['dir']):
                continue
            for dirname in os.listdir(dircfg['dir']):
                dir = os.path.join(dircfg['dir'], dirname)
                if not os.path.isdir(dir):
                    continue
                module = None
                moduleName = dircfg['prefix'] + "-" + dirname
                try:
                    module = self.loadPluginFromDir(dir, moduleName)
                except:
                    AVNLog.error("error loading plugin from %s:%s", dir,
                                 traceback.format_exc())
                if module is not None:
                    self.pluginDirs[moduleName] = os.path.realpath(dir)
                    self.instantiateHandlersFromModule(moduleName, module)
                else:
                    if os.path.exists(os.path.join(
                            dir, "plugin.js")) or os.path.exists(
                                os.path.join(dir, "plugin.css")):
                        self.pluginDirs[moduleName] = dir
        for name in self.createdPlugins.keys():
            plugin = self.createdPlugins[name]
            AVNLog.info("starting plugin %s", name)
            thread = threading.Thread(target=plugin.run)
            thread.setDaemon(True)
            thread.setName("Plugin: %s" % (name))
            thread.start()
            self.startedThreads[name] = thread

        AVNLog.info("pluginhandler finished")
Example #2
0
 def findAlarm(self, name, useDefault=False):
     definedAlarms = self.param.get('Alarm')
     rt = None
     if definedAlarms is not None:
         for cmd in definedAlarms:
             if cmd.get('name') is not None and cmd.get('name') == name:
                 param = cmd.get('parameter')
                 if param == "":
                     param = None
                 if param is not None:
                     param = AVNUtil.replaceParam(
                         param, AVNConfig.filterBaseParam(self.getParam()))
                 rt = {
                     'command': cmd.get('command'),
                     'autoclean': self.getBoolean(cmd, 'autoclean'),
                     'repeat': self.getInt(cmd, 'repeat'),
                     'parameter': param
                 }
                 break
     if rt is None and useDefault:
         rt = {
             'command': self.getStringParam('defaultCommand'),
             'parameter': self.getStringParam('defaultParameter'),
             'autoclean': True,
             'repeat': 1
         }
     return rt
Example #3
0
 def findAlarm(self,name,useDefault=False):
   definedAlarms=self.param.get('Alarm')
   rt=None
   if definedAlarms is not None:
     for cmd in definedAlarms:
       if cmd.get('name') is not None and cmd.get('name') == name:
         param=cmd.get('parameter')
         if param=="":
           param=None
         if param is not None:
           param=AVNUtil.replaceParam(param,AVNConfig.filterBaseParam(self.getParam()))
         rt= {
           'command':cmd.get('command'),
           'autoclean':self.getBoolean(cmd,'autoclean'),
           'repeat':self.getInt(cmd,'repeat'),
           'parameter':param
         }
         break
   if rt is None and useDefault:
     rt={
       'command':self.getStringParam('defaultCommand'),
       'parameter':self.getStringParam('defaultParameter'),
       'autoclean':True,
       'repeat':1}
   return rt
Example #4
0
 def findCommand(self,name):
   '''
   find a command by its name
   :param name:
   :return:
   '''
   for cmd in self.getConfiguredCommands():
     if cmd.get('name') is not None and cmd.get('name') == name:
       return {'command':AVNUtil.replaceParam(cmd.get('command'),AVNConfig.filterBaseParam(self.getParam())),'repeat':cmd.get('repeat'),'name':cmd.get('name')}
Example #5
0
 def __init__(self, param):
     AVNWorker.__init__(self, param)
     self.track = []
     #param checks
     throw = True
     self.getIntParam('cleanup', throw)
     self.getFloatParam('mindistance', throw)
     self.getFloatParam('interval', throw)
     self.tracklock = threading.Lock()
     self.trackdir = AVNConfig.getDirWithDefault(self.param, "trackdir",
                                                 'tracks')
     self.fname = None
Example #6
0
 def __init__(self, param):
     AVNWorker.__init__(self, param)
     self.importDir = None
     self.lastTimeStamps = {
     }  #a dictionary of timestamps - key is the directory/filename, value the last read timestamp
     self.candidateTimes = {
     }  #dictionary with candidates for conversion - same layout as lastTimeStamps
     self.runningConversions = {
     }  #dictionary of current running conversions (key is the filename/dirname)
     self.waittime = self.getIntParam('waittime', True)
     self.chartbase = None
     self.extensions = self.getStringParam('knownExtensions').split(',')
     self.importDir = AVNConfig.getDirWithDefault(self.param, 'importDir',
                                                  'import')
     self.workDir = AVNConfig.getDirWithDefault(self.param, 'workDir',
                                                'work')
     self.converterDir = self.getStringParam(
         'converterDir')  # the location of the coneverter python
     if self.converterDir is None or self.converterDir == '':
         self.converterDir = os.path.join(
             os.path.dirname(os.path.realpath(__file__)), "../..",
             "chartconvert")
Example #7
0
 def allowDenyWatcher(self):
   """
   checks for the current active LAN to have id_str="wlan-internal"
   and open the firewall in this case using the allowDenyCommand
   @return:
   """
   statusName="FwHandler"
   cmd=self.getStringParam(self.P_FWCOMMAND)
   if cmd is None or cmd == "":
     self.setInfo(statusName, "no  command", AVNWorker.Status.INACTIVE)
     return
   cmdparam=cmd.split(" ")
   command=[]
   for par in cmdparam:
     command.append(AVNUtil.replaceParam(par, AVNConfig.filterBaseParam(self.getParam())))
   self.setInfo(statusName,"running",AVNWorker.Status.NMEA)
   lastNet=None
   lastMode=None
   lastResult=-1
   lastSuccess=AVNUtil.utcnow()
   while True:
     try:
       status=self.getStatus()
       if status.get('wpa_state') is not None and status.get('wpa_state') == 'COMPLETED':
         ssid=status.get('ssid')
         mode="deny"
         if status.get('id_str') is not None and status.get('id_str') == self.PRIVATE_NAME:
           mode="allow"
         waittime=0
         if lastMode == mode and lastNet == ssid:
           if lastResult != 0:
             waittime=self.COMMAND_REPEAT
           else:
             waittime=self.COMMAND_REPEAT_OK
         if (AVNUtil.utcnow() - lastSuccess) >= waittime:
           lastNet=ssid
           lastMode=mode
           AVNLog.info("running command %s %s",command,mode)
           lastResult=AVNUtil.runCommand(command+[mode],statusName+"-command")
           if lastResult != 0:
             if lastResult is None:
               lastResult=-1
             AVNLog.error("%s: unable to run firewall command on %s for mode %s, return %d"%(statusName,ssid,mode,lastResult))
             self.setInfo(statusName,"unable to run firewall command on %s for %s, return %d"%(ssid,mode,lastResult),AVNWorker.Status.ERROR)
           else:
             self.setInfo(statusName, "firewall command on %s for %s ok" % (ssid,mode), AVNWorker.Status.NMEA)
           self.lastFwInfo=FwInfo(ssid,mode,lastResult)
     except:
       AVNLog.error("%s: exception %s"%(statusName,traceback.format_exc()))
     time.sleep(5)
Example #8
0
 def __init__(self,param):
   AVNWorker.__init__(self, param)
   self.track=[]
   #param checks
   throw=True
   self.getIntParam('cleanup', throw)
   self.getFloatParam('mindistance', throw)
   self.getFloatParam('interval', throw)
   self.tracklock=threading.Lock()
   trackdir=self.getStringParam("trackdir")
   if trackdir == "":
     trackdir=unicode(os.path.join(self.getStringParam(AVNConfig.BASEPARAM.DATADIR),'tracks'))
   else:
     trackdir=AVNUtil.replaceParam(os.path.expanduser(trackdir),AVNConfig.filterBaseParam(param))
   self.trackdir=trackdir
   self.fname=None
Example #9
0
 def __init__(self,param):
   AVNWorker.__init__(self, param)
   self.track=[]
   #param checks
   throw=True
   self.getIntParam('cleanup', throw)
   self.getFloatParam('mindistance', throw)
   self.getFloatParam('interval', throw)
   self.tracklock=threading.Lock()
   trackdir=self.getStringParam("trackdir")
   if trackdir == "":
     trackdir=unicode(os.path.join(self.getStringParam(AVNConfig.BASEPARAM.DATADIR),'tracks'))
   else:
     trackdir=AVNUtil.replaceParam(os.path.expanduser(trackdir),AVNConfig.filterBaseParam(param))
   self.trackdir=trackdir
   self.fname=None
Example #10
0
 def __init__(self,param):
   AVNWorker.__init__(self, param)
   self.importDir=None
   self.lastTimeStamps={}    #a dictionary of timestamps - key is the directory/filename, value the last read timestamp
   self.candidateTimes={}    #dictionary with candidates for conversion - same layout as lastTimeStamps
   self.runningConversions={} #dictionary of current running conversions (key is the filename/dirname)
   self.waittime=self.getIntParam('waittime',True)
   self.chartbase=None
   self.extensions=self.getStringParam('knownExtensions').split(',')
   self.importDir=AVNUtil.prependBase(AVNUtil.replaceParam(self.getStringParam('importDir'),AVNConfig.filterBaseParam(self.getParam())),self.getStringParam(AVNConfig.BASEPARAM.DATADIR))
   self.workDir=AVNUtil.prependBase(AVNUtil.replaceParam(self.getStringParam('workDir'),AVNConfig.filterBaseParam(self.getParam())),self.getStringParam(AVNConfig.BASEPARAM.DATADIR))
   self.converterDir=self.getStringParam('converterDir') # the location of the coneverter python
   if self.converterDir is None or self.converterDir=='':
     self.converterDir=os.path.join(os.path.dirname(os.path.realpath(__file__)),"../..","chartconvert")
Example #11
0
 def allowDenyWatcher(self):
     """
 checks for the current active LAN to have id_str="wlan-internal"
 and open the firewall in this case using the allowDenyCommand
 @return:
 """
     statusName = "FwHandler"
     cmd = self.getStringParam(self.P_FWCOMMAND)
     if cmd is None or cmd == "":
         self.setInfo(statusName, "no  command", AVNWorker.Status.INACTIVE)
         return
     cmdparam = cmd.split(" ")
     command = []
     for par in cmdparam:
         command.append(
             AVNUtil.replaceParam(
                 par, AVNConfig.filterBaseParam(self.getParam())))
     self.setInfo(statusName, "running", AVNWorker.Status.NMEA)
     lastNet = None
     lastMode = None
     lastResult = -1
     lastSuccess = AVNUtil.utcnow()
     while True:
         try:
             status = self.getStatus()
             if status.get('wpa_state') is not None and status.get(
                     'wpa_state') == 'COMPLETED':
                 ssid = status.get('ssid')
                 mode = "deny"
                 if status.get('id_str') is not None and status.get(
                         'id_str') == self.PRIVATE_NAME:
                     mode = "allow"
                 waittime = 0
                 if lastMode == mode and lastNet == ssid:
                     if lastResult != 0:
                         waittime = self.COMMAND_REPEAT
                     else:
                         waittime = self.COMMAND_REPEAT_OK
                 if (AVNUtil.utcnow() - lastSuccess) >= waittime:
                     lastNet = ssid
                     lastMode = mode
                     AVNLog.info("running command %s %s", command, mode)
                     lastResult = AVNUtil.runCommand(
                         command + [mode], statusName + "-command")
                     if lastResult != 0:
                         if lastResult is None:
                             lastResult = -1
                         AVNLog.error(
                             "%s: unable to run firewall command on %s for mode %s, return %d"
                             % (statusName, ssid, mode, lastResult))
                         self.setInfo(
                             statusName,
                             "unable to run firewall command on %s for %s, return %d"
                             % (ssid, mode, lastResult),
                             AVNWorker.Status.ERROR)
                     else:
                         self.setInfo(
                             statusName,
                             "firewall command on %s for %s ok" %
                             (ssid, mode), AVNWorker.Status.NMEA)
                         lastSuccess = AVNUtil.utcnow()
                     self.lastFwInfo = FwInfo(ssid, mode, lastResult)
         except:
             AVNLog.error("%s: exception %s" %
                          (statusName, traceback.format_exc()))
         time.sleep(5)
Example #12
0
 def run(self):
     self.setName("[%s]%s" % (AVNLog.getThreadId(), self.getName()))
     interval = self.getIntParam('interval')
     routesdir = AVNUtil.replaceParam(
         os.path.expanduser(self.getStringParam("routesdir")),
         AVNConfig.filterBaseParam(self.getParam()))
     if routesdir == "":
         routesdir = os.path.join(
             self.getStringParam(AVNConfig.BASEPARAM.DATADIR), u'routes')
     self.routesdir = routesdir
     if not os.path.isdir(self.routesdir):
         AVNLog.info("creating routes directory %s" % (self.routesdir))
         os.makedirs(self.routesdir, 0755)
     self.fillRouteInfos()
     self.currentLegFileName = os.path.join(self.routesdir,
                                            self.currentLegName)
     if os.path.exists(self.currentLegFileName):
         f = None
         try:
             f = open(self.currentLegFileName, "r")
             strleg = f.read(self.MAXROUTESIZE + 1000)
             self.currentLeg = self.parseLeg(strleg)
             if self.currentLeg.toWP is not None:
                 distance = geo.length(
                     [self.currentLeg.fromWP, self.currentLeg.toWP])
                 AVNLog.info(
                     "read current leg, route=%s, from=%s, to=%s, length=%fNM"
                     %
                     (self.currentLeg.name, unicode(self.currentLeg.fromWP),
                      unicode(self.currentLeg.toWP), distance / AVNUtil.NM))
             else:
                 AVNLog.info("read current leg, route=%s, from=%s, to=%s" %
                             (
                                 self.currentLeg.name,
                                 unicode(self.currentLeg.fromWP),
                                 "NONE",
                             ))
             if self.currentLeg.name is not None:
                 self.activeRouteName = self.currentLeg.name
             if self.currentLeg.currentRoute is not None:
                 #this will also set the active route
                 self.saveRoute(self.currentLeg.currentRoute)
                 if self.currentLeg.name != self.currentLeg.currentRoute.name:
                     AVNLog.error(
                         "leg inconsistent, name in route %s different from name in leg %s, correcting to route name",
                         self.currentLeg.name,
                         self.currentLeg.currentRoute.name)
                     self.currentLeg.name = self.currentLeg.currentRoute.name
                     self.activeRouteName = self.currentLeg.name
                     #write back the corrected leg
                     self.setCurrentLeg(self.currentLeg)
             else:
                 if self.currentLeg.name is not None:
                     self.activeRoute = self.loadRoute(self.currentLeg.name)
                     if self.activeRoute is None:
                         self.activeRoute = gpx.GPXRoute(
                             self.currentLeg.name)
                     self.currentLeg.currentRoute = self.activeRoute
         except:
             AVNLog.error("error parsing current leg %s: %s" %
                          (self.currentLegFileName, traceback.format_exc()))
         if f is not None:
             f.close()
         #TODO: open route
     else:
         AVNLog.info("no current leg %s found" %
                     (self.currentLegFileName, ))
     AVNLog.info("router main loop started")
     while True:
         hasLeg = False
         hasRMB = False
         time.sleep(interval)
         if self.currentLeg and self.currentLeg.active:
             hasLeg = True
             if self.currentLeg.anchorDistance is not None:
                 routerInfo = "Anchor watch, from %s, (anchor radius %dm)" % (
                     unicode(self.currentLeg.fromWP),
                     int(self.currentLeg.anchorDistance))
             else:
                 routerInfo = "from %s, to %s, route=%s, activeWp=%d, approach=%s (approach radius %dm)" % (
                     unicode(self.currentLeg.fromWP)
                     if self.currentLeg.fromWP else "NONE",
                     unicode(self.currentLeg.toWP) if self.currentLeg.toWP
                     else "NONE", self.currentLeg.name
                     if self.currentLeg.name is not None else "NONE",
                     self.currentLeg.currentTarget,
                     "TRUE" if self.currentLeg.approach else "FALSE",
                     int(self.currentLeg.approachDistance))
             AVNLog.debug(routerInfo)
             self.setInfo("leg", routerInfo, AVNWorker.Status.RUNNING)
         try:
             if self.currentLeg is not None and self.currentLeg.anchorDistance is not None:
                 self.computeAnchor()
             else:
                 self.startStopAlarm(False, 'anchor')
                 self.startStopAlarm(False, 'gps')
                 computeRMB = self.getBoolParam("computeRMB")
                 computeAPB = self.getBoolParam("computeAPB")
                 if computeRMB or computeAPB:
                     hasRMB = self.computeRMB(computeRMB, computeAPB)
         except Exception as e:
             AVNLog.warn("exception in computeRMB %s, retrying",
                         traceback.format_exc())
         try:
             self.computeApproach()
         except:
             AVNLog.warn("exception in computeApproach %s, retrying",
                         traceback.format_exc())
         if (not hasLeg):
             self.setInfo("leg", "no leg", AVNWorker.Status.INACTIVE)
         if (not hasRMB):
             self.setInfo("autopilot", "no autopilot data",
                          AVNWorker.Status.INACTIVE)
         try:
             curTPV = self.navdata.getMergedEntries("TPV", [])
             lat = curTPV.data.get('lat')
             lon = curTPV.data.get('lon')
             if lat is not None and lon is not None:
                 self.startStopAlarm(False, 'gps')
         except:
             pass
         AVNLog.debug("router main loop")
Example #13
0
 def getUserDir(self):
     return AVNConfig.getDirWithDefault(self.param, 'userDir', 'layout')
Example #14
0
 def run(self):
   self.setName("[%s]%s"%(AVNLog.getThreadId(),self.getName()))
   interval=self.getIntParam('interval')
   routesdir=AVNUtil.replaceParam(os.path.expanduser(self.getStringParam("routesdir")),AVNConfig.filterBaseParam(self.getParam()))
   if routesdir == "":
     routesdir=os.path.join(self.getStringParam(AVNConfig.BASEPARAM.DATADIR),u'routes')
   self.routesdir=routesdir
   if not os.path.isdir(self.routesdir):
     AVNLog.info("creating routes directory %s"%(self.routesdir))
     os.makedirs(self.routesdir,0755)
   self.fillRouteInfos()
   self.currentLegFileName=os.path.join(self.routesdir,self.currentLegName)
   if os.path.exists(self.currentLegFileName):
     f=None
     try:
       f=open(self.currentLegFileName,"r")
       strleg=f.read(self.MAXROUTESIZE+1000)
       self.currentLeg=self.parseLeg(strleg)
       if self.currentLeg.toWP is not None:
         distance=geo.length([self.currentLeg.fromWP,self.currentLeg.toWP])
         AVNLog.info("read current leg, route=%s, from=%s, to=%s, length=%fNM"%(self.currentLeg.name,
                                                                 unicode(self.currentLeg.fromWP),unicode(self.currentLeg.toWP),distance/AVNUtil.NM))
       else:
         AVNLog.info("read current leg, route=%s, from=%s, to=%s"% (self.currentLeg.name,
                                                                                  unicode(self.currentLeg.fromWP),
                                                                                  "NONE",
                                                                                  ))
       if self.currentLeg.name is not None:
         self.activeRouteName=self.currentLeg.name
       if self.currentLeg.currentRoute is not None:
         #this will also set the active route
         self.saveRoute(self.currentLeg.currentRoute)
         if self.currentLeg.name != self.currentLeg.currentRoute.name:
           AVNLog.error("leg inconsistent, name in route %s different from name in leg %s, correcting to route name",self.currentLeg.name,
                        self.currentLeg.currentRoute.name)
           self.currentLeg.name=self.currentLeg.currentRoute.name
           self.activeRouteName=self.currentLeg.name
           #write back the corrected leg
           self.setCurrentLeg(self.currentLeg)
       else:
         if self.currentLeg.name is not None:
           self.activeRoute=self.loadRoute(self.currentLeg.name)
           if self.activeRoute is None:
             self.activeRoute=gpx.GPXRoute(self.currentLeg.name)
           self.currentLeg.currentRoute=self.activeRoute
     except:
       AVNLog.error("error parsing current leg %s: %s"%(self.currentLegFileName,traceback.format_exc()))
     if f is not None:
       f.close()
     #TODO: open route
   else:
     AVNLog.info("no current leg %s found"%(self.currentLegFileName,))
   AVNLog.info("router main loop started")
   while True:
     hasLeg=False
     hasRMB=False
     time.sleep(interval)
     if self.currentLeg and self.currentLeg.active:
       hasLeg=True
       if self.currentLeg.anchorDistance is not None:
         routerInfo = "Anchor watch, from %s, (anchor radius %dm)" % (
         unicode(self.currentLeg.fromWP),
          int(self.currentLeg.anchorDistance))
       else:
         routerInfo="from %s, to %s, route=%s, activeWp=%d, approach=%s (approach radius %dm)"%(unicode(self.currentLeg.fromWP)
                  if self.currentLeg.fromWP else "NONE",unicode(self.currentLeg.toWP) if self.currentLeg.toWP else "NONE",
                  self.currentLeg.name if self.currentLeg.name is not None else "NONE", self.currentLeg.currentTarget,
                  "TRUE" if self.currentLeg.approach else "FALSE",int(self.currentLeg.approachDistance))
       AVNLog.debug(routerInfo)
       self.setInfo("leg",routerInfo
                 ,AVNWorker.Status.RUNNING)
     try:
       if self.currentLeg is not None and self.currentLeg.anchorDistance is not None:
         self.computeAnchor()
       else:
         self.startStopAlarm(False,'anchor')
         self.startStopAlarm(False, 'gps')
         computeRMB=self.getBoolParam("computeRMB")
         computeAPB=self.getBoolParam("computeAPB")
         if computeRMB or computeAPB :
           hasRMB=self.computeRMB(computeRMB,computeAPB)
     except Exception as e:
       AVNLog.warn("exception in computeRMB %s, retrying",traceback.format_exc())
     try:
       self.computeApproach()
     except:
       AVNLog.warn("exception in computeApproach %s, retrying",traceback.format_exc())
     if (not hasLeg):
       self.setInfo("leg","no leg",AVNWorker.Status.INACTIVE)
     if (not hasRMB):
       self.setInfo("autopilot","no autopilot data",AVNWorker.Status.INACTIVE)
     try:
       curTPV = self.navdata.getMergedEntries("TPV", [])
       lat = curTPV.data.get('lat')
       lon = curTPV.data.get('lon')
       if lat is not None and lon is not None:
         self.startStopAlarm(False,'gps')
     except:
       pass
     AVNLog.debug("router main loop")
Example #15
0
  def run(self):
    self.setName(self.getThreadPrefix())
    trackdir=AVNConfig.getDirWithDefault(self.param,"trackdir")
    filterstr=self.getStringParam("filter")
    if filterstr is None or filterstr == "":
      AVNLog.warn("no filter for NMEA logger, exiting logger")
      return
    feeder=self.findFeeder(self.getStringParam('feederName'))
    if feeder is None:
      raise Exception("%s: cannot find a suitable feeder (name %s)",self.getName(),self.getStringParam("feederName") or "")
    self.feeder=feeder
    nmeaFilter=filterstr.split(",")
    if trackdir is None:
      trackwriter=self.findHandlerByName(AVNTrackWriter.getConfigName())
      if trackwriter is not None:
        trackdir=trackwriter.getTrackDir()
      if trackdir is None or not trackdir :
        #2nd try with a default
        trackdir = AVNConfig.getDirWithDefault(self.param, "trackdir","tracks")
    self.trackdir=trackdir
    interval=self.getIntParam('interval')
    maxfiles=100
    try:
      mf=self.getIntParam('maxfiles')
      if mf > 0:
        maxfiles=mf
    except:
      pass
    self.maxfiles=maxfiles
    AVNLog.info("starting logger with maxfiles = %d, filter=%s, interval=%ds",maxfiles,filterstr,interval)
    fname=None
    f=None
    lastcleanup=None
    seq=0
    last={}
    initial=True
    while True:
      currentTime=datetime.datetime.utcnow()
      try:
        newFile=False
        if not os.path.isdir(self.trackdir):
          os.makedirs(self.trackdir, 0775)
        curfname=os.path.join(self.trackdir,self.createFileName(currentTime))
        #we have to consider time shift backward
        if lastcleanup is None or (currentTime > lastcleanup+datetime.timedelta(seconds=60)) or (currentTime < lastcleanup-datetime.timedelta(seconds=5)):
          self.cleanup(curfname)
          lastcleanup=currentTime
          #force reopen file
          fname=None
        if not curfname == fname:
          if fname is not None or initial:
            AVNLog.info("new nmea logfile %s",curfname)
          initial=False
          fname=curfname
          if not f is None:
            f.close()
          newFile=True
          last={}
        if newFile:
          zfname=curfname+".gz"
          f=open(curfname,"a")
          if os.path.isfile(zfname):
            #we must uncompress first
            AVNLog.info("decompressing existing nmea log %s",zfname)
            try:
              zf=gzip.open(zfname,"rb")
              while True:
                buf=zf.read(100000)
                if buf is None or len(buf) == 0:
                  break
                f.write(buf)
              zf.close()
            except:
              AVNLog.error("unable to read old compressed log %s: %s",zfname,traceback.format_exc())
            try:
              os.unlink(zfname)
            except:
              pass
          newFile=False
          self.setInfo('main', "writing to %s"%(curfname,), AVNWorker.Status.NMEA)
        seq,data=self.feeder.fetchFromHistory(seq,10,nmeafilter=nmeaFilter)
        if len(data)>0:
          for line in data:

            now=datetime.datetime.utcnow()
            key=line[0:6]
            prev=last.get(key)
            if prev is not None:
              diff=now-prev
              if diff.seconds < interval:
                continue
            last[key]=now
            self.writeLine(f,line)
      except Exception as e:
        AVNLog.error("exception in nmea logger: %s",traceback.format_exc());
        time.sleep(1)