diff --git a/.DS_Store b/.DS_Store index 40d32a3..71184cb 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/Pub_Sub/.DS_Store b/Pub_Sub/.DS_Store index 8183c9c..4d87d07 100644 Binary files a/Pub_Sub/.DS_Store and b/Pub_Sub/.DS_Store differ diff --git a/Pub_Sub/advvfdipp/.DS_Store b/Pub_Sub/advvfdipp/.DS_Store index 83012be..e7d19e0 100644 Binary files a/Pub_Sub/advvfdipp/.DS_Store and b/Pub_Sub/advvfdipp/.DS_Store differ diff --git a/Pub_Sub/advvfdipp/guidon/.DS_Store b/Pub_Sub/advvfdipp/guidon/.DS_Store index c8b0402..4bb2d79 100644 Binary files a/Pub_Sub/advvfdipp/guidon/.DS_Store and b/Pub_Sub/advvfdipp/guidon/.DS_Store differ diff --git a/Pub_Sub/advvfdipp/guidon/v2/pub/sendData.py b/Pub_Sub/advvfdipp/guidon/v2/pub/sendData.py index 261cfd7..a930375 100644 --- a/Pub_Sub/advvfdipp/guidon/v2/pub/sendData.py +++ b/Pub_Sub/advvfdipp/guidon/v2/pub/sendData.py @@ -1,9 +1,119 @@ -# Enter your python code. -import json +import json, os, uuid from common.Logger import logger from quickfaas.remotebus import publish -import re, uuid from paho.mqtt import client +from quickfaas.global_dict import get as get_params +from quickfaas.global_dict import _set_global_args + +def reboot(): + #basic = Basic() + logger.info("!" * 10 + "REBOOTING DEVICE" + "!"*10) + r = os.popen("kill -s SIGHUP `cat /var/run/python/supervisord.pid`").read() + logger.info(f"REBOOT : {r}") + +def checkFileExist(filename): + path = "/var/user/files" + if not os.path.exists(path): + logger.info("no folder making files folder in var/user") + os.makedirs(path) + with open(path + "/" + filename, "a") as f: + json.dump({}, f) + if not os.path.exists(path + "/" + filename): + logger.info("no creds file making creds file") + with open(path + "/" + filename, "a") as f: + json.dump({}, f) + +def convertDStoJSON(ds): + j = dict() + for x in ds: + j[x["key"]] = x["value"] + return j + +def convertJSONtoDS(j): + d = [] + for key in j.keys(): + d.append({"key": key, "value": j[key]}) + return d + +def checkCredentialConfig(): + logger.info("CHECKING CONFIG") + cfgpath = "/var/user/cfg/device_supervisor/device_supervisor.cfg" + credspath = "/var/user/files/creds.json" + cfg = dict() + with open(cfgpath, "r") as f: + cfg = json.load(f) + clouds = cfg.get("clouds") + logger.info(clouds) + #if not configured then try to configure from stored values + if clouds[0]["args"]["clientId"] == "unknown" or clouds[0]["args"]["username"] == "unknown" or not clouds[0]["args"]["passwd"] or clouds[0]["args"]["passwd"] == "unknown": + checkFileExist("creds.json") + with open(credspath, "r") as c: + creds = json.load(c) + if creds: + logger.info("updating config with stored data") + clouds[0]["args"]["clientId"] = creds["clientId"] + clouds[0]["args"]["username"] = creds["userName"] + clouds[0]["args"]["passwd"] = creds["password"] + cfg["clouds"] = clouds + cfg = checkParameterConfig(cfg) + with open(cfgpath, "w", encoding='utf-8') as n: + json.dump(cfg, n, indent=1, ensure_ascii=False) + reboot() + else: + #assuming clouds is filled out, if data is different then assume someone typed in something new and store it, if creds is empty fill with clouds' data + checkFileExist("creds.json") + with open(credspath, "r") as c: + logger.info("updating stored file with new data") + cfg = checkParameterConfig(cfg) + with open(cfgpath, "w", encoding='utf-8') as n: + json.dump(cfg, n, indent=1, ensure_ascii=False) + creds = json.load(c) + if creds: + if creds["clientId"] != clouds[0]["args"]["clientId"]: + creds["clientId"] = clouds[0]["args"]["clientId"] + if creds["userName"] != clouds[0]["args"]["username"]: + creds["userName"] = clouds[0]["args"]["username"] + if creds["password"] != clouds[0]["args"]["passwd"]: + creds["password"] = clouds[0]["args"]["passwd"] + else: + creds["clientId"] = clouds[0]["args"]["clientId"] + creds["userName"] = clouds[0]["args"]["username"] + creds["password"] = clouds[0]["args"]["passwd"] + with open(credspath, "w") as cw: + json.dump(creds,cw) + +def checkParameterConfig(cfg): + logger.info("Checking Parameters!!!!") + paramspath = "/var/user/files/params.json" + cfgparams = convertDStoJSON(cfg.get("labels")) + #check stored values + checkFileExist("params.json") + with open(paramspath, "r") as f: + logger.info("Opened param storage file") + params = json.load(f) + if params: + if cfgparams != params: + #go through each param + #if not "unknown" and cfg and params aren't the same take from cfg likely updated manually + #if key in cfg but not in params copy to params + logger.info("equalizing params between cfg and stored") + for key in cfgparams.keys(): + try: + if cfgparams[key] != params[key] and cfgparams[key] != "unknown": + params[key] = cfgparams[key] + except: + params[key] = cfgparams[key] + cfg["labels"] = convertJSONtoDS(params) + _set_global_args(convertJSONtoDS(params)) + with open(paramspath, "w") as p: + json.dump(params, p) + else: + with open(paramspath, "w") as p: + logger.info("initializing param file with params in memory") + json.dump(convertDStoJSON(get_params()), p) + cfg["labels"] = get_params() + + return cfg lwtData = { "init":False, @@ -18,7 +128,7 @@ def lwt(mac): lwtData["client"].will_set("meshify/db/194/_/mainHP/" + mac + ":00:00/connected",json.dumps({"value":False})) lwtData["init"] = True logger.info("Connecting to MQTT Broker for LWT purposes!!!!!!!") - lwtData["client"].connect("mq194.imistaway.net",1883, 600) + lwtData["client"].connect("mq194.imistaway.net",1883, 600) lwtData["client"].publish("meshify/db/194/_/mainHP/" + mac + ":00:00/connected", json.dumps({"value":True})) except Exception as e: logger.error("LWT DID NOT DO THE THING") @@ -28,6 +138,7 @@ def sendData(message): #logger.debug(message) mac = __topic__.split("/")[-1] #':'.join(re.findall('..', '%012x' % uuid.getnode())) lwt(mac) + checkCredentialConfig() for measure in message["measures"]: try: logger.debug(measure) @@ -40,8 +151,6 @@ def sendData(message): publish(__topic__ + ":01:99/" + measure["name"], json.dumps({"value": measure["value"]}), __qos__) except Exception as e: logger.error(e) - - #publish(__topic__, json.dumps({measure["name"]: measure["value"]}), __qos__) def convert_int(plc_tag, value): well_status_codes = { diff --git a/Pub_Sub/advvfdipp/v1/device_supervisor_advvfdippv1.cfg b/Pub_Sub/advvfdipp/mistaway/v1/device_supervisor_advvfdippv1.cfg similarity index 100% rename from Pub_Sub/advvfdipp/v1/device_supervisor_advvfdippv1.cfg rename to Pub_Sub/advvfdipp/mistaway/v1/device_supervisor_advvfdippv1.cfg diff --git a/Pub_Sub/advvfdipp/v1/pub/sendData.py b/Pub_Sub/advvfdipp/mistaway/v1/pub/sendData.py similarity index 100% rename from Pub_Sub/advvfdipp/v1/pub/sendData.py rename to Pub_Sub/advvfdipp/mistaway/v1/pub/sendData.py diff --git a/Pub_Sub/advvfdipp/v1/sub/receiveCommand.py b/Pub_Sub/advvfdipp/mistaway/v1/sub/receiveCommand.py similarity index 100% rename from Pub_Sub/advvfdipp/v1/sub/receiveCommand.py rename to Pub_Sub/advvfdipp/mistaway/v1/sub/receiveCommand.py diff --git a/Pub_Sub/advvfdipp/v2/device_supervisor_advvfdippv2.cfg b/Pub_Sub/advvfdipp/mistaway/v2/device_supervisor_advvfdippv2.cfg similarity index 100% rename from Pub_Sub/advvfdipp/v2/device_supervisor_advvfdippv2.cfg rename to Pub_Sub/advvfdipp/mistaway/v2/device_supervisor_advvfdippv2.cfg diff --git a/Pub_Sub/advvfdipp/v2/pub/sendData.py b/Pub_Sub/advvfdipp/mistaway/v2/pub/sendData.py similarity index 100% rename from Pub_Sub/advvfdipp/v2/pub/sendData.py rename to Pub_Sub/advvfdipp/mistaway/v2/pub/sendData.py diff --git a/Pub_Sub/advvfdipp/v2/sub/receiveCommand.py b/Pub_Sub/advvfdipp/mistaway/v2/sub/receiveCommand.py similarity index 100% rename from Pub_Sub/advvfdipp/v2/sub/receiveCommand.py rename to Pub_Sub/advvfdipp/mistaway/v2/sub/receiveCommand.py diff --git a/Pub_Sub/advvfdipp/mistaway/v3/advvfdipp_ma_v3.cfg b/Pub_Sub/advvfdipp/mistaway/v3/advvfdipp_ma_v3.cfg new file mode 100644 index 0000000..507b60b --- /dev/null +++ b/Pub_Sub/advvfdipp/mistaway/v3/advvfdipp_ma_v3.cfg @@ -0,0 +1,1085 @@ +{ + "controllers": [ + { + "protocol": "EtherNet/IP", + "name": "advvfdipp", + "args": {}, + "samplePeriod": 10, + "expired": 10000, + "endpoint": "192.168.1.10:44818" + } + ], + "groups": [ + { + "name": "default", + "uploadInterval": 600, + "reference": 44 + } + ], + "measures": [ + { + "name": "flowrate", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "val_Flowmeter", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "fluidlevel", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "val_FluidLevel", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "intakepressure", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "val_IntakePressure", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "intaketemperature", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "val_IntakeTemperature", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "tubingpressure", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "val_TubingPressure", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "pidcontrolmode", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "BIT", + "addr": "sts_PID_Control", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "wellstatus", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "INT", + "addr": "Device_Status_INT", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "vfdfrequency", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "VFD_SpeedFdbk", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "flowtotal", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "Flow_Total[0]", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "energytotal", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "Energy_Total[0]", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "vfdcurrent", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "VFD_OutCurrent", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "downholesensorstatus", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "INT", + "addr": "Downhole_Sensor_Status_INT", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "fluidspecificgravity", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "cfg_FluidSpecificGravity", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "flowtotalyesterday", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "Flow_Total[1]", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "energytotalyesterday", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "Energy_Total[1]", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "alarmflowrate", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "BIT", + "addr": "alarm_Flowmeter", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "alarmintakepressure", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "BIT", + "addr": "alarm_IntakePressure", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "alarmintaketemperature", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "BIT", + "addr": "alarm_IntakeTemperature", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "alarmtubingpressure", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "BIT", + "addr": "alarm_TubingPressure", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "alarmvfd", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "BIT", + "addr": "alarm_VFD", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "alarmlockout", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "BIT", + "addr": "alarm_Lockout", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "runpermissive", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "INT", + "addr": "Run_Permissive_INT", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "startpermissive", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "INT", + "addr": "Start_Permissive_INT", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "startcommand", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "BIT", + "addr": "cmd_Start", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "stopcommand", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "BIT", + "addr": "cmd_Stop", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "flowsetpoint", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "cfg_PID_FlowSP", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "fluidlevelsetpoint", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "cfg_PID_FluidLevelSP", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "manualfrequencysetpoint", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "cfg_PID_ManualSP", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "tubingpressuresetpoint", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "cfg_PID_TubingPressureSP", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "alarmfluidlevel", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "BIT", + "addr": "alarm_FluidLevel", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "pressureshutdownlimit", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "AIn_IntakePressure.Val_LoLim", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "pressurestartuplimit", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "AIn_IntakePressure.Val_HiLim", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "temperatureshutdownlimit", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "AIn_IntakeTemperature.Val_HiLim", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "temperaturestartuplimit", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "AIn_IntakeTemperature.Val_LoLim", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "sensorheight", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "cfg_DHSensorDistToIntake", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "last_vfd_fault_code", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "INT", + "addr": "PowerFlex755.Val_LastFaultCode", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "vfd_fault", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "INT", + "addr": "sts_CurrentVFDFaultCode", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "controllerfault_io", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "BIT", + "addr": "ControllerFault_IO", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "controllerfault_program", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "BIT", + "addr": "ControllerFault_Program", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "minvfdfrequency", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "PowerFlex755.Cfg_MinSpdRef", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "maxvfdfrequency", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "PowerFlex755.Cfg_MaxSpdRef", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "hartnettotal", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "in_HART_Flowmeter_Net", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "hartfwdtotal", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "in_HART_Flowmeter_Fwd", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "hartrevtotal", + "ctrlName": "advvfdipp", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "in_HART_Flowmeter_Rev", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "ctrlName": "advvfdipp", + "dataType": "BIT", + "addr": "cmd_Start", + "readWrite": "rw", + "uploadType": "periodic", + "group": "default", + "name": "cmd_Start", + "desc": "", + "unit": "", + "transformType": 0, + "gain": "1.0", + "offset": "0.0", + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "decimal": 2 + }, + { + "ctrlName": "advvfdipp", + "dataType": "BIT", + "addr": "cmd_Stop", + "readWrite": "rw", + "uploadType": "periodic", + "group": "default", + "name": "cmd_Stop", + "desc": "", + "unit": "", + "transformType": 0, + "gain": "1.0", + "offset": "0.0", + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "decimal": 2 + } + ], + "alarms": [], + "misc": { + "maxAlarmRecordSz": 2000, + "logLvl": "INFO", + "coms": [ + { + "name": "rs232", + "baud": 9600, + "bits": 8, + "stopbits": 1, + "parityChk": "n" + }, + { + "name": "rs485", + "baud": 19200, + "bits": 8, + "stopbits": 1, + "parityChk": "n" + } + ] + }, + "clouds": [ + { + "cacheSize": 100, + "enable": 1, + "type": "Standard MQTT", + "args": { + "host": "mq194.imistaway.net", + "port": 1883, + "clientId": "unknown", + "auth": 1, + "tls": 0, + "cleanSession": 1, + "mqttVersion": "v3.1.1", + "keepalive": 120, + "key": "", + "cert": "", + "rootCA": "", + "verifyServer": 0, + "verifyClient": 0, + "username": "unknown", + "passwd": "unknown", + "authType": 1 + }, + "name": "default" + } + ], + "labels": [ + { + "key": "SN", + "value": "GF5022137006251" + }, + { + "key": "MAC", + "value": "00:18:05:1a:e5:36" + } + ], + "quickfaas": { + "genericFuncs": [], + "uploadFuncs": [ + { + "name": "Send Data", + "trigger": "measure_event", + "topic": "meshify/db/194/_/advvfdipp/${MAC_LOWER}", + "qos": 1, + "groups": [ + "default" + ], + "funcName": "sendData", + "script": "# Enter your python code.\nimport json\nfrom common.Logger import logger\nfrom quickfaas.remotebus import publish\nimport re, uuid\nfrom paho.mqtt import client\n\nlwtData = {\n \"init\":False,\n \"client\": client.Client(client_id=str(uuid.uuid4()), clean_session=True, userdata=None, protocol=client.MQTTv311, transport=\"tcp\")\n}\ndef lwt(mac):\n try:\n #if not lwtData[\"connected\"]:\n if not lwtData[\"init\"]:\n logger.info(\"INITIALIZING LWT CLIENT\")\n lwtData[\"client\"].username_pw_set(username=\"admin\", password=\"columbus\")\n lwtData[\"client\"].will_set(\"meshify/db/194/_/mainHP/\" + mac + \":00:00/connected\",json.dumps({\"value\":False}))\n lwtData[\"init\"] = True\n logger.info(\"Connecting to MQTT Broker for LWT purposes!!!!!!!\")\n lwtData[\"client\"].connect(\"mq194.imistaway.net\",1883, 600)\n lwtData[\"client\"].publish(\"meshify/db/194/_/mainHP/\" + mac + \":00:00/connected\", json.dumps({\"value\":True}))\n except Exception as e:\n logger.error(\"LWT DID NOT DO THE THING\")\n logger.error(e)\n\ndef sendData(message):\n #logger.debug(message)\n mac = __topic__.split(\"/\")[-1] #':'.join(re.findall('..', '%012x' % uuid.getnode()))\n lwt(mac)\n for measure in message[\"measures\"]:\n try:\n logger.debug(measure)\n if measure[\"name\"] in [\"wellstatus\",\"pidcontrolmode\",\"downholesensorstatus\",\"alarmflowrate\",\"alarmintakepressure\",\"alarmintaketemperature\",\"alarmtubingpressure\",\"alarmvfd\",\"alarmlockout\",\"alarmfluidlevel\",\"runpermissive\",\"startpermissive\",\"last_vfd_fault_code\",\"vfd_fault\"]:\n logger.debug(\"Converting DINT/BOOL to STRING\")\n value = convert_int(measure[\"name\"], measure[\"value\"])\n logger.debug(\"Converted {} to {}\".format(measure[\"value\"], value))\n publish(__topic__ + \":01:99/\" + measure[\"name\"], json.dumps({\"value\": value}), __qos__)\n else:\n publish(__topic__ + \":01:99/\" + measure[\"name\"], json.dumps({\"value\": measure[\"value\"]}), __qos__)\n except Exception as e:\n logger.error(e)\n \n #publish(__topic__, json.dumps({measure[\"name\"]: measure[\"value\"]}), __qos__)\n\ndef convert_int(plc_tag, value):\n well_status_codes = {\n 0: \"Running\",\n 1: \"Pumped Off\",\n 2: \"Alarmed\",\n 3: \"Locked Out\",\n 4: \"Stopped\"\n }\n\n pid_control_codes = {\n 0: \"Flow\",\n 1: \"Fluid Level\",\n 2: \"Tubing Pressure\",\n 3: \"Manual\"\n }\n\n downhole_codes = {\n 0: \"OK\",\n 1: \"Connecting\",\n 2: \"Open Circuit\",\n 3: \"Shorted\",\n 4: \"Cannot Decode\"\n }\n\n permissive_codes = {\n 0: \"OK\",\n 1: \"Flow\",\n 2: \"Intake Pressure\",\n 3: \"Intake Temperature\",\n 4: \"Tubing Pressure\",\n 5: \"VFD\",\n 6: \"Fluid Level\",\n 7: \"Min. Downtime\"\n }\n\n alarm_codes = {\n 0: \"OK\",\n 1: \"Alarm\"\n }\n\n alarm_vfd_codes = {\n 0: \"OK\",\n 1: \"Locked Out\"\n }\n\n vfd_fault_codes = {\n 0: \"No Fault\",\n 2: \"Auxiliary Input\",\n 3: \"Power Loss\",\n 4: \"UnderVoltage\",\n 5: \"OverVoltage\",\n 7: \"Motor Overload\",\n 8: \"Heatsink OverTemp\",\n 9: \"Thermister OverTemp\",\n 10: \"Dynamic Brake OverTemp\",\n 12: \"Hardware OverCurrent\",\n 13: \"Ground Fault\",\n 14: \"Ground Warning\",\n 15: \"Load Loss\",\n 17: \"Input Phase Loss\",\n 18: \"Motor PTC Trip\",\n 19: \"Task Overrun\",\n 20: \"Torque Prove Speed Band\",\n 21: \"Output Phase Loss\",\n 24: \"Decel Inhibit\",\n 25: \"OverSpeed Limit\",\n 26: \"Brake Slipped\",\n 27: \"Torque Prove Conflict\",\n 28: \"TP Encls Confict\",\n 29: \"Analog In Loss\",\n 33: \"Auto Restarts Exhausted\",\n 35: \"IPM OverCurrent\",\n 36: \"SW OverCurrent\",\n 38: \"Phase U to Ground\",\n 39: \"Phase V to Ground\",\n 40: \"Phase W to Ground\",\n 41: \"Phase UV Short\",\n 42: \"Phase VW Short\",\n 43: \"Phase WU Short\",\n 44: \"Phase UNeg to Ground\",\n 45: \"Phase VNeg to Ground\",\n 46: \"Phase WNeg to Ground\",\n 48: \"System Defaulted\",\n 49: \"Drive Powerup\",\n 51: \"Clear Fault Queue\",\n 55: \"Control Board Overtemp\",\n 59: \"Invalid Code\",\n 61: \"Shear Pin 1\",\n 62: \"Shear Pin 2\",\n 64: \"Drive Overload\",\n 66: \"OW Torque Level\",\n 67: \"Pump Off\",\n 71: \"Port 1 Adapter\",\n 72: \"Port 2 Adapter\",\n 73: \"Port 3 Adapter\",\n 74: \"Port 4 Adapter\",\n 75: \"Port 5 Adapter\",\n 76: \"Port 6 Adapter\",\n 77: \"IR Volts Range\",\n 78: \"FluxAmps Ref Range\",\n 79: \"Excessive Load\",\n 80: \"AutoTune Aborted\",\n 81: \"Port 1 DPI Loss\",\n 82: \"Port 2 DPI Loss\",\n 83: \"Port 3 DPI Loss\",\n 84: \"Port 4 DPI Loss\",\n 85: \"Port 5 DPI Loss\",\n 86: \"Port 6 DPI Loss\",\n 87: \"IXo Voltage Range\",\n 91: \"Primary Velocity Feedback Loss\",\n 93: \"Hardware Enable Check\",\n 94: \"Alternate Velocity Feedback Loss\",\n 95: \"Auxiliary Velocity Feedback Loss\",\n 96: \"Position Feedback Loss\",\n 97: \"Auto Tach Switch\",\n 100: \"Parameter Checksum\",\n 101: \"Power Down NVS Blank\",\n 102: \"NVS Not Blank\",\n 103: \"Power Down NVS Incompatible\",\n 104: \"Power Board Checksum\",\n 106: \"Incompat MCB-PB\",\n 107: \"Replaced MCB-PB\",\n 108: \"Analog Calibration Checksum\",\n 110: \"Invalid Power Board Data\",\n 111: \"Power Board Invalid ID\",\n 112: \"Power Board App Min Version\",\n 113: \"Tracking DataError\",\n 115: \"Power Down Table Full\",\n 116: \"Power Down Entry Too Large\",\n 117: \"Power Down Data Checksum\",\n 118: \"Power Board Power Down Checksum\",\n 124: \"App ID Changed\",\n 125: \"Using Backup App\",\n 134: \"Start on Power Up\",\n 137: \"External Precharge Error\",\n 138: \"Precharge Open\",\n 141: \"Autotune Enc Angle\",\n 142: \"Autotune Speed Restricted\",\n 143: \"Autotune Current Regulator\",\n 144: \"Autotune Inertia\",\n 145: \"Autotune Travel\",\n 13035: \"Net IO Timeout\",\n 13037: \"Net IO Timeout\"\n\n }\n\n plc_tags = {\n \"wellstatus\": well_status_codes.get(value, \"Invalid Code\"),\n \"pidcontrolmode\": pid_control_codes.get(value, \"Invalid Code\"),\n \"downholesensorstatus\": downhole_codes.get(value, \"Invalid Code\"),\n \"alarmflowrate\": alarm_codes.get(value, \"Invalid Code\"),\n \"alarmintakepressure\": alarm_codes.get(value, \"Invalid Code\"),\n \"alarmintaketemperature\": alarm_codes.get(value, \"Invalid Code\"),\n \"alarmtubingpressure\": alarm_codes.get(value, \"Invalid Code\"),\n \"alarmvfd\": alarm_codes.get(value, \"Invalid Code\"),\n \"alarmlockout\": alarm_vfd_codes.get(value, \"Invalid Code\"),\n \"alarmfluidlevel\": alarm_codes.get(value, \"Invalid Code\"),\n \"runpermissive\": permissive_codes.get(value, \"Invalid Code\"),\n \"startpermissive\": permissive_codes.get(value, \"Invalid Code\"),\n \"last_vfd_fault_code\": vfd_fault_codes.get(value, \"Invalid Code\"),\n \"vfd_fault\": vfd_fault_codes.get(value, \"Invalid Code\")\n }\n\n return plc_tags.get(plc_tag, \"Invalid Tag\")\n\n ", + "msgType": 0, + "cloudName": "default" + } + ], + "downloadFuncs": [ + { + "name": "Commands", + "topic": "meshify/sets/194/${MAC_UPPER}:01:99", + "qos": 1, + "funcName": "receiveCommand", + "payload_type": "Plaintext", + "script": "# Enter your python code.\nimport json\nfrom quickfaas.measure import recall\nfrom common.Logger import logger\n\ndef sync(mac,value, wizard_api):\n #get new values and send\n try:\n data = recall()#json.loads(recall().decode(\"utf-8\"))\n except Exception as e:\n logger.error(e)\n logger.info(data)\n for controller in data:\n for measure in controller[\"measures\"]:\n #publish measure\n topic = \"meshify/db/194/_/advvfdipp/\" + mac + \"/\" + measure[\"name\"]\n if measure[\"name\"] in [\"wellstatus\",\"pidcontrolmode\",\"downholesensorstatus\",\"alarmflowrate\",\"alarmintakepressure\",\"alarmintaketemperature\",\"alarmtubingpressure\",\"alarmvfd\",\"alarmlockout\",\"alarmfluidlevel\",\"runpermissive\",\"startpermissive\",\"last_vfd_fault_code\",\"vfd_fault\"]:\n payload = [{\"value\": convert_int(measure[\"name\"], measure[\"value\"])}]\n else:\n payload = [{\"value\": measure[\"value\"]}]\n logger.debug(\"Sending on topic: {}\".format(topic))\n logger.debug(\"Sending value: {}\".format(payload))\n wizard_api.mqtt_publish(topic, json.dumps(payload))\ndef writeplctag(mac, value, wizard_api):\n try:\n value = json.loads(value.replace(\"'\",'\"'))\n logger.debug(value)\n message = {\"advvfdipp\":{value[\"tag\"]: value[\"val\"]}}\n wizard_api.write_plc_values(message)\n except Exception as e:\n logger.debug(e)\n \ndef receiveCommand(topic, payload, wizard_api):\n logger.debug(topic)\n logger.debug(json.loads(payload))\n p = json.loads(payload)[0]\n command = p[\"payload\"][\"name\"].split(\".\")[1]\n commands = {\n \"sync\": sync,\n \"writeplctag\": writeplctag,\n }\n commands[command](p[\"mac\"].lower(),p[\"payload\"][\"value\"], wizard_api)\n #logger.debug(command)\n ack(p[\"msgId\"], p[\"mac\"], p[\"payload\"][\"name\"].split(\".\")[1], p[\"payload\"][\"value\"], wizard_api)\n\ndef ack(msgid, mac, name, value, wizard_api):\n #logger.debug(mac)\n mac = \"\".join(mac.split(\":\")[:-2])\n #logger.debug(msgid)\n #logger.debug(mac)\n #logger.debug(name)\n #logger.debug(value)\n wizard_api.mqtt_publish(\"meshify/responses/\" + str(msgid), json.dumps([{\"value\": \"{} Success Setting: {} To: {}\".format(mac,name, value), \"msgid\": str(msgid)}]))\n\ndef convert_int(plc_tag, value):\n well_status_codes = {\n 0: \"Running\",\n 1: \"Pumped Off\",\n 2: \"Alarmed\",\n 3: \"Locked Out\",\n 4: \"Stopped\"\n }\n\n pid_control_codes = {\n 0: \"Flow\",\n 1: \"Fluid Level\",\n 2: \"Tubing Pressure\",\n 3: \"Manual\"\n }\n\n downhole_codes = {\n 0: \"OK\",\n 1: \"Connecting\",\n 2: \"Open Circuit\",\n 3: \"Shorted\",\n 4: \"Cannot Decode\"\n }\n\n permissive_codes = {\n 0: \"OK\",\n 1: \"Flow\",\n 2: \"Intake Pressure\",\n 3: \"Intake Temperature\",\n 4: \"Tubing Pressure\",\n 5: \"VFD\",\n 6: \"Fluid Level\",\n 7: \"Min. Downtime\"\n }\n\n alarm_codes = {\n 0: \"OK\",\n 1: \"Alarm\"\n }\n\n alarm_vfd_codes = {\n 0: \"OK\",\n 1: \"Locked Out\"\n }\n\n vfd_fault_codes = {\n 0: \"No Fault\",\n 2: \"Auxiliary Input\",\n 3: \"Power Loss\",\n 4: \"UnderVoltage\",\n 5: \"OverVoltage\",\n 7: \"Motor Overload\",\n 8: \"Heatsink OverTemp\",\n 9: \"Thermister OverTemp\",\n 10: \"Dynamic Brake OverTemp\",\n 12: \"Hardware OverCurrent\",\n 13: \"Ground Fault\",\n 14: \"Ground Warning\",\n 15: \"Load Loss\",\n 17: \"Input Phase Loss\",\n 18: \"Motor PTC Trip\",\n 19: \"Task Overrun\",\n 20: \"Torque Prove Speed Band\",\n 21: \"Output Phase Loss\",\n 24: \"Decel Inhibit\",\n 25: \"OverSpeed Limit\",\n 26: \"Brake Slipped\",\n 27: \"Torque Prove Conflict\",\n 28: \"TP Encls Confict\",\n 29: \"Analog In Loss\",\n 33: \"Auto Restarts Exhausted\",\n 35: \"IPM OverCurrent\",\n 36: \"SW OverCurrent\",\n 38: \"Phase U to Ground\",\n 39: \"Phase V to Ground\",\n 40: \"Phase W to Ground\",\n 41: \"Phase UV Short\",\n 42: \"Phase VW Short\",\n 43: \"Phase WU Short\",\n 44: \"Phase UNeg to Ground\",\n 45: \"Phase VNeg to Ground\",\n 46: \"Phase WNeg to Ground\",\n 48: \"System Defaulted\",\n 49: \"Drive Powerup\",\n 51: \"Clear Fault Queue\",\n 55: \"Control Board Overtemp\",\n 59: \"Invalid Code\",\n 61: \"Shear Pin 1\",\n 62: \"Shear Pin 2\",\n 64: \"Drive Overload\",\n 66: \"OW Torque Level\",\n 67: \"Pump Off\",\n 71: \"Port 1 Adapter\",\n 72: \"Port 2 Adapter\",\n 73: \"Port 3 Adapter\",\n 74: \"Port 4 Adapter\",\n 75: \"Port 5 Adapter\",\n 76: \"Port 6 Adapter\",\n 77: \"IR Volts Range\",\n 78: \"FluxAmps Ref Range\",\n 79: \"Excessive Load\",\n 80: \"AutoTune Aborted\",\n 81: \"Port 1 DPI Loss\",\n 82: \"Port 2 DPI Loss\",\n 83: \"Port 3 DPI Loss\",\n 84: \"Port 4 DPI Loss\",\n 85: \"Port 5 DPI Loss\",\n 86: \"Port 6 DPI Loss\",\n 87: \"IXo Voltage Range\",\n 91: \"Primary Velocity Feedback Loss\",\n 93: \"Hardware Enable Check\",\n 94: \"Alternate Velocity Feedback Loss\",\n 95: \"Auxiliary Velocity Feedback Loss\",\n 96: \"Position Feedback Loss\",\n 97: \"Auto Tach Switch\",\n 100: \"Parameter Checksum\",\n 101: \"Power Down NVS Blank\",\n 102: \"NVS Not Blank\",\n 103: \"Power Down NVS Incompatible\",\n 104: \"Power Board Checksum\",\n 106: \"Incompat MCB-PB\",\n 107: \"Replaced MCB-PB\",\n 108: \"Analog Calibration Checksum\",\n 110: \"Invalid Power Board Data\",\n 111: \"Power Board Invalid ID\",\n 112: \"Power Board App Min Version\",\n 113: \"Tracking DataError\",\n 115: \"Power Down Table Full\",\n 116: \"Power Down Entry Too Large\",\n 117: \"Power Down Data Checksum\",\n 118: \"Power Board Power Down Checksum\",\n 124: \"App ID Changed\",\n 125: \"Using Backup App\",\n 134: \"Start on Power Up\",\n 137: \"External Precharge Error\",\n 138: \"Precharge Open\",\n 141: \"Autotune Enc Angle\",\n 142: \"Autotune Speed Restricted\",\n 143: \"Autotune Current Regulator\",\n 144: \"Autotune Inertia\",\n 145: \"Autotune Travel\",\n 13035: \"Net IO Timeout\",\n 13037: \"Net IO Timeout\"\n\n }\n\n plc_tags = {\n \"wellstatus\": well_status_codes.get(value, \"Invalid Code\"),\n \"pidcontrolmode\": pid_control_codes.get(value, \"Invalid Code\"),\n \"downholesensorstatus\": downhole_codes.get(value, \"Invalid Code\"),\n \"alarmflowrate\": alarm_codes.get(value, \"Invalid Code\"),\n \"alarmintakepressure\": alarm_codes.get(value, \"Invalid Code\"),\n \"alarmintaketemperature\": alarm_codes.get(value, \"Invalid Code\"),\n \"alarmtubingpressure\": alarm_codes.get(value, \"Invalid Code\"),\n \"alarmvfd\": alarm_codes.get(value, \"Invalid Code\"),\n \"alarmlockout\": alarm_vfd_codes.get(value, \"Invalid Code\"),\n \"alarmfluidlevel\": alarm_codes.get(value, \"Invalid Code\"),\n \"runpermissive\": permissive_codes.get(value, \"Invalid Code\"),\n \"startpermissive\": permissive_codes.get(value, \"Invalid Code\"),\n \"last_vfd_fault_code\": vfd_fault_codes.get(value, \"Invalid Code\"),\n \"vfd_fault\": vfd_fault_codes.get(value, \"Invalid Code\")\n }\n\n return plc_tags.get(plc_tag, \"Invalid Tag\")\n", + "msgType": 0, + "trigger": "command_event", + "cloudName": "default" + } + ] + }, + "modbusSlave": { + "enable": 0, + "protocol": "Modbus-TCP", + "port": 502, + "slaveAddr": 1, + "int16Ord": "ab", + "int32Ord": "abcd", + "float32Ord": "abcd", + "maxConnection": 5, + "mapping_table": [] + }, + "iec104Server": { + "enable": 0, + "cotSize": 2, + "port": 2404, + "serverList": [ + { + "asduAddr": 1 + } + ], + "kValue": 12, + "wValue": 8, + "t0": 15, + "t1": 15, + "t2": 10, + "t3": 20, + "maximumLink": 5, + "timeSet": 1, + "byteOrder": "abcd", + "mapping_table": [] + }, + "opcuaServer": { + "enable": 0, + "port": 4840, + "maximumLink": 5, + "securityMode": 0, + "identifierType": "String", + "mapping_table": [] + }, + "bindConfig": { + "enable": 0, + "bind": { + "modelId": "", + "modelName": "", + "srcId": "", + "srcName": "", + "devId": "", + "devName": "" + }, + "varGroups": [], + "variables": [], + "alerts": [] + }, + "southMetadata": {}, + "bindMetadata": { + "version": "", + "timestamp": "" + } +} \ No newline at end of file diff --git a/Pub_Sub/advvfdipp/v3/pub/sendData.py b/Pub_Sub/advvfdipp/mistaway/v3/pub/sendData.py similarity index 55% rename from Pub_Sub/advvfdipp/v3/pub/sendData.py rename to Pub_Sub/advvfdipp/mistaway/v3/pub/sendData.py index 84f5106..700fcba 100644 --- a/Pub_Sub/advvfdipp/v3/pub/sendData.py +++ b/Pub_Sub/advvfdipp/mistaway/v3/pub/sendData.py @@ -1,9 +1,120 @@ -# Enter your python code. -import json +import json, uuid, os from common.Logger import logger from quickfaas.remotebus import publish -import re, uuid from paho.mqtt import client +from quickfaas.global_dict import get as get_params +from quickfaas.global_dict import _set_global_args + +def reboot(): + logger.info("!" * 10 + "REBOOTING DEVICE" + "!"*10) + r = os.popen("kill -s SIGHUP `cat /var/run/python/supervisord.pid`").read() + logger.info(f"REBOOT : {r}") + +def checkFileExist(filename): + path = "/var/user/files" + if not os.path.exists(path): + logger.info("no folder making files folder in var/user") + os.makedirs(path) + with open(path + "/" + filename, "a") as f: + json.dump({}, f) + if not os.path.exists(path + "/" + filename): + logger.info("no creds file making creds file") + with open(path + "/" + filename, "a") as f: + json.dump({}, f) + +def convertDStoJSON(ds): + j = dict() + for x in ds: + j[x["key"]] = x["value"] + return j + +def convertJSONtoDS(j): + d = [] + for key in j.keys(): + d.append({"key": key, "value": j[key]}) + return d + +def checkCredentialConfig(): + logger.info("CHECKING CONFIG") + cfgpath = "/var/user/cfg/device_supervisor/device_supervisor.cfg" + credspath = "/var/user/files/creds.json" + cfg = dict() + with open(cfgpath, "r") as f: + cfg = json.load(f) + clouds = cfg.get("clouds") + logger.info(clouds) + #if not configured then try to configure from stored values + if clouds[0]["args"]["clientId"] == "unknown" or clouds[0]["args"]["username"] == "unknown" or not clouds[0]["args"]["passwd"] or clouds[0]["args"]["passwd"] == "unknown": + checkFileExist("creds.json") + with open(credspath, "r") as c: + creds = json.load(c) + if creds: + logger.info("updating config with stored data") + clouds[0]["args"]["clientId"] = creds["clientId"] + clouds[0]["args"]["username"] = creds["userName"] + clouds[0]["args"]["passwd"] = creds["password"] + cfg["clouds"] = clouds + cfg = checkParameterConfig(cfg) + with open(cfgpath, "w", encoding='utf-8') as n: + json.dump(cfg, n, indent=1, ensure_ascii=False) + reboot() + else: + #assuming clouds is filled out, if data is different then assume someone typed in something new and store it, if creds is empty fill with clouds' data + checkFileExist("creds.json") + with open(credspath, "r") as c: + logger.info("updating stored file with new data") + cfg = checkParameterConfig(cfg) + with open(cfgpath, "w", encoding='utf-8') as n: + json.dump(cfg, n, indent=1, ensure_ascii=False) + creds = json.load(c) + if creds: + if creds["clientId"] != clouds[0]["args"]["clientId"]: + creds["clientId"] = clouds[0]["args"]["clientId"] + if creds["userName"] != clouds[0]["args"]["username"]: + creds["userName"] = clouds[0]["args"]["username"] + if creds["password"] != clouds[0]["args"]["passwd"]: + creds["password"] = clouds[0]["args"]["passwd"] + else: + creds["clientId"] = clouds[0]["args"]["clientId"] + creds["userName"] = clouds[0]["args"]["username"] + creds["password"] = clouds[0]["args"]["passwd"] + with open(credspath, "w") as cw: + json.dump(creds,cw) + +def checkParameterConfig(cfg): + logger.info("Checking Parameters!!!!") + paramspath = "/var/user/files/params.json" + cfgparams = convertDStoJSON(cfg.get("labels")) + #check stored values + checkFileExist("params.json") + with open(paramspath, "r") as f: + logger.info("Opened param storage file") + params = json.load(f) + if params: + if cfgparams != params: + #go through each param + #if not "unknown" and cfg and params aren't the same take from cfg likely updated manually + #if key in cfg but not in params copy to params + logger.info("equalizing params between cfg and stored") + for key in cfgparams.keys(): + try: + if cfgparams[key] != params[key] and cfgparams[key] != "unknown": + params[key] = cfgparams[key] + except: + params[key] = cfgparams[key] + cfg["labels"] = convertJSONtoDS(params) + _set_global_args(convertJSONtoDS(params)) + with open(paramspath, "w") as p: + json.dump(params, p) + else: + with open(paramspath, "w") as p: + logger.info("initializing param file with params in memory") + json.dump(convertDStoJSON(get_params()), p) + cfg["labels"] = get_params() + + return cfg + + lwtData = { "init":False, @@ -13,21 +124,24 @@ def lwt(mac): try: #if not lwtData["connected"]: if not lwtData["init"]: - logger.info("INITIALIZING LWT CLIENT") + print("INITIALIZING LWT CLIENT") lwtData["client"].username_pw_set(username="admin", password="columbus") - lwtData["client"].will_set("meshify/db/194/_/mainHP/" + mac + ":00:00/connected",json.dumps({"value":False})) + lwtData["client"].will_set("meshify/db/194/_/mainHP/" + mac + ":00:00/connected",json.dumps([{"value":False}])) + lwtData["client"].reconnect_delay_set(min_delay=10, max_delay=120) lwtData["init"] = True - logger.info("Connecting to MQTT Broker for LWT purposes!!!!!!!") + print("Connecting to MQTT Broker for LWT purposes!!!!!!!") lwtData["client"].connect("mq194.imistaway.net",1883, 600) - lwtData["client"].publish("meshify/db/194/_/mainHP/" + mac + ":00:00/connected", json.dumps({"value":True})) + lwtData["client"].reconnect() + lwtData["client"].publish("meshify/db/194/_/mainHP/" + mac + ":00:00/connected", json.dumps([{"value":True}])) except Exception as e: - logger.error("LWT DID NOT DO THE THING") - logger.error(e) + print("LWT DID NOT DO THE THING") + print(e) def sendData(message): #logger.debug(message) - mac = __topic__.split("/")[-1] #':'.join(re.findall('..', '%012x' % uuid.getnode())) + mac = __topic__.split("/")[-1] lwt(mac) + checkCredentialConfig() for measure in message["measures"]: try: logger.debug(measure) @@ -41,7 +155,6 @@ def sendData(message): except Exception as e: logger.error(e) - #publish(__topic__, json.dumps({measure["name"]: measure["value"]}), __qos__) def convert_int(plc_tag, value): well_status_codes = { diff --git a/Pub_Sub/advvfdipp/v3/sub/receiveCommand.py b/Pub_Sub/advvfdipp/mistaway/v3/sub/receiveCommand.py similarity index 100% rename from Pub_Sub/advvfdipp/v3/sub/receiveCommand.py rename to Pub_Sub/advvfdipp/mistaway/v3/sub/receiveCommand.py diff --git a/Pub_Sub/advvfdipp/v1/.DS_Store b/Pub_Sub/advvfdipp/v1/.DS_Store deleted file mode 100644 index 643c2a6..0000000 Binary files a/Pub_Sub/advvfdipp/v1/.DS_Store and /dev/null differ diff --git a/Pub_Sub/advvfdipp/v2/.DS_Store b/Pub_Sub/advvfdipp/v2/.DS_Store deleted file mode 100644 index 55d38c9..0000000 Binary files a/Pub_Sub/advvfdipp/v2/.DS_Store and /dev/null differ diff --git a/Pub_Sub/flowmeterskid/mistaway/v1/flowmonitor_ma_v1.cfg b/Pub_Sub/flowmeterskid/mistaway/v1/flowmonitor_ma_v1.cfg new file mode 100644 index 0000000..7e268d1 --- /dev/null +++ b/Pub_Sub/flowmeterskid/mistaway/v1/flowmonitor_ma_v1.cfg @@ -0,0 +1,256 @@ +{ + "controllers": [ + { + "protocol": "Modbus-RTU", + "name": "flowmonitor", + "endpoint": "rs485", + "args": { + "slaveAddr": 247, + "int16Ord": "ab", + "int32Ord": "cdab", + "float32Ord": "cdab", + "int64Ord": "abcdefgh", + "enableMsecSample": 0, + "continuousAcquisition": 1, + "maxContinuousNumber": 64, + "communicationInterval": 3, + "msecSamplePeriod": 500, + "msecPackage": 20 + }, + "samplePeriod": 10, + "expired": 10000 + } + ], + "measures": [ + { + "name": "flowrate", + "ctrlName": "flowmonitor", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "43874", + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "decimal": 2, + "gain": "1.0", + "offset": "0.0", + "msecSample": 0 + }, + { + "name": "flow_unit", + "ctrlName": "flowmonitor", + "group": "default", + "uploadType": "periodic", + "dataType": "INT", + "addr": "42103", + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "gain": "1.0", + "offset": "0.0", + "msecSample": 0 + }, + { + "name": "totalizer_1", + "ctrlName": "flowmonitor", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "42610", + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "decimal": 2, + "gain": "1.0", + "offset": "0.0", + "msecSample": 0 + }, + { + "name": "totalizer_1_unit", + "ctrlName": "flowmonitor", + "group": "default", + "uploadType": "periodic", + "dataType": "INT", + "addr": "44604", + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "gain": "1.0", + "offset": "0.0", + "msecSample": 0 + } + ], + "alarmLables": [ + "default" + ], + "alarms": [], + "groups": [ + { + "name": "default", + "uploadInterval": 600 + } + ], + "misc": { + "maxAlarmRecordSz": 2000, + "logLvl": "INFO", + "coms": [ + { + "name": "rs232", + "baud": 9600, + "bits": 8, + "parityChk": "n", + "stopbits": 1 + }, + { + "name": "rs485", + "baud": 19200, + "bits": 8, + "parityChk": "n", + "stopbits": 1 + } + ] + }, + "clouds": [ + { + "cacheSize": 10000, + "enable": 1, + "name": "default", + "type": "Standard MQTT", + "args": { + "host": "mq194.imistaway.net", + "port": 1883, + "clientId": "unknown", + "auth": 1, + "tls": 0, + "cleanSession": 0, + "mqttVersion": "v3.1.1", + "keepalive": 60, + "key": "", + "cert": "", + "rootCA": "", + "verifyServer": 0, + "verifyClient": 0, + "username": "unknown", + "passwd": "unknown" + } + } + ], + "quickfaas": { + "genericFuncs": [], + "uploadFuncs": [ + { + "qos": 1, + "funcName": "sendData", + "script": "# Enter your python code.\nimport json\nfrom datetime import datetime as dt\nfrom common.Logger import logger\nfrom quickfaas.remotebus import publish\nimport re, uuid\nfrom paho.mqtt import client\n\npayload = {}\n\ntry:\n with open(\"/var/user/files/totalizers.json\", \"r\") as t:\n totalizers = json.load(t)\n if not totalizers:\n logger.info(\"-----INITIALIZING TOTALIZERS-----\")\n totalizers = {\n \"day\": 0,\n \"month\": 0,\n \"lifetime\": 0,\n \"dayHolding\": 0,\n \"monthHolding\": 0\n }\nexcept:\n totalizers = {\n \"day\": 0,\n \"month\": 0,\n \"lifetime\": 0,\n \"dayHolding\": 0,\n \"monthHolding\": 0\n }\n\nlwtData = {\n \"init\":False,\n \"client\": client.Client(client_id=str(uuid.uuid4()), clean_session=True, userdata=None, protocol=client.MQTTv311, transport=\"tcp\")\n}\ndef lwt(mac):\n try:\n #if not lwtData[\"connected\"]:\n if not lwtData[\"init\"]:\n print(\"INITIALIZING LWT CLIENT\")\n lwtData[\"client\"].username_pw_set(username=\"admin\", password=\"columbus\")\n lwtData[\"client\"].will_set(\"meshify/db/194/_/mainHP/\" + mac + \":00:00/connected\",json.dumps([{\"value\":False}]))\n lwtData[\"client\"].reconnect_delay_set(min_delay=10, max_delay=120)\n lwtData[\"init\"] = True\n print(\"Connecting to MQTT Broker for LWT purposes!!!!!!!\")\n lwtData[\"client\"].connect(\"mq194.imistaway.net\",1883, 600)\n lwtData[\"client\"].reconnect()\n lwtData[\"client\"].publish(\"meshify/db/194/_/mainHP/\" + mac + \":00:00/connected\", json.dumps([{\"value\":True}]))\n except Exception as e:\n print(\"LWT DID NOT DO THE THING\")\n print(e)\n\ndef sendData(message,wizard_api):\n logger.debug(message)\n mac = __topic__.split(\"/\")[-1] #':'.join(re.findall('..', '%012x' % uuid.getnode()))\n lwt(mac)\n try:\n publishFlowrate( message[\"values\"][\"flowmonitor\"][\"flowrate\"][\"raw_data\"], message[\"values\"][\"flowmonitor\"][\"flow_unit\"][\"raw_data\"])\n totalizeDay(message[\"values\"][\"flowmonitor\"][\"totalizer_1\"][\"raw_data\"],message[\"values\"][\"flowmonitor\"][\"totalizer_1_unit\"][\"raw_data\"])\n totalizeMonth(message[\"values\"][\"flowmonitor\"][\"totalizer_1\"][\"raw_data\"],message[\"values\"][\"flowmonitor\"][\"totalizer_1_unit\"][\"raw_data\"])\n \n except Exception as e:\n logger.error(e)\n \n\ndef saveTotalizers():\n try:\n with open(\"/var/user/files/totalizers.json\", \"w\") as t:\n json.dump(totalizers,t)\n except Exception as e:\n logger.error(e)\n\n\ndef publishFlowrate(fr, unit):\n if unit == 45:\n publish(__topic__ + \":01:40/\" + \"gpm_flow\", json.dumps([{\"value\": f\"{fr}\"}]),__qos__)\n publish(__topic__ + \":01:40/\" + \"bpd_flow\", json.dumps([{\"value\": f\"{fr*((60*24)/42)}\"}]),__qos__)\n elif unit == 63:\n publish(__topic__ + \":01:40/\" + \"bpd_flow\", json.dumps([{\"value\": f\"{fr}\"}]),__qos__)\n publish(__topic__ + \":01:40/\" + \"gpm_flow\", json.dumps([{\"value\": f\"{fr * (42/(24*60))}\"}]),__qos__)\n\n\ndef totalizeDay(lifetime,unit):\n now = dt.now()\n reset = False\n value = lifetime - totalizers[\"dayHolding\"]\n if not int(now.strftime(\"%d\")) == int(totalizers[\"day\"]):\n totalizers[\"dayHolding\"] = lifetime\n totalizers[\"day\"] = int(now.strftime(\"%d\"))\n saveTotalizers()\n reset = True\n if unit == 11:\n publish(__topic__ + \":01:40/\" + \"gal_total\", json.dumps([{\"value\": f\"{value}\"}]),__qos__)\n publish(__topic__ + \":01:40/\" + \"bbl_total\", json.dumps([{\"value\": f\"{value/42}\"}]),__qos__)\n publish(__topic__ + \":01:40/\" + \"lifetime_flow_meter_gal\", json.dumps([{\"value\": f\"{lifetime}\"}]),__qos__)\n publish(__topic__ + \":01:40/\" + \"lifetime_flow_meter_bbls\", json.dumps([{\"value\": f\"{lifetime/42}\"}]),__qos__)\n if reset:\n publish(__topic__ + \":01:40/\" + \"gal_total\", json.dumps([{\"value\": f\"{0}\"}]),__qos__)\n publish(__topic__ + \":01:40/\" + \"bbl_total\", json.dumps([{\"value\": f\"{0}\"}]),__qos__)\n publish(__topic__ + \":01:40/\" + \"gal_total_yesterday\", json.dumps([{\"value\": f\"{value}\"}]),__qos__)\n publish(__topic__ + \":01:40/\" + \"bbl_total_yesterday\", json.dumps([{\"value\": f\"{value/42}\"}]),__qos__)\n elif unit == 15:\n publish(__topic__ + \":01:40/\" + \"bbl_total\", json.dumps([{\"value\": f\"{value}\"}]),__qos__)\n publish(__topic__ + \":01:40/\" + \"gal_total\", json.dumps([{\"value\": f\"{value*42}\"}]),__qos__)\n publish(__topic__ + \":01:40/\" + \"lifetime_flow_meter_bbls\", json.dumps([{\"value\": f\"{lifetime}\"}]),__qos__)\n publish(__topic__ + \":01:40/\" + \"lifetime_flow_meter_gal\", json.dumps([{\"value\": f\"{lifetime*42}\"}]),__qos__)\n if reset:\n publish(__topic__ + \":01:40/\" + \"bbl_total\", json.dumps([{\"value\": f\"{0}\"}]),__qos__)\n publish(__topic__ + \":01:40/\" + \"gal_total\", json.dumps([{\"value\": f\"{0}\"}]),__qos__)\n publish(__topic__ + \":01:40/\" + \"bbl_total_yesterday\", json.dumps([{\"value\": f\"{value}\"}]),__qos__)\n publish(__topic__ + \":01:40/\" + \"gal_total_yesterday\", json.dumps([{\"value\": f\"{value*42}\"}]),__qos__)\n\n\n\ndef totalizeMonth(lifetime, unit):\n now = dt.now()\n reset = False\n value = lifetime - totalizers[\"monthHolding\"]\n if not int(now.strftime(\"%m\")) == int(totalizers[\"month\"]):\n totalizers[\"monthHolding\"] = lifetime\n totalizers[\"month\"] = now.strftime(\"%m\")\n saveTotalizers()\n reset = True\n if unit == 11:\n publish(__topic__ + \":01:40/\" + \"gal_total_thismonth\", json.dumps([{\"value\": f\"{value}\"}]),__qos__)\n publish(__topic__ + \":01:40/\" + \"bbl_total_thismonth\", json.dumps([{\"value\": f\"{value/42}\"}]),__qos__)\n if reset:\n publish(__topic__ + \":01:40/\" + \"gal_total_thismonth\", json.dumps([{\"value\": f\"{0}\"}]),__qos__)\n publish(__topic__ + \":01:40/\" + \"bbl_total_thismonth\", json.dumps([{\"value\": f\"{0}\"}]),__qos__)\n publish(__topic__ + \":01:40/\" + \"gal_total_lastmonth\", json.dumps([{\"value\": f\"{value}\"}]),__qos__)\n publish(__topic__ + \":01:40/\" + \"bbl_total_lastmonth\", json.dumps([{\"value\": f\"{value/42}\"}]),__qos__)\n elif unit == 15:\n publish(__topic__ + \":01:40/\" + \"bbl_total_thismonth\", json.dumps([{\"value\": f\"{value}\"}]),__qos__)\n publish(__topic__ + \":01:40/\" + \"gal_total_thismonth\", json.dumps([{\"value\": f\"{value*42}\"}]),__qos__)\n if reset:\n publish(__topic__ + \":01:40/\" + \"bbl_total_thismonth\", json.dumps([{\"value\": f\"{0}\"}]),__qos__)\n publish(__topic__ + \":01:40/\" + \"gal_total_thismonth\", json.dumps([{\"value\": f\"{0}\"}]),__qos__)\n publish(__topic__ + \":01:40/\" + \"bbl_total_lastmonth\", json.dumps([{\"value\": f\"{value}\"}]),__qos__)\n publish(__topic__ + \":01:40/\" + \"gal_total_lastmonth\", json.dumps([{\"value\": f\"{value*42}\"}]),__qos__)\n", + "name": "Send Data", + "trigger": "measure_event", + "topic": "meshify/db/194/_/flowmonitor/${MAC}", + "cloudName": "default", + "groups": [ + "default" + ], + "msgType": 0 + } + ], + "downloadFuncs": [] + }, + "labels": [ + { + "key": "SN", + "value": "GF5022223016134" + }, + { + "key": "MAC", + "value": "00:18:05:21:b3:0a" + } + ], + "modbusSlave": { + "enable": 0, + "protocol": "Modbus-TCP", + "port": 502, + "slaveAddr": 1, + "int16Ord": "ab", + "int32Ord": "abcd", + "float32Ord": "abcd", + "maxConnection": 5, + "mapping_table": [] + }, + "modbusRTUSlave": { + "enable": 0, + "protocol": "Modbus-RTU", + "coms": "rs485", + "slaveAddr": 1, + "int16Ord": "ab", + "int32Ord": "abcd", + "float32Ord": "abcd", + "mapping_table": [] + }, + "iec104Server": { + "enable": 0, + "cotSize": 2, + "port": 2404, + "serverList": [ + { + "asduAddr": 1 + } + ], + "kValue": 12, + "wValue": 8, + "t0": 30, + "t1": 15, + "t2": 10, + "t3": 20, + "maximumLink": 5, + "timeSet": 1, + "byteOrder": "abcd", + "mapping_table": [] + }, + "iec104Client": { + "enable": 0, + "connectType": 2, + "serverAddr": "ipower.inhandcloud.cn", + "serverPort": 2404, + "communicationCode": "", + "protocol": 1, + "asduAddr": 1, + "tls": 0, + "mapping_table": { + "YX": [], + "YC": [], + "YK": [] + } + }, + "opcuaServer": { + "enable": 0, + "port": 4840, + "maximumLink": 5, + "securityMode": 0, + "identifierType": "String", + "mapping_table": [] + }, + "southMetadata": {}, + "bindMetadata": { + "version": "", + "timestamp": "" + }, + "bindConfig": { + "enable": 0, + "bind": { + "modelId": "", + "modelName": "", + "srcId": "", + "srcName": "", + "devId": "", + "devName": "" + }, + "varGroups": [], + "variables": [], + "alerts": [] + }, + "version": "2.3.1" +} \ No newline at end of file diff --git a/Pub_Sub/flowmeterskid/mistaway/v1/pub/sendData.py b/Pub_Sub/flowmeterskid/mistaway/v1/pub/sendData.py new file mode 100644 index 0000000..14f9779 --- /dev/null +++ b/Pub_Sub/flowmeterskid/mistaway/v1/pub/sendData.py @@ -0,0 +1,253 @@ +import json, os, uuid +from datetime import datetime as dt +from common.Logger import logger +from quickfaas.remotebus import publish +from paho.mqtt import client +from quickfaas.global_dict import get as get_params +from quickfaas.global_dict import _set_global_args + +def reboot(): + #basic = Basic() + logger.info("!" * 10 + "REBOOTING DEVICE" + "!"*10) + r = os.popen("kill -s SIGHUP `cat /var/run/python/supervisord.pid`").read() + logger.info(f"REBOOT : {r}") + +def checkFileExist(filename): + path = "/var/user/files" + if not os.path.exists(path): + logger.info("no folder making files folder in var/user") + os.makedirs(path) + with open(path + "/" + filename, "a") as f: + json.dump({}, f) + if not os.path.exists(path + "/" + filename): + logger.info("no creds file making creds file") + with open(path + "/" + filename, "a") as f: + json.dump({}, f) + +def convertDStoJSON(ds): + j = dict() + for x in ds: + j[x["key"]] = x["value"] + return j + +def convertJSONtoDS(j): + d = [] + for key in j.keys(): + d.append({"key": key, "value": j[key]}) + return d + +def checkCredentialConfig(): + logger.info("CHECKING CONFIG") + cfgpath = "/var/user/cfg/device_supervisor/device_supervisor.cfg" + credspath = "/var/user/files/creds.json" + cfg = dict() + with open(cfgpath, "r") as f: + cfg = json.load(f) + clouds = cfg.get("clouds") + logger.info(clouds) + #if not configured then try to configure from stored values + if clouds[0]["args"]["clientId"] == "unknown" or clouds[0]["args"]["username"] == "unknown" or not clouds[0]["args"]["passwd"] or clouds[0]["args"]["passwd"] == "unknown": + checkFileExist("creds.json") + with open(credspath, "r") as c: + creds = json.load(c) + if creds: + logger.info("updating config with stored data") + clouds[0]["args"]["clientId"] = creds["clientId"] + clouds[0]["args"]["username"] = creds["userName"] + clouds[0]["args"]["passwd"] = creds["password"] + cfg["clouds"] = clouds + cfg = checkParameterConfig(cfg) + with open(cfgpath, "w", encoding='utf-8') as n: + json.dump(cfg, n, indent=1, ensure_ascii=False) + reboot() + else: + #assuming clouds is filled out, if data is different then assume someone typed in something new and store it, if creds is empty fill with clouds' data + checkFileExist("creds.json") + with open(credspath, "r") as c: + logger.info("updating stored file with new data") + cfg = checkParameterConfig(cfg) + with open(cfgpath, "w", encoding='utf-8') as n: + json.dump(cfg, n, indent=1, ensure_ascii=False) + creds = json.load(c) + if creds: + if creds["clientId"] != clouds[0]["args"]["clientId"]: + creds["clientId"] = clouds[0]["args"]["clientId"] + if creds["userName"] != clouds[0]["args"]["username"]: + creds["userName"] = clouds[0]["args"]["username"] + if creds["password"] != clouds[0]["args"]["passwd"]: + creds["password"] = clouds[0]["args"]["passwd"] + else: + creds["clientId"] = clouds[0]["args"]["clientId"] + creds["userName"] = clouds[0]["args"]["username"] + creds["password"] = clouds[0]["args"]["passwd"] + with open(credspath, "w") as cw: + json.dump(creds,cw) + +def checkParameterConfig(cfg): + logger.info("Checking Parameters!!!!") + paramspath = "/var/user/files/params.json" + cfgparams = convertDStoJSON(cfg.get("labels")) + #check stored values + checkFileExist("params.json") + with open(paramspath, "r") as f: + logger.info("Opened param storage file") + params = json.load(f) + if params: + if cfgparams != params: + #go through each param + #if not "unknown" and cfg and params aren't the same take from cfg likely updated manually + #if key in cfg but not in params copy to params + logger.info("equalizing params between cfg and stored") + for key in cfgparams.keys(): + try: + if cfgparams[key] != params[key] and cfgparams[key] != "unknown": + params[key] = cfgparams[key] + except: + params[key] = cfgparams[key] + cfg["labels"] = convertJSONtoDS(params) + _set_global_args(convertJSONtoDS(params)) + with open(paramspath, "w") as p: + json.dump(params, p) + else: + with open(paramspath, "w") as p: + logger.info("initializing param file with params in memory") + json.dump(convertDStoJSON(get_params()), p) + cfg["labels"] = get_params() + + return cfg + + + + +payload = {} + +try: + with open("/var/user/files/totalizers.json", "r") as t: + totalizers = json.load(t) + if not totalizers: + logger.info("-----INITIALIZING TOTALIZERS-----") + totalizers = { + "day": 0, + "month": 0, + "lifetime": 0, + "dayHolding": 0, + "monthHolding": 0 + } +except: + totalizers = { + "day": 0, + "month": 0, + "lifetime": 0, + "dayHolding": 0, + "monthHolding": 0 + } + +lwtData = { + "init":False, + "client": client.Client(client_id=str(uuid.uuid4()), clean_session=True, userdata=None, protocol=client.MQTTv311, transport="tcp") +} +def lwt(mac): + try: + #if not lwtData["connected"]: + if not lwtData["init"]: + print("INITIALIZING LWT CLIENT") + lwtData["client"].username_pw_set(username="admin", password="columbus") + lwtData["client"].will_set("meshify/db/194/_/mainHP/" + mac + ":00:00/connected",json.dumps([{"value":False}])) + lwtData["client"].reconnect_delay_set(min_delay=10, max_delay=120) + lwtData["init"] = True + print("Connecting to MQTT Broker for LWT purposes!!!!!!!") + lwtData["client"].connect("mq194.imistaway.net",1883, 600) + lwtData["client"].reconnect() + lwtData["client"].publish("meshify/db/194/_/mainHP/" + mac + ":00:00/connected", json.dumps([{"value":True}])) + except Exception as e: + print("LWT DID NOT DO THE THING") + print(e) + +def sendData(message,wizard_api): + logger.debug(message) + mac = __topic__.split("/")[-1] #':'.join(re.findall('..', '%012x' % uuid.getnode())) + lwt(mac) + checkCredentialConfig() + try: + publishFlowrate( message["values"]["flowmonitor"]["flowrate"]["raw_data"], message["values"]["flowmonitor"]["flow_unit"]["raw_data"]) + totalizeDay(message["values"]["flowmonitor"]["totalizer_1"]["raw_data"],message["values"]["flowmonitor"]["totalizer_1_unit"]["raw_data"]) + totalizeMonth(message["values"]["flowmonitor"]["totalizer_1"]["raw_data"],message["values"]["flowmonitor"]["totalizer_1_unit"]["raw_data"]) + + except Exception as e: + logger.error(e) + + +def saveTotalizers(): + try: + with open("/var/user/files/totalizers.json", "w") as t: + json.dump(totalizers,t) + except Exception as e: + logger.error(e) + + +def publishFlowrate(fr, unit): + if unit == 45: + publish(__topic__ + ":01:40/" + "gpm_flow", json.dumps([{"value": f"{fr}"}]),__qos__) + publish(__topic__ + ":01:40/" + "bpd_flow", json.dumps([{"value": f"{fr*((60*24)/42)}"}]),__qos__) + elif unit == 63: + publish(__topic__ + ":01:40/" + "bpd_flow", json.dumps([{"value": f"{fr}"}]),__qos__) + publish(__topic__ + ":01:40/" + "gpm_flow", json.dumps([{"value": f"{fr * (42/(24*60))}"}]),__qos__) + + +def totalizeDay(lifetime,unit): + now = dt.now() + reset = False + value = lifetime - totalizers["dayHolding"] + if not int(now.strftime("%d")) == int(totalizers["day"]): + totalizers["dayHolding"] = lifetime + totalizers["day"] = int(now.strftime("%d")) + saveTotalizers() + reset = True + if unit == 11: + publish(__topic__ + ":01:40/" + "gal_total", json.dumps([{"value": f"{value}"}]),__qos__) + publish(__topic__ + ":01:40/" + "bbl_total", json.dumps([{"value": f"{value/42}"}]),__qos__) + publish(__topic__ + ":01:40/" + "lifetime_flow_meter_gal", json.dumps([{"value": f"{lifetime}"}]),__qos__) + publish(__topic__ + ":01:40/" + "lifetime_flow_meter_bbls", json.dumps([{"value": f"{lifetime/42}"}]),__qos__) + if reset: + publish(__topic__ + ":01:40/" + "gal_total", json.dumps([{"value": f"{0}"}]),__qos__) + publish(__topic__ + ":01:40/" + "bbl_total", json.dumps([{"value": f"{0}"}]),__qos__) + publish(__topic__ + ":01:40/" + "gal_total_yesterday", json.dumps([{"value": f"{value}"}]),__qos__) + publish(__topic__ + ":01:40/" + "bbl_total_yesterday", json.dumps([{"value": f"{value/42}"}]),__qos__) + elif unit == 15: + publish(__topic__ + ":01:40/" + "bbl_total", json.dumps([{"value": f"{value}"}]),__qos__) + publish(__topic__ + ":01:40/" + "gal_total", json.dumps([{"value": f"{value*42}"}]),__qos__) + publish(__topic__ + ":01:40/" + "lifetime_flow_meter_bbls", json.dumps([{"value": f"{lifetime}"}]),__qos__) + publish(__topic__ + ":01:40/" + "lifetime_flow_meter_gal", json.dumps([{"value": f"{lifetime*42}"}]),__qos__) + if reset: + publish(__topic__ + ":01:40/" + "bbl_total", json.dumps([{"value": f"{0}"}]),__qos__) + publish(__topic__ + ":01:40/" + "gal_total", json.dumps([{"value": f"{0}"}]),__qos__) + publish(__topic__ + ":01:40/" + "bbl_total_yesterday", json.dumps([{"value": f"{value}"}]),__qos__) + publish(__topic__ + ":01:40/" + "gal_total_yesterday", json.dumps([{"value": f"{value*42}"}]),__qos__) + + + +def totalizeMonth(lifetime, unit): + now = dt.now() + reset = False + value = lifetime - totalizers["monthHolding"] + if not int(now.strftime("%m")) == int(totalizers["month"]): + totalizers["monthHolding"] = lifetime + totalizers["month"] = now.strftime("%m") + saveTotalizers() + reset = True + if unit == 11: + publish(__topic__ + ":01:40/" + "gal_total_thismonth", json.dumps([{"value": f"{value}"}]),__qos__) + publish(__topic__ + ":01:40/" + "bbl_total_thismonth", json.dumps([{"value": f"{value/42}"}]),__qos__) + if reset: + publish(__topic__ + ":01:40/" + "gal_total_thismonth", json.dumps([{"value": f"{0}"}]),__qos__) + publish(__topic__ + ":01:40/" + "bbl_total_thismonth", json.dumps([{"value": f"{0}"}]),__qos__) + publish(__topic__ + ":01:40/" + "gal_total_lastmonth", json.dumps([{"value": f"{value}"}]),__qos__) + publish(__topic__ + ":01:40/" + "bbl_total_lastmonth", json.dumps([{"value": f"{value/42}"}]),__qos__) + elif unit == 15: + publish(__topic__ + ":01:40/" + "bbl_total_thismonth", json.dumps([{"value": f"{value}"}]),__qos__) + publish(__topic__ + ":01:40/" + "gal_total_thismonth", json.dumps([{"value": f"{value*42}"}]),__qos__) + if reset: + publish(__topic__ + ":01:40/" + "bbl_total_thismonth", json.dumps([{"value": f"{0}"}]),__qos__) + publish(__topic__ + ":01:40/" + "gal_total_thismonth", json.dumps([{"value": f"{0}"}]),__qos__) + publish(__topic__ + ":01:40/" + "bbl_total_lastmonth", json.dumps([{"value": f"{value}"}]),__qos__) + publish(__topic__ + ":01:40/" + "gal_total_lastmonth", json.dumps([{"value": f"{value*42}"}]),__qos__) diff --git a/Pub_Sub/flowmeterskid/thingsboard/flowmeterskid_tb_v1.cfg b/Pub_Sub/flowmeterskid/thingsboard/flowmeterskid_tb_v1.cfg new file mode 100644 index 0000000..2eca2b9 --- /dev/null +++ b/Pub_Sub/flowmeterskid/thingsboard/flowmeterskid_tb_v1.cfg @@ -0,0 +1,330 @@ +{ + "controllers": [ + { + "protocol": "Modbus-RTU", + "name": "flowmeter", + "endpoint": "rs485", + "args": { + "slaveAddr": 247, + "int16Ord": "ab", + "int32Ord": "cdab", + "float32Ord": "cdab", + "int64Ord": "ghefcdab", + "enableMsecSample": 0, + "continuousAcquisition": 1, + "maxContinuousNumber": 64, + "communicationInterval": 3, + "msecSamplePeriod": 500, + "msecPackage": 20 + }, + "samplePeriod": 10, + "expired": 10000 + } + ], + "measures": [ + { + "name": "flowrate", + "ctrlName": "flowmeter", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "43874", + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "decimal": 2, + "gain": "1.0", + "offset": "0.0", + "msecSample": 0 + }, + { + "name": "totalizer_1", + "ctrlName": "flowmeter", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "42610", + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "decimal": 2, + "gain": "1.0", + "offset": "0.0", + "msecSample": 0 + }, + { + "name": "totalizer_2", + "ctrlName": "flowmeter", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "42810", + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "decimal": 2, + "gain": "1.0", + "offset": "0.0", + "msecSample": 0 + }, + { + "name": "totalizer_3", + "ctrlName": "flowmeter", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "43010", + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "decimal": 2, + "gain": "1.0", + "offset": "0.0", + "msecSample": 0 + }, + { + "name": "flow_unit", + "ctrlName": "flowmeter", + "group": "default", + "uploadType": "periodic", + "dataType": "INT", + "addr": "42103", + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "gain": "1.0", + "offset": "0.0", + "msecSample": 0 + }, + { + "name": "totalizer_1_unit", + "ctrlName": "flowmeter", + "group": "default", + "uploadType": "periodic", + "dataType": "INT", + "addr": "44604", + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "gain": "1.0", + "offset": "0.0", + "msecSample": 0 + }, + { + "name": "totalizer_2_unit", + "ctrlName": "flowmeter", + "group": "default", + "uploadType": "periodic", + "dataType": "INT", + "addr": "44605", + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "gain": "1.0", + "offset": "0.0", + "msecSample": 0 + }, + { + "name": "totalizer_3_unit", + "ctrlName": "flowmeter", + "group": "default", + "uploadType": "periodic", + "dataType": "INT", + "addr": "44606", + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "gain": "1.0", + "offset": "0.0", + "msecSample": 0 + } + ], + "alarmLables": [ + "default" + ], + "alarms": [], + "groups": [ + { + "name": "default", + "uploadInterval": 600 + } + ], + "misc": { + "maxAlarmRecordSz": 2000, + "logLvl": "DEBUG", + "coms": [ + { + "name": "rs232", + "baud": 9600, + "bits": 8, + "parityChk": "n", + "stopbits": 1 + }, + { + "name": "rs485", + "baud": 19200, + "bits": 8, + "parityChk": "n", + "stopbits": 1 + } + ] + }, + "clouds": [ + { + "cacheSize": 10000, + "enable": 1, + "name": "default", + "type": "Standard MQTT", + "args": { + "host": "hp.henrypump.cloud", + "port": 1883, + "clientId": "unknown", + "auth": 1, + "tls": 0, + "cleanSession": 0, + "mqttVersion": "v3.1.1", + "keepalive": 60, + "key": "", + "cert": "", + "rootCA": "", + "verifyServer": 0, + "verifyClient": 0, + "username": "unknown", + "passwd": "unknown" + } + } + ], + "quickfaas": { + "genericFuncs": [], + "uploadFuncs": [ + { + "qos": 1, + "funcName": "sendData", + "script": "# Enter your python code.\nimport json\nfrom datetime import datetime as dt\nfrom common.Logger import logger\nfrom quickfaas.remotebus import publish\nfrom mobiuspi_lib.gps import GPS \n\npayload = {}\n\ntry:\n with open(\"/var/user/files/totalizers.json\", \"r\") as t:\n totalizers = json.load(t)\n if not totalizers:\n logger.info(\"-----INITIALIZING TOTALIZERS-----\")\n totalizers = {\n \"day\": 0,\n \"week\": 0,\n \"month\": 0,\n \"year\": 0,\n \"lifetime\": 0,\n \"dayHolding\": 0,\n \"weekHolding\": 0,\n \"monthHolding\": 0,\n \"yearHolding\": 0\n }\nexcept:\n totalizers = {\n \"day\": 0,\n \"week\": 0,\n \"month\": 0,\n \"year\": 0,\n \"lifetime\": 0,\n \"dayHolding\": 0,\n \"weekHolding\": 0,\n \"monthHolding\": 0,\n \"yearHolding\": 0\n }\n\n\n\n\ndef sendData(message,wizard_api):\n logger.debug(message)\n payload = {\"ts\": (round(dt.timestamp(dt.now())/600)*600)*1000, \"values\": {}}\n resetPayload = {\"ts\": \"\", \"values\": {}}\n for measure in message[\"values\"][\"flowmeter\"].keys():\n try:\n if measure in [\"totalizer_1\"]:\n payload[\"values\"][\"day_volume\"], dayReset = totalizeDay(message[\"values\"][\"flowmeter\"][measure][\"raw_data\"])\n payload[\"values\"][\"week_volume\"], weekReset = totalizeWeek(message[\"values\"][\"flowmeter\"][measure][\"raw_data\"])\n payload[\"values\"][\"month_volume\"], monthReset = totalizeMonth(message[\"values\"][\"flowmeter\"][measure][\"raw_data\"])\n payload[\"values\"][\"year_volume\"], yearReset = totalizeYear(message[\"values\"][\"flowmeter\"][measure][\"raw_data\"])\n payload[\"values\"][measure] = message[\"values\"][\"flowmeter\"][measure][\"raw_data\"]\n except Exception as e:\n logger.error(e)\n try:\n payload[\"values\"][\"latitude\"], payload[\"values\"][\"longitude\"], payload[\"values\"][\"speed\"] = getGPS()\n except:\n logger.error(\"Could not get GPS coordinates\")\n publish(__topic__, json.dumps(payload), __qos__)\n\n if dayReset:\n resetPayload[\"values\"][\"day_volume\"] = 0\n resetPayload[\"values\"][\"yesterday_volume\"] = payload[\"values\"][\"day_volume\"]\n if weekReset:\n resetPayload[\"values\"][\"week_volume\"] = 0\n resetPayload[\"values\"][\"last_week_volume\"] = payload[\"values\"][\"week_volume\"]\n if monthReset:\n resetPayload[\"values\"][\"month_volume\"] = 0\n resetPayload[\"values\"][\"last_month_volume\"] = payload[\"values\"][\"month_volume\"]\n if yearReset:\n resetPayload[\"values\"][\"year_volume\"] = 0 \n resetPayload[\"values\"][\"last_year_volume\"] = payload[\"values\"][\"year_volume\"]\n\n if resetPayload[\"values\"]:\n resetPayload[\"ts\"] = 1 + (round(dt.timestamp(dt.now())/600)*600)*1000\n publish(__topic__, json.dumps(resetPayload), __qos__) \n\ndef saveTotalizers():\n try:\n with open(\"/var/user/files/totalizers.json\", \"w\") as t:\n json.dump(totalizers,t)\n except Exception as e:\n logger.error(e)\n\ndef getGPS():\n # Create a gps instance\n gps = GPS()\n\n # Retrieve GPS information\n position_status = gps.get_position_status()\n logger.debug(\"position_status: \")\n logger.debug(position_status)\n latitude = position_status[\"latitude\"].split(\" \")\n longitude = position_status[\"longitude\"].split(\" \")\n lat_dec = int(latitude[0][:-1]) + (float(latitude[1][:-1])/60)\n lon_dec = int(longitude[0][:-1]) + (float(longitude[1][:-1])/60)\n if latitude[2] == \"S\":\n lat_dec = lat_dec * -1\n if longitude[2] == \"W\":\n lon_dec = lon_dec * -1\n #lat_dec = round(lat_dec, 7)\n #lon_dec = round(lon_dec, 7)\n logger.info(\"HERE IS THE GPS COORDS\")\n logger.info(f\"LATITUDE: {lat_dec}, LONGITUDE: {lon_dec}\")\n speedKnots = position_status[\"speed\"].split(\" \")\n speedMPH = float(speedKnots[0]) * 1.151\n return (f\"{lat_dec:.8f}\",f\"{lon_dec:.8f}\",f\"{speedMPH:.2f}\")\n\ndef totalizeDay(lifetime):\n now = dt.fromtimestamp(round(dt.timestamp(dt.now())/600)*600)\n reset = False\n value = lifetime - totalizers[\"dayHolding\"]\n if not int(now.strftime(\"%d\")) == int(totalizers[\"day\"]):\n totalizers[\"dayHolding\"] = lifetime\n totalizers[\"day\"] = int(now.strftime(\"%d\"))\n saveTotalizers()\n reset = True\n return (value,reset)\n\ndef totalizeWeek(lifetime):\n now = dt.fromtimestamp(round(dt.timestamp(dt.now())/600)*600)\n reset = False\n value = lifetime - totalizers[\"weekHolding\"]\n if not int(now.strftime(\"%U\")) == int(totalizers[\"week\"]) and now.strftime(\"%a\") == \"Sun\":\n totalizers[\"weekHolding\"] = lifetime\n totalizers[\"week\"] = now.strftime(\"%U\")\n saveTotalizers()\n reset = True\n return (value, reset)\n\ndef totalizeMonth(lifetime):\n now = dt.fromtimestamp(round(dt.timestamp(dt.now())/600)*600)\n reset = False\n value = lifetime - totalizers[\"monthHolding\"]\n if not int(now.strftime(\"%m\")) == int(totalizers[\"month\"]):\n totalizers[\"monthHolding\"] = lifetime\n totalizers[\"month\"] = now.strftime(\"%m\")\n saveTotalizers()\n reset = True\n return (value,reset)\n\ndef totalizeYear(lifetime):\n now = dt.fromtimestamp(round(dt.timestamp(dt.now())/600)*600)\n reset = False\n value = lifetime - totalizers[\"yearHolding\"]\n if not int(now.strftime(\"%Y\")) == int(totalizers[\"year\"]):\n totalizers[\"yearHolding\"] = lifetime\n totalizers[\"year\"] = now.strftime(\"%Y\")\n saveTotalizers()\n reset = True\n return (value, reset)", + "name": "sendData", + "trigger": "measure_event", + "topic": "v1/devices/me/telemetry", + "cloudName": "default", + "groups": [ + "default" + ], + "msgType": 0 + } + ], + "downloadFuncs": [ + { + "name": "Receive Command", + "topic": "v1/devices/me/rpc/request/+", + "qos": 1, + "funcName": "receiveCommand", + "payload_type": "JSON", + "script": "import json\nimport time\nfrom common.Logger import logger\nfrom quickfaas.remotebus import publish\n\ndef resetTotalizers():\n with open(\"/var/user/files/totalizers.json\", \"r+\") as t:\n totalizers = json.load(t)\n if totalizers:\n totalizers[\"dayHolding\"] = 0\n totalizers[\"weekHolding\"] = 0\n totalizers[\"MonthHolding\"] = 0\n totalizers[\"yearHolding\"] = 0\n json.dump(totalizers,t)\n\ndef receiveCommand(topic, payload):\n logger.debug(topic)\n logger.debug(json.loads(payload))\n p = json.loads(payload)\n command = p[\"method\"]\n if command == \"resetTotalizers\":\n resetTotalizers()\n publish(topic, json.dumps({\"msg\": {\"time\": time.time()}, \"metadata\": \"\", \"msgType\": \"\"}))\n", + "msgType": 0, + "cloudName": "default", + "trigger": "command_event" + } + ] + }, + "labels": [ + { + "key": "SN", + "value": "GF5022223016129" + }, + { + "key": "MAC", + "value": "00:18:05:21:b3:3f" + } + ], + "modbusSlave": { + "enable": 0, + "protocol": "Modbus-TCP", + "port": 502, + "slaveAddr": 1, + "int16Ord": "ab", + "int32Ord": "abcd", + "float32Ord": "abcd", + "maxConnection": 5, + "mapping_table": [] + }, + "modbusRTUSlave": { + "enable": 0, + "protocol": "Modbus-RTU", + "coms": "rs485", + "slaveAddr": 1, + "int16Ord": "ab", + "int32Ord": "abcd", + "float32Ord": "abcd", + "mapping_table": [] + }, + "iec104Server": { + "enable": 0, + "cotSize": 2, + "port": 2404, + "serverList": [ + { + "asduAddr": 1 + } + ], + "kValue": 12, + "wValue": 8, + "t0": 30, + "t1": 15, + "t2": 10, + "t3": 20, + "maximumLink": 5, + "timeSet": 1, + "byteOrder": "abcd", + "mapping_table": [] + }, + "iec104Client": { + "enable": 0, + "connectType": 2, + "serverAddr": "ipower.inhandcloud.cn", + "serverPort": 2404, + "communicationCode": "", + "protocol": 1, + "asduAddr": 1, + "tls": 0, + "mapping_table": { + "YX": [], + "YC": [], + "YK": [] + } + }, + "opcuaServer": { + "enable": 0, + "port": 4840, + "maximumLink": 5, + "securityMode": 0, + "identifierType": "String", + "mapping_table": [] + }, + "southMetadata": {}, + "bindMetadata": { + "version": "", + "timestamp": "" + }, + "bindConfig": { + "enable": 0, + "bind": { + "modelId": "", + "modelName": "", + "srcId": "", + "srcName": "", + "devId": "", + "devName": "" + }, + "varGroups": [], + "variables": [], + "alerts": [] + }, + "version": "2.3.1" +} \ No newline at end of file diff --git a/Pub_Sub/flowmeterskid/flowmeter.py b/Pub_Sub/flowmeterskid/thingsboard/pub/sendData.py similarity index 50% rename from Pub_Sub/flowmeterskid/flowmeter.py rename to Pub_Sub/flowmeterskid/thingsboard/pub/sendData.py index b9da4e1..25eea13 100644 --- a/Pub_Sub/flowmeterskid/flowmeter.py +++ b/Pub_Sub/flowmeterskid/thingsboard/pub/sendData.py @@ -1,9 +1,120 @@ -# Enter your python code. -import json +import json, os from datetime import datetime as dt from common.Logger import logger from quickfaas.remotebus import publish -from mobiuspi_lib.gps import GPS +from mobiuspi_lib.gps import GPS +from quickfaas.global_dict import get as get_params +from quickfaas.global_dict import _set_global_args + +def reboot(): + #basic = Basic() + logger.info("!" * 10 + "REBOOTING DEVICE" + "!"*10) + r = os.popen("kill -s SIGHUP `cat /var/run/python/supervisord.pid`").read() + logger.info(f"REBOOT : {r}") + +def checkFileExist(filename): + path = "/var/user/files" + if not os.path.exists(path): + logger.info("no folder making files folder in var/user") + os.makedirs(path) + with open(path + "/" + filename, "a") as f: + json.dump({}, f) + if not os.path.exists(path + "/" + filename): + logger.info("no creds file making creds file") + with open(path + "/" + filename, "a") as f: + json.dump({}, f) + +def convertDStoJSON(ds): + j = dict() + for x in ds: + j[x["key"]] = x["value"] + return j + +def convertJSONtoDS(j): + d = [] + for key in j.keys(): + d.append({"key": key, "value": j[key]}) + return d + +def checkCredentialConfig(): + logger.info("CHECKING CONFIG") + cfgpath = "/var/user/cfg/device_supervisor/device_supervisor.cfg" + credspath = "/var/user/files/creds.json" + cfg = dict() + with open(cfgpath, "r") as f: + cfg = json.load(f) + clouds = cfg.get("clouds") + logger.info(clouds) + #if not configured then try to configure from stored values + if clouds[0]["args"]["clientId"] == "unknown" or clouds[0]["args"]["username"] == "unknown" or not clouds[0]["args"]["passwd"] or clouds[0]["args"]["passwd"] == "unknown": + checkFileExist("creds.json") + with open(credspath, "r") as c: + creds = json.load(c) + if creds: + logger.info("updating config with stored data") + clouds[0]["args"]["clientId"] = creds["clientId"] + clouds[0]["args"]["username"] = creds["userName"] + clouds[0]["args"]["passwd"] = creds["password"] + cfg["clouds"] = clouds + cfg = checkParameterConfig(cfg) + with open(cfgpath, "w", encoding='utf-8') as n: + json.dump(cfg, n, indent=1, ensure_ascii=False) + reboot() + else: + #assuming clouds is filled out, if data is different then assume someone typed in something new and store it, if creds is empty fill with clouds' data + checkFileExist("creds.json") + with open(credspath, "r") as c: + logger.info("updating stored file with new data") + cfg = checkParameterConfig(cfg) + with open(cfgpath, "w", encoding='utf-8') as n: + json.dump(cfg, n, indent=1, ensure_ascii=False) + creds = json.load(c) + if creds: + if creds["clientId"] != clouds[0]["args"]["clientId"]: + creds["clientId"] = clouds[0]["args"]["clientId"] + if creds["userName"] != clouds[0]["args"]["username"]: + creds["userName"] = clouds[0]["args"]["username"] + if creds["password"] != clouds[0]["args"]["passwd"]: + creds["password"] = clouds[0]["args"]["passwd"] + else: + creds["clientId"] = clouds[0]["args"]["clientId"] + creds["userName"] = clouds[0]["args"]["username"] + creds["password"] = clouds[0]["args"]["passwd"] + with open(credspath, "w") as cw: + json.dump(creds,cw) + +def checkParameterConfig(cfg): + logger.info("Checking Parameters!!!!") + paramspath = "/var/user/files/params.json" + cfgparams = convertDStoJSON(cfg.get("labels")) + #check stored values + checkFileExist("params.json") + with open(paramspath, "r") as f: + logger.info("Opened param storage file") + params = json.load(f) + if params: + if cfgparams != params: + #go through each param + #if not "unknown" and cfg and params aren't the same take from cfg likely updated manually + #if key in cfg but not in params copy to params + logger.info("equalizing params between cfg and stored") + for key in cfgparams.keys(): + try: + if cfgparams[key] != params[key] and cfgparams[key] != "unknown": + params[key] = cfgparams[key] + except: + params[key] = cfgparams[key] + cfg["labels"] = convertJSONtoDS(params) + _set_global_args(convertJSONtoDS(params)) + with open(paramspath, "w") as p: + json.dump(params, p) + else: + with open(paramspath, "w") as p: + logger.info("initializing param file with params in memory") + json.dump(convertDStoJSON(get_params()), p) + cfg["labels"] = get_params() + + return cfg payload = {} @@ -41,6 +152,7 @@ except: def sendData(message,wizard_api): logger.debug(message) + checkCredentialConfig() payload = {"ts": (round(dt.timestamp(dt.now())/600)*600)*1000, "values": {}} resetPayload = {"ts": "", "values": {}} for measure in message["values"]["flowmeter"].keys(): diff --git a/Pub_Sub/plcfreshwater/v1/plcfreshwater_ma_v1.cfg b/Pub_Sub/plcfreshwater/v1/plcfreshwater_ma_v1.cfg new file mode 100644 index 0000000..551a856 --- /dev/null +++ b/Pub_Sub/plcfreshwater/v1/plcfreshwater_ma_v1.cfg @@ -0,0 +1,369 @@ +{ + "controllers": [ + { + "protocol": "EtherNet/IP", + "name": "plcfreshwater", + "args": {}, + "samplePeriod": 10, + "expired": 10000, + "endpoint": "192.168.1.101:44818" + } + ], + "measures": [ + { + "ctrlName": "plcfreshwater", + "dataType": "FLOAT", + "addr": "Scaled_Flow_Meter", + "readWrite": "ro", + "uploadType": "periodic", + "group": "default", + "decimal": 2, + "name": "scaled_flow_meter", + "desc": "", + "unit": "", + "transformType": 0, + "gain": "1.0", + "offset": "0.0", + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "" + }, + { + "ctrlName": "plcfreshwater", + "dataType": "FLOAT", + "addr": "Scaled_Pressure_Transducer", + "readWrite": "ro", + "uploadType": "periodic", + "group": "default", + "decimal": 2, + "name": "scaled_pressure_transducer", + "desc": "", + "unit": "", + "transformType": 0, + "gain": "1.0", + "offset": "0.0", + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "" + }, + { + "ctrlName": "plcfreshwater", + "dataType": "BIT", + "addr": "Raw_Hand_Input", + "readWrite": "ro", + "uploadType": "periodic", + "group": "default", + "name": "raw_hand_input", + "desc": "", + "unit": "", + "transformType": 0, + "gain": "1.0", + "offset": "0.0", + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "decimal": 2 + }, + { + "ctrlName": "plcfreshwater", + "dataType": "BIT", + "addr": "Raw_Auto_Input", + "readWrite": "ro", + "uploadType": "periodic", + "group": "default", + "name": "raw_auto_input", + "desc": "", + "unit": "", + "transformType": 0, + "gain": "1.0", + "offset": "0.0", + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "decimal": 2 + }, + { + "ctrlName": "plcfreshwater", + "dataType": "BIT", + "addr": "Raw_Run_Status", + "readWrite": "ro", + "uploadType": "periodic", + "group": "default", + "name": "raw_run_status", + "desc": "", + "unit": "", + "transformType": 0, + "gain": "1.0", + "offset": "0.0", + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "decimal": 2 + }, + { + "ctrlName": "plcfreshwater", + "dataType": "BIT", + "addr": "Raw_Local_Start", + "readWrite": "ro", + "uploadType": "periodic", + "group": "default", + "name": "raw_local_start", + "desc": "", + "unit": "", + "transformType": 0, + "gain": "1.0", + "offset": "0.0", + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "decimal": 2 + }, + { + "ctrlName": "plcfreshwater", + "dataType": "FLOAT", + "addr": "Lifetime_Flow_Meter_Gal", + "readWrite": "ro", + "uploadType": "periodic", + "group": "default", + "decimal": 2, + "name": "lifetime_flow_meter_gal", + "desc": "", + "unit": "", + "transformType": 0, + "gain": "1.0", + "offset": "0.0", + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "" + }, + { + "ctrlName": "plcfreshwater", + "dataType": "BIT", + "addr": "SPT_Flow_Meter_Unit", + "readWrite": "ro", + "uploadType": "periodic", + "group": "default", + "name": "spt_flow_meter_unit", + "desc": "", + "unit": "", + "transformType": 0, + "gain": "1.0", + "offset": "0.0", + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "decimal": 2 + }, + { + "ctrlName": "plcfreshwater", + "dataType": "BIT", + "addr": "Raw_Overload_Status", + "readWrite": "ro", + "uploadType": "periodic", + "group": "default", + "name": "raw_overload_status", + "desc": "", + "unit": "", + "transformType": 0, + "gain": "1.0", + "offset": "0.0", + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "decimal": 2 + }, + { + "ctrlName": "plcfreshwater", + "dataType": "BIT", + "addr": "CMD_Cloud_Control", + "readWrite": "rw", + "uploadType": "periodic", + "group": "default", + "name": "CMD_Cloud_Control", + "desc": "", + "unit": "", + "transformType": 0, + "gain": "1.0", + "offset": "0.0", + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "decimal": 2 + } + ], + "alarmLables": [ + "default" + ], + "alarms": [], + "groups": [ + { + "name": "default", + "uploadInterval": 600, + "reference": 10 + } + ], + "misc": { + "maxAlarmRecordSz": 2000, + "logLvl": "INFO", + "coms": [ + { + "name": "rs232", + "baud": 9600, + "bits": 8, + "stopbits": 1, + "parityChk": "n" + }, + { + "name": "rs485", + "baud": 9600, + "bits": 8, + "stopbits": 1, + "parityChk": "n" + } + ] + }, + "clouds": [ + { + "cacheSize": 100, + "enable": 1, + "name": "default", + "type": "Standard MQTT", + "args": { + "host": "mq194.imistaway.net", + "port": 1883, + "clientId": "unknown", + "auth": 1, + "tls": 0, + "cleanSession": 0, + "mqttVersion": "v3.1.1", + "keepalive": 60, + "key": "", + "cert": "", + "rootCA": "", + "verifyServer": 0, + "verifyClient": 0, + "username": "unknown", + "passwd": "unknown", + "authType": 1 + } + } + ], + "quickfaas": { + "genericFuncs": [], + "uploadFuncs": [ + { + "name": "Send Data", + "trigger": "measure_event", + "topic": "meshify/db/194/_/plcfreshwater/${MAC_LOWER}", + "qos": 1, + "groups": [ + "default" + ], + "funcName": "sendData", + "script": "import json, os, uuid\nfrom common.Logger import logger\nfrom quickfaas.remotebus import publish\nfrom paho.mqtt import client\nfrom quickfaas.global_dict import get as get_params\nfrom quickfaas.global_dict import _set_global_args\n\ndef reboot():\n #basic = Basic()\n logger.info(\"!\" * 10 + \"REBOOTING DEVICE\" + \"!\"*10)\n r = os.popen(\"kill -s SIGHUP `cat /var/run/python/supervisord.pid`\").read()\n logger.info(f\"REBOOT : {r}\")\n\ndef checkFileExist(filename):\n path = \"/var/user/files\"\n if not os.path.exists(path):\n logger.info(\"no folder making files folder in var/user\")\n os.makedirs(path)\n with open(path + \"/\" + filename, \"a\") as f:\n json.dump({}, f)\n if not os.path.exists(path + \"/\" + filename):\n logger.info(\"no creds file making creds file\")\n with open(path + \"/\" + filename, \"a\") as f:\n json.dump({}, f)\n\ndef convertDStoJSON(ds):\n j = dict()\n for x in ds:\n j[x[\"key\"]] = x[\"value\"]\n return j\n\ndef convertJSONtoDS(j):\n d = []\n for key in j.keys():\n d.append({\"key\": key, \"value\": j[key]})\n return d\n\ndef checkCredentialConfig():\n logger.info(\"CHECKING CONFIG\")\n cfgpath = \"/var/user/cfg/device_supervisor/device_supervisor.cfg\"\n credspath = \"/var/user/files/creds.json\"\n cfg = dict()\n with open(cfgpath, \"r\") as f:\n cfg = json.load(f)\n clouds = cfg.get(\"clouds\")\n logger.info(clouds)\n #if not configured then try to configure from stored values\n if clouds[0][\"args\"][\"clientId\"] == \"unknown\" or clouds[0][\"args\"][\"username\"] == \"unknown\" or not clouds[0][\"args\"][\"passwd\"] or clouds[0][\"args\"][\"passwd\"] == \"unknown\":\n checkFileExist(\"creds.json\")\n with open(credspath, \"r\") as c:\n creds = json.load(c)\n if creds:\n logger.info(\"updating config with stored data\")\n clouds[0][\"args\"][\"clientId\"] = creds[\"clientId\"]\n clouds[0][\"args\"][\"username\"] = creds[\"userName\"]\n clouds[0][\"args\"][\"passwd\"] = creds[\"password\"]\n cfg[\"clouds\"] = clouds\n cfg = checkParameterConfig(cfg)\n with open(cfgpath, \"w\", encoding='utf-8') as n:\n json.dump(cfg, n, indent=1, ensure_ascii=False)\n reboot()\n else:\n #assuming clouds is filled out, if data is different then assume someone typed in something new and store it, if creds is empty fill with clouds' data\n checkFileExist(\"creds.json\")\n with open(credspath, \"r\") as c:\n logger.info(\"updating stored file with new data\")\n cfg = checkParameterConfig(cfg)\n with open(cfgpath, \"w\", encoding='utf-8') as n:\n json.dump(cfg, n, indent=1, ensure_ascii=False)\n creds = json.load(c)\n if creds:\n if creds[\"clientId\"] != clouds[0][\"args\"][\"clientId\"]:\n creds[\"clientId\"] = clouds[0][\"args\"][\"clientId\"]\n if creds[\"userName\"] != clouds[0][\"args\"][\"username\"]:\n creds[\"userName\"] = clouds[0][\"args\"][\"username\"]\n if creds[\"password\"] != clouds[0][\"args\"][\"passwd\"]:\n creds[\"password\"] = clouds[0][\"args\"][\"passwd\"]\n else:\n creds[\"clientId\"] = clouds[0][\"args\"][\"clientId\"]\n creds[\"userName\"] = clouds[0][\"args\"][\"username\"]\n creds[\"password\"] = clouds[0][\"args\"][\"passwd\"]\n with open(credspath, \"w\") as cw:\n json.dump(creds,cw)\n\ndef checkParameterConfig(cfg):\n logger.info(\"Checking Parameters!!!!\")\n paramspath = \"/var/user/files/params.json\"\n cfgparams = convertDStoJSON(cfg.get(\"labels\"))\n #check stored values \n checkFileExist(\"params.json\")\n with open(paramspath, \"r\") as f:\n logger.info(\"Opened param storage file\")\n params = json.load(f)\n if params:\n if cfgparams != params:\n #go through each param\n #if not \"unknown\" and cfg and params aren't the same take from cfg likely updated manually\n #if key in cfg but not in params copy to params\n logger.info(\"equalizing params between cfg and stored\")\n for key in cfgparams.keys():\n try:\n if cfgparams[key] != params[key] and cfgparams[key] != \"unknown\":\n params[key] = cfgparams[key]\n except:\n params[key] = cfgparams[key]\n cfg[\"labels\"] = convertJSONtoDS(params)\n _set_global_args(convertJSONtoDS(params))\n with open(paramspath, \"w\") as p:\n json.dump(params, p)\n else:\n with open(paramspath, \"w\") as p:\n logger.info(\"initializing param file with params in memory\")\n json.dump(convertDStoJSON(get_params()), p)\n cfg[\"labels\"] = get_params()\n \n return cfg\n\n\nlwtData = {\n \"init\":False,\n \"client\": client.Client(client_id=str(uuid.uuid4()), clean_session=True, userdata=None, protocol=client.MQTTv311, transport=\"tcp\")\n}\ndef lwt(mac):\n try:\n #if not lwtData[\"connected\"]:\n if not lwtData[\"init\"]:\n print(\"INITIALIZING LWT CLIENT\")\n lwtData[\"client\"].username_pw_set(username=\"admin\", password=\"columbus\")\n lwtData[\"client\"].will_set(\"meshify/db/194/_/mainHP/\" + mac + \":00:00/connected\",json.dumps([{\"value\":False}]))\n lwtData[\"client\"].reconnect_delay_set(min_delay=10, max_delay=120)\n lwtData[\"init\"] = True\n print(\"Connecting to MQTT Broker for LWT purposes!!!!!!!\")\n lwtData[\"client\"].connect(\"mq194.imistaway.net\",1883, 600)\n lwtData[\"client\"].reconnect()\n lwtData[\"client\"].publish(\"meshify/db/194/_/mainHP/\" + mac + \":00:00/connected\", json.dumps([{\"value\":True}]))\n except Exception as e:\n print(\"LWT DID NOT DO THE THING\")\n print(e)\n\ndef sendData(message):\n #logger.debug(message)\n mac = __topic__.split(\"/\")[-1] #':'.join(re.findall('..', '%012x' % uuid.getnode()))\n lwt(mac)\n checkCredentialConfig()\n plc_ping = os.system(\"ping -c 1 192.168.1.101 > /dev/null 2>&1\")\n if plc_ping == 0:\n publish(__topic__ + \":01:99/\" + \"plc_ping\", json.dumps({\"value\": \"OK\"}), __qos__)\n else:\n publish(__topic__ + \":01:99/\" + \"plc_ping\", json.dumps({\"value\": \"Comms Error to PLC\"}), __qos__)\n for measure in message[\"measures\"]:\n try:\n logger.debug(measure)\n if measure[\"name\"] in [\"raw_hand_input\", \"raw_auto_input\", \"raw_run_status\", \"raw_local_start\",\"raw_overload_status\"]:\n logger.debug(\"Converting DINT/BOOL to STRING\")\n value = convert_int(measure[\"name\"], measure[\"value\"])\n logger.debug(\"Converted {} to {}\".format(measure[\"value\"], value))\n publish(__topic__ + \":01:99/\" + measure[\"name\"], json.dumps({\"value\": value}), __qos__)\n else:\n publish(__topic__ + \":01:99/\" + measure[\"name\"], json.dumps({\"value\": measure[\"value\"]}), __qos__)\n except Exception as e:\n logger.error(e)\n\ndef convert_int(plc_tag, value):\n input_codes = {\n 0: \"Off\",\n 1: \"On\"\n }\n\n run_status_codes = {\n 0: \"Stopped\",\n 1: \"Running\"\n }\n\n overload_codes = {\n 0: \"Good\",\n 1: \"Down on Overload Tripped\"\n }\n \n plc_tags = {\n \"raw_hand_input\": input_codes.get(value, \"Invalid Code\"),\n \"raw_auto_input\": input_codes.get(value, \"Invalid Code\"),\n \"raw_run_status\": run_status_codes.get(value, \"Invalid Code\"),\n \"raw_overload_status\": overload_codes.get(value, \"Invalid Code\")\n }\n\n return plc_tags.get(plc_tag, \"Invalid Tag\")\n\n ", + "msgType": 0, + "cloudName": "default" + } + ], + "downloadFuncs": [ + { + "name": "Commands", + "topic": "meshify/sets/194/${MAC_UPPER}:01:99", + "qos": 1, + "funcName": "receiveCommand", + "payload_type": "Plaintext", + "script": "# Enter your python code.\nimport json\nimport os\nfrom quickfaas.measure import recall\nfrom common.Logger import logger\n\ndef sync(mac,value, wizard_api):\n #get new values and send\n try:\n data = recall()#json.loads(recall().decode(\"utf-8\"))\n except Exception as e:\n logger.error(e)\n logger.info(data)\n plc_ping = os.system(\"ping -c 1 192.168.1.101 > /dev/null 2>&1\")\n if plc_ping == 0:\n publish(__topic__ + \":01:99/\" + \"plc_ping\", json.dumps({\"value\": \"OK\"}), __qos__)\n else:\n publish(__topic__ + \":01:99/\" + \"plc_ping\", json.dumps({\"value\": \"Comms Error to PLC\"}), __qos__)\n for controller in data:\n for measure in controller[\"measures\"]:\n #publish measure\n topic = \"meshify/db/194/_/plcfreshwater/\" + mac + \"/\" + measure[\"name\"]\n if measure[\"name\"] in [\"raw_hand_input\", \"raw_auto_input\", \"raw_run_status\", \"raw_local_start\",\"raw_overload_status\"]:\n payload = [{\"value\": convert_int(measure[\"name\"], measure[\"value\"])}]\n else:\n payload = [{\"value\": measure[\"value\"]}]\n logger.debug(\"Sending on topic: {}\".format(topic))\n logger.debug(\"Sending value: {}\".format(payload))\n wizard_api.mqtt_publish(topic, json.dumps(payload))\ndef writeplctag(mac, value, wizard_api):\n try:\n value = json.loads(value.replace(\"'\",'\"'))\n logger.debug(value)\n message = {\"plcfreshwater\":{value[\"tag\"]: value[\"val\"]}}\n wizard_api.write_plc_values(message)\n except Exception as e:\n logger.debug(e)\n \ndef receiveCommand(topic, payload, wizard_api):\n logger.debug(topic)\n logger.debug(json.loads(payload))\n p = json.loads(payload)[0]\n command = p[\"payload\"][\"name\"].split(\".\")[1]\n commands = {\n \"sync\": sync,\n \"writeplctag\": writeplctag,\n }\n commands[command](p[\"mac\"].lower(),p[\"payload\"][\"value\"], wizard_api)\n #logger.debug(command)\n ack(p[\"msgId\"], p[\"mac\"], command, p[\"payload\"][\"name\"].split(\".\")[1], p[\"payload\"][\"value\"], wizard_api)\n\ndef ack(msgid, mac, name, command, value, wizard_api):\n #logger.debug(mac)\n macsquish = \"\".join(mac.split(\":\")[:-2])\n maclower = \":\".join(mac.split(\":\")[:-2])\n maclower = maclower.lower()\n #logger.debug(msgid)\n #logger.debug(mac)\n #logger.debug(name)\n #logger.debug(value)\n wizard_api.mqtt_publish(\"meshify/responses/\" + str(msgid), json.dumps([{\"value\": \"{} Success Setting: {} To: {}\".format(macsquish,name, value), \"msgid\": str(msgid)}]))\n wizard_api.mqtt_publish(\"meshify/db/194/_/mainMeshify/\" + maclower + \":00:00/commands\", json.dumps([{\"value\": {\"status\": \"success\", \"value\": str(value), \"channel\": command}, \"msgid\": str(msgid)}]))\n\ndef convert_int(plc_tag, value):\n input_codes = {\n 0: \"Off\",\n 1: \"On\"\n }\n\n run_status_codes = {\n 0: \"Stopped\",\n 1: \"Running\"\n }\n\n overload_codes = {\n 0: \"Good\",\n 1: \"Down on Overload Tripped\"\n }\n \n plc_tags = {\n \"raw_hand_input\": input_codes.get(value, \"Invalid Code\"),\n \"raw_auto_input\": input_codes.get(value, \"Invalid Code\"),\n \"raw_run_status\": run_status_codes.get(value, \"Invalid Code\"),\n \"raw_overload_status\": overload_codes.get(value, \"Invalid Code\")\n }\n\n return plc_tags.get(plc_tag, \"Invalid Tag\")\n", + "msgType": 0, + "cloudName": "default", + "trigger": "command_event" + } + ] + }, + "labels": [ + { + "key": "SN", + "value": "GF5022211011405" + }, + { + "key": "MAC", + "value": "00:18:05:1e:ae:b8" + }, + { + "key": "MAC_LOWER", + "value": "00:18:05:1e:ae:b8" + }, + { + "key": "MAC_UPPER", + "value": "00:18:05:1E:AE:B8" + } + ], + "modbusSlave": { + "enable": 0, + "protocol": "Modbus-TCP", + "port": 502, + "slaveAddr": 1, + "int16Ord": "ab", + "int32Ord": "abcd", + "float32Ord": "abcd", + "maxConnection": 5, + "mapping_table": [] + }, + "iec104Server": { + "enable": 0, + "cotSize": 2, + "port": 2404, + "serverList": [ + { + "asduAddr": 1 + } + ], + "kValue": 12, + "wValue": 8, + "t0": 30, + "t1": 15, + "t2": 10, + "t3": 20, + "maximumLink": 5, + "timeSet": 1, + "byteOrder": "abcd", + "mapping_table": [] + }, + "opcuaServer": { + "enable": 0, + "port": 4840, + "maximumLink": 5, + "securityMode": 0, + "identifierType": "String", + "mapping_table": [] + }, + "southMetadata": {}, + "bindMetadata": { + "version": "", + "timestamp": "" + }, + "bindConfig": { + "enable": 0, + "bind": { + "modelId": "", + "modelName": "", + "srcId": "", + "srcName": "", + "devId": "", + "devName": "" + }, + "varGroups": [], + "variables": [], + "alerts": [] + }, + "version": "2.2.1" +} \ No newline at end of file diff --git a/Pub_Sub/plcfreshwater/v1/pub/sendData.py b/Pub_Sub/plcfreshwater/v1/pub/sendData.py new file mode 100644 index 0000000..11ab6bc --- /dev/null +++ b/Pub_Sub/plcfreshwater/v1/pub/sendData.py @@ -0,0 +1,188 @@ +import json, os, uuid +from common.Logger import logger +from quickfaas.remotebus import publish +from paho.mqtt import client +from quickfaas.global_dict import get as get_params +from quickfaas.global_dict import _set_global_args + +def reboot(): + #basic = Basic() + logger.info("!" * 10 + "REBOOTING DEVICE" + "!"*10) + r = os.popen("kill -s SIGHUP `cat /var/run/python/supervisord.pid`").read() + logger.info(f"REBOOT : {r}") + +def checkFileExist(filename): + path = "/var/user/files" + if not os.path.exists(path): + logger.info("no folder making files folder in var/user") + os.makedirs(path) + with open(path + "/" + filename, "a") as f: + json.dump({}, f) + if not os.path.exists(path + "/" + filename): + logger.info("no creds file making creds file") + with open(path + "/" + filename, "a") as f: + json.dump({}, f) + +def convertDStoJSON(ds): + j = dict() + for x in ds: + j[x["key"]] = x["value"] + return j + +def convertJSONtoDS(j): + d = [] + for key in j.keys(): + d.append({"key": key, "value": j[key]}) + return d + +def checkCredentialConfig(): + logger.info("CHECKING CONFIG") + cfgpath = "/var/user/cfg/device_supervisor/device_supervisor.cfg" + credspath = "/var/user/files/creds.json" + cfg = dict() + with open(cfgpath, "r") as f: + cfg = json.load(f) + clouds = cfg.get("clouds") + logger.info(clouds) + #if not configured then try to configure from stored values + if clouds[0]["args"]["clientId"] == "unknown" or clouds[0]["args"]["username"] == "unknown" or not clouds[0]["args"]["passwd"] or clouds[0]["args"]["passwd"] == "unknown": + checkFileExist("creds.json") + with open(credspath, "r") as c: + creds = json.load(c) + if creds: + logger.info("updating config with stored data") + clouds[0]["args"]["clientId"] = creds["clientId"] + clouds[0]["args"]["username"] = creds["userName"] + clouds[0]["args"]["passwd"] = creds["password"] + cfg["clouds"] = clouds + cfg = checkParameterConfig(cfg) + with open(cfgpath, "w", encoding='utf-8') as n: + json.dump(cfg, n, indent=1, ensure_ascii=False) + reboot() + else: + #assuming clouds is filled out, if data is different then assume someone typed in something new and store it, if creds is empty fill with clouds' data + checkFileExist("creds.json") + with open(credspath, "r") as c: + logger.info("updating stored file with new data") + cfg = checkParameterConfig(cfg) + with open(cfgpath, "w", encoding='utf-8') as n: + json.dump(cfg, n, indent=1, ensure_ascii=False) + creds = json.load(c) + if creds: + if creds["clientId"] != clouds[0]["args"]["clientId"]: + creds["clientId"] = clouds[0]["args"]["clientId"] + if creds["userName"] != clouds[0]["args"]["username"]: + creds["userName"] = clouds[0]["args"]["username"] + if creds["password"] != clouds[0]["args"]["passwd"]: + creds["password"] = clouds[0]["args"]["passwd"] + else: + creds["clientId"] = clouds[0]["args"]["clientId"] + creds["userName"] = clouds[0]["args"]["username"] + creds["password"] = clouds[0]["args"]["passwd"] + with open(credspath, "w") as cw: + json.dump(creds,cw) + +def checkParameterConfig(cfg): + logger.info("Checking Parameters!!!!") + paramspath = "/var/user/files/params.json" + cfgparams = convertDStoJSON(cfg.get("labels")) + #check stored values + checkFileExist("params.json") + with open(paramspath, "r") as f: + logger.info("Opened param storage file") + params = json.load(f) + if params: + if cfgparams != params: + #go through each param + #if not "unknown" and cfg and params aren't the same take from cfg likely updated manually + #if key in cfg but not in params copy to params + logger.info("equalizing params between cfg and stored") + for key in cfgparams.keys(): + try: + if cfgparams[key] != params[key] and cfgparams[key] != "unknown": + params[key] = cfgparams[key] + except: + params[key] = cfgparams[key] + cfg["labels"] = convertJSONtoDS(params) + _set_global_args(convertJSONtoDS(params)) + with open(paramspath, "w") as p: + json.dump(params, p) + else: + with open(paramspath, "w") as p: + logger.info("initializing param file with params in memory") + json.dump(convertDStoJSON(get_params()), p) + cfg["labels"] = get_params() + + return cfg + + +lwtData = { + "init":False, + "client": client.Client(client_id=str(uuid.uuid4()), clean_session=True, userdata=None, protocol=client.MQTTv311, transport="tcp") +} +def lwt(mac): + try: + #if not lwtData["connected"]: + if not lwtData["init"]: + print("INITIALIZING LWT CLIENT") + lwtData["client"].username_pw_set(username="admin", password="columbus") + lwtData["client"].will_set("meshify/db/194/_/mainHP/" + mac + ":00:00/connected",json.dumps([{"value":False}])) + lwtData["client"].reconnect_delay_set(min_delay=10, max_delay=120) + lwtData["init"] = True + print("Connecting to MQTT Broker for LWT purposes!!!!!!!") + lwtData["client"].connect("mq194.imistaway.net",1883, 600) + lwtData["client"].reconnect() + lwtData["client"].publish("meshify/db/194/_/mainHP/" + mac + ":00:00/connected", json.dumps([{"value":True}])) + except Exception as e: + print("LWT DID NOT DO THE THING") + print(e) + +def sendData(message): + #logger.debug(message) + mac = __topic__.split("/")[-1] #':'.join(re.findall('..', '%012x' % uuid.getnode())) + lwt(mac) + checkCredentialConfig() + plc_ping = os.system("ping -c 1 192.168.1.101 > /dev/null 2>&1") + if plc_ping == 0: + publish(__topic__ + ":01:99/" + "plc_ping", json.dumps({"value": "OK"}), __qos__) + else: + publish(__topic__ + ":01:99/" + "plc_ping", json.dumps({"value": "Comms Error to PLC"}), __qos__) + for measure in message["measures"]: + try: + logger.debug(measure) + if measure["name"] in ["raw_hand_input", "raw_auto_input", "raw_run_status", "raw_local_start","raw_overload_status"]: + logger.debug("Converting DINT/BOOL to STRING") + value = convert_int(measure["name"], measure["value"]) + logger.debug("Converted {} to {}".format(measure["value"], value)) + publish(__topic__ + ":01:99/" + measure["name"], json.dumps({"value": value}), __qos__) + else: + publish(__topic__ + ":01:99/" + measure["name"], json.dumps({"value": measure["value"]}), __qos__) + except Exception as e: + logger.error(e) + +def convert_int(plc_tag, value): + input_codes = { + 0: "Off", + 1: "On" + } + + run_status_codes = { + 0: "Stopped", + 1: "Running" + } + + overload_codes = { + 0: "Good", + 1: "Down on Overload Tripped" + } + + plc_tags = { + "raw_hand_input": input_codes.get(value, "Invalid Code"), + "raw_auto_input": input_codes.get(value, "Invalid Code"), + "raw_run_status": run_status_codes.get(value, "Invalid Code"), + "raw_overload_status": overload_codes.get(value, "Invalid Code") + } + + return plc_tags.get(plc_tag, "Invalid Tag") + + \ No newline at end of file diff --git a/Pub_Sub/plcfreshwater/v1/sub/receiveCommand.py b/Pub_Sub/plcfreshwater/v1/sub/receiveCommand.py new file mode 100644 index 0000000..2acbed1 --- /dev/null +++ b/Pub_Sub/plcfreshwater/v1/sub/receiveCommand.py @@ -0,0 +1,87 @@ +# Enter your python code. +import json +import os +from quickfaas.measure import recall +from common.Logger import logger + +def sync(mac,value, wizard_api): + #get new values and send + try: + data = recall()#json.loads(recall().decode("utf-8")) + except Exception as e: + logger.error(e) + logger.info(data) + plc_ping = os.system("ping -c 1 192.168.1.101 > /dev/null 2>&1") + if plc_ping == 0: + publish(__topic__ + ":01:99/" + "plc_ping", json.dumps({"value": "OK"}), __qos__) + else: + publish(__topic__ + ":01:99/" + "plc_ping", json.dumps({"value": "Comms Error to PLC"}), __qos__) + for controller in data: + for measure in controller["measures"]: + #publish measure + topic = "meshify/db/194/_/plcfreshwater/" + mac + "/" + measure["name"] + if measure["name"] in ["raw_hand_input", "raw_auto_input", "raw_run_status", "raw_local_start","raw_overload_status"]: + payload = [{"value": convert_int(measure["name"], measure["value"])}] + else: + payload = [{"value": measure["value"]}] + logger.debug("Sending on topic: {}".format(topic)) + logger.debug("Sending value: {}".format(payload)) + wizard_api.mqtt_publish(topic, json.dumps(payload)) +def writeplctag(mac, value, wizard_api): + try: + value = json.loads(value.replace("'",'"')) + logger.debug(value) + message = {"plcfreshwater":{value["tag"]: value["val"]}} + wizard_api.write_plc_values(message) + except Exception as e: + logger.debug(e) + +def receiveCommand(topic, payload, wizard_api): + logger.debug(topic) + logger.debug(json.loads(payload)) + p = json.loads(payload)[0] + command = p["payload"]["name"].split(".")[1] + commands = { + "sync": sync, + "writeplctag": writeplctag, + } + commands[command](p["mac"].lower(),p["payload"]["value"], wizard_api) + #logger.debug(command) + ack(p["msgId"], p["mac"], command, p["payload"]["name"].split(".")[1], p["payload"]["value"], wizard_api) + +def ack(msgid, mac, name, command, value, wizard_api): + #logger.debug(mac) + macsquish = "".join(mac.split(":")[:-2]) + maclower = ":".join(mac.split(":")[:-2]) + maclower = maclower.lower() + #logger.debug(msgid) + #logger.debug(mac) + #logger.debug(name) + #logger.debug(value) + wizard_api.mqtt_publish("meshify/responses/" + str(msgid), json.dumps([{"value": "{} Success Setting: {} To: {}".format(macsquish,name, value), "msgid": str(msgid)}])) + wizard_api.mqtt_publish("meshify/db/194/_/mainMeshify/" + maclower + ":00:00/commands", json.dumps([{"value": {"status": "success", "value": str(value), "channel": command}, "msgid": str(msgid)}])) + +def convert_int(plc_tag, value): + input_codes = { + 0: "Off", + 1: "On" + } + + run_status_codes = { + 0: "Stopped", + 1: "Running" + } + + overload_codes = { + 0: "Good", + 1: "Down on Overload Tripped" + } + + plc_tags = { + "raw_hand_input": input_codes.get(value, "Invalid Code"), + "raw_auto_input": input_codes.get(value, "Invalid Code"), + "raw_run_status": run_status_codes.get(value, "Invalid Code"), + "raw_overload_status": overload_codes.get(value, "Invalid Code") + } + + return plc_tags.get(plc_tag, "Invalid Tag") diff --git a/Pub_Sub/recycle_train/.DS_Store b/Pub_Sub/recycle_train/.DS_Store index a88502d..626503c 100644 Binary files a/Pub_Sub/recycle_train/.DS_Store and b/Pub_Sub/recycle_train/.DS_Store differ diff --git a/Pub_Sub/recycle_train/v1/device_supervisor_recycle_trainv1.cfg b/Pub_Sub/recycle_train/mistaway/v1/device_supervisor_recycle_trainv1.cfg similarity index 100% rename from Pub_Sub/recycle_train/v1/device_supervisor_recycle_trainv1.cfg rename to Pub_Sub/recycle_train/mistaway/v1/device_supervisor_recycle_trainv1.cfg diff --git a/Pub_Sub/recycle_train/v1/pub/sendData.py b/Pub_Sub/recycle_train/mistaway/v1/pub/sendData.py similarity index 100% rename from Pub_Sub/recycle_train/v1/pub/sendData.py rename to Pub_Sub/recycle_train/mistaway/v1/pub/sendData.py diff --git a/Pub_Sub/recycle_train/v1/sub/receiveCommand.py b/Pub_Sub/recycle_train/mistaway/v1/sub/receiveCommand.py similarity index 100% rename from Pub_Sub/recycle_train/v1/sub/receiveCommand.py rename to Pub_Sub/recycle_train/mistaway/v1/sub/receiveCommand.py diff --git a/Pub_Sub/recycle_train/mistaway/v2/pub/sendData.py b/Pub_Sub/recycle_train/mistaway/v2/pub/sendData.py new file mode 100644 index 0000000..3ac25a9 --- /dev/null +++ b/Pub_Sub/recycle_train/mistaway/v2/pub/sendData.py @@ -0,0 +1,152 @@ +import json, os, uuid +from common.Logger import logger +from quickfaas.remotebus import publish +from paho.mqtt import client +from quickfaas.global_dict import get as get_params +from quickfaas.global_dict import _set_global_args + +def reboot(): + #basic = Basic() + logger.info("!" * 10 + "REBOOTING DEVICE" + "!"*10) + r = os.popen("kill -s SIGHUP `cat /var/run/python/supervisord.pid`").read() + logger.info(f"REBOOT : {r}") + +def checkFileExist(filename): + path = "/var/user/files" + if not os.path.exists(path): + logger.info("no folder making files folder in var/user") + os.makedirs(path) + with open(path + "/" + filename, "a") as f: + json.dump({}, f) + if not os.path.exists(path + "/" + filename): + logger.info("no creds file making creds file") + with open(path + "/" + filename, "a") as f: + json.dump({}, f) + +def convertDStoJSON(ds): + j = dict() + for x in ds: + j[x["key"]] = x["value"] + return j + +def convertJSONtoDS(j): + d = [] + for key in j.keys(): + d.append({"key": key, "value": j[key]}) + return d + +def checkCredentialConfig(): + logger.info("CHECKING CONFIG") + cfgpath = "/var/user/cfg/device_supervisor/device_supervisor.cfg" + credspath = "/var/user/files/creds.json" + cfg = dict() + with open(cfgpath, "r") as f: + cfg = json.load(f) + clouds = cfg.get("clouds") + logger.info(clouds) + #if not configured then try to configure from stored values + if clouds[0]["args"]["clientId"] == "unknown" or clouds[0]["args"]["username"] == "unknown" or not clouds[0]["args"]["passwd"] or clouds[0]["args"]["passwd"] == "unknown": + checkFileExist("creds.json") + with open(credspath, "r") as c: + creds = json.load(c) + if creds: + logger.info("updating config with stored data") + clouds[0]["args"]["clientId"] = creds["clientId"] + clouds[0]["args"]["username"] = creds["userName"] + clouds[0]["args"]["passwd"] = creds["password"] + cfg["clouds"] = clouds + cfg = checkParameterConfig(cfg) + with open(cfgpath, "w", encoding='utf-8') as n: + json.dump(cfg, n, indent=1, ensure_ascii=False) + reboot() + else: + #assuming clouds is filled out, if data is different then assume someone typed in something new and store it, if creds is empty fill with clouds' data + checkFileExist("creds.json") + with open(credspath, "r") as c: + logger.info("updating stored file with new data") + cfg = checkParameterConfig(cfg) + with open(cfgpath, "w", encoding='utf-8') as n: + json.dump(cfg, n, indent=1, ensure_ascii=False) + creds = json.load(c) + if creds: + if creds["clientId"] != clouds[0]["args"]["clientId"]: + creds["clientId"] = clouds[0]["args"]["clientId"] + if creds["userName"] != clouds[0]["args"]["username"]: + creds["userName"] = clouds[0]["args"]["username"] + if creds["password"] != clouds[0]["args"]["passwd"]: + creds["password"] = clouds[0]["args"]["passwd"] + else: + creds["clientId"] = clouds[0]["args"]["clientId"] + creds["userName"] = clouds[0]["args"]["username"] + creds["password"] = clouds[0]["args"]["passwd"] + with open(credspath, "w") as cw: + json.dump(creds,cw) + +def checkParameterConfig(cfg): + logger.info("Checking Parameters!!!!") + paramspath = "/var/user/files/params.json" + cfgparams = convertDStoJSON(cfg.get("labels")) + #check stored values + checkFileExist("params.json") + with open(paramspath, "r") as f: + logger.info("Opened param storage file") + params = json.load(f) + if params: + if cfgparams != params: + #go through each param + #if not "unknown" and cfg and params aren't the same take from cfg likely updated manually + #if key in cfg but not in params copy to params + logger.info("equalizing params between cfg and stored") + for key in cfgparams.keys(): + try: + if cfgparams[key] != params[key] and cfgparams[key] != "unknown": + params[key] = cfgparams[key] + except: + params[key] = cfgparams[key] + cfg["labels"] = convertJSONtoDS(params) + _set_global_args(convertJSONtoDS(params)) + with open(paramspath, "w") as p: + json.dump(params, p) + else: + with open(paramspath, "w") as p: + logger.info("initializing param file with params in memory") + json.dump(convertDStoJSON(get_params()), p) + cfg["labels"] = get_params() + + return cfg + +lwtData = { + "init":False, + "client": client.Client(client_id=str(uuid.uuid4()), clean_session=True, userdata=None, protocol=client.MQTTv311, transport="tcp") +} +def lwt(mac): + try: + #if not lwtData["connected"]: + if not lwtData["init"]: + print("INITIALIZING LWT CLIENT") + lwtData["client"].username_pw_set(username="admin", password="columbus") + lwtData["client"].will_set("meshify/db/194/_/mainHP/" + mac + ":00:00/connected",json.dumps([{"value":False}])) + lwtData["client"].reconnect_delay_set(min_delay=10, max_delay=120) + lwtData["init"] = True + print("Connecting to MQTT Broker for LWT purposes!!!!!!!") + lwtData["client"].connect("mq194.imistaway.net",1883, 600) + lwtData["client"].reconnect() + lwtData["client"].publish("meshify/db/194/_/mainHP/" + mac + ":00:00/connected", json.dumps([{"value":True}])) + except Exception as e: + print("LWT DID NOT DO THE THING") + print(e) + +def sendData(message): + #logger.debug(message) + mac = __topic__.split("/")[-1] #':'.join(re.findall('..', '%012x' % uuid.getnode())) + lwt(mac) + checkCredentialConfig() + for measure in message["measures"]: + try: + logger.debug(measure) + publish(__topic__ + ":01:99/" + measure["name"], json.dumps({"value": measure["value"]}), __qos__) + except Exception as e: + logger.error(e) + + + \ No newline at end of file diff --git a/Pub_Sub/recycle_train/v2/device_supervisor_recycle_trainv2.cfg b/Pub_Sub/recycle_train/mistaway/v2/recycletrain_ma_v2.cfg similarity index 98% rename from Pub_Sub/recycle_train/v2/device_supervisor_recycle_trainv2.cfg rename to Pub_Sub/recycle_train/mistaway/v2/recycletrain_ma_v2.cfg index 7c2fc85..02add51 100644 --- a/Pub_Sub/recycle_train/v2/device_supervisor_recycle_trainv2.cfg +++ b/Pub_Sub/recycle_train/mistaway/v2/recycletrain_ma_v2.cfg @@ -635,7 +635,7 @@ ], "misc": { "maxAlarmRecordSz": 2000, - "logLvl": "DEBUG", + "logLvl": "INFO", "coms": [ { "name": "rs232", @@ -661,7 +661,7 @@ "args": { "host": "mq194.imistaway.net", "port": 1883, - "clientId": "sv-inhand-demo", + "clientId": "unknown", "auth": 1, "tls": 0, "cleanSession": 1, @@ -672,8 +672,8 @@ "rootCA": "", "verifyServer": 0, "verifyClient": 0, - "username": "admin", - "passwd": "columbus", + "username": "unknown", + "passwd": "unknown", "authType": 1 }, "name": "default" @@ -718,14 +718,6 @@ { "key": "MAC", "value": "00:18:05:1a:e5:36" - }, - { - "key": "MAC_UPPER", - "value": "00:18:05:1A:E5:37" - }, - { - "key": "MAC_LOWER", - "value": "00:18:05:1a:e5:37" } ], "modbusSlave": { diff --git a/Pub_Sub/recycle_train/v2/sub/receiveCommand.py b/Pub_Sub/recycle_train/mistaway/v2/sub/receiveCommand.py similarity index 100% rename from Pub_Sub/recycle_train/v2/sub/receiveCommand.py rename to Pub_Sub/recycle_train/mistaway/v2/sub/receiveCommand.py diff --git a/Pub_Sub/recycle_train/v1/.DS_Store b/Pub_Sub/recycle_train/v1/.DS_Store deleted file mode 100644 index 41348a4..0000000 Binary files a/Pub_Sub/recycle_train/v1/.DS_Store and /dev/null differ diff --git a/Pub_Sub/recycle_train/v2/.DS_Store b/Pub_Sub/recycle_train/v2/.DS_Store deleted file mode 100644 index 623de63..0000000 Binary files a/Pub_Sub/recycle_train/v2/.DS_Store and /dev/null differ diff --git a/Pub_Sub/recycle_train/v2/pub/.DS_Store b/Pub_Sub/recycle_train/v2/pub/.DS_Store deleted file mode 100644 index 5008ddf..0000000 Binary files a/Pub_Sub/recycle_train/v2/pub/.DS_Store and /dev/null differ diff --git a/Pub_Sub/recycle_train/v2/pub/sendData.py b/Pub_Sub/recycle_train/v2/pub/sendData.py deleted file mode 100644 index 1b3a90d..0000000 --- a/Pub_Sub/recycle_train/v2/pub/sendData.py +++ /dev/null @@ -1,41 +0,0 @@ -# Enter your python code. -import json -from common.Logger import logger -from quickfaas.remotebus import publish -import re, uuid -from paho.mqtt import client - -lwtData = { - "init":False, - "client": client.Client(client_id=str(uuid.uuid4()), clean_session=True, userdata=None, protocol=client.MQTTv311, transport="tcp") -} -def lwt(mac): - try: - #if not lwtData["connected"]: - if not lwtData["init"]: - logger.info("INITIALIZING LWT CLIENT") - lwtData["client"].username_pw_set(username="admin", password="columbus") - lwtData["client"].will_set("meshify/db/194/_/mainHP/" + mac + ":00:00/connected",json.dumps({"value":False})) - lwtData["init"] = True - logger.info("Connecting to MQTT Broker for LWT purposes!!!!!!!") - lwtData["client"].connect("mq194.imistaway.net",1883, 600) - lwtData["client"].publish("meshify/db/194/_/mainHP/" + mac + ":00:00/connected", json.dumps({"value":True})) - except Exception as e: - logger.error("LWT DID NOT DO THE THING") - logger.error(e) - -def sendData(message): - #logger.debug(message) - mac = __topic__.split("/")[-1] #':'.join(re.findall('..', '%012x' % uuid.getnode())) - lwt(mac) - for measure in message["measures"]: - try: - logger.debug(measure) - publish(__topic__ + ":01:99/" + measure["name"], json.dumps({"value": measure["value"]}), __qos__) - except Exception as e: - logger.error(e) - - #publish(__topic__, json.dumps({measure["name"]: measure["value"]}), __qos__) - - - \ No newline at end of file diff --git a/Pub_Sub/rigpump/.DS_Store b/Pub_Sub/rigpump/.DS_Store index 064f66b..09aed8c 100644 Binary files a/Pub_Sub/rigpump/.DS_Store and b/Pub_Sub/rigpump/.DS_Store differ diff --git a/Pub_Sub/rigpump/v3/device_supervisor_rigpumpv3.cfg b/Pub_Sub/rigpump/mistaway/v3/device_supervisor_rigpumpv3.cfg similarity index 100% rename from Pub_Sub/rigpump/v3/device_supervisor_rigpumpv3.cfg rename to Pub_Sub/rigpump/mistaway/v3/device_supervisor_rigpumpv3.cfg diff --git a/Pub_Sub/rigpump/v3/pub/sendData.py b/Pub_Sub/rigpump/mistaway/v3/pub/sendData.py similarity index 100% rename from Pub_Sub/rigpump/v3/pub/sendData.py rename to Pub_Sub/rigpump/mistaway/v3/pub/sendData.py diff --git a/Pub_Sub/rigpump/v3/sub/receiveCommand.py b/Pub_Sub/rigpump/mistaway/v3/sub/receiveCommand.py similarity index 100% rename from Pub_Sub/rigpump/v3/sub/receiveCommand.py rename to Pub_Sub/rigpump/mistaway/v3/sub/receiveCommand.py diff --git a/Pub_Sub/rigpump/mistaway/v4/pub/sendData.py b/Pub_Sub/rigpump/mistaway/v4/pub/sendData.py new file mode 100644 index 0000000..7ac120c --- /dev/null +++ b/Pub_Sub/rigpump/mistaway/v4/pub/sendData.py @@ -0,0 +1,210 @@ +import json, os, uuid +from common.Logger import logger +from quickfaas.remotebus import publish +from paho.mqtt import client +from mobiuspi_lib.gps import GPS +from quickfaas.global_dict import get as get_params +from quickfaas.global_dict import _set_global_args + +def reboot(): + #basic = Basic() + logger.info("!" * 10 + "REBOOTING DEVICE" + "!"*10) + r = os.popen("kill -s SIGHUP `cat /var/run/python/supervisord.pid`").read() + logger.info(f"REBOOT : {r}") + +def checkFileExist(filename): + path = "/var/user/files" + if not os.path.exists(path): + logger.info("no folder making files folder in var/user") + os.makedirs(path) + with open(path + "/" + filename, "a") as f: + json.dump({}, f) + if not os.path.exists(path + "/" + filename): + logger.info("no creds file making creds file") + with open(path + "/" + filename, "a") as f: + json.dump({}, f) + +def convertDStoJSON(ds): + j = dict() + for x in ds: + j[x["key"]] = x["value"] + return j + +def convertJSONtoDS(j): + d = [] + for key in j.keys(): + d.append({"key": key, "value": j[key]}) + return d + +def checkCredentialConfig(): + logger.info("CHECKING CONFIG") + cfgpath = "/var/user/cfg/device_supervisor/device_supervisor.cfg" + credspath = "/var/user/files/creds.json" + cfg = dict() + with open(cfgpath, "r") as f: + cfg = json.load(f) + clouds = cfg.get("clouds") + logger.info(clouds) + #if not configured then try to configure from stored values + if clouds[0]["args"]["clientId"] == "unknown" or clouds[0]["args"]["username"] == "unknown" or not clouds[0]["args"]["passwd"] or clouds[0]["args"]["passwd"] == "unknown": + checkFileExist("creds.json") + with open(credspath, "r") as c: + creds = json.load(c) + if creds: + logger.info("updating config with stored data") + clouds[0]["args"]["clientId"] = creds["clientId"] + clouds[0]["args"]["username"] = creds["userName"] + clouds[0]["args"]["passwd"] = creds["password"] + cfg["clouds"] = clouds + cfg = checkParameterConfig(cfg) + with open(cfgpath, "w", encoding='utf-8') as n: + json.dump(cfg, n, indent=1, ensure_ascii=False) + reboot() + else: + #assuming clouds is filled out, if data is different then assume someone typed in something new and store it, if creds is empty fill with clouds' data + checkFileExist("creds.json") + with open(credspath, "r") as c: + logger.info("updating stored file with new data") + cfg = checkParameterConfig(cfg) + with open(cfgpath, "w", encoding='utf-8') as n: + json.dump(cfg, n, indent=1, ensure_ascii=False) + creds = json.load(c) + if creds: + if creds["clientId"] != clouds[0]["args"]["clientId"]: + creds["clientId"] = clouds[0]["args"]["clientId"] + if creds["userName"] != clouds[0]["args"]["username"]: + creds["userName"] = clouds[0]["args"]["username"] + if creds["password"] != clouds[0]["args"]["passwd"]: + creds["password"] = clouds[0]["args"]["passwd"] + else: + creds["clientId"] = clouds[0]["args"]["clientId"] + creds["userName"] = clouds[0]["args"]["username"] + creds["password"] = clouds[0]["args"]["passwd"] + with open(credspath, "w") as cw: + json.dump(creds,cw) + +def checkParameterConfig(cfg): + logger.info("Checking Parameters!!!!") + paramspath = "/var/user/files/params.json" + cfgparams = convertDStoJSON(cfg.get("labels")) + #check stored values + checkFileExist("params.json") + with open(paramspath, "r") as f: + logger.info("Opened param storage file") + params = json.load(f) + if params: + if cfgparams != params: + #go through each param + #if not "unknown" and cfg and params aren't the same take from cfg likely updated manually + #if key in cfg but not in params copy to params + logger.info("equalizing params between cfg and stored") + for key in cfgparams.keys(): + try: + if cfgparams[key] != params[key] and cfgparams[key] != "unknown": + params[key] = cfgparams[key] + except: + params[key] = cfgparams[key] + cfg["labels"] = convertJSONtoDS(params) + _set_global_args(convertJSONtoDS(params)) + with open(paramspath, "w") as p: + json.dump(params, p) + else: + with open(paramspath, "w") as p: + logger.info("initializing param file with params in memory") + json.dump(convertDStoJSON(get_params()), p) + cfg["labels"] = get_params() + + return cfg + +lwtData = { + "init":False, + "client": client.Client(client_id=str(uuid.uuid4()), clean_session=True, userdata=None, protocol=client.MQTTv311, transport="tcp") +} +def lwt(mac): + try: + #if not lwtData["connected"]: + if not lwtData["init"]: + print("INITIALIZING LWT CLIENT") + lwtData["client"].username_pw_set(username="admin", password="columbus") + lwtData["client"].will_set("meshify/db/194/_/mainHP/" + mac + ":00:00/connected",json.dumps([{"value":False}])) + lwtData["client"].reconnect_delay_set(min_delay=10, max_delay=120) + lwtData["init"] = True + print("Connecting to MQTT Broker for LWT purposes!!!!!!!") + lwtData["client"].connect("mq194.imistaway.net",1883, 600) + lwtData["client"].reconnect() + lwtData["client"].publish("meshify/db/194/_/mainHP/" + mac + ":00:00/connected", json.dumps([{"value":True}])) + except Exception as e: + print("LWT DID NOT DO THE THING") + print(e) + +def getGPS(mac): + # Create a gps instance + gps = GPS() + + # Retrieve GPS information + position_status = gps.get_position_status() + logger.debug("position_status: ") + logger.debug(position_status) + latitude = position_status["latitude"].split(" ") + longitude = position_status["longitude"].split(" ") + lat_dec = int(latitude[0][:-1]) + (float(latitude[1][:-1])/60) + lon_dec = int(longitude[0][:-1]) + (float(longitude[1][:-1])/60) + if latitude[2] == "S": + lat_dec = lat_dec * -1 + if longitude[2] == "W": + lon_dec = lon_dec * -1 + #lat_dec = round(lat_dec, 7) + #lon_dec = round(lon_dec, 7) + logger.info("HERE IS THE GPS COORDS") + logger.info(f"LATITUDE: {lat_dec}, LONGITUDE: {lon_dec}") + topic = f"meshify/db/194/_/M1/{mac}:00:30/gps" + publish(topic, json.dumps([{"value":f"{lat_dec:.8f},{lon_dec:.8f}"}]), __qos__) + + +def sendData(message): + #logger.debug(message) + mac = __topic__.split("/")[-1] #':'.join(re.findall('..', '%012x' % uuid.getnode())) + lwt(mac) + getGPS(mac) + checkCredentialConfig() + for measure in message["measures"]: + try: + logger.debug(measure) + if measure["name"] in ["auto_manual", "auto_control_mode", "device_status"]: + logger.debug("Converting DINT/BOOL to STRING") + value = convert_int(measure["name"], measure["value"]) + logger.debug("Converted {} to {}".format(measure["value"], value)) + publish(__topic__ + ":01:99/" + measure["name"], json.dumps({"value": value}), __qos__) + else: + publish(__topic__ + ":01:99/" + measure["name"], json.dumps({"value": measure["value"]}), __qos__) + except Exception as e: + logger.error(e) + + +def convert_int(plc_tag, value): + auto_manual = { + 0: "Manual", + 1: "Auto" + } + + auto_control_mode = { + 0: "Pressure", + 1: "Flow" + } + + device_status = { + 1: "Running", + 64: "Idle", + 128: "Overpressure", + 1024: "Faulted" + } + + plc_tags = { + "auto_manual": auto_manual.get(value, "Invalid Code"), + "auto_control_mode": auto_control_mode.get(value, "Invalid Code"), + "device_status": device_status.get(value, "Invalid Code"), + } + + return plc_tags.get(plc_tag, "Invalid Tag") + + \ No newline at end of file diff --git a/Pub_Sub/rigpump/v4/device_supervisor_rigpumpv4.cfg b/Pub_Sub/rigpump/mistaway/v4/rigpump_ma_v4.cfg similarity index 97% rename from Pub_Sub/rigpump/v4/device_supervisor_rigpumpv4.cfg rename to Pub_Sub/rigpump/mistaway/v4/rigpump_ma_v4.cfg index 548035f..71cd3c8 100644 --- a/Pub_Sub/rigpump/v4/device_supervisor_rigpumpv4.cfg +++ b/Pub_Sub/rigpump/mistaway/v4/rigpump_ma_v4.cfg @@ -231,7 +231,7 @@ ], "misc": { "maxAlarmRecordSz": 2000, - "logLvl": "DEBUG", + "logLvl": "INFO", "coms": [ { "name": "rs232", @@ -257,7 +257,7 @@ "args": { "host": "mq194.imistaway.net", "port": 1883, - "clientId": "sv-inhand-demo", + "clientId": "unknown", "auth": 1, "tls": 0, "cleanSession": 1, @@ -268,8 +268,8 @@ "rootCA": "", "verifyServer": 0, "verifyClient": 0, - "username": "admin", - "passwd": "columbus", + "username": "unknown", + "passwd": "unknown", "authType": 1 }, "name": "default" @@ -314,14 +314,6 @@ { "key": "MAC", "value": "00:18:05:1a:e5:36" - }, - { - "key": "MAC_UPPER", - "value": "00:18:05:1A:E5:37" - }, - { - "key": "MAC_LOWER", - "value": "00:18:05:1a:e5:37" } ], "modbusSlave": { diff --git a/Pub_Sub/rigpump/v4/sub/receiveCommand.py b/Pub_Sub/rigpump/mistaway/v4/sub/receiveCommand.py similarity index 100% rename from Pub_Sub/rigpump/v4/sub/receiveCommand.py rename to Pub_Sub/rigpump/mistaway/v4/sub/receiveCommand.py diff --git a/Pub_Sub/rigpump/v3/.DS_Store b/Pub_Sub/rigpump/v3/.DS_Store deleted file mode 100644 index 52003cb..0000000 Binary files a/Pub_Sub/rigpump/v3/.DS_Store and /dev/null differ diff --git a/Pub_Sub/rigpump/v4/.DS_Store b/Pub_Sub/rigpump/v4/.DS_Store deleted file mode 100644 index 09387f4..0000000 Binary files a/Pub_Sub/rigpump/v4/.DS_Store and /dev/null differ diff --git a/Pub_Sub/rigpump/v4/pub/sendData.py b/Pub_Sub/rigpump/v4/pub/sendData.py deleted file mode 100644 index c735225..0000000 --- a/Pub_Sub/rigpump/v4/pub/sendData.py +++ /dev/null @@ -1,98 +0,0 @@ -# Enter your python code. -import json -from common.Logger import logger -from quickfaas.remotebus import publish -import re, uuid -from paho.mqtt import client -from mobiuspi_lib.gps import GPS - -lwtData = { - "init":False, - "client": client.Client(client_id=str(uuid.uuid4()), clean_session=True, userdata=None, protocol=client.MQTTv311, transport="tcp") -} -def lwt(mac): - try: - #if not lwtData["connected"]: - if not lwtData["init"]: - logger.info("INITIALIZING LWT CLIENT") - lwtData["client"].username_pw_set(username="admin", password="columbus") - lwtData["client"].will_set("meshify/db/194/_/mainHP/" + mac + ":00:00/connected",json.dumps({"value":False})) - lwtData["init"] = True - logger.info("Connecting to MQTT Broker for LWT purposes!!!!!!!") - lwtData["client"].connect("mq194.imistaway.net",1883, 600) - lwtData["client"].publish("meshify/db/194/_/mainHP/" + mac + ":00:00/connected", json.dumps({"value":True})) - except Exception as e: - logger.error("LWT DID NOT DO THE THING") - logger.error(e) - -def getGPS(mac): - # Create a gps instance - gps = GPS() - - # Retrieve GPS information - position_status = gps.get_position_status() - logger.debug("position_status: ") - logger.debug(position_status) - latitude = position_status["latitude"].split(" ") - longitude = position_status["longitude"].split(" ") - lat_dec = int(latitude[0][:-1]) + (float(latitude[1][:-1])/60) - lon_dec = int(longitude[0][:-1]) + (float(longitude[1][:-1])/60) - if latitude[2] == "S": - lat_dec = lat_dec * -1 - if longitude[2] == "W": - lon_dec = lon_dec * -1 - #lat_dec = round(lat_dec, 7) - #lon_dec = round(lon_dec, 7) - logger.info("HERE IS THE GPS COORDS") - logger.info(f"LATITUDE: {lat_dec}, LONGITUDE: {lon_dec}") - topic = f"meshify/db/194/_/M1/{mac}:00:30/gps" - publish(topic, json.dumps([{"value":f"{lat_dec:.8f},{lon_dec:.8f}"}]), __qos__) - - -def sendData(message): - #logger.debug(message) - mac = __topic__.split("/")[-1] #':'.join(re.findall('..', '%012x' % uuid.getnode())) - lwt(mac) - getGPS(mac) - for measure in message["measures"]: - try: - logger.debug(measure) - if measure["name"] in ["auto_manual", "auto_control_mode", "device_status"]: - logger.debug("Converting DINT/BOOL to STRING") - value = convert_int(measure["name"], measure["value"]) - logger.debug("Converted {} to {}".format(measure["value"], value)) - publish(__topic__ + ":01:99/" + measure["name"], json.dumps({"value": value}), __qos__) - else: - publish(__topic__ + ":01:99/" + measure["name"], json.dumps({"value": measure["value"]}), __qos__) - except Exception as e: - logger.error(e) - - #publish(__topic__, json.dumps({measure["name"]: measure["value"]}), __qos__) - -def convert_int(plc_tag, value): - auto_manual = { - 0: "Manual", - 1: "Auto" - } - - auto_control_mode = { - 0: "Pressure", - 1: "Flow" - } - - device_status = { - 1: "Running", - 64: "Idle", - 128: "Overpressure", - 1024: "Faulted" - } - - plc_tags = { - "auto_manual": auto_manual.get(value, "Invalid Code"), - "auto_control_mode": auto_control_mode.get(value, "Invalid Code"), - "device_status": device_status.get(value, "Invalid Code"), - } - - return plc_tags.get(plc_tag, "Invalid Tag") - - \ No newline at end of file