wu_xinjun
2022-02-10 d78e213656461834adb890b5f1c7d0789725a6de
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
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)