Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 13 additions & 15 deletions src/centralnode.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -75,22 +76,22 @@ 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
@param dest_slave slave of destination
@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
Expand Down Expand Up @@ -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)
Expand All @@ -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")
Expand Down Expand Up @@ -184,5 +184,3 @@ def quantity_poll(self):
if self.lastpollsize != 0:
n += 1
return n


56 changes: 34 additions & 22 deletions src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,31 +17,33 @@
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:
restart_button = LED(23)
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
Expand All @@ -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


Expand Down Expand Up @@ -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

Expand All @@ -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)
Expand All @@ -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)
47 changes: 25 additions & 22 deletions src/post_http.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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
Expand All @@ -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)

Expand All @@ -66,54 +66,58 @@ 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"]
updates_list = []
#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)
log.debug(meter_update_object.address)
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

Expand All @@ -140,4 +144,3 @@ def get_meter_updates():
}
#post_scada(aux_dic)
print(get_meter_updates())