def timeChanged(self): AVNLog.info("%s: time changed, re-register", self.getName()) try: self._deregisterAll() except: pass self.stateSequence += 1
def writeFileFromInput(self, outname, rlen, overwrite=False, stream=None): if os.path.exists(outname) and not overwrite: raise Exception("file %s already exists" % outname) writename = outname + ".tmp" AVNLog.info("start upload of file %s", outname) fh = open(writename, "wb") if fh is None: raise Exception("unable to write to %s" % outname) if stream is None: stream = self.rfile bToRead = int(rlen) bufSize = 1000000 try: while bToRead > 0: buf = stream.read(bufSize if bToRead >= bufSize else bToRead) if len(buf) == 0 or buf is None: raise Exception("no more data received") bToRead -= len(buf) fh.write(buf) fh.close() if os.path.exists(outname): os.unlink(outname) os.rename(writename, outname) except: try: os.unlink(writename) except: pass raise
def createOverview(self): zoomlevels = [] zoomLevelBoundings = {} connection = sqlite3.connect(self.filename) if connection is None: raise Exception("unable to open mbtiles file %s" % (self.filename)) AVNLog.info("opening mbtiles file %s", self.filename) cu = None hasAvnavScheme = False try: cu = connection.cursor() for sr in cu.execute("select value from metadata where name=?", ["avnav_scheme"]): v = sr[0] if v is not None: v = v.lower() if v in ['tms', 'xyz']: AVNLog.info("setting scheme for %s to %s", self.filename, v) self.schemeTMS = False if v == "xyz" else True self.schemeInconsistent = False hasAvnavScheme = True #check if there is a schema entry for sr in cu.execute("select value from metadata where name=?", ["scheme"]): v = sr[0] if v is not None: v = v.lower() self.originalScheme = v if not hasAvnavScheme: self.schemeInconsistent = True for zl in cu.execute("select distinct zoom_level from tiles;"): zoomlevels.append(zl[0]) for zl in zoomlevels: el = {} for rowmima in cu.execute( "select min(tile_row),max(tile_row) from tiles where zoom_level=?", [zl]): # names must match getGemfInfo in create_overview if self.schemeTMS: el['ymin'] = self.rowToY(zl, rowmima[1]) el['ymax'] = self.rowToY(zl, rowmima[0]) else: el['ymin'] = self.rowToY(zl, rowmima[0]) el['ymax'] = self.rowToY(zl, rowmima[1]) for colmima in cu.execute( "select min(tile_column),max(tile_column) from tiles where zoom_level=?", [zl]): el['xmin'] = self.colToX(zl, colmima[0]) el['xmax'] = self.colToX(zl, colmima[1]) zoomLevelBoundings[zl] = el except Exception as e: AVNLog.error("error reading base info from %s:%s", self.filename, str(e)) self.zoomlevels = zoomlevels self.zoomLevelBoundings = zoomLevelBoundings if cu is not None: cu.close() connection.close() self.changeCount = AVNUtil.utcnow()
def _newService(self, interface, protocol, name, stype, domain, flags): AVNLog.info("detected new service %s.%s at %i.%i", stype, name, interface, protocol) try: self.foundServices.add( FoundService(stype, name, interface, protocol)) except Exception as e: AVNLog.error("unable to add service: %s", e)
def registerHandler(handler): """add a handler class""" if not issubclass(handler, worker.AVNWorker): raise TypeError("handler is not of type AVNWorker") name = handler.getConfigName() if handlerList.get(name) is not None: return logger.info("register handler %s", name) handlerList[name] = handler
def setInfo(self,name,info,status,childId=None,canDelete=False,timeout=None): existing=self.status.get(name) if existing: if existing.update(status,info,timeout=timeout): AVNLog.info("%s",str(existing)) return True else: ns=WorkerStatus(name,status,info,childId=childId,canDelete=canDelete,timeout=timeout) self.status[name]=ns AVNLog.info("%s",str(ns))
def _runInternal(self): self.usedResources=[] AVNLog.info("run started") try: self.run() self.setInfo('main','handler stopped',WorkerStatus.INACTIVE) except Exception as e: self.setInfo('main','handler stopped with %s'%str(e),WorkerStatus.ERROR) AVNLog.error("handler run stopped with exception %s",traceback.format_exc()) self.usedResources=[] self.currentThread=None
def startStopAlarm(self, start, name=ALARMS.waypoint): alert = self.findHandlerByName("AVNAlarmHandler") if alert is None: return if start: if self.activatedAlarms.get(name) is None: AVNLog.info("starting alarm %s", name) self.activatedAlarms[name] = True alert.startAlarm(name) else: if self.activatedAlarms.get(name) is not None: AVNLog.info("stopping alarm %s", name) del self.activatedAlarms[name] alert.stopAlarm(name)
def _deregister(self, description: ServiceDescription) -> object: if description.group is None: description.reset() return try: AVNLog.info("deregister") description.reset() description.group.Reset() description.group.Free() description.group = None self.deleteInfo(description.getKey()) except Exception as e: AVNLog.error("unable to deregister: %s", str(e)) self.setInfo(description.getKey(), "error in deregister %s" % str(e), WorkerStatus.ERROR)
def getAvnavXml(self,upzoom=2): if not self.isOpen: return None try: data = self.getSources() options = {} options['upzoom'] = upzoom rt = create_overview.getGemfInfo(data, options) AVNLog.info("created GEMF overview for %s", self.filename) AVNLog.debug("overview for %s:%s", self.filename, rt) return rt except: AVNLog.error("error while trying to get the overview data for %s %s", self.filename, traceback.format_exc()) return None
def startInstance(self,navdata): """ @type navdata: AVNStore """ self.navdata=navdata self.feeder = self.findFeeder(self.getStringParam('feederName')) try: self.checkConfig(self.param) except Exception as e: self.setInfo('main','%s'%str(e),WorkerStatus.ERROR) raise if not self.isDisabled(): self.startThread() else: self.setInfo('main','disabled',WorkerStatus.INACTIVE) AVNLog.info("not starting %s (disabled) with config %s", self.getName(), self.getConfigString())
def setCurrentLeg(self, leg): # type: (AVNRoutingLeg) -> object changed = self.currentLeg == None or not self.currentLeg.equal(leg) if changed: self.navdata.updateChangeCounter(self.LEG_CHANGE_KEY) self.currentLeg = leg if leg is None: if os.path.exists(self.currentLegFileName): os.unlink(self.currentLegFileName) AVNLog.info("current leg removed") return AVNLog.info("new leg %s", str(leg)) f = open(self.currentLegFileName, "w", encoding='utf-8') try: f.write(json.dumps(leg.getJson())) except: f.close() raise f.close() if not leg.isActive(): self.computeApproach( ) #ensure that we immediately switch off alarms
def onPreRun(self): self.currentLegFileName = os.path.join(self.baseDir, self.currentLegName) if os.path.exists(self.currentLegFileName): f = None try: f = open(self.currentLegFileName, "r", encoding='utf-8') strleg = f.read(self.MAXROUTESIZE + 1000) self.currentLeg = AVNRoutingLeg(json.loads(strleg)) if self.currentLeg.getTo() is not None: distance = AVNUtil.distanceM( self.wpToLatLon(self.currentLeg.getFrom()), self.wpToLatLon(self.currentLeg.getTo())) AVNLog.info( "read current leg, route=%s, from=%s, to=%s, length=%fNM" % (self.currentLeg.getRouteName(), str(self.currentLeg.getFrom()), str(self.currentLeg.getTo()), distance / AVNUtil.NM)) else: AVNLog.info("read current leg, route=%s, from=%s, to=%s" % ( self.currentLeg.getRouteName(), str(self.currentLeg.getFrom()), "NONE", )) self.setCurrentLeg(self.currentLeg) except: AVNLog.error("error parsing current leg %s: %s" % (self.currentLegFileName, traceback.format_exc())) if f is not None: f.close() else: AVNLog.info("no current leg %s found" % (self.currentLegFileName, )) self.setCurrentLeg(AVNRoutingLeg({})) AVNLog.info("router main loop started")
def updateConfig(self,param,child=None): ''' change of config parameters the handler must update its data and store the values using changeMultiConfig, changeChildConfig @param param: a dictonary with the keyes matching the keys from getEditableParameters @type param: dict @param child: a child id or None @return: ''' if child is not None: raise Exception("cannot modify child %s"%str(child)) checked = WorkerParameter.checkValuesFor(self.getEditableParameters(id=self.id), param, self.getParam()) newEnable = None if 'enabled' in checked: newEnable=checked.get('enabled',True) if type(newEnable) is str: newEnable=newEnable.upper() != 'FALSE' if newEnable == True or not self.isDisabled(): checkConfig=self.param.copy() checkConfig.update(checked) self.checkConfig(checkConfig) rt = self.changeMultiConfig(checked) if self.canDisable() or self.canDeleteHandler(): if 'enabled' in checked: if newEnable != self.isDisabled(): if not newEnable: AVNLog.info("handler disabled, stopping") self.stop() else: AVNLog.info("handler enabled, starting") self.startThread() if self.ENABLE_PARAM_DESCRIPTION.fromDict(self.param,True) and self.currentThread is None: #was not running - start now AVNLog.info("handler was stopped, starting now") self.startThread() return rt
def run(self): sequence = self.stateSequence if not hasDbus: raise Exception("no DBUS found, cannot register avahi") httpServer = self.findHandlerByName('AVNHttpServer') if httpServer is None: raise Exception("unable to find AVNHTTPServer") self.setInfo('main', 'starting', WorkerStatus.STARTED) self.loop = None try: self.loop = GLib.MainLoop() loopThread = threading.Thread(target=self.loop.run, daemon=True, name="AVNAvahi DBUS loop") loopThread.start() bus = dbus.SystemBus() bus.add_signal_receiver( self._newService, dbus_interface=self.DBUS_INTERFACE_SERVICE_BROWSER, signal_name="ItemNew") bus.add_signal_receiver( self._removedService, dbus_interface=self.DBUS_INTERFACE_SERVICE_BROWSER, signal_name="ItemRemove") bus.add_signal_receiver(self._serverStateChange, dbus_interface=self.DBUS_INTERFACE_SERVER, signal_name="StateChanged") self.setInfo('main', 'get avahi interface', WorkerStatus.INACTIVE) self.server = None while self.server is None and not self.shouldStop(): try: self.server = dbus.Interface( bus.get_object(self.DBUS_NAME, self.DBUS_PATH_SERVER), self.DBUS_INTERFACE_SERVER) #self.server.connect_to_signal("StateChanged",self._serverStateChange) self._startServiceBrowser() except Exception as e: self.setInfo('main', 'unable to get avahi interface %s' % str(e), WorkerStatus.ERROR) self.wait(3000) hasError = False while not self.shouldStop(): if self.stateSequence != sequence: sequence = self.stateSequence AVNLog.info("daemon restart detected") self.server = dbus.Interface( dbus.SystemBus().get_object(self.DBUS_NAME, self.DBUS_PATH_SERVER), self.DBUS_INTERFACE_SERVER) self._deregisterAll() self._startServiceBrowser() #compute the entry for the web service webService = ServiceDescription( self.type, self.getParamValue('serviceName'), httpServer.server_port) existing = self.services.get(-1) if not webService.equal(existing): if existing is not None: existing.update(webService) else: self.services[-1] = webService if not hasError: self.setInfo('main', 'running', WorkerStatus.NMEA) for key, description in list(self.services.items()): if not description.isRegistered: try: self._publish(description) except Exception as e: self.setInfo(description.getKey(), "error: " + str(e), WorkerStatus.ERROR) description.isRegistered = False if description.name is None or description.name == '': self.lock.acquire() try: del self.services[key] finally: self.lock.release() self.wait(1) except Exception as e: self._stopLoop() self._deregisterAll() raise self._stopLoop() self._deregisterAll()
def startThread(self): AVNLog.info("starting %s with config %s", self.getName(), self.getConfigString()) self.currentThread = threading.Thread(target=self._runInternal, name=self.name or '') self.currentThread.setDaemon(True) self.currentThread.start()
def _serverStateChange(self, newState, p): AVNLog.info("Avahi server state change %s", str(newState)) if newState == self.SERVER_RUNNING: self.stateSequence += 1
def _publish(self, description: ServiceDescription) -> object: if description.group is not None: try: description.group.Reset() except: pass try: description.group.Free() except: pass try: description.group = None if description.oldKey is not None: self.deleteInfo(description.oldKey) else: self.deleteInfo(description.getKey()) except: pass if description.name is None or description.name == '': return False description.group = dbus.Interface( dbus.SystemBus().get_object(self.DBUS_NAME, self.server.EntryGroupNew()), self.DBUS_INTERFACE_ENTRY_GROUP) timeout = self.getFloatParam('timeout') retries = self.getIntParam('maxRetries') num = 0 retry = True self.setInfo(description.getKey(), "trying to register", WorkerStatus.STARTED) while retry: retry = False AVNLog.info("trying to register %s for %s", description.currentName, str(self.port)) try: description.group.AddService(self.IF_UNSPEC, self.PROTO_INET, dbus.UInt32(0), description.currentName, description.type, self.server.GetDomainName(), self.server.GetHostNameFqdn(), description.port, '') description.group.Commit() except Exception as e: AVNLog.warn("unable to register avahi service %s, error: %s", description.currentName, str(e)) if description.retry(retries): retry = True continue waitTime = timeout * 10 state = description.group.GetState() while state in [ self.ENTRY_GROUP_REGISTERING, self.ENTRY_GROUP_UNCOMMITED ] and waitTime > 0: waitTime -= 1 time.sleep(0.1) state = description.group.GetState() if state == self.ENTRY_GROUP_COLLISION: if not description.retry(retries): AVNLog.error("max retries reached for %s", description.name) else: retry = True continue if state != self.ENTRY_GROUP_ESTABLISHED: try: description.group.Reset() except: pass description.group = None self.setInfo( description.getKey(), "unable to register service, state=%s" % str(state), WorkerStatus.ERROR) return False description.isRegistered = True self.setInfo(description.getKey(), "registered", WorkerStatus.NMEA) self.hostname = self.server.GetHostNameFqdn() return True self.setInfo(description.getKey(), "unable to register service after retries", WorkerStatus.ERROR) return False
def _removedService(self, interface, protocol, name, stype, domain, flags): AVNLog.info("detected removed service %s.%s at %i.%i", stype, name, interface, protocol) self.foundServices.remove( FoundService(stype, name, interface, protocol))
def computeApproach(self): if self.currentLeg is None: AVNLog.debug("currentLeg is None") self.startStopAlarm(False, self.ALARMS.waypoint) self.startStopAlarm(False, self.ALARMS.mob) return if not self.currentLeg.isActive(): AVNLog.debug("currentLeg inactive") self.startStopAlarm(False, self.ALARMS.waypoint) self.startStopAlarm(False, self.ALARMS.mob) return if self.currentLeg.isMob(): AVNLog.debug("currentLeg MOB") self.startStopAlarm(False, self.ALARMS.waypoint) if self.activatedAlarms.get(self.ALARMS.mob) is None: self.startStopAlarm(True, self.ALARMS.mob) return self.startStopAlarm(False, self.ALARMS.mob) curGps = self.navdata.getDataByPrefix(AVNStore.BASE_KEY_GPS, 1) lat = curGps.get('lat') lon = curGps.get('lon') if lat is None or lon is None: self.startStopAlarm(False, self.ALARMS.waypoint) return currentLocation = (lat, lon) dst = AVNUtil.distanceM(currentLocation, self.wpToLatLon(self.currentLeg.getTo())) AVNLog.debug("approach current distance=%f", float(dst)) if (dst > self.currentLeg.getApproachDistance()): old = self.currentLeg.isApproach() self.currentLeg.setApproach(False) self.startStopAlarm(False, self.ALARMS.waypoint) if old: #save leg self.setCurrentLeg(self.currentLeg) self.lastDistanceToCurrent = None self.lastDistanceToNext = None return if self.activatedAlarms.get(self.ALARMS.waypoint) is None: self.startStopAlarm(True, self.ALARMS.waypoint) if not self.currentLeg.isApproach(): self.currentLeg.setApproach(True) #save the leg self.setCurrentLeg(self.currentLeg) AVNLog.info("Route: approaching wp %d (%s) currentDistance=%f", self.currentLeg.currentTarget, str(self.currentLeg.toWP), float(dst)) route = self.currentLeg.getCurrentRoute() if route is None or route.get('points') is None: AVNLog.debug("Approach: no route active") #TODO: stop routing? return currentTarget = self.currentLeg.getCurrentTarget() hasNextWp = True nextWpNum = 0 if currentTarget is None: hasNextWp = False else: nextWpNum = currentTarget + 1 nextDistance = 0 if nextWpNum >= len(route['points']): AVNLog.debug("already at last WP of route %d", (nextWpNum - 1)) hasNextWp = False if hasNextWp: nextWp = route['points'][nextWpNum] nextDistance = AVNUtil.distanceM(currentLocation, self.wpToLatLon(nextWp)) if self.lastDistanceToNext is None or self.lastDistanceToNext is None: #first time in approach self.lastDistanceToNext = nextDistance self.lastDistanceToCurrent = dst return #check if the distance to own wp increases and to the next decreases diffcurrent = dst - self.lastDistanceToCurrent if (diffcurrent <= 0): #still decreasing self.lastDistanceToCurrent = dst self.lastDistanceToNext = nextDistance return diffnext = nextDistance - self.lastDistanceToNext if (diffnext > 0): #increases to next self.lastDistanceToCurrent = dst self.lastDistanceToNext = nextDistance return else: AVNLog.info("last WP of route reached, switch of routing") self.currentLeg.setActive(False) self.setCurrentLeg(self.currentLeg) self.lastDistanceToCurrent = None self.lastDistanceToNext = None return #should we wait for some time??? AVNLog.info("switching to next WP num=%d, wp=%s", nextWpNum, str(nextWp)) self.currentLeg.setNewLeg(nextWpNum, self.currentLeg.getTo(), nextWp) self.lastDistanceToCurrent = None self.lastDistanceToNext = None self.setCurrentLeg(self.currentLeg)