{ "controllers": [ { "enable": 1, "protocol": "AllenBradley MicroCip", "name": "plcpond", "samplePeriod": 10, "desc": "", "expired": 1000, "args": { "slot": 0, "connectTimeOut": 10000 }, "enableDebug": 0, "enablePerOnchange": 0, "endpoint": "192.168.1.12:44818" } ], "measures": [ { "name": "pond_1_level", "ctrlName": "plcpond", "group": "default", "uploadType": "periodic", "dataType": "FLOAT", "addr": "Pond_1_Lev", "decimal": 2, "len": 1, "readWrite": "ro", "unit": "", "desc": "", "transformType": 0, "maxValue": "", "minValue": "", "maxScaleValue": "", "minScaleValue": "", "gain": "", "offset": "", "storageLwTSDB": 0 }, { "name": "pond_1_total_bbls", "ctrlName": "plcpond", "group": "default", "uploadType": "periodic", "dataType": "FLOAT", "addr": "Pond_1_Total_Barrels", "decimal": 2, "len": 1, "readWrite": "ro", "unit": "", "desc": "", "transformType": 0, "maxValue": "", "minValue": "", "maxScaleValue": "", "minScaleValue": "", "gain": "", "offset": "", "storageLwTSDB": 0 }, { "name": "pond_1_hi_alm", "ctrlName": "plcpond", "group": "default", "uploadType": "periodic", "dataType": "BIT", "addr": "Pond_1_Hi_Alarm", "decimal": 2, "len": 1, "readWrite": "ro", "unit": "", "desc": "", "transformType": 0, "maxValue": "", "minValue": "", "maxScaleValue": "", "minScaleValue": "", "gain": "", "offset": "", "bitMap": 0, "reverseBit": 0, "storageLwTSDB": 0 }, { "name": "pond_1_hi_spt", "ctrlName": "plcpond", "group": "default", "uploadType": "periodic", "dataType": "FLOAT", "addr": "Pond_1_Hi_Setpoint", "decimal": 2, "len": 1, "readWrite": "rw", "unit": "", "desc": "", "transformType": 0, "maxValue": "", "minValue": "", "maxScaleValue": "", "minScaleValue": "", "gain": "", "offset": "", "storageLwTSDB": 0 }, { "name": "pond_1_hi_clr_spt", "ctrlName": "plcpond", "group": "default", "uploadType": "periodic", "dataType": "FLOAT", "addr": "Pond_1_Hi_Clr_Setpoint", "decimal": 2, "len": 1, "readWrite": "rw", "unit": "", "desc": "", "transformType": 0, "maxValue": "", "minValue": "", "maxScaleValue": "", "minScaleValue": "", "gain": "", "offset": "", "storageLwTSDB": 0 }, { "name": "pond_1_lo_alm", "ctrlName": "plcpond", "group": "default", "uploadType": "periodic", "dataType": "BIT", "addr": "Pond_1_Lo_Alarm", "decimal": 2, "len": 1, "readWrite": "ro", "unit": "", "desc": "", "transformType": 0, "maxValue": "", "minValue": "", "maxScaleValue": "", "minScaleValue": "", "gain": "", "offset": "", "bitMap": 0, "reverseBit": 0, "storageLwTSDB": 0 }, { "name": "pond_1_lo_spt", "ctrlName": "plcpond", "group": "default", "uploadType": "periodic", "dataType": "FLOAT", "addr": "Pond_1_Lo_Setpoint", "decimal": 2, "len": 1, "readWrite": "rw", "unit": "", "desc": "", "transformType": 0, "maxValue": "", "minValue": "", "maxScaleValue": "", "minScaleValue": "", "gain": "", "offset": "", "storageLwTSDB": 0 }, { "name": "pond_1_lo_clr_spt", "ctrlName": "plcpond", "group": "default", "uploadType": "periodic", "dataType": "FLOAT", "addr": "Pond_1_Lo_Clr_Setpoint", "decimal": 2, "len": 1, "readWrite": "rw", "unit": "", "desc": "", "transformType": 0, "maxValue": "", "minValue": "", "maxScaleValue": "", "minScaleValue": "", "gain": "", "offset": "", "storageLwTSDB": 0 }, { "name": "pond_2_level", "ctrlName": "plcpond", "group": "default", "uploadType": "periodic", "dataType": "FLOAT", "addr": "Pond_2_Lev", "decimal": 2, "len": 1, "readWrite": "ro", "unit": "", "desc": "", "transformType": 0, "maxValue": "", "minValue": "", "maxScaleValue": "", "minScaleValue": "", "gain": "", "offset": "", "storageLwTSDB": 0 }, { "name": "pond_2_total_bbls", "ctrlName": "plcpond", "group": "default", "uploadType": "periodic", "dataType": "FLOAT", "addr": "Pond_2_Total_Barrels", "decimal": 2, "len": 1, "readWrite": "ro", "unit": "", "desc": "", "transformType": 0, "maxValue": "", "minValue": "", "maxScaleValue": "", "minScaleValue": "", "gain": "", "offset": "", "storageLwTSDB": 0 }, { "name": "pond_2_hi_alm", "ctrlName": "plcpond", "group": "default", "uploadType": "periodic", "dataType": "BIT", "addr": "Pond_2_Hi_Alarm", "decimal": 2, "len": 1, "readWrite": "ro", "unit": "", "desc": "", "transformType": 0, "maxValue": "", "minValue": "", "maxScaleValue": "", "minScaleValue": "", "gain": "", "offset": "", "bitMap": 0, "reverseBit": 0, "storageLwTSDB": 0 }, { "name": "pond_2_hi_spt", "ctrlName": "plcpond", "group": "default", "uploadType": "periodic", "dataType": "FLOAT", "addr": "Pond_2_Hi_Setpoint", "decimal": 2, "len": 1, "readWrite": "rw", "unit": "", "desc": "", "transformType": 0, "maxValue": "", "minValue": "", "maxScaleValue": "", "minScaleValue": "", "gain": "", "offset": "", "storageLwTSDB": 0 }, { "name": "pond_2_hi_clr_spt", "ctrlName": "plcpond", "group": "default", "uploadType": "periodic", "dataType": "FLOAT", "addr": "Pond_2_Hi_Clr_Setpoint", "decimal": 2, "len": 1, "readWrite": "rw", "unit": "", "desc": "", "transformType": 0, "maxValue": "", "minValue": "", "maxScaleValue": "", "minScaleValue": "", "gain": "1.0", "offset": "0.0", "storageLwTSDB": 0 }, { "name": "pond_2_lo_alm", "ctrlName": "plcpond", "group": "default", "uploadType": "periodic", "dataType": "BIT", "addr": "Pond_2_Lo_Alarm", "decimal": 2, "len": 1, "readWrite": "ro", "unit": "", "desc": "", "transformType": 0, "maxValue": "", "minValue": "", "maxScaleValue": "", "minScaleValue": "", "gain": "", "offset": "", "bitMap": 0, "reverseBit": 0, "storageLwTSDB": 0 }, { "name": "pond_2_lo_spt", "ctrlName": "plcpond", "group": "default", "uploadType": "periodic", "dataType": "FLOAT", "addr": "Pond_2_Lo_Setpoint", "decimal": 2, "len": 1, "readWrite": "rw", "unit": "", "desc": "", "transformType": 0, "maxValue": "", "minValue": "", "maxScaleValue": "", "minScaleValue": "", "gain": "", "offset": "", "storageLwTSDB": 0 }, { "name": "pond_2_lo_clr_spt", "ctrlName": "plcpond", "group": "default", "uploadType": "periodic", "dataType": "FLOAT", "addr": "Pond_2_Lo_Clr_Setpoint", "decimal": 2, "len": 1, "readWrite": "rw", "unit": "", "desc": "", "transformType": 0, "maxValue": "", "minValue": "", "maxScaleValue": "", "minScaleValue": "", "gain": "", "offset": "", "storageLwTSDB": 0 } ], "alarmLables": [ "default" ], "alarms": [], "groups": [ { "name": "default", "uploadInterval": 600, "reference": 16, "LwTSDBSize": 1000, "strategy": 1, "historyDataPath": "/var/user/data/dbhome/device_supervisor/LwTSDB", "enablePerOnchange": 0 } ], "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" } ], "cachePath": "/var/user/data/dbhome/device_supervisor/offlinedata", "cacheSize": 10000, "debugLogPath": "/var/user/data/dbhome/device_supervisor/debugLog", "debugLogSize": 2000 }, "clouds": [ { "cacheSize": 100, "enable": 1, "name": "default", "type": "Standard MQTT", "args": { "host": "hp.henrypump.cloud", "port": 1883, "clientId": "unknown", "auth": 1, "tls": 0, "cleanSession": 0, "mqttVersion": "v3.1.1", "keepalive": 60, "key": "", "cert": "", "rootCA": "", "verifyServer": 0, "verifyClient": 0, "username": "unknown", "passwd": "unknown", "authType": 1, "willQos": 0, "willRetain": 0, "willTopic": "", "willPayload": "", "tlsAuth": "caSelfSigned" }, "uploadRules": [] } ], "quickfaas": { "genericFuncs": [], "uploadFuncs": [ { "name": "sendData", "trigger": "measure_event", "topic": "v1/devices/me/telemetry", "qos": 1, "groups": [ "default" ], "funcName": "sendData", "script": "# Enter your python code.\nimport json, os\nfrom datetime import datetime as dt\nfrom common.Logger import logger\nfrom quickfaas.remotebus import publish\nfrom quickfaas.global_dict import get as get_params\nfrom quickfaas.global_dict import _set_global_args\n\ndef reboot():\n #basic = Basic()\n logger.info(\"!\" * 10 + \"REBOOTING DEVICE\" + \"!\"*10)\n r = os.popen(\"kill -s SIGHUP `cat /var/run/python/supervisord.pid`\").read()\n logger.info(f\"REBOOT : {r}\")\n\ndef checkFileExist(filename):\n path = \"/var/user/files\"\n if not os.path.exists(path):\n logger.info(\"no folder making files folder in var/user\")\n os.makedirs(path)\n with open(path + \"/\" + filename, \"a\") as f:\n json.dump({}, f)\n if not os.path.exists(path + \"/\" + filename):\n logger.info(\"no creds file making creds file\")\n with open(path + \"/\" + filename, \"a\") as f:\n json.dump({}, f)\n\ndef convertDStoJSON(ds):\n j = dict()\n for x in ds:\n j[x[\"key\"]] = x[\"value\"]\n return j\n\ndef convertJSONtoDS(j):\n d = []\n for key in j.keys():\n d.append({\"key\": key, \"value\": j[key]})\n return d\n\ndef checkCredentialConfig():\n logger.info(\"CHECKING CONFIG\")\n cfgpath = \"/var/user/cfg/device_supervisor/device_supervisor.cfg\"\n credspath = \"/var/user/files/creds.json\"\n cfg = dict()\n with open(cfgpath, \"r\") as f:\n cfg = json.load(f)\n clouds = cfg.get(\"clouds\")\n logger.info(clouds)\n #if not configured then try to configure from stored values\n if clouds[0][\"args\"][\"clientId\"] == \"unknown\" or clouds[0][\"args\"][\"username\"] == \"unknown\" or not clouds[0][\"args\"][\"passwd\"] or clouds[0][\"args\"][\"passwd\"] == \"unknown\":\n checkFileExist(\"creds.json\")\n with open(credspath, \"r\") as c:\n creds = json.load(c)\n if creds:\n logger.info(\"updating config with stored data\")\n clouds[0][\"args\"][\"clientId\"] = creds[\"clientId\"]\n clouds[0][\"args\"][\"username\"] = creds[\"userName\"]\n clouds[0][\"args\"][\"passwd\"] = creds[\"password\"]\n cfg[\"clouds\"] = clouds\n cfg = checkParameterConfig(cfg)\n with open(cfgpath, \"w\", encoding='utf-8') as n:\n json.dump(cfg, n, indent=1, ensure_ascii=False)\n reboot()\n else:\n #assuming clouds is filled out, if data is different then assume someone typed in something new and store it, if creds is empty fill with clouds' data\n checkFileExist(\"creds.json\")\n with open(credspath, \"r\") as c:\n logger.info(\"updating stored file with new data\")\n cfg = checkParameterConfig(cfg)\n with open(cfgpath, \"w\", encoding='utf-8') as n:\n json.dump(cfg, n, indent=1, ensure_ascii=False)\n creds = json.load(c)\n if creds:\n if creds[\"clientId\"] != clouds[0][\"args\"][\"clientId\"]:\n creds[\"clientId\"] = clouds[0][\"args\"][\"clientId\"]\n if creds[\"userName\"] != clouds[0][\"args\"][\"username\"]:\n creds[\"userName\"] = clouds[0][\"args\"][\"username\"]\n if creds[\"password\"] != clouds[0][\"args\"][\"passwd\"]:\n creds[\"password\"] = clouds[0][\"args\"][\"passwd\"]\n else:\n creds[\"clientId\"] = clouds[0][\"args\"][\"clientId\"]\n creds[\"userName\"] = clouds[0][\"args\"][\"username\"]\n creds[\"password\"] = clouds[0][\"args\"][\"passwd\"]\n with open(credspath, \"w\") as cw:\n json.dump(creds,cw)\n\ndef checkParameterConfig(cfg):\n logger.info(\"Checking Parameters!!!!\")\n paramspath = \"/var/user/files/params.json\"\n cfgparams = convertDStoJSON(cfg.get(\"labels\"))\n #check stored values \n checkFileExist(\"params.json\")\n with open(paramspath, \"r\") as f:\n logger.info(\"Opened param storage file\")\n params = json.load(f)\n if params:\n if cfgparams != params:\n #go through each param\n #if not \"unknown\" and cfg and params aren't the same take from cfg likely updated manually\n #if key in cfg but not in params copy to params\n logger.info(\"equalizing params between cfg and stored\")\n for key in cfgparams.keys():\n try:\n if cfgparams[key] != params[key] and cfgparams[key] != \"unknown\":\n params[key] = cfgparams[key]\n except:\n params[key] = cfgparams[key]\n cfg[\"labels\"] = convertJSONtoDS(params)\n _set_global_args(convertJSONtoDS(params))\n with open(paramspath, \"w\") as p:\n json.dump(params, p)\n else:\n with open(paramspath, \"w\") as p:\n logger.info(\"initializing param file with params in memory\")\n json.dump(convertDStoJSON(get_params()), p)\n cfg[\"labels\"] = get_params()\n \n return cfg\n\n\n\n\ndef sendData(message):\n payload = {}\n payload[\"ts\"] = (round(dt.timestamp(dt.now())/600)*600)*1000\n payload[\"values\"] = {}\n try:\n checkCredentialConfig()\n except Exception as e:\n logger.error(e)\n for measure in message[\"measures\"]:\n try:\n logger.debug(measure)\n payload[\"values\"][measure[\"name\"]] = measure[\"value\"]\n except Exception as e:\n logger.error(e)\n publish(__topic__, json.dumps(payload), __qos__)", "msgType": 0, "cloudName": "default" } ], "downloadFuncs": [] }, "labels": [ { "key": "SN", "value": "GF5022311031664" }, { "key": "MAC", "value": "00:18:05:28:4a:40" } ], "modbusSlave": { "enable": 0, "protocol": "Modbus-TCP", "port": 502, "slaveAddr": 1, "int16Ord": "ab", "int32Ord": "abcd", "float32Ord": "abcd", "maxConnection": 5, "mapping_table": [] }, "modbusRTUSlave": { "enable": 0, "protocol": "Modbus-RTU", "coms": "rs485", "slaveAddr": 1, "int16Ord": "ab", "int32Ord": "abcd", "float32Ord": "abcd", "mapping_table": [] }, "iec104Server": { "enable": 0, "cotSize": 2, "port": 2404, "serverList": [ { "asduAddr": 1 } ], "kValue": 12, "wValue": 8, "t0": 30, "t1": 15, "t2": 10, "t3": 20, "maximumLink": 5, "timeSet": 1, "byteOrder": "abcd", "mapping_table": [] }, "iec101Server": { "enable": 0, "coms": "rs485", "mode": "UnBalance", "linkLen": 2, "linkAddr": 1, "asduLen": 2, "ioaLen": 3, "cotLen": 2, "serverList": [ { "asduAddr": 1 } ], "linkTimeOut": 2000, "timeSet": 1, "idleTimeOut": 10000, "byteOrder": "abcd", "mapping_table": { "YX": [], "YC": [], "YK": [] } }, "iec104Client": { "enable": 0, "connectType": 2, "serverAddr": "ipower.inhandcloud.cn", "serverPort": 2404, "communicationCode": "", "protocol": 1, "asduAddr": 1, "tls": 0, "mapping_table": { "YX": [], "YC": [], "YK": [] } }, "opcuaServer": { "enable": 0, "port": 4840, "maximumLink": 5, "securityMode": 0, "identifierType": "String", "mapping_table": [], "certificate": "None", "privateKey": "None", "pubsub": 0 }, "sl651Slave": { "enable": 0, "centerAaddr": 1, "remoteAddr": "", "addrCode": "", "password": "", "platform_list": [], "mapping_table": [] }, "hj212Client": { "enable": 0, "platform_list": [], "block_list": [], "mapping_table": [] }, "southMetadata": {}, "bindMetadata": { "version": "", "timestamp": "" }, "bindConfig": { "enable": 0, "bind": { "modelId": "", "modelName": "", "srcId": "", "srcName": "", "devId": "", "devName": "" }, "varGroups": [], "variables": [], "alerts": [] }, "templates": {}, "version": "2.7.1" }