The weather station generates data that comes into NR from rtl_433 via MQTT. The rain data comes in as a running total of inches of precipitation. I put that directly into the DB. The same message that gets put in the DB is also sent to this new code that calculates the period total which should also save that value to the DB.
I can change the approach if there is a better way to do it, but what my intent was is to save the raw data (running total of precipitation) for now but eventually only keep the period accumulations. The other option that would be easily accomplished would be to record the instantaneous accumulation. That would simply require storing the last reading and time and finding the difference and dividing by time delta. I'm at a point where nothing is final so any suggestions are very much appreciated.
This is the code I'm using right now. It's based on the link above so it's not my creation (not taking credit for it).
[{"id":"319cd392.9843cc","type":"function","z":"c473a0c1.c75468","name":"kWh metering","func":"var global_name = \"kWhstat\"; // Name of the global variable\nvar hourlysize = 24; // Number of hourly stat to collect (24 for the last 24 hours)\nvar dailysize = 10; // Number of daily stat to collect\nvar weeklysize = 10; // Number of weekly stat to collect\nvar current = new Date();\nvar i = 0;\nvar delta = 0;\n\nvar kWhstat = global.get(global_name);\nif (kWhstat===undefined) {\n kWhstat = {};\n}\n\n// If the message is coming from sensor, save the current value\nif (msg.topic===\"reading\") {\n if (msg.payload!==undefined) {\n context.set(\"kWh\",msg.payload);\n msg.topic=\"reading\";\n }\n}\n\n// Do not process stats until we have a valid reading\nif (context.get(\"kWh\")!==undefined) {\n\n // Update the hourly stats\n if (msg.topic===\"hourly\") {\n msg.topic=\"hourly\";\n // First update the historical readings\n if (kWhstat.hourlyvalues===undefined) {\n // this is the first reading, create the array first\n kWhstat.hourlyvalues = [];\n kWhstat.hourlyvalues.push({epoch: current.getTime(), reading:context.get(\"kWh\")});\n } else {\n if (kWhstat.hourlyvalues.length<hourlysize-1) {\n // there is not enough history collected yet, add to the array\n kWhstat.hourlyvalues.push({epoch: current.getTime(), reading:context.get(\"kWh\")});\n } else {\n // the array is full need to shift values\n for (i=1;i<kWhstat.hourlyvalues.length;i++) {\n kWhstat.hourlyvalues[i-1]=kWhstat.hourlyvalues[i];\n }\n // add the current value to the end of the array\n kWhstat.hourlyvalues[hourlysize-1]={epoch: current.getTime(), reading:context.get(\"kWh\")};\n }\n }\n \n // Calculate the delta values\n kWhstat.hourlydelta = [];\n if (kWhstat.hourlyvalues.length>1) {\n // We need at least two readings\n for (i=1;i<kWhstat.hourlyvalues.length;i++) {\n delta = Math.round((kWhstat.hourlyvalues[i].reading - kWhstat.hourlyvalues[i-1].reading)*10)/10;\n if (delta<0) {\n // If for any reason readings from the sensor reset use delta as zero instead of a high negative value\n delta = 0;\n }\n kWhstat.hourlydelta.push({epoch: kWhstat.hourlyvalues[i].epoch, delta:delta});\n }\n }\n \n }\n \n // Update the daily stats\n if (msg.topic===\"daily\") {\n msg.topic=\"daily\";\n // First update the historical readings\n if (kWhstat.dailyvalues===undefined) {\n // this is the first reading, create the array first\n kWhstat.dailyvalues = [];\n kWhstat.dailyvalues.push({epoch: current.getTime(), reading:context.get(\"kWh\")});\n } else {\n if (kWhstat.dailyvalues.length<dailysize-1) {\n // there is not enough history collected yet, add to the array\n kWhstat.dailyvalues.push({epoch: current.getTime(), reading:context.get(\"kWh\")});\n } else {\n // the array is full need to shift values\n for (i=1;i<kWhstat.dailyvalues.length;i++) {\n kWhstat.dailyvalues[i-1]=kWhstat.dailyvalues[i];\n }\n // add the current value to the end of the array\n kWhstat.dailyvalues[dailysize-1]={epoch: current.getTime(), reading:context.get(\"kWh\")};\n }\n }\n \n // Calculate the delta values\n kWhstat.dailydelta = [];\n if (kWhstat.dailyvalues.length>1) {\n // We need at least two readings\n for (i=1;i<kWhstat.dailyvalues.length;i++) {\n delta = Math.round((kWhstat.dailyvalues[i].reading - kWhstat.dailyvalues[i-1].reading)*10)/10;\n if (delta<0) {\n // If for any reason readings from the sensor reset use delta as zero instead of a high negative value\n delta = 0;\n }\n kWhstat.dailydelta.push({epoch: kWhstat.dailyvalues[i].epoch, delta:delta});\n }\n }\n \n }\n \n // Update the weekly stats\n if (msg.topic===\"weekly\") {\n msg.topic=\"weekly\";\n // First update the historical readings\n if (kWhstat.weeklyvalues===undefined) {\n // this is the first reading, create the array first\n kWhstat.weeklyvalues = [];\n kWhstat.weeklyvalues.push({epoch: current.getTime(), reading:context.get(\"kWh\")});\n } else {\n if (kWhstat.weeklyvalues.length<weeklysize-1) {\n // there is not enough history collected yet, add to the array\n kWhstat.weeklyvalues.push({epoch: current.getTime(), reading:context.get(\"kWh\")});\n } else {\n // the array is full need to shift values\n for (i=1;i<kWhstat.weeklyvalues.length;i++) {\n kWhstat.weeklyvalues[i-1]=kWhstat.weeklyvalues[i];\n }\n // add the current value to the end of the array\n kWhstat.weeklyvalues[weeklysize-1]={epoch: current.getTime(), reading:context.get(\"kWh\")};\n }\n }\n \n // Calculate the delta values\n kWhstat.weeklydelta = [];\n if (kWhstat.weeklyvalues.length>1) {\n // We need at least two readings\n for (i=1;i<kWhstat.weeklyvalues.length;i++) {\n delta = Math.round((kWhstat.weeklyvalues[i].reading - kWhstat.weeklyvalues[i-1].reading)*10)/10;\n if (delta<0) {\n // If for any reason readings from the sensor reset use delta as zero instead of a high negative value\n delta = 0;\n }\n kWhstat.weeklydelta.push({epoch: kWhstat.weeklyvalues[i].epoch, delta:delta});\n }\n }\n \n }\n\n\n // This week calculation\n if (kWhstat.weeklyvalues!==undefined) {\n if (kWhstat.weeklyvalues.length>0) {\n kWhstat.thisweek = Math.round((context.get(\"kWh\") - kWhstat.weeklyvalues[kWhstat.weeklyvalues.length-1].reading)*10)/10;\n if (kWhstat.thisweek<0) {\n kWhstat.thisweek = 0.0;\n }\n } else {\n kWhstat.thisweek = 0.0;\n }\n }\n // Today calculation\n if (kWhstat.dailyvalues!==undefined) {\n if (kWhstat.dailyvalues.length>0) {\n kWhstat.today = Math.round((context.get(\"kWh\") - kWhstat.dailyvalues[kWhstat.dailyvalues.length-1].reading)*10)/10;\n if (kWhstat.today<0) {\n kWhstat.today = 0.0;\n }\n } else {\n kWhstat.today = 0.0;\n }\n }\n // This hour calculation\n if (kWhstat.hourlyvalues!==undefined) {\n if (kWhstat.hourlyvalues.length>0) {\n kWhstat.thishour = Math.round((context.get(\"kWh\") - kWhstat.hourlyvalues[kWhstat.hourlyvalues.length-1].reading)*10)/10;\n if (kWhstat.thishour<0) {\n kWhstat.thishour = 0.0;\n }\n } else {\n kWhstat.thishour = 0.0;\n }\n } \n \n // Store the updates\n global.set(global_name,kWhstat);\n msg.payload = kWhstat;\n node.status({fill:\"blue\",shape:\"ring\",text:msg.topic+\" performed\"});\n return msg;\n} else {\n node.status({fill:\"red\",shape:\"ring\",text:\"No reading\"});\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","x":400,"y":560,"wires":[["667e06d3.19dc58","1371047c.8c00c4"]]},{"id":"1fa8bf73.a25af9","type":"inject","z":"c473a0c1.c75468","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"3600","crontab":"","once":false,"onceDelay":"","topic":"hourly","payload":"","payloadType":"date","x":150,"y":620,"wires":[["319cd392.9843cc"]]},{"id":"667e06d3.19dc58","type":"debug","z":"c473a0c1.c75468","name":"","active":true,"tosidebar":true,"console":false,"complete":"false","statusVal":"","statusType":"auto","x":630,"y":560,"wires":[]},{"id":"9119e00.74dcc2","type":"inject","z":"c473a0c1.c75468","d":true,"name":"","repeat":"","crontab":"","once":false,"topic":"","payload":"","payloadType":"date","x":960,"y":1140,"wires":[["2fb6dcc6.6c3254"]]},{"id":"2fb6dcc6.6c3254","type":"function","z":"c473a0c1.c75468","d":true,"name":"Delete history","func":"var rainstat = {};\nglobal.set(\"rainstat\",rainstat);\n","outputs":1,"noerr":0,"x":1160,"y":1140,"wires":[[]]},{"id":"23b110e2.b69ac","type":"inject","z":"c473a0c1.c75468","name":"","repeat":"","crontab":"01 00 * * *","once":false,"onceDelay":"","topic":"daily","payload":"","payloadType":"date","x":150,"y":660,"wires":[["319cd392.9843cc"]]},{"id":"1371047c.8c00c4","type":"switch","z":"c473a0c1.c75468","name":"","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"reading","vt":"str"},{"t":"eq","v":"hourly","vt":"str"},{"t":"eq","v":"daily","vt":"str"},{"t":"eq","v":"weekly","vt":"str"}],"checkall":"true","repair":false,"outputs":4,"x":630,"y":620,"wires":[[],["3f529c79.3d369c"],["6aa4718d.86dc2"],["6925f6dd.5160a"]]},{"id":"3f529c79.3d369c","type":"function","z":"c473a0c1.c75468","name":"Hourly SQL Update","func":"// This logic prevents multiple zero (delta) readings being stored in the database\n// if the (delta) reading is zero and the previous was zero as well, it will not be stored\nvar delta = msg.payload.hourlydelta[msg.payload.hourlydelta.length-1].delta;\nvar store = true;\nif (delta===0) {\n if (context.get(\"last\")!==undefined) {\n if (context.get(\"last\")===0) {\n store = false;\n }\n }\n} \n\nif (store) {\n context.set(\"last\", delta);\n msg.topic=\"INSERT OR REPLACE INTO sensor_aggr (epoch,device,sensor,value) VALUES(\"+msg.payload.hourlydelta[msg.payload.hourlydelta.length-1].epoch+\",'maplin','rain_hourly',\"+delta+\");\";\n return msg;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","x":890,"y":620,"wires":[["1df0d1ef.f15bfe","6b44aa1e.d0e494"]]},{"id":"6aa4718d.86dc2","type":"function","z":"c473a0c1.c75468","name":"Daily SQL Update","func":"msg.topic=\"INSERT OR REPLACE INTO sensor_aggr (epoch,device,sensor,value) VALUES(\"+msg.payload.dailydelta[msg.payload.dailydelta.length-1].epoch+\",'maplin','rain_daily',\"+msg.payload.dailydelta[msg.payload.dailydelta.length-1].delta+\");\";\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":890,"y":740,"wires":[["d8329cfc.3b17a","4d140d91.b52154"]]},{"id":"6925f6dd.5160a","type":"function","z":"c473a0c1.c75468","name":"Weekly SQL Update","func":"msg.topic=\"INSERT OR REPLACE INTO sensor_aggr (epoch,device,sensor,value) VALUES(\"+msg.payload.weeklydelta[msg.payload.weeklydelta.length-1].epoch+\",'maplin','rain_weekly',\"+msg.payload.weeklydelta[msg.payload.weeklydelta.length-1].delta+\");\";\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":900,"y":860,"wires":[["90416865.1b61c","7facd5a5.b37e9c"]]},{"id":"c7fb44e7.0e7d1","type":"inject","z":"c473a0c1.c75468","name":"","repeat":"","crontab":"02 00 * * 1","once":false,"onceDelay":"","topic":"weekly","payload":"","payloadType":"date","x":150,"y":700,"wires":[["319cd392.9843cc"]]},{"id":"f308ef97.4ed3b8","type":"inject","z":"c473a0c1.c75468","name":"","props":[{"p":"payload","v":"rainstat","vt":"global"},{"p":"topic","v":"","vt":"string"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"rainstat","payloadType":"global","x":950,"y":1200,"wires":[["afbc5e3b.7c404"]]},{"id":"afbc5e3b.7c404","type":"debug","z":"c473a0c1.c75468","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1150,"y":1200,"wires":[]},{"id":"8fd376b3.8b048","type":"link in","z":"c473a0c1.c75468","name":"kWhAccumulated rtl_433","links":["28caa636.ad69b2"],"x":75,"y":560,"wires":[["5cbe4259.7abf1c"]]},{"id":"c5859912.8d4b88","type":"debug","z":"c473a0c1.c75468","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":390,"y":520,"wires":[]},{"id":"5cbe4259.7abf1c","type":"change","z":"c473a0c1.c75468","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"reading","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":190,"y":560,"wires":[["c5859912.8d4b88","319cd392.9843cc"]]},{"id":"1df0d1ef.f15bfe","type":"influxdb out","z":"c473a0c1.c75468","influxdb":"93285a9.26cb8a8","name":"kWh Hourly","measurement":"rtl_433/Blueline_PowerCost_Monitor/kWh_hourly","precision":"","retentionPolicy":"","database":"database","precisionV18FluxV20":"ms","retentionPolicyV18Flux":"","org":"organisation","bucket":"bucket","x":1110,"y":620,"wires":[]},{"id":"d8329cfc.3b17a","type":"influxdb out","z":"c473a0c1.c75468","influxdb":"93285a9.26cb8a8","name":"kWh Daily","measurement":"rtl_433/Blueline_PowerCost_Monitor/kWh_daily","precision":"","retentionPolicy":"","database":"database","precisionV18FluxV20":"ms","retentionPolicyV18Flux":"","org":"organisation","bucket":"bucket","x":1100,"y":740,"wires":[]},{"id":"90416865.1b61c","type":"influxdb out","z":"c473a0c1.c75468","influxdb":"93285a9.26cb8a8","name":"kWh Weekly","measurement":"rtl_433/Blueline_PowerCost_Monitor/kWh_weekly","precision":"","retentionPolicy":"","database":"database","precisionV18FluxV20":"ms","retentionPolicyV18Flux":"","org":"organisation","bucket":"bucket","x":1110,"y":860,"wires":[]},{"id":"6b44aa1e.d0e494","type":"function","z":"c473a0c1.c75468","name":"PUD cost calculator","func":"//https://www.snopud.com/Site/Content/Documents/rates/electricrates_010121.pdf\n/*\neffective date $/kWh\n1 Oct 2017 0.10414\n1 Apr 2021 0.10118\n1 Apr 2022 0.09822\n1 Apr 2023 0.09527\n1 Apr 2024 0.09231\n1 Apr 2025 0.08935\n*/\n\n/*\nvar now = new Date(\"1/15/2021\");\nvar rate = -1;\n\n//var now = Date().getTime(); // 1501653935994\n//var from = new Date(\"02/08/2017\").getTime(); // gives 1486492200000\n//var to = new Date(\"05/08/2017\").getTime();\n\nif(now <= Date(\"1/4/2021\")) {\n rate = 0.10414;\n}\n\nelse if(now <= Date(\"1/4/2022\")) {\n rate = 0.10118;\n}\nelse if(now <= Date(\"1/4/2023\")) {\n rate = 0.09822;\n}\nelse if(now <= Date(\"1/4/2024\")) {\n rate = 0.09527;\n}\nelse if(now <= Date(\"1/4/2025\")) {\n rate = 0.08935;\n}\n\n//msg.payload = msg.payload * rate;\nmsg.payload = rate;\nreturn msg;\n*/\n\nconst now = new Date().getTime();\nnode.warn(now)\nvar rate = -1;\n\nif(now <= new Date(\"2021-4-1\").getTime()) {\n rate = 0.10414;\n}\nelse if(now <= new Date(\"2022-4-1\").getTime()) {\n rate = 0.10118;\n}\nelse if(now <= new Date(\"2023-4-1\").getTime()) {\n rate = 0.09822;\n}\nelse if(now <= new Date(\"2024-4-1\").getTime()) {\n rate = 0.09527;\n}\nelse if(now <= new Date(\"2025-4-1\").getTime()) {\n rate = 0.08935;\n}\n\nmsg.payload = msg.payload * rate;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1130,"y":660,"wires":[["63081499.452104","9f6a9114.8fc648"]]},{"id":"9f6a9114.8fc648","type":"influxdb out","z":"c473a0c1.c75468","influxdb":"93285a9.26cb8a8","name":"AccumulatedCost_hourly","measurement":"rtl_433/Blueline_PowerCost_Monitor/AccumulatedCost_hourly","precision":"","retentionPolicy":"","database":"database","precisionV18FluxV20":"ms","retentionPolicyV18Flux":"","org":"organisation","bucket":"bucket","x":1370,"y":660,"wires":[]},{"id":"63081499.452104","type":"debug","z":"c473a0c1.c75468","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1330,"y":620,"wires":[]},{"id":"4d140d91.b52154","type":"function","z":"c473a0c1.c75468","name":"PUD cost calculator","func":"//https://www.snopud.com/Site/Content/Documents/rates/electricrates_010121.pdf\n/*\neffective date $/kWh\n1 Oct 2017 0.10414\n1 Apr 2021 0.10118\n1 Apr 2022 0.09822\n1 Apr 2023 0.09527\n1 Apr 2024 0.09231\n1 Apr 2025 0.08935\n*/\n\n/*\nvar now = new Date(\"1/15/2021\");\nvar rate = -1;\n\n//var now = Date().getTime(); // 1501653935994\n//var from = new Date(\"02/08/2017\").getTime(); // gives 1486492200000\n//var to = new Date(\"05/08/2017\").getTime();\n\nif(now <= Date(\"1/4/2021\")) {\n rate = 0.10414;\n}\n\nelse if(now <= Date(\"1/4/2022\")) {\n rate = 0.10118;\n}\nelse if(now <= Date(\"1/4/2023\")) {\n rate = 0.09822;\n}\nelse if(now <= Date(\"1/4/2024\")) {\n rate = 0.09527;\n}\nelse if(now <= Date(\"1/4/2025\")) {\n rate = 0.08935;\n}\n\n//msg.payload = msg.payload * rate;\nmsg.payload = rate;\nreturn msg;\n*/\n\nconst now = new Date().getTime();\nnode.warn(now)\nvar rate = -1;\n\nif(now <= new Date(\"2021-4-1\").getTime()) {\n rate = 0.10414;\n}\nelse if(now <= new Date(\"2022-4-1\").getTime()) {\n rate = 0.10118;\n}\nelse if(now <= new Date(\"2023-4-1\").getTime()) {\n rate = 0.09822;\n}\nelse if(now <= new Date(\"2024-4-1\").getTime()) {\n rate = 0.09527;\n}\nelse if(now <= new Date(\"2025-4-1\").getTime()) {\n rate = 0.08935;\n}\n\nmsg.payload = msg.payload * rate;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1130,"y":780,"wires":[["2f65d0c1.67598","35918af8.7b724e"]]},{"id":"35918af8.7b724e","type":"influxdb out","z":"c473a0c1.c75468","influxdb":"93285a9.26cb8a8","name":"AccumulatedCost_daily","measurement":"rtl_433/Blueline_PowerCost_Monitor/AccumulatedCost_daily","precision":"","retentionPolicy":"","database":"database","precisionV18FluxV20":"ms","retentionPolicyV18Flux":"","org":"organisation","bucket":"bucket","x":1370,"y":780,"wires":[]},{"id":"2f65d0c1.67598","type":"debug","z":"c473a0c1.c75468","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1330,"y":740,"wires":[]},{"id":"7facd5a5.b37e9c","type":"function","z":"c473a0c1.c75468","name":"PUD cost calculator","func":"//https://www.snopud.com/Site/Content/Documents/rates/electricrates_010121.pdf\n/*\neffective date $/kWh\n1 Oct 2017 0.10414\n1 Apr 2021 0.10118\n1 Apr 2022 0.09822\n1 Apr 2023 0.09527\n1 Apr 2024 0.09231\n1 Apr 2025 0.08935\n*/\n\n/*\nvar now = new Date(\"1/15/2021\");\nvar rate = -1;\n\n//var now = Date().getTime(); // 1501653935994\n//var from = new Date(\"02/08/2017\").getTime(); // gives 1486492200000\n//var to = new Date(\"05/08/2017\").getTime();\n\nif(now <= Date(\"1/4/2021\")) {\n rate = 0.10414;\n}\n\nelse if(now <= Date(\"1/4/2022\")) {\n rate = 0.10118;\n}\nelse if(now <= Date(\"1/4/2023\")) {\n rate = 0.09822;\n}\nelse if(now <= Date(\"1/4/2024\")) {\n rate = 0.09527;\n}\nelse if(now <= Date(\"1/4/2025\")) {\n rate = 0.08935;\n}\n\n//msg.payload = msg.payload * rate;\nmsg.payload = rate;\nreturn msg;\n*/\n\nconst now = new Date().getTime();\nnode.warn(now)\nvar rate = -1;\n\nif(now <= new Date(\"2021-4-1\").getTime()) {\n rate = 0.10414;\n}\nelse if(now <= new Date(\"2022-4-1\").getTime()) {\n rate = 0.10118;\n}\nelse if(now <= new Date(\"2023-4-1\").getTime()) {\n rate = 0.09822;\n}\nelse if(now <= new Date(\"2024-4-1\").getTime()) {\n rate = 0.09527;\n}\nelse if(now <= new Date(\"2025-4-1\").getTime()) {\n rate = 0.08935;\n}\n\nmsg.payload = msg.payload * rate;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1130,"y":900,"wires":[["c204bda8.68d478","f0ee9503.01a6e8"]]},{"id":"f0ee9503.01a6e8","type":"influxdb out","z":"c473a0c1.c75468","influxdb":"93285a9.26cb8a8","name":"AccumulatedCost_weekly","measurement":"rtl_433/Blueline_PowerCost_Monitor/AccumulatedCost_weekly","precision":"","retentionPolicy":"","database":"database","precisionV18FluxV20":"ms","retentionPolicyV18Flux":"","org":"organisation","bucket":"bucket","x":1370,"y":900,"wires":[]},{"id":"c204bda8.68d478","type":"debug","z":"c473a0c1.c75468","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1330,"y":860,"wires":[]},{"id":"93285a9.26cb8a8","type":"influxdb","hostname":"127.0.0.1","port":"8086","protocol":"http","database":"sensors","name":"sensors","usetls":false,"tls":"","influxdbVersion":"1.x","url":"http://localhost:8086","rejectUnauthorized":true}]`
I'm seeing the following error though. It appears that the hourly etc nodes are not being processed correctly.