configuration in json and offline client support
Program will now work even if some of rpi are offline. Server settings are now saved in settings.json for easier update on servers. Uploaded more testing files. Also slight improvments of formating and comenting of the code
This commit is contained in:
parent
a8152f9ca3
commit
1df6405a3d
19
engine.py
19
engine.py
@ -2,14 +2,17 @@ from datetime import datetime
|
|||||||
|
|
||||||
|
|
||||||
class Log():
|
class Log():
|
||||||
def __init__(self, save_e=True, save_w=False, save_m=False, print_e=True, print_w=True, print_m=False, debug=False):
|
def __init__(self, settings=None):
|
||||||
self.save_error = save_e
|
if settings is None:
|
||||||
self.save_warning = save_w
|
settings = {"save_error": True, "print_error": True, "save_warning": True, "print_warning": True,
|
||||||
self.save_messages = save_m
|
"save_message": False, "print_message": True, "enable_debug": False}
|
||||||
self.print_error = print_e
|
self.save_error = settings["save_error"]
|
||||||
self.print_warning = print_w
|
self.save_warning = settings["save_warning"]
|
||||||
self.print_messages = print_m
|
self.save_messages = settings["save_message"]
|
||||||
self.debug_e = debug
|
self.print_error = settings["print_error"]
|
||||||
|
self.print_warning = settings["print_warning"]
|
||||||
|
self.print_messages = settings["print_message"]
|
||||||
|
self.debug_e = settings["enable_debug"]
|
||||||
|
|
||||||
def error(self, error):
|
def error(self, error):
|
||||||
if self.print_error:
|
if self.print_error:
|
||||||
|
BIN
files/test.jpg
Normal file
BIN
files/test.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 354 KiB |
@ -1 +1 @@
|
|||||||
toto je test číslo 1
|
toto je test číslo 1 zo serveru s ID 2
|
@ -1 +1 @@
|
|||||||
toto je test n. 2
|
toto je test n. 2 zo serveru ID2
|
3
log.txt
3
log.txt
@ -1,3 +0,0 @@
|
|||||||
|
|
||||||
2021-03-10 12:20:52.490547 -> ERROR: heartbeat > list indices must be integers or slices, not str
|
|
||||||
2021-03-10 12:29:03.690483 -> ERROR: heartbeat > list indices must be integers or slices, not str
|
|
76
main.py
76
main.py
@ -8,33 +8,34 @@ import json
|
|||||||
import os
|
import os
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
app = FastAPI()
|
with open("settings.json", "r") as f: #loading settings
|
||||||
|
settings = json.load(f)
|
||||||
|
|
||||||
sensors = {
|
IP = settings["IP"]
|
||||||
|
ID = settings["ID"]
|
||||||
|
location = settings["location"]
|
||||||
|
|
||||||
|
app = FastAPI() #init of FastAPI
|
||||||
|
log = engine.Log(settings["log"]) # init of LOG
|
||||||
|
offline = []
|
||||||
|
|
||||||
|
time_to_heartbeat = settings["time_to_heartbeat"] # Raspberry will be requesting heartbeat every __ seconds
|
||||||
|
time_to_heartbeat_offline = settings["time_to_heartbeat_offline"] # Raspberry will be requesting heartbeat every __ seconds from offline rpi
|
||||||
|
|
||||||
|
# json variables
|
||||||
|
filesystem = { # Here will be files saved on this raspberry
|
||||||
|
"otvaracie_hod": ["t", {"pon": "10-25"}, {"uto": "10-25"}],
|
||||||
|
"prehliadka": ["pdf", "/files/prehliadka.pdf"],
|
||||||
|
"fotky_hrad": ["png_z", ["/files/hrad1.png", "/files/hrad2.png"]]
|
||||||
|
}
|
||||||
|
heartbeat_table = settings["heartbeat_table"]
|
||||||
|
sensors = { # List of "live" data like tempeature, etc.
|
||||||
"teplota": 24,
|
"teplota": 24,
|
||||||
"vlhkosť": 25,
|
"vlhkosť": 25,
|
||||||
"počet ľudí": 10,
|
"počet ľudí": 10,
|
||||||
"doba čakania": 2
|
"doba čakania": 2
|
||||||
}
|
}
|
||||||
log = engine.Log(print_m=True, debug=False)
|
|
||||||
|
|
||||||
time_to_heartbeat = 20 # Seconds
|
|
||||||
location = "2"
|
|
||||||
ID = 2
|
|
||||||
IP = "192.168.1.99"
|
|
||||||
|
|
||||||
filesystem = {
|
|
||||||
"otvaracie_hod": ["t", {"pon": "10-25"}, {"uto": "10-25"}],
|
|
||||||
"prehliadka": ["pdf", "/files/prehliadka.pdf"],
|
|
||||||
"fotky_hrad": ["png_z", ["/files/hrad1.png", "/files/hrad2.png"]]
|
|
||||||
}
|
|
||||||
heartbeat_table = {
|
|
||||||
"ID": [1],
|
|
||||||
"IP": ["192.168.1.231"],
|
|
||||||
"location": ["1"],
|
|
||||||
"file_system": ["x"],
|
|
||||||
"last_heartbeat": [20]
|
|
||||||
}
|
|
||||||
heartbeat_table["ID"].append(ID)
|
heartbeat_table["ID"].append(ID)
|
||||||
heartbeat_table["IP"].append(IP)
|
heartbeat_table["IP"].append(IP)
|
||||||
heartbeat_table["location"].append(location)
|
heartbeat_table["location"].append(location)
|
||||||
@ -44,7 +45,7 @@ heartbeat_table["last_heartbeat"].append(time_to_heartbeat)
|
|||||||
|
|
||||||
# Todo better "host" ID handeling
|
# Todo better "host" ID handeling
|
||||||
|
|
||||||
class Server_table(BaseModel):
|
class Server_table(BaseModel): # table of content for heartbeat request
|
||||||
ID: list
|
ID: list
|
||||||
IP: list
|
IP: list
|
||||||
location: list
|
location: list
|
||||||
@ -54,7 +55,7 @@ class Server_table(BaseModel):
|
|||||||
|
|
||||||
@app.post("/heartbeat")
|
@app.post("/heartbeat")
|
||||||
def heartbeat(s_table: Server_table, request: Request):
|
def heartbeat(s_table: Server_table, request: Request):
|
||||||
log.message(f"heartbeat requested: {request.client.host}:{request.client.port}")
|
log.message(f"server requested heartbeat {request.client.host}:{request.client.port}")
|
||||||
log.debug(f"Recieved server table: {s_table}")
|
log.debug(f"Recieved server table: {s_table}")
|
||||||
try:
|
try:
|
||||||
for position, server_id in enumerate(s_table.ID):
|
for position, server_id in enumerate(s_table.ID):
|
||||||
@ -64,7 +65,8 @@ def heartbeat(s_table: Server_table, request: Request):
|
|||||||
heartbeat_table["last_heartbeat"][heartbeat_table["ID"].index(server_id)] = s_table.last_heartbeat[
|
heartbeat_table["last_heartbeat"][heartbeat_table["ID"].index(server_id)] = s_table.last_heartbeat[
|
||||||
position]
|
position]
|
||||||
log.debug(f"updated {server_id}`s heartbeat to {s_table.last_heartbeat[position]}")
|
log.debug(f"updated {server_id}`s heartbeat to {s_table.last_heartbeat[position]}")
|
||||||
# Todo update filesystem too. Now updating only last heartbeat
|
heartbeat_table["file_system"][heartbeat_table["ID"].index(server_id)] = s_table.file_system[
|
||||||
|
position]
|
||||||
elif server_id == ID:
|
elif server_id == ID:
|
||||||
log.debug(f"Updated my heartbeat from {s_table.last_heartbeat[position]} to {time_to_heartbeat}")
|
log.debug(f"Updated my heartbeat from {s_table.last_heartbeat[position]} to {time_to_heartbeat}")
|
||||||
heartbeat_table["last_heartbeat"][heartbeat_table["ID"].index(ID)] = time_to_heartbeat
|
heartbeat_table["last_heartbeat"][heartbeat_table["ID"].index(ID)] = time_to_heartbeat
|
||||||
@ -76,6 +78,9 @@ def heartbeat(s_table: Server_table, request: Request):
|
|||||||
heartbeat_table["last_heartbeat"].append(s_table.last_heartbeat[position])
|
heartbeat_table["last_heartbeat"].append(s_table.last_heartbeat[position])
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
log.error(f"heartbeat > {error}")
|
log.error(f"heartbeat > {error}")
|
||||||
|
if heartbeat_table["ID"][heartbeat_table["IP"].index(request.client.host)] in offline:
|
||||||
|
offline.remove(heartbeat_table["ID"][heartbeat_table["IP"].index(request.client.host)])
|
||||||
|
log.message(f"{request.client.host} gone online")
|
||||||
return heartbeat_table, {"ID": ID, "file_system": filesystem, "location": location}
|
return heartbeat_table, {"ID": ID, "file_system": filesystem, "location": location}
|
||||||
|
|
||||||
|
|
||||||
@ -91,7 +96,8 @@ def get_file(IDx: int, file: str):
|
|||||||
if IDx == ID:
|
if IDx == ID:
|
||||||
return FileResponse(f"files/{file}")
|
return FileResponse(f"files/{file}")
|
||||||
elif IDx in heartbeat_table["ID"]:
|
elif IDx in heartbeat_table["ID"]:
|
||||||
r = requests.get(f"""http://{heartbeat_table["IP"][heartbeat_table["ID"].index(IDx)]}:8000/files/{IDx}/{file}""")
|
r = requests.get(
|
||||||
|
f"""http://{heartbeat_table["IP"][heartbeat_table["ID"].index(IDx)]}:8000/files/{IDx}/{file}""")
|
||||||
r.encoding = "utf-8"
|
r.encoding = "utf-8"
|
||||||
if os.path.isdir(f"cache/{IDx}"):
|
if os.path.isdir(f"cache/{IDx}"):
|
||||||
if os.path.isfile(f"cache/{IDx}/{file}"):
|
if os.path.isfile(f"cache/{IDx}/{file}"):
|
||||||
@ -105,7 +111,6 @@ def get_file(IDx: int, file: str):
|
|||||||
with open(f"cache/{IDx}/{file}", "wb") as save:
|
with open(f"cache/{IDx}/{file}", "wb") as save:
|
||||||
save.write(bytes(r.content))
|
save.write(bytes(r.content))
|
||||||
return FileResponse(f"cache/{IDx}/{file}")
|
return FileResponse(f"cache/{IDx}/{file}")
|
||||||
# Todo Get files function for client (phone/ther rpi)
|
|
||||||
|
|
||||||
|
|
||||||
@app.post("/update")
|
@app.post("/update")
|
||||||
@ -113,12 +118,12 @@ def update_sensors():
|
|||||||
pass
|
pass
|
||||||
# Todo Make option to upload "live data" manually to rpi
|
# Todo Make option to upload "live data" manually to rpi
|
||||||
|
|
||||||
def send_heartbeat(ip):
|
|
||||||
|
def send_heartbeat(ip, id):
|
||||||
global heartbeat_table
|
global heartbeat_table
|
||||||
log.message(f"requesting heartbeat from {ip}")
|
log.message(f"""sending heartbeat to {ip}({"offline" if id in offline else "online"})""")
|
||||||
cache_request = requests.post(f"http://{ip}:8000/heartbeat", data=json.dumps(heartbeat_table))
|
cache_request = requests.post(f"http://{ip}:8000/heartbeat", data=json.dumps(heartbeat_table))
|
||||||
heartbeat_table = dict(cache_request.json()[0])
|
heartbeat_table = dict(cache_request.json()[0])
|
||||||
#Todo test heartbeat table update
|
|
||||||
log.debug(json.dumps(cache_request.json(), indent=4))
|
log.debug(json.dumps(cache_request.json(), indent=4))
|
||||||
|
|
||||||
|
|
||||||
@ -127,7 +132,17 @@ def mainloop():
|
|||||||
for device_number, device_ID in enumerate(heartbeat_table["ID"]):
|
for device_number, device_ID in enumerate(heartbeat_table["ID"]):
|
||||||
if device_ID != ID:
|
if device_ID != ID:
|
||||||
if heartbeat_table["last_heartbeat"][device_number] < 0:
|
if heartbeat_table["last_heartbeat"][device_number] < 0:
|
||||||
send_heartbeat(heartbeat_table["IP"][device_number])
|
try:
|
||||||
|
send_heartbeat(heartbeat_table["IP"][device_number], heartbeat_table["ID"][device_number])
|
||||||
|
except requests.exceptions.ConnectionError:
|
||||||
|
if heartbeat_table["ID"][device_number] not in offline:
|
||||||
|
log.warning(f"""{heartbeat_table["IP"][device_number]} disconnected/is not available""")
|
||||||
|
offline.append(heartbeat_table["ID"][device_number])
|
||||||
|
heartbeat_table["last_heartbeat"][int(device_number)] = int(time_to_heartbeat_offline)
|
||||||
|
else:
|
||||||
|
if heartbeat_table["ID"][device_number] in offline:
|
||||||
|
offline.remove(heartbeat_table["ID"][device_number])
|
||||||
|
log.message(f"""{heartbeat_table["IP"][device_number]} gone online""")
|
||||||
heartbeat_table["last_heartbeat"][int(device_number)] = int(time_to_heartbeat) + 5
|
heartbeat_table["last_heartbeat"][int(device_number)] = int(time_to_heartbeat) + 5
|
||||||
log.debug(f"""{device_ID} : time to heartbeat : {heartbeat_table["last_heartbeat"][device_number]}""")
|
log.debug(f"""{device_ID} : time to heartbeat : {heartbeat_table["last_heartbeat"][device_number]}""")
|
||||||
heartbeat_table["last_heartbeat"][device_number] -= 1
|
heartbeat_table["last_heartbeat"][device_number] -= 1
|
||||||
@ -136,3 +151,6 @@ def mainloop():
|
|||||||
|
|
||||||
thread_1 = threading.Thread(target=mainloop, daemon=True)
|
thread_1 = threading.Thread(target=mainloop, daemon=True)
|
||||||
thread_1.start()
|
thread_1.start()
|
||||||
|
|
||||||
|
# Todo in next release: disconnect offline client after set time
|
||||||
|
# Todo better formating code + comments
|
23
settings.json
Normal file
23
settings.json
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"ID": 0,
|
||||||
|
"IP": "192.168.1.99",
|
||||||
|
"location": "izba",
|
||||||
|
"time_to_heartbeat": 20,
|
||||||
|
"time_to_heartbeat_offline": 25,
|
||||||
|
"log": {
|
||||||
|
"save_error": true,
|
||||||
|
"print_error": true,
|
||||||
|
"save_warning": true,
|
||||||
|
"print_warning": true,
|
||||||
|
"save_message": false,
|
||||||
|
"print_message": true,
|
||||||
|
"enable_debug": false
|
||||||
|
},
|
||||||
|
"heartbeat_table": {
|
||||||
|
"ID": [],
|
||||||
|
"IP": [],
|
||||||
|
"location": [],
|
||||||
|
"file_system": [],
|
||||||
|
"last_heartbeat": []
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user