7de018ec399024ac3a4cae0432849f91d4de0fbf
[ealt-edge.git] / example-apps / ROBO / retail_app / inventry / retail_app.py
1 #
2 # Copyright 2020 Huawei Technologies Co., Ltd.
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 #     http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 #
16
17 import config
18 from flask_sslify import SSLify
19 from flask import Flask, request, jsonify, Response
20 from flask_cors import CORS
21 from camera_driver.capture_frame import VideoCamera, VideoFile
22 from influxdb import InfluxDBClient
23 import json
24 import time
25 import requests
26
27
28 app = Flask(__name__)
29 CORS(app)
30 sslify = SSLify(app)
31 app.config['JSON_AS_ASCII'] = False
32 app.config['UPLOAD_PATH'] = '/usr/app/images/'
33 app.config['supports_credentials'] = True
34 app.config['CORS_SUPPORTS_CREDENTIALS'] = True
35 app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024
36 ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg'])
37 count = 0
38 listOfMsgs = []
39 listOfCameras = []
40 listOfVideos = []
41
42
43 class inventry_info:
44     """
45     Store the data and manage multiple input video feeds
46     """
47     def __init__(self, current_count=0, total_count=0, time=0):
48         self.type = "Shelf_INV"
49         self.labels = "Bottles"
50         self.current_count = current_count
51         self.total_count = total_count
52         self.time = time
53
54     def setcurrentcount(self, current_count):
55         self.current_count = current_count
56
57     def settotalcount(self, total_count):
58         self.total_count = total_count
59
60     def getcurrentcount(self):
61         return self.current_count
62
63     def gettotalcount(self):
64         return self.total_count
65
66     def setlabel(self, labels):
67         self.labels = labels
68
69     def getlabel(self):
70         return self.labels
71
72     def settime(self, time):
73         self.labels = time
74
75     def gettime(self):
76         return self.time
77
78
79 def store_data(inventry_info):
80     """
81     store time series data in influx db
82     """
83     # TODO config, schema table, DB, fill data set
84     create_database()
85     store_info_db(inventry_info)
86
87
88 def shelf_inventry(video_capture, camera_info):
89     """
90     人脸识别
91     """
92     global count
93     labels = "bottles"
94     process_this_frame = 0
95     while True:
96         success, frame = video_capture.get_frame()
97         if not success:
98             break
99         if process_this_frame == 0:
100             url = config.detection_url + "/v1/obj_detection/detect"
101             # info1 = cv2.imencode(".jpg", rgb_small_frame)[1].tobytes()
102             data = json.loads(requests.post(url, data=frame,
103                                             verify=config.ssl_cacertpath).text)
104         inven_info = inventry_info()
105         current_count = data[count]
106         labels = data[labels]
107         total_count = inven_info.current_count + inven_info.total_count
108         inven_info.setcurrentcount(current_count)
109         inven_info.settotalcount(total_count)
110         inven_info.setlabel(labels)
111         inven_info.utime = time.time()
112         store_data(inven_info)
113
114
115 def store_info_db(inven_info):
116     """
117     Send "shelf" data to InfluxDB
118
119     :param inven_info: Inventry object
120     :return: None
121     """
122     global db_client
123     json_body = [
124         {
125             "measurement": inven_info.type,
126             "tags": {
127                 "object": "bottles",
128             },
129             "fields": {
130                 "time": inven_info.time,
131                 "Current Count": inven_info.current_count,
132                 "Total Count": inven_info.total_count,
133             }
134         }]
135     db_client.write_points(json_body)
136
137
138 def create_database():
139     """
140     Connect to InfluxDB and create the database
141
142     :return: None
143     """
144     global db_client
145
146     proxy = {"http": "http://{}:{}".format(config.IPADDRESS, config.PORT)}
147     db_client = InfluxDBClient(host=config.IPADDRESS, port=config.PORT,
148                                proxies=proxy, database=config.DATABASE_NAME)
149     db_client.create_database(config.DATABASE_NAME)
150
151
152 @app.route('/v1/monitor/cameras', methods=['POST'])
153 def add_camera():
154     camera_info = request.json
155     app.logger.info("Received message from ClientIP [" + request.remote_addr
156                     + "] Operation [" + request.method + "]" +
157                     " Resource [" + request.url + "]")
158     camera_info = {"name": camera_info["name"],
159                    "rtspurl": camera_info["rtspurl"],
160                    "location": camera_info["location"]}
161     listOfCameras.append(camera_info)
162     return Response("success")
163
164
165 @app.route('/v1/monitor/cameras/<name>/<rtspurl>/<location>', methods=['GET'])
166 def get_camera(name, rtspurl, location):
167     """
168     register camera with location
169     """
170     app.logger.info("Received message from ClientIP [" + request.remote_addr
171                     + "] Operation [" + request.method + "]" +
172                     " Resource [" + request.url + "]")
173     camera_info = {"name": name, "rtspurl": rtspurl, "location": location}
174     if "mp4" in camera_info["rtspurl"]:
175         video_file = VideoFile(camera_info["rtspurl"])
176         video_dict = {camera_info["name"]: video_file}
177         listOfVideos.append(video_dict)
178         return Response(shelf_inventry(video_file, camera_info["name"]),
179                         mimetype='multipart/x-mixed-replace; boundary=frame')
180     else:
181         video_file = VideoCamera(camera_info["rtspurl"])
182         video_dict = {camera_info["name"]: video_file}
183         listOfVideos.append(video_dict)
184         return Response(shelf_inventry(video_file, camera_info["name"]),
185                         mimetype='multipart/x-mixed-replace; boundary=frame')
186
187
188 @app.route('/v1/monitor/cameras/<camera_name>', methods=['DELETE'])
189 def delete_camera(camera_name):
190     app.logger.info("Received message from ClientIP [" + request.remote_addr
191                     + "] Operation [" + request.method + "]" +
192                     " Resource [" + request.url + "]")
193     for video1 in listOfVideos:
194         if camera_name in video1:
195             video_obj = video1[camera_name]
196             video_obj.delete()
197     for camera in listOfCameras:
198         if camera_name == camera["name"]:
199             listOfCameras.remove(camera)
200     for msg in listOfMsgs:
201         if camera_name in msg["msg"]:
202             listOfMsgs.remove(msg)
203     return Response("success")
204
205
206 @app.route('/v1/monitor/cameras')
207 def query_cameras():
208     app.logger.info("Received message from ClientIP [" + request.remote_addr
209                     + "] Operation [" + request.method + "]" +
210                     " Resource [" + request.url + "]")
211     return jsonify(listOfCameras)
212     return Response("success")
213
214
215 def start_server(handler):
216     app.logger.addHandler(handler)
217     if config.ssl_enabled:
218         context = (config.ssl_certfilepath, config.ssl_keyfilepath)
219         app.run(host=config.server_address, debug=True, ssl_context=context,
220                 threaded=True, port=config.server_port)
221     else:
222         app.run(host=config.server_address, debug=True, threaded=True,
223                 port=config.server_port)