-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.py
More file actions
145 lines (114 loc) · 4.88 KB
/
server.py
File metadata and controls
145 lines (114 loc) · 4.88 KB
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
from flask import Flask, render_template
from flask_restful import Api, Resource, reqparse
from flask_sqlalchemy import SQLAlchemy
import json
import time
import logging
REFRESH_PAGE = 5
app = Flask(__name__)
api = Api(app)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///database.db'
db = SQLAlchemy(app)
logging.basicConfig(level=logging.INFO, filename='server_log.log')
class Device(db.Model):
id = db.Column(db.Integer, primary_key=True)
status = db.Column(db.Boolean, nullable=False)
config = db.Column(db.Integer, nullable=False)
data = db.relationship('Data', backref='device', lazy=True, cascade="all, delete-orphan")
class Data(db.Model):
id_device = db.Column(db.Integer, db.ForeignKey('device.id'), primary_key=True)
timestamp = db.Column(db.Float, primary_key=True)
data = db.Column(db.Float, nullable=False)
def __repr__(self):
return f"Data(id_device = {self.id_device}, timestamp = {self.timestamp}, data = {self.data})"
device_data_put_args = reqparse.RequestParser()
device_data_put_args.add_argument("id_device", type=int, help="id device", required=True)
device_data_put_args.add_argument("timestamp", type=float, help="timestamp epoc", required=True)
device_data_put_args.add_argument("data", type=float, help="data", required=True)
device_data_delete_args = reqparse.RequestParser()
device_data_delete_args.add_argument("id_device", type=int, help="id device", required=True)
device_data_delete_args.add_argument("timestamp", type=float, help="timestamp epoc", required=True)
class DataDevice(Resource):
def put(self):
""" it receives the data from the devices and puts them in the database
:return:
"""
args = device_data_put_args.parse_args()
# check if the device exist
device = Device.query.get(args['id_device'])
if device is None:
# device is not in the database so we add to it
device = Device(id=args['id_device'], status=True, config=0)
# add data to the database
data = Data(id_device=args['id_device'], timestamp=args['timestamp'], data=args['data'])
device.data.append(data)
device.status = True
db.session.add(device)
db.session.add(data)
db.session.commit()
response = app.response_class(
response=json.dumps(device.config),
status=201,
mimetype='application/json')
return response
def delete(self):
""" delete a row from Data Table
:return:
"""
args = device_data_delete_args.parse_args()
n_delete = Data.query.filter(Data.id_device == args['id_device'], Data.timestamp == args['timestamp']).delete()
db.session.commit()
after_n_delete = Data.query.filter(Data.id_device == args['id_device']).all()
if not after_n_delete:
Device.query.filter(Device.id == args['id_device']).delete()
db.session.commit()
if n_delete >= 1:
return '', 204
else:
return '', 404
class DeviceStatus(Resource):
def get(self, id_device):
""" is the device online?
:param id_device: id device
:return:
"""
args = device_time_check_connection_args.parse_args()
# check if the last data from the device is recent
seconds = time.time() - args['time_check']
data = Data.query.with_entities(Data.data).filter(Data.id_device == id_device,
Data.timestamp >= seconds).all()
device = Device.query.get(id_device)
if not data:
device.status = False
db.session.add(device)
db.session.commit()
response = app.response_class(
response=json.dumps(device.status),
status=200,
mimetype='application/json')
return response
api.add_resource(DeviceStatus, "/device_status/<int:id_device>")
api.add_resource(DataDevice, "/data_device")
@app.route("/")
def home():
""" Home page for data visualization
:return:
"""
devices_id = []
seconds = time.time() - REFRESH_PAGE
devices = Device.query.all()
all_data = []
for device in devices:
data = Data.query.with_entities(Data.data).filter(Data.id_device == device.id,
Data.timestamp >= seconds).all()
if data:
data = {'id_device': device.id, 'config': device.config, 'status': device.status,
'data': [item for sublist in data for item in sublist]}
else:
data = {'id_device': device.id, 'config': device.config, 'status': device.status,
'data': []}
all_data.append(data)
return render_template("index.html", all_data=all_data, refresh=REFRESH_PAGE)
if __name__ == '__main__':
db.create_all()
app.run(host='localhost', port=5000)