import datetime import os import sys import threading sys.path.append('../') # NOQA: E402 from protos import aerial_pb2 as pb from flask import Flask, request import pika class MyServer(Flask): def __init__(self, *args, **kwargs): Flask.__init__(self, *args, **kwargs) self.message_received: int = 0 self._def_routes() self.devices = {} self.route('/api', methods=['POST'])(self.api) self.route('/', methods=['GET'])(self.hello) def init_rabbmitmq(self, host: str, user: str, password: str, queue: str): credentials = pika.PlainCredentials(user, password) parameters = pika.ConnectionParameters( credentials=credentials, host=host) connection = pika.BlockingConnection(parameters) self.channel = connection.channel() self.channel.queue_declare(queue=queue, durable=True) self.channel.basic_qos(prefetch_count=1) self.channel.basic_consume( on_message_callback=self._on_request, queue=queue) def _def_routes(self): self.routes = { pb.SysCommand.SYS_COMMAND: self._on_sys_command, pb.SysCommand.SENSOR_COMMAND: self._on_sensor_command, pb.SysCommand.FIVE_G_COMMAND: self._on_five_g_command, pb.SysCommand.MICRO_WAVE_COMMAND: self._on_micro_wave_command, } def _get_device(self, device_id: str): device = self.devices.get(device_id, None) if device is None: start = datetime.datetime.now() if not os.path.exists('./Images'): os.mkdir('./Images') path = f"./Images/{device_id}-{start.strftime('%Y-%m-%d-%H-%M-%S')}" if not os.path.exists(path): os.mkdir(path) device = dict(power_on=True, srart=start, path=path, images=0, micro_wave=0) self.devices[device_id] = device return device def _on_sys_command(self, req: pb.RequestCommand, resp: pb.ResponseCommand): if pb.SubCommand.POWER_ON_SUB_COMMAND == req.sub_command: print('power on message received') self._get_device(req.device_id) elif pb.SubCommand.POWER_OFF_SUB_COMMAND == req.sub_command: device = self.devices[req.device_id] device['power_on'] = False print('power off message received') return def _on_sensor_command(self, req: pb.RequestCommand, resp: pb.ResponseCommand): print('sensor command') def _write_image(self, device: dict, idx: int, image: bytes): if (image is None) | (len(image) == 0): return filename = f'{device["path"]}/{idx}-{device["images"]}.jpg' with open(filename, 'wb') as f: f.write(image) def _on_five_g_command(self, req: pb.RequestCommand, resp: pb.ResponseCommand): # print('five g command') if pb.SubCommand.FIVE_G_SEND_IMAGE_SUB_COMMAND == req.sub_command: print( f'send image sub command received, length={req.data1.length}') if req.data1.length > 0: device = self._get_device(req.device_id) img_msg = pb.ImagesMessage() img_msg.ParseFromString(req.data1.data) # print(img_msg.image1) count = device["images"] self._write_image(device, 1, img_msg.image1) self._write_image(device, 2, img_msg.image2) self._write_image(device, 3, img_msg.image3) self._write_image(device, 4, img_msg.image4) self._write_image(device, 5, img_msg.image5) device['images'] += 1 def _on_micro_wave_command(self, req: pb.RequestCommand, resp: pb.ResponseCommand): print('micro wave command') if pb.SubCommand.MICRO_WAVE_SUB_COMMAND == req.sub_command: print('micro wave sub command received') device = self._get_device(req.device_id) micro_wave_msg = pb.MicroWaveMessage() if (micro_wave_msg.length == len(micro_wave_msg.data)): filename = f'{device["path"]}/{device["micro_wave"]}.micro_wave' with open(filename, 'wb') as f: f.write(micro_wave_msg.data) device['micro_wave'] += 1 def _default(self, req: pb.RequestCommand, resp: pb.ResponseCommand): print('onknown command') def _on_request(self, ch, method, properties, body): req = pb.RequestCommand() req.ParseFromString(body) dispatcher = self.routes.get(req.sys_command, self._default) resp = pb.ResponseCommand() dispatcher(req, resp) resp.checksum = 12345 resp.state = pb.ResponseState.SUCCESS if properties.reply_to != None: ch.basic_publish(exchange='', routing_key=properties.reply_to, # 收消息的队列 properties=pika.BasicProperties( correlation_id=properties.correlation_id), # 返回消息的队列 body=resp.SerializeToString()) # 返回结果数据 ch.basic_ack(delivery_tag=method.delivery_tag) # 确保消息被 客户端接收 self.message_received += 1 return def api(self): req = pb.RequestCommand() req.ParseFromString(request.data) dispatcher = self.routes.get(req.sys_command, self._default) resp = pb.ResponseCommand() dispatcher(req, resp) resp.checksum = 12345 response = Flask.response_class( resp.SerializeToString(), mimetype='application/x-protobuf' ) return response, 200 def hello(self): return 'Hello, World!' def consuming(self): print(' [*] RabbitMQ Server started. Waiting for messages.') self.channel.start_consuming() def run_rabbitmq(self): t = threading.Thread(target=self.consuming) t.start() def run_all(self, host="localhost", port=5000): self.run_rabbitmq() self.run(debug=False, host=host, port=port) if __name__ == "__main__": server = MyServer(__name__) server.init_rabbmitmq(host='localhost', user='chai', password='password123', queue='aerial_rpc') server.run_all(host="0.0.0.0", port=5000)