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
26 changes: 12 additions & 14 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):
def __init__(self):
self.message = "Can not config"
Expand Down Expand Up @@ -61,14 +62,14 @@ 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):
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 @@ -97,8 +98,7 @@ def config_trama(self):

def init_lora(self):

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 @@ -117,11 +117,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 All @@ -140,5 +140,3 @@ def quantity_poll(self):
if self.lastpollsize != 0:
n += 1
return n


32 changes: 17 additions & 15 deletions src/files_management.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,28 @@
import logging
from pip.utils.outdated import SELFCHECK_DATE_FMT


log = logging.getLogger('files')
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 MeterUpdate(object):
def __init__(self, object_dic):
self.lora_id =int(object_dic["meterid"][0:4],16)
self.address = int(object_dic["meterid"][4:6],16)
if self.address==0:
self.lora_id = int(object_dic["meterid"][0:4], 16)
self.address = int(object_dic["meterid"][4:6], 16)
if self.address == 0:
self.address = self.lora_id
if object_dic["isPowered"]:
self.function = "Relay"
self.value = object_dic["powerValue"]
else:
self.function = "Reset"
self.value = True
self.value = True


def save2file(file, data):
file.seek(0)
Expand All @@ -50,7 +51,8 @@ def update_energy_file(serial, data):
with open("output/energy.json", 'r+') as energy_file:
energy_dic = json.load(energy_file)
energy_dic[serial.hex()] = data
log.info("Updated %s: %s at %s", serial.hex(), str(data),str(datetime.datetime.now()) )
log.info("Updated %s: %s at %s", serial.hex(), str(data),
str(datetime.datetime.now()))
save2file(energy_file, energy_dic)


Expand Down Expand Up @@ -97,8 +99,8 @@ def f_post_boot(loras, post_path):
post_dic['updates'] = updates
save2file(post_file, post_dic)
post_file.close()


def get_meter_updates():
#get json from cloud
with open("json/states.json") as status_file:
Expand All @@ -117,9 +119,9 @@ def get_meter_updates():
#payload = get_modbus_adu_update(meter_update_object.lora_id, meter_update_object.function,meter_update_object.address,meter_update_object.value)
#log.debug(updates_list)
return updates_list



if __name__ == "__main__":
meter_updates =get_meter_updates()
for update in meter_updates:
print(update.lora_id)

meter_updates = get_meter_updates()
for update in meter_updates:
print(update.lora_id)
10 changes: 5 additions & 5 deletions src/logger.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import logging
import sys


dateformat = "%m/%d/%Y %H:%M:%S"
logformat = "%(asctime)s [%(levelname)-5.5s] [%(name)s] %(message)s"
consoleforma = "[%(levelname)-5.5s] [%(name)s] %(message)s"


def build_logger():

logFormatter = logging.Formatter(logformat,datefmt = dateformat)
consoleFormatter = logging.Formatter("[%(levelname)-5.5s] [%(name)s] %(message)s")

logFormatter = logging.Formatter(logformat, datefmt=dateformat)
consoleFormatter = logging.Formatter(
"[%(levelname)-5.5s] [%(name)s] %(message)s")
log = logging.getLogger()

fileHandler = logging.FileHandler("{0}/{1}.log".format(".","logs"))
fileHandler = logging.FileHandler("{0}/{1}.log".format(".", "logs"))
fileHandler.setFormatter(logFormatter)
fileHandler.setLevel(logging.WARNING)
log.addHandler(fileHandler)
Expand Down
51 changes: 31 additions & 20 deletions src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,32 @@
from threading import Timer

send_pre = [5, 0, 1, 14, 0, 2, 0, 7, 1, 8]

def post_thread():


def post_thread():
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_scada(node.post_path,args.production)
counter += 1
log.info("Posting in %s s", str(post_time_s - counter + 1))
if counter == post_time_s:
post_scada(node.post_path, args.production)
counter = 0
post_timer = Timer(1.0,post_thread)
post_timer = Timer(1.0, post_thread)
post_timer.start()


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 @@ -87,35 +95,38 @@ def poll_loras(loras):

update_energy_file(serial_meter, data[j])
update_post_file(serial_meter, data[j])

meter_updates = get_meter_updates()
for update in meter_updates:
time.sleep(1)

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__":

args = build_argparser().parse_args()
log = build_logger()

Expand All @@ -131,13 +142,13 @@ def poll_loras(loras):
f_post_boot(node.loras, node.post_path)
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 @@ -154,4 +165,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)
11 changes: 7 additions & 4 deletions src/modbus_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,19 @@
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)

def get_modbus_adu_update(id,function,address, value):

def get_modbus_adu_update(id, function, address, value):
adu = []
adu.append(id)
adu.append(5) #Write single coil
adu.append(5) #Write single coil
adu.append(0)
if function == "Reset":
adu.append(address) #TODO reset another address
adu.append(address) #TODO reset another address
else:
adu.append(address)
if value == True:
Expand All @@ -28,6 +30,7 @@ def get_modbus_adu_update(id,function,address, value):
log.debug("modbus adu to send: %s", str(adu))
return adu


def get_modbus_adu(id_slave, function_code, start_add, quantity):
if quantity > 125:
return None
Expand Down