137 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			137 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #!/usr/bin/env python
 | |
| 
 | |
| import ctypes
 | |
| import glob
 | |
| import os
 | |
| import sys
 | |
| import time
 | |
| 
 | |
| import zmq
 | |
| import zmq.auth
 | |
| 
 | |
| from aman.com import AircraftReport_pb2
 | |
| from aman.com import Communication_pb2
 | |
| from aman.config.Server import Server
 | |
| from threading import Thread, _active
 | |
| 
 | |
| class ReceiverThread(Thread):
 | |
|     def __init__(self, socket, aman):
 | |
|         Thread.__init__(self)
 | |
|         self.Socket = socket
 | |
|         self.AMAN = aman
 | |
| 
 | |
|     def run(self):
 | |
|         while True:
 | |
|             try:
 | |
|                 msg = self.Socket.recv(zmq.NOBLOCK)
 | |
| 
 | |
|                 # parse the received message
 | |
|                 report = Communication_pb2.AircraftUpdate()
 | |
|                 report.ParseFromString(msg)
 | |
| 
 | |
|                 # try to associate the received aircrafts to airports
 | |
|                 for inbound in report.reports:
 | |
|                     self.AMAN.updateAircraftReport(inbound)
 | |
| 
 | |
|             except zmq.ZMQError as error:
 | |
|                 if zmq.EAGAIN == error.errno:
 | |
|                     time.sleep(0.5)
 | |
|                     continue
 | |
|                 else:
 | |
|                     return
 | |
| 
 | |
| # @brief Receives and sends messages to EuroScope plugins
 | |
| class Euroscope:
 | |
|     def __init__(self, configPath : str, config : Server, aman):
 | |
|         self.Context = None
 | |
|         self.ReceiverSocket = None
 | |
|         self.ReceiverThread = None
 | |
|         self.NotificationSocket = None
 | |
|         self.Context = zmq.Context()
 | |
| 
 | |
|         # find the key directories
 | |
|         serverKeyPath = os.path.join(os.path.join(configPath, 'keys'), 'server')
 | |
|         if False == os.path.isdir(serverKeyPath):
 | |
|             sys.stderr.write('No directory for the server key found')
 | |
|             sys.exit(-1)
 | |
|         print('Path to the server key: ' + serverKeyPath)
 | |
| 
 | |
|         clientKeyPath = os.path.join(os.path.join(configPath, 'keys'), 'clients')
 | |
|         if False == os.path.isdir(clientKeyPath):
 | |
|             sys.stderr.write('No directory for the client keys found')
 | |
|             sys.exit(-1)
 | |
|         print('Path to the client keys: ' + clientKeyPath)
 | |
| 
 | |
|         # read the certificates
 | |
|         keyPairPath = glob.glob(os.path.join(serverKeyPath, '*.key_secret'))
 | |
|         if 1 != len(keyPairPath):
 | |
|             sys.stderr.write('No public-private keypair found for the server certificate')
 | |
|             sys.exit(-1)
 | |
|         keyPair = zmq.auth.load_certificate(keyPairPath[0])
 | |
| 
 | |
|         # initialize the receiver
 | |
|         self.ReceiverSocket = zmq.Socket(self.Context, zmq.SUB)
 | |
|         self.ReceiverSocket.setsockopt(zmq.CURVE_PUBLICKEY, keyPair[0])
 | |
|         self.ReceiverSocket.setsockopt(zmq.CURVE_SECRETKEY, keyPair[1])
 | |
|         self.ReceiverSocket.setsockopt(zmq.CURVE_SERVER, True)
 | |
|         self.ReceiverSocket.bind('tcp://' + config.Address + ':' + str(config.PortReceiver))
 | |
|         self.ReceiverSocket.setsockopt(zmq.SUBSCRIBE, b'')
 | |
|         self.ReceiverThread = ReceiverThread(self.ReceiverSocket, aman)
 | |
|         self.ReceiverThread.setDaemon(True)
 | |
|         self.ReceiverThread.start()
 | |
|         print('Listening to tcp://' + config.Address + ':' + str(config.PortReceiver))
 | |
| 
 | |
|         # initialize the notification
 | |
|         self.NotificationSocket = zmq.Socket(self.Context, zmq.PUB)
 | |
|         self.NotificationSocket.setsockopt(zmq.CURVE_PUBLICKEY, keyPair[0])
 | |
|         self.NotificationSocket.setsockopt(zmq.CURVE_SECRETKEY, keyPair[1])
 | |
|         self.NotificationSocket.setsockopt(zmq.CURVE_SERVER, True)
 | |
|         self.NotificationSocket.bind('tcp://' + config.Address + ':' + str(config.PortNotification))
 | |
|         print('Publishing to tcp://' + config.Address + ':' + str(config.PortNotification))
 | |
| 
 | |
|     def sendSequence(self, airport : str, inbounds, weather):
 | |
|         if None == self.NotificationSocket:
 | |
|             return
 | |
| 
 | |
|         sequence = Communication_pb2.AircraftSequence()
 | |
|         sequence.airport = airport
 | |
| 
 | |
|         # convert the wind data
 | |
|         if None != weather.Altitudes:
 | |
|             for i in range(0, len(weather.Altitudes)):
 | |
|                 entry = sequence.windData.add()
 | |
|                 entry.altitude = int(weather.Altitudes[i])
 | |
|                 entry.direction = int(weather.Directions[i])
 | |
|                 entry.speed = int(weather.Windspeeds[i])
 | |
| 
 | |
|         # convert the inbound sequence
 | |
|         for inbound in inbounds:
 | |
|             entry = sequence.sequence.add()
 | |
|             entry.callsign = inbound.Callsign
 | |
|             entry.fixed = inbound.FixedSequence
 | |
|             entry.arrivalRoute = inbound.PlannedStar.Name
 | |
|             entry.arrivalRunway = inbound.PlannedRunway.Name
 | |
| 
 | |
|             #performance = entry.performance.add()
 | |
|             entry.performance.iasAboveFL240 = int(round(inbound.PerformanceData.SpeedAboveFL240))
 | |
|             entry.performance.iasAboveFL100 = int(round(inbound.PerformanceData.SpeedAboveFL100))
 | |
|             entry.performance.iasBelowFL100 = int(round(inbound.PerformanceData.SpeedBelowFL100))
 | |
|             entry.performance.iasApproach = int(round(inbound.PerformanceData.SpeedApproach))
 | |
| 
 | |
|             for waypoint in inbound.PlannedArrivalRoute:
 | |
|                 wp = entry.waypoints.add()
 | |
|                 wp.name = waypoint.Waypoint.Name
 | |
|                 wp.altitude = int(round(waypoint.Altitude))
 | |
|                 wp.indicatedAirspeed = int(round(waypoint.IndicatedAirspeed))
 | |
|                 wp.groundSpeed = int(round(waypoint.GroundSpeed))
 | |
| 
 | |
|                 pta = str(waypoint.PTA)
 | |
|                 delimiter = pta.find('.')
 | |
|                 if -1 == delimiter:
 | |
|                     delimiter = pta.find('+')
 | |
| 
 | |
|                 wp.pta = pta[0:delimiter]
 | |
| 
 | |
|         message = sequence.SerializeToString()
 | |
|         self.NotificationSocket.send(message)
 |