{ "controllers": [ { "protocol": "EtherNet/IP", "name": "valvecontroller", "args": {}, "samplePeriod": 2, "expired": 10000, "endpoint": "192.168.1.12:44818" } ], "measures": [ { "ctrlName": "valvecontroller", "dataType": "FLOAT", "addr": "Open_Setpoint", "readWrite": "rw", "uploadType": "periodic", "group": "default", "decimal": 1, "name": "open_spt", "desc": "", "unit": "", "transformType": 0, "gain": "1.0", "offset": "0.0", "maxValue": "", "minValue": "", "maxScaleValue": "", "minScaleValue": "" }, { "ctrlName": "valvecontroller", "dataType": "FLOAT", "addr": "Close_Setpoint", "readWrite": "rw", "uploadType": "periodic", "group": "default", "decimal": 1, "name": "close_spt", "desc": "", "unit": "", "transformType": 0, "gain": "1.0", "offset": "0.0", "maxValue": "", "minValue": "", "maxScaleValue": "", "minScaleValue": "" }, { "ctrlName": "valvecontroller", "dataType": "BIT", "addr": "Open_Valve_Cmd", "readWrite": "rw", "uploadType": "periodic", "group": "default", "name": "open_cmd", "desc": "", "unit": "", "transformType": 0, "gain": "1.0", "offset": "0.0", "maxValue": "", "minValue": "", "maxScaleValue": "", "minScaleValue": "", "decimal": 2 }, { "ctrlName": "valvecontroller", "dataType": "BIT", "addr": "Close_Valve_Cmd", "readWrite": "rw", "uploadType": "periodic", "group": "default", "name": "close_cmd", "desc": "", "unit": "", "transformType": 0, "gain": "1.0", "offset": "0.0", "maxValue": "", "minValue": "", "maxScaleValue": "", "minScaleValue": "", "decimal": 2 }, { "ctrlName": "valvecontroller", "dataType": "FLOAT", "addr": "Scaled_Tank_Lev", "readWrite": "ro", "uploadType": "periodic", "group": "default", "decimal": 1, "name": "tank_level", "desc": "", "unit": "", "transformType": 0, "gain": "1.0", "offset": "0.0", "maxValue": "", "minValue": "", "maxScaleValue": "", "minScaleValue": "" }, { "ctrlName": "valvecontroller", "dataType": "BIT", "addr": "Valve_Open_Status", "readWrite": "ro", "uploadType": "periodic", "group": "default", "name": "valve_open_status", "desc": "", "unit": "", "transformType": 0, "gain": "1.0", "offset": "0.0", "maxValue": "", "minValue": "", "maxScaleValue": "", "minScaleValue": "", "decimal": 2 }, { "ctrlName": "valvecontroller", "dataType": "BIT", "addr": "Valve_Closed_Status", "readWrite": "ro", "uploadType": "periodic", "group": "default", "name": "valve_close_status", "desc": "", "unit": "", "transformType": 0, "gain": "1.0", "offset": "0.0", "maxValue": "", "minValue": "", "maxScaleValue": "", "minScaleValue": "", "decimal": 2 }, { "ctrlName": "valvecontroller", "dataType": "BIT", "addr": "Valve_Fail", "readWrite": "ro", "uploadType": "periodic", "group": "default", "name": "valve_failure", "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": 8 } ], "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": 10000, "enable": 1, "name": "default", "type": "Standard MQTT", "args": { "host": "thingsboard.cloud", "port": 1883, "clientId": "valve-controller", "auth": 1, "tls": 0, "cleanSession": 0, "mqttVersion": "v3.1.1", "keepalive": 60, "key": "", "cert": "", "rootCA": "", "verifyServer": 0, "verifyClient": 0, "username": "faskensmqtt", "passwd": "faskensmqtt@1903", "authType": 1 } } ], "quickfaas": { "genericFuncs": [], "uploadFuncs": [ { "qos": 1, "funcName": "sendData", "script": "# Enter your python code.\nimport json\nimport time\nfrom common.Logger import logger\nfrom quickfaas.remotebus import publish\n\ndef sendData(message):\n logger.debug(message)\n #publish(__topic__, json.dumps(message), __qos__)\n try:\n payload = {\"ts\": int(time.time()*1000), \"values\": {}}\n valve_open = 0\n valve_close = 0\n for measure in message[\"measures\"]:\n if measure[\"name\"] in [\"valve_failure\"]:\n value = convert_int(measure[\"name\"], measure[\"value\"])\n payload[\"values\"][measure[\"name\"]] = value\n elif measure[\"name\"] == \"valve_open_status\":\n valve_open = measure[\"value\"]\n elif measure[\"name\"] == \"valve_close_status\":\n valve_close = measure[\"value\"]\n elif \"_cmd\" in measure[\"name\"]:\n pass\n else:\n payload[\"values\"][measure[\"name\"]] = measure[\"value\"]\n if valve_open:\n payload[\"values\"][\"valve_status\"] = 1\n elif valve_close:\n payload[\"values\"][\"valve_status\"] = 0\n else:\n payload[\"values\"][\"valve_status\"] = -1\n publish(__topic__, json.dumps(payload), __qos__)\n except Exception as e:\n logger.error(e)\n\n\ndef convert_int(name, value):\n valve_failure = {\n 0: \"OK\",\n 1: \"Failure\"\n }\n\n names = {\n \"valve_failure\": valve_failure.get(value, \"Invalid Code\")\n }\n return names.get(name, \"Invalid Name\")", "name": "sendData", "trigger": "measure_event", "topic": "v1/devices/me/telemetry", "cloudName": "default", "groups": [ "default" ], "msgType": 0 } ], "downloadFuncs": [ { "name": "Commands", "topic": "v1/devices/me/rpc/request/+", "qos": 1, "funcName": "receiveCommand", "payload_type": "Plaintext", "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 topic = \"v1/devices/me/telemetry\"\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 payload = {\"ts\": int(time.time()*1000), \"values\": {}}\n valve_open = 0\n valve_close = 0\n for measure in message[\"measures\"]:\n if measure[\"name\"] in [\"valve_failure\"]:\n value = convert_int(measure[\"name\"], measure[\"value\"])\n payload[\"values\"][measure[\"name\"]] = value\n elif measure[\"name\"] == \"valve_open_status\":\n valve_open = measure[\"value\"]\n elif measure[\"name\"] == \"valve_close_status\":\n valve_close = measure[\"value\"]\n elif \"_cmd\" in measure[\"name\"]:\n pass\n else:\n payload[\"values\"][measure[\"name\"]] = measure[\"value\"]\n if valve_open:\n payload[\"values\"][\"valve_status\"] = \"Open\"\n elif valve_close:\n payload[\"values\"][\"valve_status\"] = \"Closed\"\n else:\n payload[\"values\"][\"valve_status\"] = \"Unknown\"\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 = {\"valvecontroller\":{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 elif command == \"changeSetpoint\":\n try:\n params_type = {\"measurement\": \"pidcontrolmode\", \"value\": p[\"params\"][\"setpointType\"]}\n if params_type[\"value\"]:\n commands[\"writeplctag\"](params_type, wizard_api)\n time.sleep(2)\n except:\n pass\n try:\n modes = {0: \"flowsetpoint\", 1: \"fluidlevelsetpoint\", 2: \"tubingpressuresetpoint\", 3: \"manualfrequencysetpoint\"}\n params_value = {\"value\": p[\"params\"][\"setpointValue\"]}\n if params_value[\"value\"]:\n params_value[\"measurement\"] = modes[getMode()]\n commands[\"writeplctag\"](params_value, wizard_api)\n except Exception as e:\n logger.debug(\"DID NOT WRITE SETPOINT\")\n logger.debug(e)\n \n #logger.debug(command)\n ack(topic.split(\"/\")[-1], wizard_api)\n time.sleep(5)\n sync(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 getMode():\n try:\n data = recall()\n for controller in data:\n for measure in controller[\"measures\"]:\n if measure[\"name\"] == \"pidcontrolmode\":\n return measure[\"value\"]\n except:\n return None\n\ndef convert_int(name, value):\n valve_failure = {\n 0: \"OK\",\n 1: \"Failure\"\n }\n\n names = {\n \"valve_failure\": valve_failure.get(value, \"Invalid Code\")\n }\n return names.get(name, \"Invalid Name\")\n", "msgType": 0, "cloudName": "default", "trigger": "command_event" } ] }, "labels": [ { "key": "SN", "value": "GF5022215013070" }, { "key": "MAC", "value": "00:18:05:1f:8d:4c" } ], "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": [] }, "southMetadata": {}, "bindMetadata": { "version": "", "timestamp": "" }, "bindConfig": { "enable": 0, "bind": { "modelId": "", "modelName": "", "srcId": "", "srcName": "", "devId": "", "devName": "" }, "varGroups": [], "variables": [], "alerts": [] } }