diff --git a/engine.py b/engine.py index b589e64..be87120 100644 --- a/engine.py +++ b/engine.py @@ -2,14 +2,17 @@ from datetime import datetime 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): - self.save_error = save_e - self.save_warning = save_w - self.save_messages = save_m - self.print_error = print_e - self.print_warning = print_w - self.print_messages = print_m - self.debug_e = debug + def __init__(self, settings=None): + if settings is None: + settings = {"save_error": True, "print_error": True, "save_warning": True, "print_warning": True, + "save_message": False, "print_message": True, "enable_debug": False} + self.save_error = settings["save_error"] + self.save_warning = settings["save_warning"] + self.save_messages = settings["save_message"] + 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): if self.print_error: diff --git a/files/test.jpg b/files/test.jpg new file mode 100644 index 0000000..7777c36 Binary files /dev/null and b/files/test.jpg differ diff --git a/files/test.txt b/files/test.txt index 57dbbb2..e63327e 100644 --- a/files/test.txt +++ b/files/test.txt @@ -1 +1 @@ -toto je test číslo 1 \ No newline at end of file +toto je test číslo 1 zo serveru s ID 2 \ No newline at end of file diff --git a/files/test2.txt b/files/test2.txt index 96a90c6..e4c078a 100644 --- a/files/test2.txt +++ b/files/test2.txt @@ -1 +1 @@ -toto je test n. 2 \ No newline at end of file +toto je test n. 2 zo serveru ID2 \ No newline at end of file diff --git a/log.txt b/log.txt index 60bcbdd..e69de29 100644 --- a/log.txt +++ b/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 \ No newline at end of file diff --git a/main.py b/main.py index 5c9d426..e9b9a59 100644 --- a/main.py +++ b/main.py @@ -8,33 +8,34 @@ import json import os 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, "vlhkosť": 25, "počet ľudí": 10, "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["IP"].append(IP) heartbeat_table["location"].append(location) @@ -44,7 +45,7 @@ heartbeat_table["last_heartbeat"].append(time_to_heartbeat) # Todo better "host" ID handeling -class Server_table(BaseModel): +class Server_table(BaseModel): # table of content for heartbeat request ID: list IP: list location: list @@ -54,7 +55,7 @@ class Server_table(BaseModel): @app.post("/heartbeat") 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}") try: 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[ 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: 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 @@ -76,6 +78,9 @@ def heartbeat(s_table: Server_table, request: Request): heartbeat_table["last_heartbeat"].append(s_table.last_heartbeat[position]) except Exception as 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} @@ -91,7 +96,8 @@ def get_file(IDx: int, file: str): if IDx == ID: return FileResponse(f"files/{file}") 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" if os.path.isdir(f"cache/{IDx}"): 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: save.write(bytes(r.content)) return FileResponse(f"cache/{IDx}/{file}") - # Todo Get files function for client (phone/ther rpi) @app.post("/update") @@ -113,12 +118,12 @@ def update_sensors(): pass # Todo Make option to upload "live data" manually to rpi -def send_heartbeat(ip): + +def send_heartbeat(ip, id): 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)) heartbeat_table = dict(cache_request.json()[0]) - #Todo test heartbeat table update log.debug(json.dumps(cache_request.json(), indent=4)) @@ -127,8 +132,18 @@ def mainloop(): for device_number, device_ID in enumerate(heartbeat_table["ID"]): if device_ID != ID: if heartbeat_table["last_heartbeat"][device_number] < 0: - send_heartbeat(heartbeat_table["IP"][device_number]) - heartbeat_table["last_heartbeat"][int(device_number)] = int(time_to_heartbeat) + 5 + 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 log.debug(f"""{device_ID} : time to heartbeat : {heartbeat_table["last_heartbeat"][device_number]}""") heartbeat_table["last_heartbeat"][device_number] -= 1 time.sleep(1) @@ -136,3 +151,6 @@ def mainloop(): thread_1 = threading.Thread(target=mainloop, daemon=True) thread_1.start() + +# Todo in next release: disconnect offline client after set time +# Todo better formating code + comments \ No newline at end of file diff --git a/settings.json b/settings.json new file mode 100644 index 0000000..e670bca --- /dev/null +++ b/settings.json @@ -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": [] +} +} \ No newline at end of file