diff --git a/src/centralnode.py b/src/centralnode.py index 40be888..d0816d1 100644 --- a/src/centralnode.py +++ b/src/centralnode.py @@ -6,14 +6,15 @@ import logging from Crypto.Util.number import size - log = logging.getLogger('central') ch = logging.NullHandler() ch.setLevel(logging.DEBUG) -formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') +formatter = logging.Formatter( + '%(asctime)s - %(name)s - %(levelname)s - %(message)s') ch.setFormatter(formatter) log.addHandler(ch) + class ConfigError(Exception): """! Set error message @@ -75,7 +76,7 @@ def build_send_frame(payload, dest_slave): frame.append(check_sum) return frame - def send(self, payload, dest_slave, quant = 0): + def send(self, payload, dest_slave, quant=0): """! Send received information of the pool @param payload charge of the meter @@ -83,14 +84,14 @@ def send(self, payload, dest_slave, quant = 0): @param quant maximum size of the poll @return result information of the data - """ + """ frame = self.build_send_frame(payload, dest_slave) #self.ser = serial.Serial(self.lora_port, timeout=14) self.ser.write(bytearray(frame)) - result = self.ser.read(size = 8) + result = self.ser.read(size=8) log.debug("Data sent : %s", str(frame)) - self.expected_size = 22 + 2 * quant -8 - if quant == 0 : + self.expected_size = 22 + 2 * quant - 8 + if quant == 0: self.expected_size = 17 return result @@ -131,8 +132,7 @@ def init_lora(self): @return True or False value of the Lora configuration """ - expect = [ - 1, 0, 129, 12, 165, 165, 108, 64, 18, 7, 0, 0, 1, 1, 0, 3, 0] + expect = [1, 0, 129, 12, 165, 165, 108, 64, 18, 7, 0, 0, 1, 1, 0, 3, 0] try: expect[12] = self.networkid check_sum = reduce(lambda x, y: x ^ y, expect) @@ -151,11 +151,11 @@ def init_lora(self): os._exit(0) if list(response) != expect: expect[3] = 13 - expect[17] = expect[17]+1 + expect[17] = expect[17] + 1 if list(response) == expect: - self.ser.close() - log.info("Lora Config Successfull") - return True + self.ser.close() + log.info("Lora Config Successfull") + return True return False self.ser.close() log.info("Lora Config Successfull") @@ -184,5 +184,3 @@ def quantity_poll(self): if self.lastpollsize != 0: n += 1 return n - - \ No newline at end of file diff --git a/src/main.py b/src/main.py index 1490f20..d6133c2 100755 --- a/src/main.py +++ b/src/main.py @@ -17,7 +17,8 @@ from gpiozero import LED send_pre = [5, 0, 1, 14, 0, 2, 0, 7, 1, 8] - + + def restart_lora(): log.info("Restart LoRa module") if args.production: @@ -25,23 +26,24 @@ def restart_lora(): restart.off() time.sleep(1) restart.on() - -def post_thread(): + + +def post_thread(): """! Post meters information """ global counter global post_time_s - counter+=1 - log.info("Posting in %s s",str(post_time_s - counter + 1)) - if counter == post_time_s : - post_json = load_json( node.id, node.key) - post_scada(post_json,args.production) + counter += 1 + log.info("Posting in %s s", str(post_time_s - counter + 1)) + if counter == post_time_s: + post_json = load_json(node.id, node.key) + post_scada(post_json, args.production) counter = 0 restart_lora() - post_timer = Timer(1.0,post_thread) + post_timer = Timer(1.0, post_thread) post_timer.start() - + def build_argparser(): """! Set command line interface @@ -50,8 +52,15 @@ def build_argparser(): """ label = subprocess.check_output(["git", "describe"]).strip() parser = argparse.ArgumentParser(description="To select production code") - parser.add_argument('-p','--production', action='store_true', default=False, help = "Create production code") - parser.add_argument('-v','--version', action='version', version=label.decode("utf-8")) + parser.add_argument('-p', + '--production', + action='store_true', + default=False, + help="Create production code") + parser.add_argument('-v', + '--version', + action='version', + version=label.decode("utf-8")) return parser @@ -115,29 +124,32 @@ def poll_loras(loras): meter_updates = get_meter_updates() for update in meter_updates: time.sleep(3) - - payload = get_modbus_adu_update(update.lora_id, update.function,update.address,update.value) + + payload = get_modbus_adu_update(update.lora_id, update.function, + update.address, update.value) unencripted_payload = payload log.debug(payload) dest_slave = payload[0] if node.cipher: - payload = encrypt_md(payload, "CFB") + payload = encrypt_md(payload, "CFB") result = node.send(payload, dest_slave) log.debug("Result %s", str(list(result))) log.info("Result code from sent [%d] ", result[6]) - + response = node.receive() if response is None: - continue + continue if node.cipher: response = decrypt_md(response, "CFB") - + log.debug("message received: %s", str(unencripted_payload)) - + if set(unencripted_payload) == set(response): log.info("Wrote Coils Successfully") else: log.info("Something went wrong writing coils") + + if __name__ == "__main__": """! Main program entry @@ -157,13 +169,13 @@ def poll_loras(loras): energy_load(node.loras) counter = 0 post_time_s = node.post_time - post_timer = Timer(1.0,post_thread) + post_timer = Timer(1.0, post_thread) post_timer.start() node.ser = serial.Serial(node.lora_port, timeout=14) wtd_start.stop() except Watchdog: log.error("Reseting script due to wdt boot") - wtd = Watchdog(300) # 5min + wtd = Watchdog(300) # 5min try: while True: poll_loras(node.loras) @@ -180,4 +192,4 @@ def poll_loras(loras): log.error("App Crashed!") log.error("Problems? %s", sys.exc_info()) log.info("Restarting...") - os.execv(sys.executable, ['python'] + sys.argv) + os.execv(sys.executable, ['python'] + sys.argv) diff --git a/src/post_http.py b/src/post_http.py index 2b3b0cc..cad2017 100644 --- a/src/post_http.py +++ b/src/post_http.py @@ -7,10 +7,12 @@ log = logging.getLogger('post') ch = logging.NullHandler() ch.setLevel(logging.DEBUG) -formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') +formatter = logging.Formatter( + '%(asctime)s - %(name)s - %(levelname)s - %(message)s') ch.setFormatter(formatter) log.addHandler(ch) + def post_json(file, is_production): """! Get the status of the data @@ -22,12 +24,10 @@ def post_json(file, is_production): headers = {'Content-type': 'application/json'} scada_url = 'https://postman-echo.com/post' if is_production: - scada_url = "https://apimedidores.ciexpro.com/api/push/custom_create/" - log,debug(scada_url) + scada_url = "https://apimedidores.ciexpro.com/api/push/custom_create/" + log, debug(scada_url) try: - r = requests.post(scada_url, - json=file, - headers=headers) + r = requests.post(scada_url, json=file, headers=headers) log.info("Status code is : %s", str(r.status_code)) log.debug(str(r)) return r.status_code @@ -45,7 +45,7 @@ def post_scada(data_dic, is_production): @param is_production chech if there is a new data to add """ log.info("Posting to Scada") - success_code =201 + success_code = 201 log.debug("Data to post: %s", str(data_dic)) r_code = post_json(data_dic, is_production) @@ -66,28 +66,30 @@ def post_scada(data_dic, is_production): with open("output/send_later.txt", "a") as file: file.write(text) file.close() - + + class MeterUpdate(object): def __init__(self, object_dic): - self.lora_id =int(object_dic["meter"][0:4],16) - self.address = int(object_dic["meter"][4:6],16) - if self.address==0: + self.lora_id = int(object_dic["meter"][0:4], 16) + self.address = int(object_dic["meter"][4:6], 16) + if self.address == 0: self.address = self.lora_id if "next_state" in object_dic: self.function = "Relay" self.value = object_dic["next_state"] else: self.function = "Reset" - self.value = True - + self.value = True + + def get_meter_updates(): #get json from cloud - + update_endpoint = "https://apimedidores.ciexpro.com/api/meter_conection/reconnect" location = "Estelio_CA" - PARAMS = {'address':location} + PARAMS = {'address': location} - r = requests.get(url = update_endpoint, params = PARAMS) + r = requests.get(url=update_endpoint, params=PARAMS) status_dic = r.json() print(status_dic) updates = status_dic["meters"] @@ -95,10 +97,10 @@ def get_meter_updates(): #log.debug(status_dic)s log.debug(updates) - + json_back = {} dic_back = [] - + for update in updates: meter_update_object = MeterUpdate(update) log.debug(meter_update_object.lora_id) @@ -106,14 +108,16 @@ def get_meter_updates(): log.debug(meter_update_object.function) log.debug(meter_update_object.value) updates_list.append(meter_update_object) - + dic_back.append(update["meter"]) print(update["next_state"]) - + json_back["meters"] = dic_back URL = "https://apimedidores.ciexpro.com/api/meter_conection/change_state/" - r = requests.post(url = URL, headers = PARAMS,json=json_back) + r = requests.post(url=URL, headers=PARAMS, json=json_back) return updates_list + + if __name__ == "__main__": """! Main program entry @@ -140,4 +144,3 @@ def get_meter_updates(): } #post_scada(aux_dic) print(get_meter_updates()) -