diff --git a/.DS_Store b/.DS_Store index bb21bdb..ea3918d 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/Pub_Sub/.DS_Store b/Pub_Sub/.DS_Store index 9c0baab..0417bcb 100644 Binary files a/Pub_Sub/.DS_Store and b/Pub_Sub/.DS_Store differ diff --git a/Pub_Sub/abbflow/.DS_Store b/Pub_Sub/abbflow/.DS_Store index fb3fcbd..505e911 100644 Binary files a/Pub_Sub/abbflow/.DS_Store and b/Pub_Sub/abbflow/.DS_Store differ diff --git a/Pub_Sub/abbflow/thingsboard/device_supervisor_abbflow_tb_v1.cfg b/Pub_Sub/abbflow/thingsboard/device_supervisor_abbflow_tb_v1.cfg new file mode 100644 index 0000000..83255a8 --- /dev/null +++ b/Pub_Sub/abbflow/thingsboard/device_supervisor_abbflow_tb_v1.cfg @@ -0,0 +1,388 @@ +{ + "controllers": [ + { + "protocol": "Modbus-RTU", + "name": "abbflow", + "args": { + "slaveAddr": 1, + "int16Ord": "ab", + "int32Ord": "abcd", + "float32Ord": "abcd", + "continuousAcquisition": 1, + "maxContinuousNumber": 64 + }, + "endpoint": "rs232", + "samplePeriod": 10, + "expired": 10000 + } + ], + "groups": [ + { + "name": "default", + "uploadInterval": 3600, + "reference": 10 + } + ], + "measures": [ + { + "name": "volume_flow", + "ctrlName": "abbflow", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "44004", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "regAddr": "44004", + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "today_volume", + "ctrlName": "abbflow", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "44006", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "regAddr": "44006", + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "battery_voltage", + "ctrlName": "abbflow", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "44002", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "regAddr": "44002", + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "differential_pressure", + "ctrlName": "abbflow", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "44014", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "regAddr": "44014", + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "yesterday_volume", + "ctrlName": "abbflow", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "44008", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "regAddr": "44008", + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "accumulated_volume", + "ctrlName": "abbflow", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "44010", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "regAddr": "44010", + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "static_pressure", + "ctrlName": "abbflow", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "44016", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "regAddr": "44016", + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "temperature", + "ctrlName": "abbflow", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "44018", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "regAddr": "44018", + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "charger_voltage", + "ctrlName": "abbflow", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "44020", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "regAddr": "44020", + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + }, + { + "name": "last_calculation_period_volume", + "ctrlName": "abbflow", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "44013", + "decimal": 2, + "len": 1, + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "regAddr": "44013", + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "gain": "", + "offset": "" + } + ], + "alarms": [], + "misc": { + "maxAlarmRecordSz": 2000, + "logLvl": "DEBUG", + "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": "thingsboard.cloud", + "port": 1883, + "clientId": "clientid", + "auth": 1, + "tls": 0, + "cleanSession": 1, + "mqttVersion": "v3.1.1", + "keepalive": 60, + "key": "", + "cert": "", + "rootCA": "", + "verifyServer": 0, + "verifyClient": 0, + "username": "username", + "passwd": "password", + "authType": 1 + } + } + ], + "labels": [ + { + "key": "SN", + "value": "GF5022210011338" + }, + { + "key": "MAC", + "value": "00:18:05:1e:94:f4" + }, + { + "key": "MAC_UPPER", + "value": "00:18:05:1A:E5:57" + } + ], + "quickfaas": { + "genericFuncs": [], + "uploadFuncs": [ + { + "name": "Mistaway", + "trigger": "measure_event", + "topic": "v1/devices/me/telemetry", + "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\n\n\ndef sendData(message):\n logger.debug(message)\n payload = {}\n for measure in message[\"measures\"]:\n payload[measure[\"name\"]] = measure[\"value\"]\n\n publish(__topic__, json.dumps(payload), __qos__)\n ", + "msgType": 0, + "cloudName": "default" + } + ], + "downloadFuncs": [ + { + "name": "Commands", + "topic": "v1/devices/me/rpc/request/+", + "qos": 1, + "funcName": "receiveCommand", + "payload_type": "JSON", + "script": "# Enter your python code.\nimport json\nfrom quickfaas.measure import recall\nfrom common.Logger import logger\n\ndef sync(wizard_api):\n #get new values and send\n payload = {}\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 = \"v1/devices/me/telemetry\"\n payload[measure[\"name\"]] = 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(value, wizard_api):\n try:\n #value = json.loads(value.replace(\"'\",'\"'))\n logger.debug(value)\n message = {\"advvfdipp\":{value[\"measurement\"]: value[\"value\"]}}\n resp = wizard_api.write_plc_values(message)\n #logger.debug(\"RETURN FROM WRITE: {}\".format(resp))\n return True\n except Exception as e:\n logger.debug(e)\n return False\n \ndef receiveCommand(topic, payload, wizard_api):\n try:\n logger.debug(topic)\n logger.debug(json.loads(payload))\n p = json.loads(payload)\n command = p[\"method\"]\n commands = {\n \"sync\": sync,\n \"writeplctag\": writeplctag,\n } \n if command == \"setPLCTag\":\n result = commands[\"writeplctag\"](p[\"params\"],wizard_api)\n if result:\n sync(wizard_api)\n #commands[command](p[\"mac\"].lower(),p[\"payload\"][\"value\"], wizard_api)\n #logger.debug(command)\n ack(topic.split(\"/\")[-1], wizard_api)\n except Exception as e:\n logger.debug(e)\n \n\ndef ack(msgid, wizard_api):\n #logger.debug(msgid)\n #logger.debug(mac)\n #logger.debug(name)\n #logger.debug(value)\n wizard_api.mqtt_publish(\"v1/devices/me/rpc/response/\" + str(msgid), json.dumps({\"msg\": {\"time\": time.time()}, \"metadata\": \"\", \"msgType\": \"\"}))", + "msgType": 0, + "cloudName": "default", + "trigger": "command_event" + } + ] + }, + "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/abbflow/thingsboard/pub/sendData.py b/Pub_Sub/abbflow/thingsboard/pub/sendData.py new file mode 100644 index 0000000..baea6fd --- /dev/null +++ b/Pub_Sub/abbflow/thingsboard/pub/sendData.py @@ -0,0 +1,15 @@ +# Enter your python code. +import json +from common.Logger import logger +from quickfaas.remotebus import publish +import re, uuid + + +def sendData(message): + logger.debug(message) + payload = {} + for measure in message["measures"]: + payload[measure["name"]] = measure["value"] + + publish(__topic__, json.dumps(payload), __qos__) + \ No newline at end of file diff --git a/Pub_Sub/abbflow/thingsboard/sub/receiveCommand.py b/Pub_Sub/abbflow/thingsboard/sub/receiveCommand.py new file mode 100644 index 0000000..c6d3980 --- /dev/null +++ b/Pub_Sub/abbflow/thingsboard/sub/receiveCommand.py @@ -0,0 +1,60 @@ +# Enter your python code. +import json +from quickfaas.measure import recall +from common.Logger import logger + +def sync(wizard_api): + #get new values and send + payload = {} + try: + data = recall()#json.loads(recall().decode("utf-8")) + except Exception as e: + logger.error(e) + logger.info(data) + for controller in data: + for measure in controller["measures"]: + #publish measure + topic = "v1/devices/me/telemetry" + payload[measure["name"]] = 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(value, wizard_api): + try: + #value = json.loads(value.replace("'",'"')) + logger.debug(value) + message = {"advvfdipp":{value["measurement"]: value["value"]}} + resp = wizard_api.write_plc_values(message) + #logger.debug("RETURN FROM WRITE: {}".format(resp)) + return True + except Exception as e: + logger.debug(e) + return False + +def receiveCommand(topic, payload, wizard_api): + try: + logger.debug(topic) + logger.debug(json.loads(payload)) + p = json.loads(payload) + command = p["method"] + commands = { + "sync": sync, + "writeplctag": writeplctag, + } + if command == "setPLCTag": + result = commands["writeplctag"](p["params"],wizard_api) + if result: + sync(wizard_api) + #commands[command](p["mac"].lower(),p["payload"]["value"], wizard_api) + #logger.debug(command) + ack(topic.split("/")[-1], wizard_api) + except Exception as e: + logger.debug(e) + + +def ack(msgid, wizard_api): + #logger.debug(msgid) + #logger.debug(mac) + #logger.debug(name) + #logger.debug(value) + wizard_api.mqtt_publish("v1/devices/me/rpc/response/" + str(msgid), json.dumps({"msg": {"time": time.time()}, "metadata": "", "msgType": ""})) \ No newline at end of file diff --git a/Pub_Sub/advvfdipp/.DS_Store b/Pub_Sub/advvfdipp/.DS_Store index a01e80f..907a266 100644 Binary files a/Pub_Sub/advvfdipp/.DS_Store and b/Pub_Sub/advvfdipp/.DS_Store differ diff --git a/Pub_Sub/advvfdipp/thingsboard/v1/device_supervisor_advvfdipp_tb_v1.cfg b/Pub_Sub/advvfdipp/thingsboard/v1/device_supervisor_advvfdipp_tb_v1.cfg new file mode 100644 index 0000000..7d86413 --- /dev/null +++ b/Pub_Sub/advvfdipp/thingsboard/v1/device_supervisor_advvfdipp_tb_v1.cfg @@ -0,0 +1,1067 @@ +{ + "controllers": [ + { + "protocol": "EtherNet/IP", + "name": "advvfdipp", + "args": {}, + "samplePeriod": 10, + "expired": 10000, + "endpoint": "192.168.1.10:44818" + } + ], + "groups": [ + { + "name": "default", + "uploadInterval": 600, + "reference": 45 + } + ], + "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": "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": "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": "startcommand", + "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": "stopcommand", + "desc": "", + "unit": "", + "transformType": 0, + "gain": "1.0", + "offset": "0.0", + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "decimal": 2 + }, + { + "ctrlName": "advvfdipp", + "dataType": "INT", + "addr": "sts_PID_Control", + "readWrite": "rw", + "uploadType": "periodic", + "group": "default", + "name": "pidcontrolmode", + "desc": "", + "unit": "", + "transformType": 0, + "gain": "1.0", + "offset": "0.0", + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "decimal": 2 + }, + { + "ctrlName": "advvfdipp", + "dataType": "FLOAT", + "addr": "cfg_PID_FlowSP", + "readWrite": "rw", + "uploadType": "periodic", + "group": "default", + "decimal": 2, + "name": "flowsetpoint", + "desc": "", + "unit": "", + "transformType": 0, + "gain": "1.0", + "offset": "0.0", + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "" + }, + { + "ctrlName": "advvfdipp", + "dataType": "FLOAT", + "addr": "cfg_PID_TubingPressureSP", + "readWrite": "rw", + "uploadType": "periodic", + "group": "default", + "decimal": 2, + "name": "tubingpressuresetpoint", + "desc": "", + "unit": "", + "transformType": 0, + "gain": "1.0", + "offset": "0.0", + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "" + }, + { + "ctrlName": "advvfdipp", + "dataType": "FLOAT", + "addr": "cfg_PID_FluidLevelSP", + "readWrite": "rw", + "uploadType": "periodic", + "group": "default", + "decimal": 2, + "name": "fluidlevelsetpoint", + "desc": "", + "unit": "", + "transformType": 0, + "gain": "1.0", + "offset": "0.0", + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "" + }, + { + "ctrlName": "advvfdipp", + "dataType": "FLOAT", + "addr": "cfg_PID_ManualSP", + "readWrite": "rw", + "uploadType": "periodic", + "group": "default", + "decimal": 2, + "name": "manualfrequencysetpoint", + "desc": "", + "unit": "", + "transformType": 0, + "gain": "1.0", + "offset": "0.0", + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "" + }, + { + "ctrlName": "advvfdipp", + "dataType": "BIT", + "addr": "cmd_ResetAlarms", + "readWrite": "rw", + "uploadType": "periodic", + "group": "default", + "name": "resetalarms", + "desc": "", + "unit": "", + "transformType": 0, + "gain": "1.0", + "offset": "0.0", + "maxValue": "", + "minValue": "", + "maxScaleValue": "", + "minScaleValue": "", + "decimal": 2 + } + ], + "alarms": [], + "misc": { + "maxAlarmRecordSz": 2000, + "logLvl": "DEBUG", + "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": "thingsboard.cloud", + "port": 1883, + "clientId": "faskens-test", + "auth": 1, + "tls": 0, + "cleanSession": 1, + "mqttVersion": "v3.1.1", + "keepalive": 120, + "key": "", + "cert": "", + "rootCA": "", + "verifyServer": 0, + "verifyClient": 0, + "username": "hpfaskens", + "passwd": "hpfaskens", + "authType": 1 + }, + "name": "default" + } + ], + "labels": [ + { + "key": "SN", + "value": "GF5022137006251" + }, + { + "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" + } + ], + "quickfaas": { + "genericFuncs": [], + "uploadFuncs": [ + { + "name": "Send Data", + "trigger": "measure_event", + "topic": "v1/devices/me/telemetry", + "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\n\ndef sendData(message):\n #logger.debug(message)\n payload = {}\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 payload[measure[\"name\"]] = value\n payload[measure[\"name\"] + \"_int\"] = measure[\"value\"]\n else:\n payload[measure[\"name\"]] = measure[\"value\"] \n except Exception as e:\n logger.error(e)\n \n publish(__topic__, json.dumps(payload), __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": "v1/devices/me/rpc/request/+", + "qos": 1, + "funcName": "receiveCommand", + "payload_type": "JSON", + "script": "# Enter your python code.\nimport json\nimport time\nfrom quickfaas.measure import recall\nfrom common.Logger import logger\n\ndef sync(wizard_api):\n #get new values and send\n payload = {}\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 = \"v1/devices/me/telemetry\"\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[measure[\"name\"]] = convert_int(measure[\"name\"], measure[\"value\"])\n payload[measure[\"name\"]+ \"_int\"] = measure[\"value\"]\n else:\n payload[measure[\"name\"]] = 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(value, wizard_api):\n try:\n #value = json.loads(value.replace(\"'\",'\"'))\n logger.debug(value)\n message = {\"advvfdipp\":{value[\"measurement\"]: value[\"value\"]}}\n resp = wizard_api.write_plc_values(message)\n #logger.debug(\"RETURN FROM WRITE: {}\".format(resp))\n return True\n except Exception as e:\n logger.debug(e)\n return False\n \ndef receiveCommand(topic, payload, wizard_api):\n try:\n logger.debug(topic)\n logger.debug(json.loads(payload))\n p = json.loads(payload)\n command = p[\"method\"]\n commands = {\n \"sync\": sync,\n \"writeplctag\": writeplctag,\n } \n if command == \"setPLCTag\":\n result = commands[\"writeplctag\"](p[\"params\"],wizard_api)\n if result:\n sync(wizard_api)\n #commands[command](p[\"mac\"].lower(),p[\"payload\"][\"value\"], wizard_api)\n #logger.debug(command)\n ack(topic.split(\"/\")[-1], wizard_api)\n except Exception as e:\n logger.debug(e)\n \n\ndef ack(msgid, wizard_api):\n #logger.debug(msgid)\n #logger.debug(mac)\n #logger.debug(name)\n #logger.debug(value)\n wizard_api.mqtt_publish(\"v1/devices/me/rpc/response/\" + str(msgid), json.dumps({\"msg\": {\"time\": time.time()}, \"metadata\": \"\", \"msgType\": \"\"}))\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/thingsboard/v1/pub/sendData.py b/Pub_Sub/advvfdipp/thingsboard/v1/pub/sendData.py new file mode 100644 index 0000000..6ba8ad4 --- /dev/null +++ b/Pub_Sub/advvfdipp/thingsboard/v1/pub/sendData.py @@ -0,0 +1,194 @@ +# Enter your python code. +import json +from common.Logger import logger +from quickfaas.remotebus import publish +import re, uuid +from paho.mqtt import client + + +def sendData(message): + #logger.debug(message) + payload = {} + for measure in message["measures"]: + try: + logger.debug(measure) + if measure["name"] in ["wellstatus","pidcontrolmode","downholesensorstatus","alarmflowrate","alarmintakepressure","alarmintaketemperature","alarmtubingpressure","alarmvfd","alarmlockout","alarmfluidlevel","runpermissive","startpermissive","last_vfd_fault_code","vfd_fault", "flowmeter_fault"]: + logger.debug("Converting DINT/BOOL to STRING") + value = convert_int(measure["name"], measure["value"]) + logger.debug("Converted {} to {}".format(measure["value"], value)) + payload[measure["name"]] = value + payload[measure["name"] + "_int"] = measure["value"] + else: + payload[measure["name"]] = measure["value"] + except Exception as e: + logger.error(e) + + publish(__topic__, json.dumps(payload), __qos__) + +def convert_int(plc_tag, value): + well_status_codes = { + 0: "Running", + 1: "Pumped Off", + 2: "Alarmed", + 3: "Locked Out", + 4: "Stopped" + } + + pid_control_codes = { + 0: "Flow", + 1: "Fluid Level", + 2: "Tubing Pressure", + 3: "Manual" + } + + downhole_codes = { + 0: "OK", + 1: "Connecting", + 2: "Open Circuit", + 3: "Shorted", + 4: "Cannot Decode" + } + + permissive_codes = { + 0: "OK", + 1: "Flow", + 2: "Intake Pressure", + 3: "Intake Temperature", + 4: "Tubing Pressure", + 5: "VFD", + 6: "Fluid Level", + 7: "Min. Downtime" + } + + alarm_codes = { + 0: "OK", + 1: "Alarm" + } + + alarm_vfd_codes = { + 0: "OK", + 1: "Locked Out" + } + + vfd_fault_codes = { + 0: "No Fault", + 2: "Auxiliary Input", + 3: "Power Loss", + 4: "UnderVoltage", + 5: "OverVoltage", + 7: "Motor Overload", + 8: "Heatsink OverTemp", + 9: "Thermister OverTemp", + 10: "Dynamic Brake OverTemp", + 12: "Hardware OverCurrent", + 13: "Ground Fault", + 14: "Ground Warning", + 15: "Load Loss", + 17: "Input Phase Loss", + 18: "Motor PTC Trip", + 19: "Task Overrun", + 20: "Torque Prove Speed Band", + 21: "Output Phase Loss", + 24: "Decel Inhibit", + 25: "OverSpeed Limit", + 26: "Brake Slipped", + 27: "Torque Prove Conflict", + 28: "TP Encls Confict", + 29: "Analog In Loss", + 33: "Auto Restarts Exhausted", + 35: "IPM OverCurrent", + 36: "SW OverCurrent", + 38: "Phase U to Ground", + 39: "Phase V to Ground", + 40: "Phase W to Ground", + 41: "Phase UV Short", + 42: "Phase VW Short", + 43: "Phase WU Short", + 44: "Phase UNeg to Ground", + 45: "Phase VNeg to Ground", + 46: "Phase WNeg to Ground", + 48: "System Defaulted", + 49: "Drive Powerup", + 51: "Clear Fault Queue", + 55: "Control Board Overtemp", + 59: "Invalid Code", + 61: "Shear Pin 1", + 62: "Shear Pin 2", + 64: "Drive Overload", + 66: "OW Torque Level", + 67: "Pump Off", + 71: "Port 1 Adapter", + 72: "Port 2 Adapter", + 73: "Port 3 Adapter", + 74: "Port 4 Adapter", + 75: "Port 5 Adapter", + 76: "Port 6 Adapter", + 77: "IR Volts Range", + 78: "FluxAmps Ref Range", + 79: "Excessive Load", + 80: "AutoTune Aborted", + 81: "Port 1 DPI Loss", + 82: "Port 2 DPI Loss", + 83: "Port 3 DPI Loss", + 84: "Port 4 DPI Loss", + 85: "Port 5 DPI Loss", + 86: "Port 6 DPI Loss", + 87: "IXo Voltage Range", + 91: "Primary Velocity Feedback Loss", + 93: "Hardware Enable Check", + 94: "Alternate Velocity Feedback Loss", + 95: "Auxiliary Velocity Feedback Loss", + 96: "Position Feedback Loss", + 97: "Auto Tach Switch", + 100: "Parameter Checksum", + 101: "Power Down NVS Blank", + 102: "NVS Not Blank", + 103: "Power Down NVS Incompatible", + 104: "Power Board Checksum", + 106: "Incompat MCB-PB", + 107: "Replaced MCB-PB", + 108: "Analog Calibration Checksum", + 110: "Invalid Power Board Data", + 111: "Power Board Invalid ID", + 112: "Power Board App Min Version", + 113: "Tracking DataError", + 115: "Power Down Table Full", + 116: "Power Down Entry Too Large", + 117: "Power Down Data Checksum", + 118: "Power Board Power Down Checksum", + 124: "App ID Changed", + 125: "Using Backup App", + 134: "Start on Power Up", + 137: "External Precharge Error", + 138: "Precharge Open", + 141: "Autotune Enc Angle", + 142: "Autotune Speed Restricted", + 143: "Autotune Current Regulator", + 144: "Autotune Inertia", + 145: "Autotune Travel", + 13035: "Net IO Timeout", + 13037: "Net IO Timeout" + + } + + plc_tags = { + "wellstatus": well_status_codes.get(value, "Invalid Code"), + "pidcontrolmode": pid_control_codes.get(value, "Invalid Code"), + "downholesensorstatus": downhole_codes.get(value, "Invalid Code"), + "alarmflowrate": alarm_codes.get(value, "Invalid Code"), + "alarmintakepressure": alarm_codes.get(value, "Invalid Code"), + "alarmintaketemperature": alarm_codes.get(value, "Invalid Code"), + "alarmtubingpressure": alarm_codes.get(value, "Invalid Code"), + "alarmvfd": alarm_codes.get(value, "Invalid Code"), + "alarmlockout": alarm_vfd_codes.get(value, "Invalid Code"), + "alarmfluidlevel": alarm_codes.get(value, "Invalid Code"), + "runpermissive": permissive_codes.get(value, "Invalid Code"), + "startpermissive": permissive_codes.get(value, "Invalid Code"), + "last_vfd_fault_code": vfd_fault_codes.get(value, "Invalid Code"), + "vfd_fault": vfd_fault_codes.get(value, "Invalid Code"), + "flowmeter_fault": alarm_codes.get(value, "Invalid Code") + } + + return plc_tags.get(plc_tag, "Invalid Tag") + + \ No newline at end of file diff --git a/Pub_Sub/advvfdipp/thingsboard/v1/sub/receiveCommand.py b/Pub_Sub/advvfdipp/thingsboard/v1/sub/receiveCommand.py new file mode 100644 index 0000000..082b02f --- /dev/null +++ b/Pub_Sub/advvfdipp/thingsboard/v1/sub/receiveCommand.py @@ -0,0 +1,257 @@ +# Enter your python code. +import json +import time +from quickfaas.measure import recall +from common.Logger import logger + +def sync(wizard_api): + #get new values and send + payload = {} + topic = "v1/devices/me/telemetry" + try: + data = recall()#json.loads(recall().decode("utf-8")) + except Exception as e: + logger.error(e) + logger.info(data) + for controller in data: + for measure in controller["measures"]: + #publish measure + if measure["name"] in ["wellstatus","pidcontrolmode","downholesensorstatus","alarmflowrate","alarmintakepressure","alarmintaketemperature","alarmtubingpressure","alarmvfd","alarmlockout","alarmfluidlevel","runpermissive","startpermissive","last_vfd_fault_code","vfd_fault", "flowmeter_fault"]: + payload[measure["name"]] = convert_int(measure["name"], measure["value"]) + payload[measure["name"]+ "_int"] = measure["value"] + else: + payload[measure["name"]] = 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(value, wizard_api): + try: + #value = json.loads(value.replace("'",'"')) + logger.debug(value) + message = {"advvfdipp":{value["measurement"]: value["value"]}} + resp = wizard_api.write_plc_values(message) + #logger.debug("RETURN FROM WRITE: {}".format(resp)) + return True + except Exception as e: + logger.debug(e) + return False + +def receiveCommand(topic, payload, wizard_api): + try: + logger.debug(topic) + logger.debug(json.loads(payload)) + p = json.loads(payload) + command = p["method"] + commands = { + "sync": sync, + "writeplctag": writeplctag, + } + if command == "setPLCTag": + result = commands["writeplctag"](p["params"],wizard_api) + elif command == "changeSetpoint": + try: + params_type = {"measurement": "pidcontrolmode", "value": p["params"]["setpointType"]} + if params_type["value"]: + commands["writeplctag"](params_type, wizard_api) + time.sleep(2) + except: + pass + try: + modes = {0: "flowsetpoint", 1: "fluidlevelsetpoint", 2: "tubingpressuresetpoint", 3: "manualfrequencysetpoint"} + params_value = {"value": p["params"]["setpointValue"]} + if params_value["value"]: + params_value["measurement"] = modes[getMode()] + commands["writeplctag"](params_value, wizard_api) + except: + pass + + #logger.debug(command) + ack(topic.split("/")[-1], wizard_api) + time.sleep(5) + sync(wizard_api) + except Exception as e: + logger.debug(e) + + +def ack(msgid, wizard_api): + #logger.debug(msgid) + #logger.debug(mac) + #logger.debug(name) + #logger.debug(value) + wizard_api.mqtt_publish("v1/devices/me/rpc/response/" + str(msgid), json.dumps({"msg": {"time": time.time()}, "metadata": "", "msgType": ""})) + +def getMode(): + try: + data = recall() + for controller in data: + for measure in controller["measures"]: + if measure["name"] == "pidcontrolmode": + return measure["value"] + except: + return None + +def convert_int(plc_tag, value): + well_status_codes = { + 0: "Running", + 1: "Pumped Off", + 2: "Alarmed", + 3: "Locked Out", + 4: "Stopped" + } + + pid_control_codes = { + 0: "Flow", + 1: "Fluid Level", + 2: "Tubing Pressure", + 3: "Manual" + } + + downhole_codes = { + 0: "OK", + 1: "Connecting", + 2: "Open Circuit", + 3: "Shorted", + 4: "Cannot Decode" + } + + permissive_codes = { + 0: "OK", + 1: "Flow", + 2: "Intake Pressure", + 3: "Intake Temperature", + 4: "Tubing Pressure", + 5: "VFD", + 6: "Fluid Level", + 7: "Min. Downtime" + } + + alarm_codes = { + 0: "OK", + 1: "Alarm" + } + + alarm_vfd_codes = { + 0: "OK", + 1: "Locked Out" + } + + vfd_fault_codes = { + 0: "No Fault", + 2: "Auxiliary Input", + 3: "Power Loss", + 4: "UnderVoltage", + 5: "OverVoltage", + 7: "Motor Overload", + 8: "Heatsink OverTemp", + 9: "Thermister OverTemp", + 10: "Dynamic Brake OverTemp", + 12: "Hardware OverCurrent", + 13: "Ground Fault", + 14: "Ground Warning", + 15: "Load Loss", + 17: "Input Phase Loss", + 18: "Motor PTC Trip", + 19: "Task Overrun", + 20: "Torque Prove Speed Band", + 21: "Output Phase Loss", + 24: "Decel Inhibit", + 25: "OverSpeed Limit", + 26: "Brake Slipped", + 27: "Torque Prove Conflict", + 28: "TP Encls Confict", + 29: "Analog In Loss", + 33: "Auto Restarts Exhausted", + 35: "IPM OverCurrent", + 36: "SW OverCurrent", + 38: "Phase U to Ground", + 39: "Phase V to Ground", + 40: "Phase W to Ground", + 41: "Phase UV Short", + 42: "Phase VW Short", + 43: "Phase WU Short", + 44: "Phase UNeg to Ground", + 45: "Phase VNeg to Ground", + 46: "Phase WNeg to Ground", + 48: "System Defaulted", + 49: "Drive Powerup", + 51: "Clear Fault Queue", + 55: "Control Board Overtemp", + 59: "Invalid Code", + 61: "Shear Pin 1", + 62: "Shear Pin 2", + 64: "Drive Overload", + 66: "OW Torque Level", + 67: "Pump Off", + 71: "Port 1 Adapter", + 72: "Port 2 Adapter", + 73: "Port 3 Adapter", + 74: "Port 4 Adapter", + 75: "Port 5 Adapter", + 76: "Port 6 Adapter", + 77: "IR Volts Range", + 78: "FluxAmps Ref Range", + 79: "Excessive Load", + 80: "AutoTune Aborted", + 81: "Port 1 DPI Loss", + 82: "Port 2 DPI Loss", + 83: "Port 3 DPI Loss", + 84: "Port 4 DPI Loss", + 85: "Port 5 DPI Loss", + 86: "Port 6 DPI Loss", + 87: "IXo Voltage Range", + 91: "Primary Velocity Feedback Loss", + 93: "Hardware Enable Check", + 94: "Alternate Velocity Feedback Loss", + 95: "Auxiliary Velocity Feedback Loss", + 96: "Position Feedback Loss", + 97: "Auto Tach Switch", + 100: "Parameter Checksum", + 101: "Power Down NVS Blank", + 102: "NVS Not Blank", + 103: "Power Down NVS Incompatible", + 104: "Power Board Checksum", + 106: "Incompat MCB-PB", + 107: "Replaced MCB-PB", + 108: "Analog Calibration Checksum", + 110: "Invalid Power Board Data", + 111: "Power Board Invalid ID", + 112: "Power Board App Min Version", + 113: "Tracking DataError", + 115: "Power Down Table Full", + 116: "Power Down Entry Too Large", + 117: "Power Down Data Checksum", + 118: "Power Board Power Down Checksum", + 124: "App ID Changed", + 125: "Using Backup App", + 134: "Start on Power Up", + 137: "External Precharge Error", + 138: "Precharge Open", + 141: "Autotune Enc Angle", + 142: "Autotune Speed Restricted", + 143: "Autotune Current Regulator", + 144: "Autotune Inertia", + 145: "Autotune Travel", + 13035: "Net IO Timeout", + 13037: "Net IO Timeout" + + } + + plc_tags = { + "wellstatus": well_status_codes.get(value, "Invalid Code"), + "pidcontrolmode": pid_control_codes.get(value, "Invalid Code"), + "downholesensorstatus": downhole_codes.get(value, "Invalid Code"), + "alarmflowrate": alarm_codes.get(value, "Invalid Code"), + "alarmintakepressure": alarm_codes.get(value, "Invalid Code"), + "alarmintaketemperature": alarm_codes.get(value, "Invalid Code"), + "alarmtubingpressure": alarm_codes.get(value, "Invalid Code"), + "alarmvfd": alarm_codes.get(value, "Invalid Code"), + "alarmlockout": alarm_vfd_codes.get(value, "Invalid Code"), + "alarmfluidlevel": alarm_codes.get(value, "Invalid Code"), + "runpermissive": permissive_codes.get(value, "Invalid Code"), + "startpermissive": permissive_codes.get(value, "Invalid Code"), + "last_vfd_fault_code": vfd_fault_codes.get(value, "Invalid Code"), + "vfd_fault": vfd_fault_codes.get(value, "Invalid Code"), + "flowmeter_fault": alarm_codes.get(value, "Invalid Code") + } + + return plc_tags.get(plc_tag, "Invalid Tag") diff --git a/Pub_Sub/advvfdipp/v3/pub/sendData.py b/Pub_Sub/advvfdipp/v3/pub/sendData.py new file mode 100644 index 0000000..84f5106 --- /dev/null +++ b/Pub_Sub/advvfdipp/v3/pub/sendData.py @@ -0,0 +1,211 @@ +# 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) + if measure["name"] in ["wellstatus","pidcontrolmode","downholesensorstatus","alarmflowrate","alarmintakepressure","alarmintaketemperature","alarmtubingpressure","alarmvfd","alarmlockout","alarmfluidlevel","runpermissive","startpermissive","last_vfd_fault_code","vfd_fault"]: + 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): + well_status_codes = { + 0: "Running", + 1: "Pumped Off", + 2: "Alarmed", + 3: "Locked Out", + 4: "Stopped" + } + + pid_control_codes = { + 0: "Flow", + 1: "Fluid Level", + 2: "Tubing Pressure", + 3: "Manual" + } + + downhole_codes = { + 0: "OK", + 1: "Connecting", + 2: "Open Circuit", + 3: "Shorted", + 4: "Cannot Decode" + } + + permissive_codes = { + 0: "OK", + 1: "Flow", + 2: "Intake Pressure", + 3: "Intake Temperature", + 4: "Tubing Pressure", + 5: "VFD", + 6: "Fluid Level", + 7: "Min. Downtime" + } + + alarm_codes = { + 0: "OK", + 1: "Alarm" + } + + alarm_vfd_codes = { + 0: "OK", + 1: "Locked Out" + } + + vfd_fault_codes = { + 0: "No Fault", + 2: "Auxiliary Input", + 3: "Power Loss", + 4: "UnderVoltage", + 5: "OverVoltage", + 7: "Motor Overload", + 8: "Heatsink OverTemp", + 9: "Thermister OverTemp", + 10: "Dynamic Brake OverTemp", + 12: "Hardware OverCurrent", + 13: "Ground Fault", + 14: "Ground Warning", + 15: "Load Loss", + 17: "Input Phase Loss", + 18: "Motor PTC Trip", + 19: "Task Overrun", + 20: "Torque Prove Speed Band", + 21: "Output Phase Loss", + 24: "Decel Inhibit", + 25: "OverSpeed Limit", + 26: "Brake Slipped", + 27: "Torque Prove Conflict", + 28: "TP Encls Confict", + 29: "Analog In Loss", + 33: "Auto Restarts Exhausted", + 35: "IPM OverCurrent", + 36: "SW OverCurrent", + 38: "Phase U to Ground", + 39: "Phase V to Ground", + 40: "Phase W to Ground", + 41: "Phase UV Short", + 42: "Phase VW Short", + 43: "Phase WU Short", + 44: "Phase UNeg to Ground", + 45: "Phase VNeg to Ground", + 46: "Phase WNeg to Ground", + 48: "System Defaulted", + 49: "Drive Powerup", + 51: "Clear Fault Queue", + 55: "Control Board Overtemp", + 59: "Invalid Code", + 61: "Shear Pin 1", + 62: "Shear Pin 2", + 64: "Drive Overload", + 66: "OW Torque Level", + 67: "Pump Off", + 71: "Port 1 Adapter", + 72: "Port 2 Adapter", + 73: "Port 3 Adapter", + 74: "Port 4 Adapter", + 75: "Port 5 Adapter", + 76: "Port 6 Adapter", + 77: "IR Volts Range", + 78: "FluxAmps Ref Range", + 79: "Excessive Load", + 80: "AutoTune Aborted", + 81: "Port 1 DPI Loss", + 82: "Port 2 DPI Loss", + 83: "Port 3 DPI Loss", + 84: "Port 4 DPI Loss", + 85: "Port 5 DPI Loss", + 86: "Port 6 DPI Loss", + 87: "IXo Voltage Range", + 91: "Primary Velocity Feedback Loss", + 93: "Hardware Enable Check", + 94: "Alternate Velocity Feedback Loss", + 95: "Auxiliary Velocity Feedback Loss", + 96: "Position Feedback Loss", + 97: "Auto Tach Switch", + 100: "Parameter Checksum", + 101: "Power Down NVS Blank", + 102: "NVS Not Blank", + 103: "Power Down NVS Incompatible", + 104: "Power Board Checksum", + 106: "Incompat MCB-PB", + 107: "Replaced MCB-PB", + 108: "Analog Calibration Checksum", + 110: "Invalid Power Board Data", + 111: "Power Board Invalid ID", + 112: "Power Board App Min Version", + 113: "Tracking DataError", + 115: "Power Down Table Full", + 116: "Power Down Entry Too Large", + 117: "Power Down Data Checksum", + 118: "Power Board Power Down Checksum", + 124: "App ID Changed", + 125: "Using Backup App", + 134: "Start on Power Up", + 137: "External Precharge Error", + 138: "Precharge Open", + 141: "Autotune Enc Angle", + 142: "Autotune Speed Restricted", + 143: "Autotune Current Regulator", + 144: "Autotune Inertia", + 145: "Autotune Travel", + 13035: "Net IO Timeout", + 13037: "Net IO Timeout" + + } + + plc_tags = { + "wellstatus": well_status_codes.get(value, "Invalid Code"), + "pidcontrolmode": pid_control_codes.get(value, "Invalid Code"), + "downholesensorstatus": downhole_codes.get(value, "Invalid Code"), + "alarmflowrate": alarm_codes.get(value, "Invalid Code"), + "alarmintakepressure": alarm_codes.get(value, "Invalid Code"), + "alarmintaketemperature": alarm_codes.get(value, "Invalid Code"), + "alarmtubingpressure": alarm_codes.get(value, "Invalid Code"), + "alarmvfd": alarm_codes.get(value, "Invalid Code"), + "alarmlockout": alarm_vfd_codes.get(value, "Invalid Code"), + "alarmfluidlevel": alarm_codes.get(value, "Invalid Code"), + "runpermissive": permissive_codes.get(value, "Invalid Code"), + "startpermissive": permissive_codes.get(value, "Invalid Code"), + "last_vfd_fault_code": vfd_fault_codes.get(value, "Invalid Code"), + "vfd_fault": vfd_fault_codes.get(value, "Invalid Code") + } + + return plc_tags.get(plc_tag, "Invalid Tag") + + \ No newline at end of file diff --git a/Pub_Sub/advvfdipp/v3/sub/receiveCommand.py b/Pub_Sub/advvfdipp/v3/sub/receiveCommand.py new file mode 100644 index 0000000..ff6b6d0 --- /dev/null +++ b/Pub_Sub/advvfdipp/v3/sub/receiveCommand.py @@ -0,0 +1,221 @@ +# Enter your python code. +import json +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) + for controller in data: + for measure in controller["measures"]: + #publish measure + topic = "meshify/db/194/_/advvfdipp/" + mac + "/" + measure["name"] + if measure["name"] in ["wellstatus","pidcontrolmode","downholesensorstatus","alarmflowrate","alarmintakepressure","alarmintaketemperature","alarmtubingpressure","alarmvfd","alarmlockout","alarmfluidlevel","runpermissive","startpermissive","last_vfd_fault_code","vfd_fault"]: + 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 = {"advvfdipp":{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): + well_status_codes = { + 0: "Running", + 1: "Pumped Off", + 2: "Alarmed", + 3: "Locked Out", + 4: "Stopped" + } + + pid_control_codes = { + 0: "Flow", + 1: "Fluid Level", + 2: "Tubing Pressure", + 3: "Manual" + } + + downhole_codes = { + 0: "OK", + 1: "Connecting", + 2: "Open Circuit", + 3: "Shorted", + 4: "Cannot Decode" + } + + permissive_codes = { + 0: "OK", + 1: "Flow", + 2: "Intake Pressure", + 3: "Intake Temperature", + 4: "Tubing Pressure", + 5: "VFD", + 6: "Fluid Level", + 7: "Min. Downtime" + } + + alarm_codes = { + 0: "OK", + 1: "Alarm" + } + + alarm_vfd_codes = { + 0: "OK", + 1: "Locked Out" + } + + vfd_fault_codes = { + 0: "No Fault", + 2: "Auxiliary Input", + 3: "Power Loss", + 4: "UnderVoltage", + 5: "OverVoltage", + 7: "Motor Overload", + 8: "Heatsink OverTemp", + 9: "Thermister OverTemp", + 10: "Dynamic Brake OverTemp", + 12: "Hardware OverCurrent", + 13: "Ground Fault", + 14: "Ground Warning", + 15: "Load Loss", + 17: "Input Phase Loss", + 18: "Motor PTC Trip", + 19: "Task Overrun", + 20: "Torque Prove Speed Band", + 21: "Output Phase Loss", + 24: "Decel Inhibit", + 25: "OverSpeed Limit", + 26: "Brake Slipped", + 27: "Torque Prove Conflict", + 28: "TP Encls Confict", + 29: "Analog In Loss", + 33: "Auto Restarts Exhausted", + 35: "IPM OverCurrent", + 36: "SW OverCurrent", + 38: "Phase U to Ground", + 39: "Phase V to Ground", + 40: "Phase W to Ground", + 41: "Phase UV Short", + 42: "Phase VW Short", + 43: "Phase WU Short", + 44: "Phase UNeg to Ground", + 45: "Phase VNeg to Ground", + 46: "Phase WNeg to Ground", + 48: "System Defaulted", + 49: "Drive Powerup", + 51: "Clear Fault Queue", + 55: "Control Board Overtemp", + 59: "Invalid Code", + 61: "Shear Pin 1", + 62: "Shear Pin 2", + 64: "Drive Overload", + 66: "OW Torque Level", + 67: "Pump Off", + 71: "Port 1 Adapter", + 72: "Port 2 Adapter", + 73: "Port 3 Adapter", + 74: "Port 4 Adapter", + 75: "Port 5 Adapter", + 76: "Port 6 Adapter", + 77: "IR Volts Range", + 78: "FluxAmps Ref Range", + 79: "Excessive Load", + 80: "AutoTune Aborted", + 81: "Port 1 DPI Loss", + 82: "Port 2 DPI Loss", + 83: "Port 3 DPI Loss", + 84: "Port 4 DPI Loss", + 85: "Port 5 DPI Loss", + 86: "Port 6 DPI Loss", + 87: "IXo Voltage Range", + 91: "Primary Velocity Feedback Loss", + 93: "Hardware Enable Check", + 94: "Alternate Velocity Feedback Loss", + 95: "Auxiliary Velocity Feedback Loss", + 96: "Position Feedback Loss", + 97: "Auto Tach Switch", + 100: "Parameter Checksum", + 101: "Power Down NVS Blank", + 102: "NVS Not Blank", + 103: "Power Down NVS Incompatible", + 104: "Power Board Checksum", + 106: "Incompat MCB-PB", + 107: "Replaced MCB-PB", + 108: "Analog Calibration Checksum", + 110: "Invalid Power Board Data", + 111: "Power Board Invalid ID", + 112: "Power Board App Min Version", + 113: "Tracking DataError", + 115: "Power Down Table Full", + 116: "Power Down Entry Too Large", + 117: "Power Down Data Checksum", + 118: "Power Board Power Down Checksum", + 124: "App ID Changed", + 125: "Using Backup App", + 134: "Start on Power Up", + 137: "External Precharge Error", + 138: "Precharge Open", + 141: "Autotune Enc Angle", + 142: "Autotune Speed Restricted", + 143: "Autotune Current Regulator", + 144: "Autotune Inertia", + 145: "Autotune Travel", + 13035: "Net IO Timeout", + 13037: "Net IO Timeout" + + } + + plc_tags = { + "wellstatus": well_status_codes.get(value, "Invalid Code"), + "pidcontrolmode": pid_control_codes.get(value, "Invalid Code"), + "downholesensorstatus": downhole_codes.get(value, "Invalid Code"), + "alarmflowrate": alarm_codes.get(value, "Invalid Code"), + "alarmintakepressure": alarm_codes.get(value, "Invalid Code"), + "alarmintaketemperature": alarm_codes.get(value, "Invalid Code"), + "alarmtubingpressure": alarm_codes.get(value, "Invalid Code"), + "alarmvfd": alarm_codes.get(value, "Invalid Code"), + "alarmlockout": alarm_vfd_codes.get(value, "Invalid Code"), + "alarmfluidlevel": alarm_codes.get(value, "Invalid Code"), + "runpermissive": permissive_codes.get(value, "Invalid Code"), + "startpermissive": permissive_codes.get(value, "Invalid Code"), + "last_vfd_fault_code": vfd_fault_codes.get(value, "Invalid Code"), + "vfd_fault": vfd_fault_codes.get(value, "Invalid Code") + } + + return plc_tags.get(plc_tag, "Invalid Tag") diff --git a/Pub_Sub/plcfreshwater/v1/cloud.json b/Pub_Sub/plcfreshwater/v1/cloud.json new file mode 100644 index 0000000..88fd4d9 --- /dev/null +++ b/Pub_Sub/plcfreshwater/v1/cloud.json @@ -0,0 +1,53 @@ +{ + "cloud": { + "cacheSize": 100, + "enable": 1, + "type": "Standard MQTT", + "args": { + "host": "mq194.imistaway.net", + "port": 1883, + "clientId": "client-id", + "auth": 1, + "tls": 0, + "cleanSession": 0, + "mqttVersion": "v3.1.1", + "keepalive": 60, + "key": "", + "cert": "", + "rootCA": "", + "verifyServer": 0, + "verifyClient": 0, + "username": "admin", + "passwd": "columbus", + "authType": 1 + } + }, + "quickfaas": { + "uploadFuncs": [ + { + "name": "Send Data", + "trigger": "measure_event", + "topic": "meshify/db/194/_/plcfreshwater/${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\nimport os\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 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 \n #publish(__topic__, json.dumps({measure[\"name\"]: measure[\"value\"]}), __qos__)\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 + } + ], + "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, + "trigger": "command_event" + } + ] + } +} \ No newline at end of file diff --git a/Pub_Sub/plcfreshwater/v1/measure.csv b/Pub_Sub/plcfreshwater/v1/measure.csv new file mode 100644 index 0000000..1ea527b --- /dev/null +++ b/Pub_Sub/plcfreshwater/v1/measure.csv @@ -0,0 +1,11 @@ +MeasuringPointName,ControllerName,GroupName,UploadType,DataType,Address,Decimal,Len,ReadWrite,Unit,Description,Transform Type,MaxValue,MinValue,MaxScale,MinScale,Gain,Offset,startBit,endBit +scaled_flow_meter,plcfreshwater,default,periodic,FLOAT,Scaled_Flow_Meter,2,1,ro,,,none,,,,,,,, +scaled_pressure_transducer,plcfreshwater,default,periodic,FLOAT,Scaled_Pressure_Transducer,2,1,ro,,,none,,,,,,,, +raw_hand_input,plcfreshwater,default,periodic,BIT,Raw_Hand_Input,2,1,ro,,,none,,,,,,,, +raw_auto_input,plcfreshwater,default,periodic,BIT,Raw_Auto_Input,2,1,ro,,,none,,,,,,,, +raw_run_status,plcfreshwater,default,periodic,BIT,Raw_Run_Status,2,1,ro,,,none,,,,,,,, +raw_local_start,plcfreshwater,default,periodic,BIT,Raw_Local_Start,2,1,ro,,,none,,,,,,,, +lifetime_flow_meter_gal,plcfreshwater,default,periodic,FLOAT,Lifetime_Flow_Meter_Gal,2,1,ro,,,none,,,,,,,, +spt_flow_meter_unit,plcfreshwater,default,periodic,BIT,SPT_Flow_Meter_Unit,2,1,ro,,,none,,,,,,,, +raw_overload_status,plcfreshwater,default,periodic,BIT,Raw_Overload_Status,2,1,ro,,,none,,,,,,,, +CMD_Cloud_Control,plcfreshwater,default,periodic,BIT,CMD_Cloud_Control,2,1,rw,,,none,,,,,,,, diff --git a/Pub_Sub/rigpump/v4/.DS_Store b/Pub_Sub/rigpump/v4/.DS_Store index 5740606..54ddc14 100644 Binary files a/Pub_Sub/rigpump/v4/.DS_Store and b/Pub_Sub/rigpump/v4/.DS_Store differ diff --git a/Pub_Sub/rigpump/v4/pub/sendData.py b/Pub_Sub/rigpump/v4/pub/sendData.py index 6b1fd89..c735225 100644 --- a/Pub_Sub/rigpump/v4/pub/sendData.py +++ b/Pub_Sub/rigpump/v4/pub/sendData.py @@ -4,6 +4,7 @@ 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, @@ -24,10 +25,35 @@ def lwt(mac): 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) diff --git a/Pub_Sub/transferlite/v1/pub/sendData.py b/Pub_Sub/transferlite/v1/pub/sendData.py index e69de29..35c87cb 100644 --- a/Pub_Sub/transferlite/v1/pub/sendData.py +++ b/Pub_Sub/transferlite/v1/pub/sendData.py @@ -0,0 +1,85 @@ +# 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) + if measure["name"] in ["auto_manual", "system1_hasleveltransmitter", "system2_hasleveltransmitter", "state_supervisor", "state_system1", "state_system2"]: + 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): + + + TRUE_FALSE = { + 0: "false", + 1: "true" + } + + AUTO_MANUAL = { + 0: "Auto", + 1: "Manual" + } + + PHASE_STATES = { + 1: "Running", + 2: "Holding", + 4: "Restarting", + 8: "Stopping", + 16: "Aborting", + 32: "Resetting", + 64: "Idle", + 128: "Held", + 256: "Complete", + 512: "Stopped", + 1024: "Aborted" + } + + + plc_tags = { + "auto_manual": AUTO_MANUAL.get(value, "Invalid Code"), + "system1_hasleveltransmitter": TRUE_FALSE.get(value, "Invalid Code"), + "system2_hasleveltransmitter": TRUE_FALSE.get(value, "Invalid Code"), + "state_supervisor": PHASE_STATES.get(value, "Invalid Code"), + "state_system1": PHASE_STATES.get(value, "Invalid Code"), + "state_system2": PHASE_STATES.get(value, "Invalid Code") + } + + return plc_tags.get(plc_tag, "Invalid Tag") + + \ No newline at end of file diff --git a/Pub_Sub/transferlite/v1/sub/receiveCommand.py b/Pub_Sub/transferlite/v1/sub/receiveCommand.py index e69de29..d7f2254 100644 --- a/Pub_Sub/transferlite/v1/sub/receiveCommand.py +++ b/Pub_Sub/transferlite/v1/sub/receiveCommand.py @@ -0,0 +1,94 @@ +# Enter your python code. +import json +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) + for controller in data: + for measure in controller["measures"]: + #publish measure + topic = "meshify/db/194/_/transferlite/" + mac + "/" + measure["name"] + if measure["name"] in ["auto_manual", "system1_hasleveltransmitter", "system2_hasleveltransmitter", "state_supervisor", "state_system1", "state_system2"]: + 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 = {"transferlite":{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"], p["payload"]["name"].split(".")[1], p["payload"]["value"], wizard_api) + +def ack(msgid, mac, name, value, wizard_api): + #logger.debug(mac) + mac = "".join(mac.split(":")[:-2]) + #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(mac,name, value), "msgid": str(msgid)}])) + +def convert_int(plc_tag, value): + + + TRUE_FALSE = { + 0: "false", + 1: "true" + } + + AUTO_MANUAL = { + 0: "Auto", + 1: "Manual" + } + + PHASE_STATES = { + 1: "Running", + 2: "Holding", + 4: "Restarting", + 8: "Stopping", + 16: "Aborting", + 32: "Resetting", + 64: "Idle", + 128: "Held", + 256: "Complete", + 512: "Stopped", + 1024: "Aborted" + } + + + plc_tags = { + "auto_manual": AUTO_MANUAL.get(value, "Invalid Code"), + "system1_hasleveltransmitter": TRUE_FALSE.get(value, "Invalid Code"), + "system2_hasleveltransmitter": TRUE_FALSE.get(value, "Invalid Code"), + "state_supervisor": PHASE_STATES.get(value, "Invalid Code"), + "state_system1": PHASE_STATES.get(value, "Invalid Code"), + "state_system2": PHASE_STATES.get(value, "Invalid Code") + } + + return plc_tags.get(plc_tag, "Invalid Tag") + + \ No newline at end of file