|
[{"id":"c4f163ca.1c882","type":"function","z":"a9289d4a.d3a0b","name":"Rain metering","func":"var global_name = \"rainstat\"; // 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();\n\nvar rainstat = global.get(global_name);\nif (rainstat===undefined) {\n rainstat = {};\n}\n\n// If the message is coming from sensor, save the current value\nif (msg.topic===\"rflink\") {\n if (msg.msg433.RAIN!==undefined) {\n context.set(\"RAIN\",msg.msg433.RAIN);\n msg.topic=\"reading\";\n }\n}\n\n// Do not process stats until we have a valid reading\nif (context.get(\"RAIN\")!==undefined) {\n\n // Update the hourly stats\n if (msg.topic===\"hourly\") {\n msg.topic=\"hourly\";\n // First update the historical readings\n if (rainstat.hourlyvalues===undefined) {\n // this is the first reading, create the array first\n rainstat.hourlyvalues = [];\n rainstat.hourlyvalues.push({epoch: current.getTime(), reading:context.get(\"RAIN\")});\n } else {\n if (rainstat.hourlyvalues.length<hourlysize-1) {\n // there is not enough history collected yet, add to the array\n rainstat.hourlyvalues.push({epoch: current.getTime(), reading:context.get(\"RAIN\")});\n } else {\n // the array is full need to shift values\n for (var i=1;i<rainstat.hourlyvalues.length;i++) {\n rainstat.hourlyvalues[i-1]=rainstat.hourlyvalues[i];\n }\n // add the current value to the end of the array\n rainstat.hourlyvalues[hourlysize-1]={epoch: current.getTime(), reading:context.get(\"RAIN\")};\n }\n }\n \n // Calculate the delta values\n rainstat.hourlydelta = [];\n if (rainstat.hourlyvalues.length>1) {\n // We need at least two readings\n for (var i=1;i<rainstat.hourlyvalues.length;i++) {\n var delta = Math.round((rainstat.hourlyvalues[i].reading - rainstat.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 rainstat.hourlydelta.push({epoch: rainstat.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 (rainstat.dailyvalues===undefined) {\n // this is the first reading, create the array first\n rainstat.dailyvalues = [];\n rainstat.dailyvalues.push({epoch: current.getTime(), reading:context.get(\"RAIN\")});\n } else {\n if (rainstat.dailyvalues.length<dailysize-1) {\n // there is not enough history collected yet, add to the array\n rainstat.dailyvalues.push({epoch: current.getTime(), reading:context.get(\"RAIN\")});\n } else {\n // the array is full need to shift values\n for (var i=1;i<rainstat.dailyvalues.length;i++) {\n rainstat.dailyvalues[i-1]=rainstat.dailyvalues[i];\n }\n // add the current value to the end of the array\n rainstat.dailyvalues[dailysize-1]={epoch: current.getTime(), reading:context.get(\"RAIN\")};\n }\n }\n \n // Calculate the delta values\n rainstat.dailydelta = [];\n if (rainstat.dailyvalues.length>1) {\n // We need at least two readings\n for (var i=1;i<rainstat.dailyvalues.length;i++) {\n var delta = Math.round((rainstat.dailyvalues[i].reading - rainstat.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 rainstat.dailydelta.push({epoch: rainstat.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 (rainstat.weeklyvalues===undefined) {\n // this is the first reading, create the array first\n rainstat.weeklyvalues = [];\n rainstat.weeklyvalues.push({epoch: current.getTime(), reading:context.get(\"RAIN\")});\n } else {\n if (rainstat.weeklyvalues.length<weeklysize-1) {\n // there is not enough history collected yet, add to the array\n rainstat.weeklyvalues.push({epoch: current.getTime(), reading:context.get(\"RAIN\")});\n } else {\n // the array is full need to shift values\n for (var i=1;i<rainstat.weeklyvalues.length;i++) {\n rainstat.weeklyvalues[i-1]=rainstat.weeklyvalues[i];\n }\n // add the current value to the end of the array\n rainstat.weeklyvalues[weeklysize-1]={epoch: current.getTime(), reading:context.get(\"RAIN\")};\n }\n }\n \n // Calculate the delta values\n rainstat.weeklydelta = [];\n if (rainstat.weeklyvalues.length>1) {\n // We need at least two readings\n for (var i=1;i<rainstat.weeklyvalues.length;i++) {\n var delta = Math.round((rainstat.weeklyvalues[i].reading - rainstat.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 rainstat.weeklydelta.push({epoch: rainstat.weeklyvalues[i].epoch, delta:delta});\n }\n }\n \n }\n\n\n // This week rainfall calculation\n if (rainstat.weeklyvalues!==undefined) {\n if (rainstat.weeklyvalues.length>0) {\n rainstat.thisweek = Math.round((context.get(\"RAIN\") - rainstat.weeklyvalues[rainstat.weeklyvalues.length-1].reading)*10)/10;\n if (rainstat.thisweek<0) {\n rainstat.thisweek = 0.0;\n }\n } else {\n rainstat.thisweek = 0.0;\n }\n }\n // Today rainfall calculation\n if (rainstat.dailyvalues!==undefined) {\n if (rainstat.dailyvalues.length>0) {\n rainstat.today = Math.round((context.get(\"RAIN\") - rainstat.dailyvalues[rainstat.dailyvalues.length-1].reading)*10)/10;\n if (rainstat.today<0) {\n rainstat.today = 0.0;\n }\n } else {\n rainstat.today = 0.0;\n }\n }\n // This hour rainfall calculation\n if (rainstat.hourlyvalues!==undefined) {\n if (rainstat.hourlyvalues.length>0) {\n rainstat.thishour = Math.round((context.get(\"RAIN\") - rainstat.hourlyvalues[rainstat.hourlyvalues.length-1].reading)*10)/10;\n if (rainstat.thishour<0) {\n rainstat.thishour = 0.0;\n }\n } else {\n rainstat.thishour = 0.0;\n }\n } \n \n // Store the updates\n global.set(global_name,rainstat);\n msg.payload = rainstat;\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,"x":1620,"y":200,"wires":[["e91b0036.c04d2","b87bdc60.5a221"]]},{"id":"2e21bbb7.f3b0d4","type":"inject","z":"a9289d4a.d3a0b","name":"","topic":"hourly","payload":"","payloadType":"date","repeat":"3600","crontab":"","once":false,"onceDelay":"","x":1370,"y":260,"wires":[["c4f163ca.1c882"]]},{"id":"e91b0036.c04d2","type":"debug","z":"a9289d4a.d3a0b","name":"","active":false,"console":"false","complete":"false","x":1850,"y":200,"wires":[]},{"id":"1f9cf1d1.272c7e","type":"inject","z":"a9289d4a.d3a0b","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":2180,"y":780,"wires":[["de96e720.7b9dd8"]]},{"id":"de96e720.7b9dd8","type":"function","z":"a9289d4a.d3a0b","name":"Delete history","func":"var rainstat = {};\nglobal.set(\"rainstat\",rainstat);\n","outputs":1,"noerr":0,"x":2380,"y":780,"wires":[[]]},{"id":"7f45e72a.3b59b8","type":"inject","z":"a9289d4a.d3a0b","name":"","topic":"daily","payload":"","payloadType":"date","repeat":"","crontab":"01 00 * * *","once":false,"onceDelay":"","x":1370,"y":300,"wires":[["c4f163ca.1c882"]]},{"id":"5e297958.0d96d8","type":"function","z":"a9289d4a.d3a0b","name":"Generate hourly graph","func":"//msg.payload = global.get(\"rainstat\"); //uncomment this for debugging\n// Skeleton data structure for the bar graph\nvar m={\n \"series\":[\"Hourly rainfall\"],\n \"data\":[[]],\n \"labels\":[]\n};\n\n// Transform the data\nif (msg.payload.hourlydelta!==undefined) {\n if (msg.payload.hourlydelta.length>0) {\n for (var i=0;i<msg.payload.hourlydelta.length;i++) {\n m.data[0].push(msg.payload.hourlydelta[i].delta);\n var d = new Date();\n d.setTime(msg.payload.hourlydelta[i].epoch-1000*60*60);\n var d2 = new Date();\n d2.setTime(msg.payload.hourlydelta[i].epoch);\n m.labels.push(d.getHours()+\"-\"+d2.getHours());\n }\n }\n}\n\n\nreturn {payload:[m]};\n\n/* sample data\n\nvar m={\n \"series\":[\"Daily rainfall\"],\n \"data\":[[5,3,6]],\n \"labels\":[\"D-3\",\"D-2\",\"D-1\"]\n};\n\n*/","outputs":1,"noerr":0,"x":2160,"y":360,"wires":[["d035184c.6b2d18"]]},{"id":"d41e4cfe.fc601","type":"function","z":"a9289d4a.d3a0b","name":"Generate daily graph","func":"function getGetOrdinal(n) {\n var s=[\"th\",\"st\",\"nd\",\"rd\"],\n v=n%100;\n return n+(s[(v-20)%10]||s[v]||s[0]);\n }\n\nvar dL = [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"];\nvar dS = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\n//msg.payload = global.get(\"rainstat\"); // uncomment this line if you want to debug\n// Skeleton data structure for the bar graph\nvar m={\n \"series\":[\"Daily rainfall\"],\n \"data\":[[]],\n \"labels\":[]\n};\n\n// Transform the data\nif (msg.payload.dailydelta!==undefined) {\n if (msg.payload.dailydelta.length>0) {\n for (var i=0;i<msg.payload.dailydelta.length;i++) {\n m.data[0].push(msg.payload.dailydelta[i].delta);\n var d = new Date();\n d.setTime(msg.payload.dailydelta[i].epoch-1000*60*60*24);\n m.labels.push(dL[d.getDay()]+\", \"+getGetOrdinal(d.getDate()));\n }\n }\n}\n\n\nreturn {payload:[m]};\n\n/* sample data\n\nvar m={\n \"series\":[\"Daily rainfall\"],\n \"data\":[[5,3,6]],\n \"labels\":[\"D-3\",\"D-2\",\"D-1\"]\n};\n\n*/","outputs":1,"noerr":0,"x":2160,"y":500,"wires":[["2d882ae5.f5b606"]]},{"id":"2d882ae5.f5b606","type":"ui_chart","z":"a9289d4a.d3a0b","name":"","group":"d5bfb431.21f7c8","order":13,"width":0,"height":0,"label":"Daily rainfall [mm]","chartType":"bar","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"no data","dot":false,"ymin":"","ymax":"","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":true,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"x":2470,"y":540,"wires":[["64c35a51.d618c4"],[]]},{"id":"9457d83b.d28268","type":"inject","z":"a9289d4a.d3a0b","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":1860,"y":500,"wires":[["d41e4cfe.fc601"]]},{"id":"d035184c.6b2d18","type":"ui_chart","z":"a9289d4a.d3a0b","name":"","group":"d5bfb431.21f7c8","order":11,"width":0,"height":0,"label":"Hourly rainfall [mm]","chartType":"bar","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"no data","dot":false,"ymin":"","ymax":"","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":true,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"x":2470,"y":400,"wires":[["bda1bd38.4f974"],[]]},{"id":"70478835.ea9f38","type":"inject","z":"a9289d4a.d3a0b","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":1860,"y":360,"wires":[["5e297958.0d96d8"]]},{"id":"b87bdc60.5a221","type":"switch","z":"a9289d4a.d3a0b","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":1850,"y":260,"wires":[["7ea5cf9a.72897","3a9afab4.8b1fa6","baffe812.b0adb8"],["5e297958.0d96d8","b561ecc5.b768f"],["d41e4cfe.fc601","2f5f5d47.de27f2"],["b0de5ed4.2de47","40be628a.8ca5ac"]]},{"id":"7ea5cf9a.72897","type":"ui_text","z":"a9289d4a.d3a0b","group":"d5bfb431.21f7c8","order":10,"width":0,"height":0,"name":"","label":"This hour's rainfall","format":"{{msg.payload.thishour}} mm","layout":"row-spread","x":2310,"y":180,"wires":[]},{"id":"3a9afab4.8b1fa6","type":"ui_text","z":"a9289d4a.d3a0b","group":"d5bfb431.21f7c8","order":12,"width":0,"height":0,"name":"","label":"Today's rainfall","format":"{{msg.payload.today}} mm","layout":"row-spread","x":2300,"y":220,"wires":[]},{"id":"ef518175.a2257","type":"inject","z":"a9289d4a.d3a0b","name":"Startup","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"x":1940,"y":400,"wires":[["1ab80f69.de7111"]]},{"id":"1ab80f69.de7111","type":"file in","z":"a9289d4a.d3a0b","name":"Chart dump","filename":"/home/pi/charts/hourly_rainfall.dump","format":"utf8","sendError":true,"x":2110,"y":400,"wires":[["7851fb4a.697884"]]},{"id":"7851fb4a.697884","type":"json","z":"a9289d4a.d3a0b","name":"","x":2270,"y":400,"wires":[["d035184c.6b2d18"]]},{"id":"bda1bd38.4f974","type":"file","z":"a9289d4a.d3a0b","name":"Chart dump","filename":"/home/pi/charts/hourly_rainfall.dump","appendNewline":true,"createDir":false,"overwriteFile":"true","x":2679,"y":401,"wires":[]},{"id":"8c8a5b8b.8c4648","type":"inject","z":"a9289d4a.d3a0b","name":"Startup","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"x":1940,"y":540,"wires":[["6c469bf8.9f1c44"]]},{"id":"6c469bf8.9f1c44","type":"file in","z":"a9289d4a.d3a0b","name":"Chart dump","filename":"/home/pi/charts/daily_rainfall.dump","format":"utf8","sendError":true,"x":2110,"y":540,"wires":[["fb1b1dbf.30c7b"]]},{"id":"fb1b1dbf.30c7b","type":"json","z":"a9289d4a.d3a0b","name":"","x":2270,"y":540,"wires":[["2d882ae5.f5b606"]]},{"id":"64c35a51.d618c4","type":"file","z":"a9289d4a.d3a0b","name":"Chart dump","filename":"/home/pi/charts/daily_rainfall.dump","appendNewline":true,"createDir":false,"overwriteFile":"true","x":2679,"y":541,"wires":[]},{"id":"b561ecc5.b768f","type":"function","z":"a9289d4a.d3a0b","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,"x":2150,"y":320,"wires":[["b5a0a403.37d298"]]},{"id":"2f5f5d47.de27f2","type":"function","z":"a9289d4a.d3a0b","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,"x":2150,"y":460,"wires":[["26ed52a6.8f993e"]]},{"id":"baffe812.b0adb8","type":"ui_text","z":"a9289d4a.d3a0b","group":"d5bfb431.21f7c8","order":14,"width":0,"height":0,"name":"","label":"This week's rainfall","format":"{{msg.payload.thisweek}} mm","layout":"row-spread","x":2310,"y":260,"wires":[]},{"id":"40be628a.8ca5ac","type":"function","z":"a9289d4a.d3a0b","name":"Generate weekly graph","func":"function getGetOrdinal(n) {\n var s=[\"th\",\"st\",\"nd\",\"rd\"],\n v=n%100;\n return n+(s[(v-20)%10]||s[v]||s[0]);\n }\n\nvar mL = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];\nvar mS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'June', 'July', 'Aug', 'Sept', 'Oct', 'Nov', 'Dec'];\n//msg.payload = global.get(\"rainstat\"); // uncomment this line for debugging\n// Skeleton data structure for the bar graph\nvar m={\n \"series\":[\"Weekly rainfall\"],\n \"data\":[[]],\n \"labels\":[]\n};\n\n// Transform the data\nif (msg.payload.weeklydelta!==undefined) {\n if (msg.payload.weeklydelta.length>0) {\n for (var i=0;i<msg.payload.weeklydelta.length;i++) {\n m.data[0].push(msg.payload.weeklydelta[i].delta);\n var d = new Date();\n d.setTime(msg.payload.weeklydelta[i].epoch-1000*60*60*24*7);\n m.labels.push(\"w/c \"+getGetOrdinal(d.getDate())+\" of \"+mL[d.getMonth()]);\n }\n }\n}\n\n\nreturn {payload:[m]};\n\n/* sample data\n\nvar m={\n \"series\":[\"Daily rainfall\"],\n \"data\":[[5,3,6]],\n \"labels\":[\"D-3\",\"D-2\",\"D-1\"]\n};\n\n*/","outputs":1,"noerr":0,"x":2170,"y":640,"wires":[["ed29e60.1f04118"]]},{"id":"ed29e60.1f04118","type":"ui_chart","z":"a9289d4a.d3a0b","name":"","group":"d5bfb431.21f7c8","order":15,"width":0,"height":0,"label":"Weekly rainfall [mm]","chartType":"bar","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"no data","dot":false,"ymin":"","ymax":"","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":true,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"x":2480,"y":680,"wires":[["abd070eb.e529e"],[]]},{"id":"3b3a54ec.6db53c","type":"inject","z":"a9289d4a.d3a0b","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":1860,"y":640,"wires":[["40be628a.8ca5ac"]]},{"id":"b632948.206b968","type":"inject","z":"a9289d4a.d3a0b","name":"Startup","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"x":1940,"y":680,"wires":[["22fcc6d6.ea002a"]]},{"id":"22fcc6d6.ea002a","type":"file in","z":"a9289d4a.d3a0b","name":"Chart dump","filename":"/home/pi/charts/weekly_rainfall.dump","format":"utf8","sendError":true,"x":2110,"y":680,"wires":[["6cf2e833.ec5ae8"]]},{"id":"6cf2e833.ec5ae8","type":"json","z":"a9289d4a.d3a0b","name":"","x":2270,"y":680,"wires":[["ed29e60.1f04118"]]},{"id":"abd070eb.e529e","type":"file","z":"a9289d4a.d3a0b","name":"Chart dump","filename":"/home/pi/charts/weekly_rainfall.dump","appendNewline":true,"createDir":false,"overwriteFile":"true","x":2679,"y":681,"wires":[]},{"id":"b0de5ed4.2de47","type":"function","z":"a9289d4a.d3a0b","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,"x":2160,"y":600,"wires":[["f65d1e22.029cd"]]},{"id":"517c0724.afd378","type":"inject","z":"a9289d4a.d3a0b","name":"","topic":"weekly","payload":"","payloadType":"date","repeat":"","crontab":"02 00 * * 1","once":false,"onceDelay":"","x":1370,"y":340,"wires":[["c4f163ca.1c882"]]},{"id":"b5a0a403.37d298","type":"sqlite","z":"a9289d4a.d3a0b","mydb":"1c25415d.b8427f","name":"Node Red DB","x":2380,"y":320,"wires":[[]]},{"id":"26ed52a6.8f993e","type":"sqlite","z":"a9289d4a.d3a0b","mydb":"1c25415d.b8427f","name":"Node Red DB","x":2380,"y":460,"wires":[[]]},{"id":"f65d1e22.029cd","type":"sqlite","z":"a9289d4a.d3a0b","mydb":"1c25415d.b8427f","name":"Node Red DB","x":2380,"y":600,"wires":[[]]},{"id":"ee3be947.55d498","type":"inject","z":"a9289d4a.d3a0b","name":"","topic":"","payload":"rainstat","payloadType":"global","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":2170,"y":840,"wires":[["753a6afc.b518e4"]]},{"id":"753a6afc.b518e4","type":"debug","z":"a9289d4a.d3a0b","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":2370,"y":840,"wires":[]},{"id":"d5bfb431.21f7c8","type":"ui_group","z":"","name":"Maplin Weather Station","tab":"7489c36d.a74f5c","order":1,"disp":true,"width":"6"},{"id":"1c25415d.b8427f","type":"sqlitedb","z":0,"db":"/home/pi/sqlite/nodered"},{"id":"7489c36d.a74f5c","type":"ui_tab","z":"","name":"RFLink","icon":"settings_remote","order":19}] |