From 8a5875166ffc783c0082b170a89f4b12eb7220dc Mon Sep 17 00:00:00 2001 From: Nico Melone Date: Thu, 1 Sep 2022 22:28:43 -0500 Subject: [PATCH] updated flowmeterskid to have previous increment --- .DS_Store | Bin 8196 -> 8196 bytes Pub_Sub/config_manager.ipynb | 4 +- .../flowmeterskid_tb_v0.cfg} | 0 .../thingsboard/v1/flowmeterskid_tb_v1.cfg | 330 ++++++++++++++++++ .../thingsboard/{ => v1}/pub/sendData.py | 4 + 5 files changed, 336 insertions(+), 2 deletions(-) rename Pub_Sub/flowmeterskid/thingsboard/{flowmeterskid_tb_v1.cfg => v0/flowmeterskid_tb_v0.cfg} (100%) create mode 100644 Pub_Sub/flowmeterskid/thingsboard/v1/flowmeterskid_tb_v1.cfg rename Pub_Sub/flowmeterskid/thingsboard/{ => v1}/pub/sendData.py (96%) diff --git a/.DS_Store b/.DS_Store index 40d32a302e6244688ffa732c693e24d6214be193..71184cb6fd92d89ee8d11bd8bb512ceadda0a2b5 100644 GIT binary patch delta 18 ZcmZp1XmQx^Pk@nevZA2yW+A~(d;mTD1@`~| delta 16 XcmZp1XmQx^PhhfwpvYz+!B2buH&_Mr diff --git a/Pub_Sub/config_manager.ipynb b/Pub_Sub/config_manager.ipynb index d822723..fd2d9e1 100644 --- a/Pub_Sub/config_manager.ipynb +++ b/Pub_Sub/config_manager.ipynb @@ -17,9 +17,9 @@ "outputs": [], "source": [ "root = \"/Users/nico/Documents/GitHub/HP_InHand_IG502/Pub_Sub/\"\n", - "devicetype = \"advvfdipp\"\n", + "devicetype = \"flowmeterskid\"\n", "platform = \"thingsboard\" #\"mistaway\"\n", - "startversion = 2\n", + "startversion = 0\n", "deviceconfig = devicetype + \"_tb_\" +\"v\" + str(startversion) + \".cfg\"\n" ] }, diff --git a/Pub_Sub/flowmeterskid/thingsboard/flowmeterskid_tb_v1.cfg b/Pub_Sub/flowmeterskid/thingsboard/v0/flowmeterskid_tb_v0.cfg similarity index 100% rename from Pub_Sub/flowmeterskid/thingsboard/flowmeterskid_tb_v1.cfg rename to Pub_Sub/flowmeterskid/thingsboard/v0/flowmeterskid_tb_v0.cfg diff --git a/Pub_Sub/flowmeterskid/thingsboard/v1/flowmeterskid_tb_v1.cfg b/Pub_Sub/flowmeterskid/thingsboard/v1/flowmeterskid_tb_v1.cfg new file mode 100644 index 0000000..7ad4fdf --- /dev/null +++ b/Pub_Sub/flowmeterskid/thingsboard/v1/flowmeterskid_tb_v1.cfg @@ -0,0 +1,330 @@ +{ + "controllers": [ + { + "protocol": "Modbus-RTU", + "name": "flowmeter", + "endpoint": "rs485", + "args": { + "slaveAddr": 247, + "int16Ord": "ab", + "int32Ord": "cdab", + "float32Ord": "cdab", + "int64Ord": "ghefcdab", + "enableMsecSample": 0, + "continuousAcquisition": 1, + "maxContinuousNumber": 64, + "communicationInterval": 3, + "msecSamplePeriod": 500, + "msecPackage": 20 + }, + "samplePeriod": 10, + "expired": 10000 + } + ], + "measures": [ + { + "name": "flowrate", + "ctrlName": "flowmeter", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "43874", + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "decimal": 2, + "gain": "1.0", + "offset": "0.0", + "msecSample": 0 + }, + { + "name": "totalizer_1", + "ctrlName": "flowmeter", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "42610", + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "decimal": 2, + "gain": "1.0", + "offset": "0.0", + "msecSample": 0 + }, + { + "name": "totalizer_2", + "ctrlName": "flowmeter", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "42810", + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "decimal": 2, + "gain": "1.0", + "offset": "0.0", + "msecSample": 0 + }, + { + "name": "totalizer_3", + "ctrlName": "flowmeter", + "group": "default", + "uploadType": "periodic", + "dataType": "FLOAT", + "addr": "43010", + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "decimal": 2, + "gain": "1.0", + "offset": "0.0", + "msecSample": 0 + }, + { + "name": "flow_unit", + "ctrlName": "flowmeter", + "group": "default", + "uploadType": "periodic", + "dataType": "INT", + "addr": "42103", + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "gain": "1.0", + "offset": "0.0", + "msecSample": 0 + }, + { + "name": "totalizer_1_unit", + "ctrlName": "flowmeter", + "group": "default", + "uploadType": "periodic", + "dataType": "INT", + "addr": "44604", + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "gain": "1.0", + "offset": "0.0", + "msecSample": 0 + }, + { + "name": "totalizer_2_unit", + "ctrlName": "flowmeter", + "group": "default", + "uploadType": "periodic", + "dataType": "INT", + "addr": "44605", + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "gain": "1.0", + "offset": "0.0", + "msecSample": 0 + }, + { + "name": "totalizer_3_unit", + "ctrlName": "flowmeter", + "group": "default", + "uploadType": "periodic", + "dataType": "INT", + "addr": "44606", + "readWrite": "ro", + "unit": "", + "desc": "", + "transformType": 0, + "gain": "1.0", + "offset": "0.0", + "msecSample": 0 + } + ], + "alarmLables": [ + "default" + ], + "alarms": [], + "groups": [ + { + "name": "default", + "uploadInterval": 600 + } + ], + "misc": { + "maxAlarmRecordSz": 2000, + "logLvl": "INFO", + "coms": [ + { + "name": "rs232", + "baud": 9600, + "bits": 8, + "parityChk": "n", + "stopbits": 1 + }, + { + "name": "rs485", + "baud": 19200, + "bits": 8, + "parityChk": "n", + "stopbits": 1 + } + ] + }, + "clouds": [ + { + "cacheSize": 10000, + "enable": 1, + "name": "default", + "type": "Standard MQTT", + "args": { + "host": "hp.henrypump.cloud", + "port": 1883, + "clientId": "unknown", + "auth": 1, + "tls": 0, + "cleanSession": 0, + "mqttVersion": "v3.1.1", + "keepalive": 60, + "key": "", + "cert": "", + "rootCA": "", + "verifyServer": 0, + "verifyClient": 0, + "username": "unknown", + "passwd": "unknown" + } + } + ], + "quickfaas": { + "genericFuncs": [], + "uploadFuncs": [ + { + "qos": 1, + "funcName": "sendData", + "script": "import json, os\nfrom datetime import datetime as dt\nfrom common.Logger import logger\nfrom quickfaas.remotebus import publish\nfrom mobiuspi_lib.gps import GPS\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\npayload = {}\n\ntry:\n with open(\"/var/user/files/totalizers.json\", \"r\") as t:\n totalizers = json.load(t)\n if not totalizers:\n logger.info(\"-----INITIALIZING TOTALIZERS-----\")\n totalizers = {\n \"day\": 0,\n \"week\": 0,\n \"month\": 0,\n \"year\": 0,\n \"lifetime\": 0,\n \"dayHolding\": 0,\n \"weekHolding\": 0,\n \"monthHolding\": 0,\n \"yearHolding\": 0\n }\nexcept:\n totalizers = {\n \"day\": 0,\n \"week\": 0,\n \"month\": 0,\n \"year\": 0,\n \"lifetime\": 0,\n \"dayHolding\": 0,\n \"weekHolding\": 0,\n \"monthHolding\": 0,\n \"yearHolding\": 0\n }\n\n\n\n\ndef sendData(message,wizard_api):\n logger.debug(message)\n checkCredentialConfig()\n payload = {\"ts\": (round(dt.timestamp(dt.now())/600)*600)*1000, \"values\": {}}\n resetPayload = {\"ts\": \"\", \"values\": {}}\n for measure in message[\"values\"][\"flowmeter\"].keys():\n try:\n if measure in [\"totalizer_1\"]:\n payload[\"values\"][\"day_volume\"], dayReset = totalizeDay(message[\"values\"][\"flowmeter\"][measure][\"raw_data\"])\n payload[\"values\"][\"week_volume\"], weekReset = totalizeWeek(message[\"values\"][\"flowmeter\"][measure][\"raw_data\"])\n payload[\"values\"][\"month_volume\"], monthReset = totalizeMonth(message[\"values\"][\"flowmeter\"][measure][\"raw_data\"])\n payload[\"values\"][\"year_volume\"], yearReset = totalizeYear(message[\"values\"][\"flowmeter\"][measure][\"raw_data\"])\n payload[\"values\"][measure] = message[\"values\"][\"flowmeter\"][measure][\"raw_data\"]\n except Exception as e:\n logger.error(e)\n try:\n payload[\"values\"][\"latitude\"], payload[\"values\"][\"longitude\"], payload[\"values\"][\"speed\"] = getGPS()\n except:\n logger.error(\"Could not get GPS coordinates\")\n publish(__topic__, json.dumps(payload), __qos__)\n\n if dayReset:\n resetPayload[\"values\"][\"day_volume\"] = 0\n if weekReset:\n resetPayload[\"values\"][\"week_volume\"] = 0\n if monthReset:\n resetPayload[\"values\"][\"month_volume\"] = 0\n if yearReset:\n resetPayload[\"values\"][\"year_volume\"] = 0 \n\n if resetPayload[\"values\"]:\n resetPayload[\"ts\"] = 1 + (round(dt.timestamp(dt.now())/600)*600)*1000\n publish(__topic__, json.dumps(resetPayload), __qos__) \n\ndef saveTotalizers():\n try:\n with open(\"/var/user/files/totalizers.json\", \"w\") as t:\n json.dump(totalizers,t)\n except Exception as e:\n logger.error(e)\n\ndef getGPS():\n # Create a gps instance\n gps = GPS()\n\n # Retrieve GPS information\n position_status = gps.get_position_status()\n logger.debug(\"position_status: \")\n logger.debug(position_status)\n latitude = position_status[\"latitude\"].split(\" \")\n longitude = position_status[\"longitude\"].split(\" \")\n lat_dec = int(latitude[0][:-1]) + (float(latitude[1][:-1])/60)\n lon_dec = int(longitude[0][:-1]) + (float(longitude[1][:-1])/60)\n if latitude[2] == \"S\":\n lat_dec = lat_dec * -1\n if longitude[2] == \"W\":\n lon_dec = lon_dec * -1\n #lat_dec = round(lat_dec, 7)\n #lon_dec = round(lon_dec, 7)\n logger.info(\"HERE IS THE GPS COORDS\")\n logger.info(f\"LATITUDE: {lat_dec}, LONGITUDE: {lon_dec}\")\n speedKnots = position_status[\"speed\"].split(\" \")\n speedMPH = float(speedKnots[0]) * 1.151\n return (f\"{lat_dec:.8f}\",f\"{lon_dec:.8f}\",f\"{speedMPH:.2f}\")\n\ndef totalizeDay(lifetime):\n now = dt.fromtimestamp(round(dt.timestamp(dt.now())/600)*600)\n reset = False\n value = lifetime - totalizers[\"dayHolding\"]\n if not int(now.strftime(\"%d\")) == int(totalizers[\"day\"]):\n totalizers[\"dayHolding\"] = lifetime\n totalizers[\"day\"] = int(now.strftime(\"%d\"))\n saveTotalizers()\n reset = True\n return (value,reset)\n\ndef totalizeWeek(lifetime):\n now = dt.fromtimestamp(round(dt.timestamp(dt.now())/600)*600)\n reset = False\n value = lifetime - totalizers[\"weekHolding\"]\n if not now.strftime(\"%U\") == totalizers[\"week\"] and now.strftime(\"%a\") == \"Sun\":\n totalizers[\"weekHolding\"] = lifetime\n totalizers[\"week\"] = now.strftime(\"%U\")\n saveTotalizers()\n reset = True\n return (value, reset)\n\ndef totalizeMonth(lifetime):\n now = dt.fromtimestamp(round(dt.timestamp(dt.now())/600)*600)\n reset = False\n value = lifetime - totalizers[\"monthHolding\"]\n if not int(now.strftime(\"%m\")) == int(totalizers[\"month\"]):\n totalizers[\"monthHolding\"] = lifetime\n totalizers[\"month\"] = now.strftime(\"%m\")\n saveTotalizers()\n reset = True\n return (value,reset)\n\ndef totalizeYear(lifetime):\n now = dt.fromtimestamp(round(dt.timestamp(dt.now())/600)*600)\n reset = False\n value = lifetime - totalizers[\"yearHolding\"]\n if not int(now.strftime(\"%Y\")) == int(totalizers[\"year\"]):\n totalizers[\"yearHolding\"] = lifetime\n totalizers[\"year\"] = now.strftime(\"%Y\")\n saveTotalizers()\n reset = True\n return (value, reset)", + "name": "sendData", + "trigger": "measure_event", + "topic": "v1/devices/me/telemetry", + "cloudName": "default", + "groups": [ + "default" + ], + "msgType": 0 + } + ], + "downloadFuncs": [ + { + "name": "Receive Command", + "topic": "v1/devices/me/rpc/request/+", + "qos": 1, + "funcName": "receiveCommand", + "payload_type": "JSON", + "script": "import json\nimport time\nfrom common.Logger import logger\nfrom quickfaas.remotebus import publish\n\ndef resetTotalizers():\n with open(\"/var/user/files/totalizers.json\", \"r+\") as t:\n totalizers = json.load(t)\n if totalizers:\n totalizers[\"dayHolding\"] = 0\n totalizers[\"weekHolding\"] = 0\n totalizers[\"MonthHolding\"] = 0\n totalizers[\"yearHolding\"] = 0\n json.dump(totalizers,t)\n\ndef receiveCommand(topic, payload):\n logger.debug(topic)\n logger.debug(json.loads(payload))\n p = json.loads(payload)\n command = p[\"method\"]\n if command == \"resetTotalizers\":\n resetTotalizers()\n publish(topic, json.dumps({\"msg\": {\"time\": time.time()}, \"metadata\": \"\", \"msgType\": \"\"}))\n", + "msgType": 0, + "cloudName": "default", + "trigger": "command_event" + } + ] + }, + "labels": [ + { + "key": "SN", + "value": "GF5022223016129" + }, + { + "key": "MAC", + "value": "00:18:05:21:b3:3f" + } + ], + "modbusSlave": { + "enable": 0, + "protocol": "Modbus-TCP", + "port": 502, + "slaveAddr": 1, + "int16Ord": "ab", + "int32Ord": "abcd", + "float32Ord": "abcd", + "maxConnection": 5, + "mapping_table": [] + }, + "modbusRTUSlave": { + "enable": 0, + "protocol": "Modbus-RTU", + "coms": "rs485", + "slaveAddr": 1, + "int16Ord": "ab", + "int32Ord": "abcd", + "float32Ord": "abcd", + "mapping_table": [] + }, + "iec104Server": { + "enable": 0, + "cotSize": 2, + "port": 2404, + "serverList": [ + { + "asduAddr": 1 + } + ], + "kValue": 12, + "wValue": 8, + "t0": 30, + "t1": 15, + "t2": 10, + "t3": 20, + "maximumLink": 5, + "timeSet": 1, + "byteOrder": "abcd", + "mapping_table": [] + }, + "iec104Client": { + "enable": 0, + "connectType": 2, + "serverAddr": "ipower.inhandcloud.cn", + "serverPort": 2404, + "communicationCode": "", + "protocol": 1, + "asduAddr": 1, + "tls": 0, + "mapping_table": { + "YX": [], + "YC": [], + "YK": [] + } + }, + "opcuaServer": { + "enable": 0, + "port": 4840, + "maximumLink": 5, + "securityMode": 0, + "identifierType": "String", + "mapping_table": [] + }, + "southMetadata": {}, + "bindMetadata": { + "version": "", + "timestamp": "" + }, + "bindConfig": { + "enable": 0, + "bind": { + "modelId": "", + "modelName": "", + "srcId": "", + "srcName": "", + "devId": "", + "devName": "" + }, + "varGroups": [], + "variables": [], + "alerts": [] + }, + "version": "2.3.1" +} \ No newline at end of file diff --git a/Pub_Sub/flowmeterskid/thingsboard/pub/sendData.py b/Pub_Sub/flowmeterskid/thingsboard/v1/pub/sendData.py similarity index 96% rename from Pub_Sub/flowmeterskid/thingsboard/pub/sendData.py rename to Pub_Sub/flowmeterskid/thingsboard/v1/pub/sendData.py index 25eea13..1b51308 100644 --- a/Pub_Sub/flowmeterskid/thingsboard/pub/sendData.py +++ b/Pub_Sub/flowmeterskid/thingsboard/v1/pub/sendData.py @@ -172,12 +172,16 @@ def sendData(message,wizard_api): publish(__topic__, json.dumps(payload), __qos__) if dayReset: + resetPayload["values"]["yesterday_volume"] = payload["values"]["day_volume"] resetPayload["values"]["day_volume"] = 0 if weekReset: + resetPayload["values"]["last_week_volume"] = payload["values"]["week_volume"] resetPayload["values"]["week_volume"] = 0 if monthReset: + resetPayload["values"]["last_month_volume"] = payload["values"]["month_volume"] resetPayload["values"]["month_volume"] = 0 if yearReset: + resetPayload["values"]["last_year_volume"] = payload["values"]["year_volume"] resetPayload["values"]["year_volume"] = 0 if resetPayload["values"]: