Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- [{"id":"9b4dbc77.3dc54","type":"tab","label":"Brewfather","disabled":false,"info":""},{"id":"bfb81e59.ff7c6","type":"tab","label":"Garasje","disabled":false,"info":""},{"id":"97d46aa8.590d48","type":"tab","label":"whois","disabled":false,"info":""},{"id":"6dc4c6ac.83d2b8","type":"tab","label":"BC","disabled":false,"info":""},{"id":"1649e3f6.45d0ec","type":"subflow","name":"Process Simulation","info":"","in":[{"x":37,"y":103,"wires":[{"id":"48afb9b1.cc79c8"}]}],"out":[{"x":728.5,"y":294,"wires":[{"id":"192e13d6.0a382c","port":0}]}]},{"id":"673d2f6.8407cd","type":"subflow","name":"Subflow 1","info":"","in":[],"out":[{"x":340,"y":80,"wires":[{"id":"10dfe4c4.d0508b","port":0}]}]},{"id":"eb1127af.550128","type":"key-value-store","z":"","filepath":"store1.json","namespace":"","name":""},{"id":"a12977.e4f5b688","type":"mqtt-broker","z":"","name":"","broker":"192.168.88.38","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthRetain":"false","birthPayload":"","closeTopic":"","closeRetain":"false","closePayload":"","willTopic":"","willQos":"0","willRetain":"false","willPayload":""},{"id":"f0ab3a53.fdd7a8","type":"ui_base","z":"","theme":{"name":"theme-light","lightTheme":{"default":"#0094CE","baseColor":"#0094CE","baseFont":"-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif","edited":true,"reset":false},"darkTheme":{"default":"#097479","baseColor":"#097479","baseFont":"-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif","edited":false},"customTheme":{"name":"Untitled Theme 1","default":"#4B7930","baseColor":"#4B7930","baseFont":"-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif"},"themeState":{"base-color":{"default":"#0094CE","value":"#0094CE","edited":false},"page-titlebar-backgroundColor":{"value":"#0094CE","edited":false},"page-backgroundColor":{"value":"#fafafa","edited":false},"page-sidebar-backgroundColor":{"value":"#ffffff","edited":false},"group-textColor":{"value":"#1bbfff","edited":false},"group-borderColor":{"value":"#ffffff","edited":false},"group-backgroundColor":{"value":"#ffffff","edited":false},"widget-textColor":{"value":"#111111","edited":false},"widget-backgroundColor":{"value":"#0094ce","edited":false},"widget-borderColor":{"value":"#ffffff","edited":false},"base-font":{"value":"-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif"}},"angularTheme":{"primary":"indigo","accents":"blue","warn":"red","background":"grey"}},"site":{"name":"Node-RED Dashboard","hideToolbar":"false","allowSwipe":"false","lockMenu":"false","allowTempTheme":"true","dateFormat":"DD/MM/YYYY","sizes":{"sx":48,"sy":48,"gx":6,"gy":6,"cx":6,"cy":6,"px":0,"py":0}}},{"id":"efa09baa.c93168","type":"ui_tab","z":"","name":"Home","icon":"dashboard","disabled":false,"hidden":true},{"id":"4e7e5911.c33cb8","type":"ui_group","z":"","name":"default","tab":"efa09baa.c93168","order":1,"disp":false,"width":"27","collapse":false},{"id":"6b19cfc5.22db6","type":"modbus-client","z":"","name":"","clienttype":"tcp","bufferCommands":true,"stateLogEnabled":false,"queueLogEnabled":false,"tcpHost":"192.168.88.85","tcpPort":"502","tcpType":"TPC-RTU-BUFFERED","serialPort":"/dev/ttyUSB","serialType":"RTU-BUFFERD","serialBaudrate":"9600","serialDatabits":"8","serialStopbits":"1","serialParity":"none","serialConnectionDelay":"100","unit_id":"","commandDelay":"1","clientTimeout":"1000","reconnectOnTimeout":true,"reconnectTimeout":"2000","parallelUnitIdsAllowed":true},{"id":"445c05cf.41736c","type":"blynk-ws-client","z":"","name":"Roomtemp","path":"ws://blynk-cloud.com/websockets","key":"d-6jb2u_ohwit0qU0PxxwN0npAYwa0KT","dbg_all":false,"dbg_read":false,"dbg_write":false,"dbg_notify":false,"dbg_mail":false,"dbg_prop":false,"dbg_sync":false,"dbg_bridge":false,"dbg_low":false,"dbg_pins":"","multi_cmd":false,"proxy_type":"no","proxy_url":"","enabled":true},{"id":"63a9af38.0679d","type":"mqtt-broker","z":"","name":"","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"ff12ede2.fff3b","type":"influxdb","z":"","hostname":"192.168.88.232","port":"8086","protocol":"http","database":"brewery","name":"","usetls":false,"tls":"","influxdbVersion":"1.x"},{"id":"a9cb6e6b.36fa4","type":"blynk-ws-client","z":"","name":"Roomtemp","path":"ws://blynk-cloud.com/websockets","key":"d-6jb2u_ohwit0qU0PxxwN0npAYwa0KT","dbg_all":false,"dbg_read":false,"dbg_write":false,"dbg_notify":false,"dbg_mail":false,"dbg_prop":false,"dbg_sync":false,"dbg_bridge":false,"dbg_low":false,"dbg_pins":"","multi_cmd":false,"proxy_type":"no","proxy_url":"","enabled":true},{"id":"e54e7367.6f767","type":"http in","z":"9b4dbc77.3dc54","name":"","url":"/brewfather","method":"post","upload":false,"swaggerDoc":"","x":80,"y":120,"wires":[["4f5df3fb.e58f6c","50c06659.71b498","4ac47708.2b8e38","460946f3.dcf408"]]},{"id":"733a50b8.48292","type":"function","z":"9b4dbc77.3dc54","name":"BF to BC","func":"//flow.set('recipe' , msg.payload.recipe.fermentation)\n//flow.set('fbeername' , msg.payload.recipe.name)\n\nfunction numberDes(a,b) {\n return b-a;\n }\n \nfunction stringsort(b,a) {\n return (Number(a.match(/(\\d+)/g)[0]) - Number((b.match(/(\\d+)/g)[0])));\n}\n \nfunction time_convert(num)\n { \n var hours = Math.floor(num / 60); \n var minutes = num % 60;\n return + hours + \":\" + minutes + \":00\"; \n}\nvar hopstandhoptime=[];\nvar hopstandhopname=[];\nvar hopstandhopamount=[];\nvar hopstand\nvar hopstandtemp\nif (msg.payload.recipe.hops.length > 0){\n if (msg.payload.recipe.hopStandMinutes > 0) {\n hopstand = true\n hopstandtemp = msg.payload.recipe.avgWeightedHopstandTemp\n for(var x=0; x<msg.payload.recipe.hops.length; x++){\n if (msg.payload.recipe.hops[x].use == \"Aroma\") {\n hopstandhoptime.push(msg.payload.recipe.hops[x].time)\n hopstandhopname.push(msg.payload.recipe.hops[x].name)\n hopstandhopamount.push(msg.payload.recipe.hops[x].amount)\n }\n }\n \n }\n else {\n hopstandtemp = 0\n hopstand = false\n }\n}\n\nconst {\n dupstand\n} = hopstandhoptime.reduce(\n (acc, curr) => {\n acc.items[curr] = acc.items[curr] ? acc.items[curr] += 1 : 1\n if (acc.items[curr] === 2) acc.dupstand.push(curr)\n return acc\n }, {\n items: {},\n dupstand: []\n }\n)\n\nfor (x= 0; x<hopstandhoptime.length;x++){\n hopstandhopname[x] = hopstandhopamount[x]+\"g \"+hopstandhopname[x]\n}\n\n\nif (dupstand.length > 0) {\nfor (var i = 0; i<dupstand.length; i++) {\n for (x = (hopstandhoptime.indexOf(dupstand[i])); x < hopstandhoptime.lastIndexOf(dupstand[i]); x++) {\n hopstandhopname[hopstandhoptime.indexOf(dupstand[i])] += \" and \"+ hopstandhopname[x+1] \n delete hopstandhopname[x+1]\n delete hopstandhoptime[x+1]\n }\n} \n \n}\n\nfor (i=0; i<hopstandhoptime.length; i++) {\n if (hopstandhoptime[i] == null) {\n hopstandhoptime.splice(i,1);\n hopstandhopname.splice(i,1);\n i -= 1;\n }\n}\nfor (i=0; i<hopstandhoptime.length; i++) {\n hopstandhopname[i] = hopstandhoptime[i]+\"min \"+ hopstandhopname[i]\n}\n\nhopstandhoptime.sort(numberDes);\nhopstandhopname.sort(stringsort);\n\n\nhopstandhoptime.push(0,0,0,0,0,0,0,0,0,0)\nhopstandhoptime.length = 5\nhopstandhopname.push(\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\")\nhopstandhopname.length = 5\n\nvar firstwort\nvar firstworthopname=[];\nvar firstworthopamount=[];\nif (msg.payload.recipe.hops.length > 0){\n if (msg.payload.recipe.hops[0].use == \"First Wort\") {\n firstwort = true\n for( x=0; x<msg.payload.recipe.hops.length; x++){\n if (msg.payload.recipe.hops[x].use == \"First Wort\") {\n firstworthopname.push(msg.payload.recipe.hops[x].name)\n firstworthopamount.push(msg.payload.recipe.hops[x].amount)\n }\n }\n for (x= 0; x<firstworthopname.length;x++){\n firstworthopname[x] = firstworthopamount[x]+\"g \"+firstworthopname[x]\n } \n if (firstworthopname.length > 1) {\n for (x = 1; x <firstworthopname.length; x++) {\n firstworthopname[0] += \" and \"+ firstworthopname[x] \n //delete firstworthopname[x+1]\n }\n //for (i=0; i<firstworthopname.length; i++) {\n // if (firstworthopname[i] === null) {\n // firstworthopname.splice(i,1);\n // i -= 1;\n // } \n //}\n \n }\n }\n else {\n firstwort = false\n}\n //else {\n //firstwort = false\n }\n\n\nvar boilhoptime=[];\nvar boilhopname=[];\nvar boilhopamount=[];\nif (msg.payload.recipe.hops.length > 0){\nfor( x=0;x<msg.payload.recipe.hops.length;x++){\n if (msg.payload.recipe.hops[x].use == \"Boil\") {\n boilhoptime.push(msg.payload.recipe.hops[x].time);\n boilhopname.push(msg.payload.recipe.hops[x].name);\n boilhopamount.push(msg.payload.recipe.hops[x].amount);\n }\n} \n}\nif (msg.payload.batchMiscs.length > 0) {\n for ( x=0;x<msg.payload.batchMiscs.length;x++){\n if (msg.payload.batchMiscs[x].use == \"Boil\") {\n boilhoptime.push(msg.payload.batchMiscs[x].time)\n boilhopname.push(msg.payload.batchMiscs[x].name)\n boilhopamount.push(msg.payload.batchMiscs[x].amount)\n }\n }\n}\n\nconst {\n dup\n} = boilhoptime.reduce(\n (acc, curr) => {\n acc.items[curr] = acc.items[curr] ? acc.items[curr] += 1 : 1\n if (acc.items[curr] === 2) acc.dup.push(curr)\n return acc\n }, {\n items: {},\n dup: []\n }\n)\n\nfor (x= 0; x<boilhoptime.length;x++){\n boilhopname[x] = boilhopamount[x]+\"g \"+boilhopname[x]\n}\n\nif (dup.length > 0) {\nfor (var i = 0; i<dup.length; i++) {\n for (x = (boilhoptime.indexOf(dup[i])); x < boilhoptime.lastIndexOf(dup[i]); x++) {\n boilhopname[boilhoptime.indexOf(dup[i])] += \" and \"+ boilhopname[x+1] \n delete boilhopname[x+1]\n delete boilhoptime[x+1]\n }\n} \n}\n\nfor (i=0; i<boilhoptime.length; i++) {\n if (boilhoptime[i] == null) {\n boilhoptime.splice(i,1);\n boilhopname.splice(i,1);\n i -= 1;\n }\n}\nfor (i=0; i<boilhoptime.length; i++) {\n boilhopname[i] = boilhoptime[i]+\"min \"+ boilhopname[i]\n}\n\nboilhoptime.sort(numberDes);\nboilhopname.sort(stringsort);\n\n\nboilhoptime.push(0,0,0,0,0,0,0,0,0,0)\nboilhoptime.length = 10\nboilhopname.push(\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\")\nboilhopname.length = 10\n\nvar mashtime=[];\nfor(var y=0;y<msg.payload.mashStepsCount;y++){\n mashtime[y]= msg.payload.recipe.mash.steps[y].stepTime;\n }\nmashtime.push(0,0,0,0,0);\nmashtime.length = 5\n\nvar mashsteps = msg.payload.mashStepsCount - 1;\nvar mashtemp=[];\nfor(var z=0;z<msg.payload.mashStepsCount;z++){\n mashtemp[z]= msg.payload.recipe.mash.steps[z].stepTemp;\n }\nmashtemp.push(mashtemp[mashsteps], mashtemp[mashsteps], mashtemp[mashsteps], mashtemp[mashsteps], mashtemp[mashsteps], mashtemp[mashsteps])\nmashtemp.length = 6\n\nmsg.payload = [ \n\n{ \"Name\": \"Preboil volume\", \"Value\": msg.payload.recipe.boilSize } , \n{ \"Name\": \"HLT fillvolume\" , \"Value\": msg.payload.recipe.data.hltWaterAmount } , \n{ \"Name\": \"Sparge volume\" , \"Value\": msg.payload.recipe.data.spargeWaterAmount } , \n{ \"Name\": \"Strike temp\" , \"Value\": msg.payload.recipe.data.strikeTemp } , \n{ \"Name\": \"Mash volume\" , \"Value\": msg.payload.recipe.data.mashWaterAmount } , \n{ \"Name\": \"Mash temp\" , \"Value\": mashtemp[0] } ,\n{ \"Name\": \"Mash temp1\" , \"Value\": mashtemp[1] } , \n{ \"Name\": \"Mash temp2\" , \"Value\": mashtemp[2] } ,\n{ \"Name\": \"Mash temp3\" , \"Value\": mashtemp[3] } ,\n{ \"Name\": \"Mash temp4\" , \"Value\": mashtemp[4] } ,\n{ \"Name\": \"Mash temp5\" , \"Value\": mashtemp[5] } ,\n{ \"Name\": \"Mash time1\" , \"Value\": time_convert(mashtime[0]) } ,\n{ \"Name\": \"Mash time2\" , \"Value\": time_convert(mashtime[1]) } ,\n{ \"Name\": \"Mash time3\" , \"Value\": time_convert(mashtime[2]) } ,\n{ \"Name\": \"Mash time4\" , \"Value\": time_convert(mashtime[3]) } ,\n{ \"Name\": \"Mash time5\" , \"Value\": time_convert(mashtime[4]) } ,\n{ \"Name\": \"Hop time0\" , \"Value\": time_convert(boilhoptime[0]) } ,\n{ \"Name\": \"Hop time1\" , \"Value\": time_convert(boilhoptime[1]) } ,\n{ \"Name\": \"Hop time2\" , \"Value\": time_convert(boilhoptime[2]) } ,\n{ \"Name\": \"Hop time3\" , \"Value\": time_convert(boilhoptime[3]) } ,\n{ \"Name\": \"Hop time4\" , \"Value\": time_convert(boilhoptime[4]) } ,\n{ \"Name\": \"Hop time5\" , \"Value\": time_convert(boilhoptime[5]) } ,\n{ \"Name\": \"Hop time6\" , \"Value\": time_convert(boilhoptime[6]) } ,\n{ \"Name\": \"Hop time7\" , \"Value\": time_convert(boilhoptime[7]) } ,\n{ \"Name\": \"Hop time8\" , \"Value\": time_convert(boilhoptime[8]) } ,\n{ \"Name\": \"Hop time9\" , \"Value\": time_convert(boilhoptime[9]) } ,\n{ \"Name\": \"Boilhopname0\" , \"Value\": boilhopname[0] } ,\n{ \"Name\": \"Boilhopname1\" , \"Value\": boilhopname[1] } ,\n{ \"Name\": \"Boilhopname2\" , \"Value\": boilhopname[2] } ,\n{ \"Name\": \"Boilhopname3\" , \"Value\": boilhopname[3] } ,\n{ \"Name\": \"Boilhopname4\" , \"Value\": boilhopname[4] } ,\n{ \"Name\": \"Boilhopname5\" , \"Value\": boilhopname[5] } ,\n{ \"Name\": \"Boilhopname6\" , \"Value\": boilhopname[6] } ,\n{ \"Name\": \"Boilhopname7\" , \"Value\": boilhopname[7] } ,\n{ \"Name\": \"Boilhopname8\" , \"Value\": boilhopname[8] } ,\n{ \"Name\": \"Boilhopname9\" , \"Value\": boilhopname[9] } ,\n{ \"Name\": \"Boilsteps\" , \"Value\": msg.payload.boilSteps.length } ,\n{ \"Name\": \"Hopstandtime0\" , \"Value\": time_convert(hopstandhoptime[0])},\n//{ \"Name\": \"Hopstandtime1\" , \"Value\": time_convert(hopstandhoptime[1])},\n//{ \"Name\": \"Hopstandtime2\" , \"Value\": time_convert(hopstandhoptime[2])},\n//{ \"Name\": \"Hopstandtime3\" , \"Value\": time_convert(hopstandhoptime[3])},\n//{ \"Name\": \"Hopstandtime4\" , \"Value\": time_convert(hopstandhoptime[4])},\n{ \"Name\": \"Hopstandhopname0\" , \"Value\": hopstandhopname[0]},//String(hopstandhopamount[0]) +\"g\" +\" \" +String(hopstandhopname[0]) } ,\n//{ \"Name\": \"Hopstandhopname2\" , \"Value\": hopstandhopname[1]},//String(hopstandhopamount[1]) +\"g\" +\" \" +String(hopstandhopname[1]) } ,\n//{ \"Name\": \"Hopstandhopname3\" , \"Value\": hopstandhopname[2]},//String(hopstandhopamount[2]) +\"g\" +\" \" +String(hopstandhopname[2]) } ,\n//{ \"Name\": \"Hopstandhopname4\" , \"Value\": hopstandhopname[3]},//String(hopstandhopamount[3]) +\"g\" +\" \" +String(hopstandhopname[3]) } ,\n//{ \"Name\": \"Hopstandhopname5\" , \"Value\": hopstandhopname[4]},//String(hopstandhopamount[4]) +\"g\" +\" \" +String(hopstandhopname[4]) } ,\n{ \"Name\": \"Hopstand\" , \"Value\": hopstand } ,\n{ \"Name\": \"Boil time\" , \"Value\": time_convert(msg. payload.recipe.boilTime) } ,\n{ \"Name\": \"Hopstand temp\" , \"Value\": hopstandtemp } ,\n{ \"Name\": \"First wort\" , \"Value\": firstwort } ,\n{ \"Name\": \"Status\" , \"Value\": new Date().toDateString()+\" \"+new Date().getHours()+\":\"+new Date().getMinutes()+\" \" +\"#\"+msg.topic+\" \"+msg.payload.recipe.name }\n\n];\n\nreturn msg;\n","outputs":1,"noerr":0,"x":660,"y":60,"wires":[["c1fd8caf.51cb2","50299b6d.aeb604"]]},{"id":"c1fd8caf.51cb2","type":"http request","z":"9b4dbc77.3dc54","name":"","method":"PUT","ret":"txt","paytoqs":false,"url":"http://192.168.77.246:8000/globals","tls":"","persist":false,"proxy":"","authType":"","x":870,"y":60,"wires":[[]]},{"id":"4f5df3fb.e58f6c","type":"http response","z":"9b4dbc77.3dc54","name":"","statusCode":"200","headers":{},"x":300,"y":140,"wires":[]},{"id":"33fc917b.85563e","type":"key-value-write","z":"9b4dbc77.3dc54","store":"eb1127af.550128","action":"set","key":"","keyvalue":"","name":"","x":510,"y":60,"wires":[["733a50b8.48292"]]},{"id":"50c06659.71b498","type":"change","z":"9b4dbc77.3dc54","name":"set batchnumber","rules":[{"t":"set","p":"topic","pt":"msg","to":"$string(payload.batchNo)\t","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":330,"y":60,"wires":[["33fc917b.85563e"]]},{"id":"4ac47708.2b8e38","type":"debug","z":"9b4dbc77.3dc54","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":310,"y":220,"wires":[]},{"id":"460946f3.dcf408","type":"http request","z":"9b4dbc77.3dc54","name":"","method":"POST","ret":"txt","paytoqs":false,"url":"http://192.168.88.38:1880/brewfather","tls":"","persist":false,"proxy":"","authType":"","x":310,"y":180,"wires":[[]]},{"id":"50299b6d.aeb604","type":"debug","z":"9b4dbc77.3dc54","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":870,"y":100,"wires":[]},{"id":"24a79051.bcdc9","type":"function","z":"1649e3f6.45d0ec","name":"30 sec RC + 20","func":"// Applies a simple RC low pass filter to incoming payload values\nvar tc = 30*1000; // time constant in milliseconds\n\nvar lastValue = context.get('lastValue');\nif (typeof lastValue == \"undefined\") lastValue = msg.payload;\nvar lastTime = context.get('lastTime') || null;\nvar now = new Date();\nvar currentValue = msg.payload;\nif (lastTime === null) {\n // first time through\n newValue = currentValue;\n} else {\n var dt = now - lastTime;\n var newValue;\n \n if (dt > 0) {\n var dtotc = dt / tc;\n newValue = lastValue * (1 - dtotc) + currentValue * dtotc;\n } else {\n // no time has elapsed leave output the same as last time\n newValue = lastValue;\n }\n}\ncontext.set('lastValue', newValue);\ncontext.set('lastTime', now);\n\nmsg.payload = newValue + 20;\nreturn msg;","outputs":1,"noerr":0,"x":626.5,"y":207,"wires":[["192e13d6.0a382c"]]},{"id":"396a9a21.d8af36","type":"inject","z":"1649e3f6.45d0ec","name":"Inject -0.2 at start","topic":"","payload":"-0.2","payloadType":"num","repeat":"","crontab":"","once":true,"x":134.5,"y":30,"wires":[["48afb9b1.cc79c8"]]},{"id":"a94fff69.5ca7e","type":"function","z":"1649e3f6.45d0ec","name":"10 sec RC","func":"// Applies a simple RC low pass filter to incoming payload values\nvar tc = 10*1000; // time constant in milliseconds\n\nvar lastValue = context.get('lastValue');\nif (typeof lastValue == \"undefined\") lastValue = msg.payload;\nvar lastTime = context.get('lastTime') || null;\nvar now = new Date();\nvar currentValue = msg.payload;\nif (lastTime === null) {\n // first time through\n newValue = currentValue;\n} else {\n var dt = now - lastTime;\n var newValue;\n \n if (dt > 0) {\n var dtotc = dt / tc;\n newValue = lastValue * (1 - dtotc) + currentValue * dtotc;\n } else {\n // no time has elapsed leave output the same as last time\n newValue = lastValue;\n }\n}\ncontext.set('lastValue', newValue);\ncontext.set('lastTime', now);\n\nmsg.payload = newValue;\nreturn msg;","outputs":1,"noerr":0,"x":451,"y":207,"wires":[["24a79051.bcdc9"]]},{"id":"48afb9b1.cc79c8","type":"delay","z":"1649e3f6.45d0ec","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":268,"y":104,"wires":[["470fdbcb.1ce384"]]},{"id":"bb1060b6.259cb","type":"function","z":"1649e3f6.45d0ec","name":"2 msg transport delay","func":"// stores messages in a fifo until the specified number have been received, \n// then releases them as new messages are received.\n// during the filling phase the earliest message is passed on each time \n// a message is received, but it is also left in the fifo\nvar fifoMaxLength = 2;\nvar fifo = context.get('fifo') || [];\n// push the new message onto the top of the array, messages are shifted down and\n// drop off the front\nvar length = fifo.push(msg); // returns new length\nif (length > fifoMaxLength) {\n newMsg = fifo.shift();\n} else {\n // not full yet, make a copy of the msg and pass it on\n var newMsg = JSON.parse(JSON.stringify(fifo[0]));\n}\ncontext.set('fifo', fifo);\nreturn newMsg;","outputs":1,"noerr":0,"x":258,"y":208,"wires":[["a94fff69.5ca7e"]]},{"id":"192e13d6.0a382c","type":"function","z":"1649e3f6.45d0ec","name":"Clear all except payload","func":"msg2 = {payload: msg.payload};\nreturn msg2;","outputs":1,"noerr":0,"x":545,"y":293,"wires":[[]]},{"id":"470fdbcb.1ce384","type":"range","z":"1649e3f6.45d0ec","minin":"0","maxin":"1","minout":"0","maxout":"100","action":"scale","round":false,"name":"","x":87,"y":208,"wires":[["bb1060b6.259cb"]]},{"id":"10dfe4c4.d0508b","type":"mqtt in","z":"673d2f6.8407cd","name":"fridge status","topic":"shellies/F3/relay/+","qos":"2","datatype":"auto","broker":"a12977.e4f5b688","x":190,"y":80,"wires":[[]]},{"id":"a959d527.9d91e8","type":"debug","z":"9b4dbc77.3dc54","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":910,"y":240,"wires":[]},{"id":"8d28a214.8e0ae","type":"mqtt in","z":"9b4dbc77.3dc54","name":"","topic":"zwave2mqtt/2/#","qos":"2","datatype":"auto","broker":"a12977.e4f5b688","x":480,"y":280,"wires":[["a959d527.9d91e8"]]},{"id":"be1ae3f9.3132f","type":"debug","z":"9b4dbc77.3dc54","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":910,"y":340,"wires":[]},{"id":"eb85ee75.9fa92","type":"mqtt out","z":"9b4dbc77.3dc54","name":"Door relock","topic":"zwave2mqtt/2/112/1/5/set","qos":"","retain":"","broker":"a12977.e4f5b688","x":750,"y":560,"wires":[]},{"id":"c6c986e5.f64f58","type":"inject","z":"9b4dbc77.3dc54","name":"door relock off","topic":"","payload":"Disabled","payloadType":"str","repeat":"","crontab":"02 07 * * *","once":false,"onceDelay":0.1,"x":460,"y":500,"wires":[["eb85ee75.9fa92"]]},{"id":"b3c5f096.59505","type":"mqtt out","z":"9b4dbc77.3dc54","name":"lock/unlock","topic":"zwave2mqtt/2/98/1/0/set","qos":"","retain":"","broker":"a12977.e4f5b688","x":750,"y":620,"wires":[]},{"id":"96694b5b.d0d248","type":"inject","z":"9b4dbc77.3dc54","name":"lock","topic":"","payload":"LOCK","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":430,"y":620,"wires":[["b3c5f096.59505"]]},{"id":"cc8c5fac.ccaa5","type":"inject","z":"9b4dbc77.3dc54","name":"unlock","topic":"","payload":"UNLOCK","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":430,"y":660,"wires":[["b3c5f096.59505"]]},{"id":"5d17fd43.628394","type":"inject","z":"9b4dbc77.3dc54","name":"door relock on","topic":"","payload":"Enabled","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":460,"y":540,"wires":[["eb85ee75.9fa92"]]},{"id":"2f5bea52.949ab6","type":"mqtt out","z":"9b4dbc77.3dc54","name":"Door lock mode","topic":"zwave2mqtt/2/112/1/1/set","qos":"","retain":"","broker":"a12977.e4f5b688","x":760,"y":680,"wires":[]},{"id":"3015d696.36c22a","type":"inject","z":"9b4dbc77.3dc54","name":"","topic":"","payload":"Auto lock, Away on","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":470,"y":700,"wires":[["2f5bea52.949ab6"]]},{"id":"2a2b77e2.c9a908","type":"inject","z":"9b4dbc77.3dc54","name":"","topic":"","payload":"Auto lock, Away off","payloadType":"str","repeat":"","crontab":"01 23 * * *","once":false,"onceDelay":0.1,"x":480,"y":740,"wires":[["2f5bea52.949ab6"]]},{"id":"fd0bfca2.ffa7b","type":"inject","z":"9b4dbc77.3dc54","name":"Manual lock, Away off","topic":"","payload":"Manual lock, Away off","payloadType":"str","repeat":"","crontab":"59 05 * * *","once":false,"onceDelay":0.1,"x":480,"y":780,"wires":[["2f5bea52.949ab6"]]},{"id":"27298999.495fa6","type":"inject","z":"9b4dbc77.3dc54","name":"","topic":"","payload":"Manual lock, Away on","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":480,"y":820,"wires":[["2f5bea52.949ab6"]]},{"id":"435fb4e9.2e565c","type":"mqtt in","z":"9b4dbc77.3dc54","name":"","topic":"zwave2mqtt/2/98/1/0","qos":"2","datatype":"json","broker":"a12977.e4f5b688","x":450,"y":440,"wires":[["e5146e65.74e47"]]},{"id":"e5146e65.74e47","type":"switch","z":"9b4dbc77.3dc54","name":"","property":"payload.value","propertyType":"msg","rules":[{"t":"true"},{"t":"false"}],"checkall":"true","repair":false,"outputs":2,"x":630,"y":440,"wires":[["be1ae3f9.3132f"],["f6db4d41.3df95"]]},{"id":"f6db4d41.3df95","type":"debug","z":"9b4dbc77.3dc54","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":910,"y":380,"wires":[]},{"id":"21faf5ee.3147ba","type":"mqtt in","z":"9b4dbc77.3dc54","name":"","topic":"zwave2mqtt/2/98/1/1","qos":"2","datatype":"json","broker":"a12977.e4f5b688","x":480,"y":340,"wires":[[]]},{"id":"360dc8a5.385de","type":"inject","z":"9b4dbc77.3dc54","name":"lock at night","topic":"","payload":"LOCK","payloadType":"str","repeat":"","crontab":"00 23 * * *","once":false,"onceDelay":0.1,"x":450,"y":580,"wires":[["b3c5f096.59505"]]},{"id":"81ecf60.1206e08","type":"inject","z":"9b4dbc77.3dc54","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":440,"y":980,"wires":[["fda64bba.381128"]]},{"id":"230f6cf1.a346c4","type":"inject","z":"9b4dbc77.3dc54","name":"true","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":430,"y":900,"wires":[["2b092fc7.9f144"]]},{"id":"2b092fc7.9f144","type":"change","z":"9b4dbc77.3dc54","name":"","rules":[{"t":"set","p":"test","pt":"flow","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":610,"y":900,"wires":[[]]},{"id":"4a8bd296.cb0efc","type":"inject","z":"9b4dbc77.3dc54","name":"false","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":430,"y":940,"wires":[["dc27fb68.554498"]]},{"id":"dc27fb68.554498","type":"change","z":"9b4dbc77.3dc54","name":"","rules":[{"t":"set","p":"test","pt":"flow","to":"false","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":610,"y":940,"wires":[[]]},{"id":"fda64bba.381128","type":"switch","z":"9b4dbc77.3dc54","name":"","property":"test","propertyType":"flow","rules":[{"t":"true"},{"t":"false"}],"checkall":"true","repair":false,"outputs":2,"x":590,"y":980,"wires":[["e3bd4c7c.36661"],["b302078c.9b6668"]]},{"id":"e3bd4c7c.36661","type":"debug","z":"9b4dbc77.3dc54","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":790,"y":980,"wires":[]},{"id":"b302078c.9b6668","type":"debug","z":"9b4dbc77.3dc54","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":790,"y":1020,"wires":[]},{"id":"5b0adc63.924d24","type":"mqtt in","z":"9b4dbc77.3dc54","name":"","topic":"zwave2mqtt/3/#","qos":"2","datatype":"json","broker":"a12977.e4f5b688","x":480,"y":220,"wires":[["a959d527.9d91e8"]]},{"id":"1855c00f.80d9e","type":"json","z":"97d46aa8.590d48","name":"","x":2050,"y":340,"wires":[["8e0522ae.106e38"]]},{"id":"8e0522ae.106e38","type":"file","z":"97d46aa8.590d48","name":"writeFile","filename":"","appendNewline":false,"overwriteFile":true,"x":2178.0001220703125,"y":340,"wires":[[]]},{"id":"8d3ad658.9e0058","type":"file in","z":"97d46aa8.590d48","name":"readFile","filename":"","format":"utf8","x":603.2505073547363,"y":313.0000762939453,"wires":[["c170604f.bbdaa"]]},{"id":"a6529dac.a17928","type":"inject","z":"97d46aa8.590d48","name":"","topic":"filename","payload":"rs3","payloadType":"str","repeat":"240","crontab":"","once":true,"onceDelay":"","x":150,"y":380,"wires":[["b699983f.6129e8"]]},{"id":"b699983f.6129e8","type":"change","z":"97d46aa8.590d48","name":"filename","action":"replace","property":"filename","from":"","to":"msg.payload","reg":false,"x":179.00015258789062,"y":318.99964141845703,"wires":[["4c22dd3a.8ffb6c"]]},{"id":"30ccf4e.318cc0c","type":"change","z":"97d46aa8.590d48","name":"myPublicIp.json","action":"replace","property":"filename","from":"","to":"myPublicIp.json","reg":false,"x":447.0001678466797,"y":352.9998245239258,"wires":[["8d3ad658.9e0058"]]},{"id":"4c22dd3a.8ffb6c","type":"switch","z":"97d46aa8.590d48","name":"","property":"filename.length","rules":[{"t":"gt","v":0,"v2":0},{"t":"else"}],"checkall":"false","outputs":2,"x":302.0001678466797,"y":319.9996109008789,"wires":[["8d3ad658.9e0058"],["30ccf4e.318cc0c"]]},{"id":"c170604f.bbdaa","type":"switch","z":"97d46aa8.590d48","name":"","property":"payload.length","rules":[{"t":"gt","v":0,"v2":0},{"t":"else"}],"checkall":"true","outputs":2,"x":724.0001525878906,"y":312.99976348876953,"wires":[["bb58560a.a69138"],["e1d46089.0c4e2"]]},{"id":"629f442.b044dbc","type":"change","z":"97d46aa8.590d48","name":"last ip from file","action":"replace","property":"lastip","from":"","to":"msg.payload","reg":false,"x":1009.0001831054688,"y":279.99964141845703,"wires":[["5294426b.6081fc"]]},{"id":"6acc0be8.7f5754","type":"debug","z":"97d46aa8.590d48","name":"Stable IP","active":false,"console":"false","complete":"false","x":1940,"y":280,"wires":[]},{"id":"1ba01446.2b255c","type":"function","z":"97d46aa8.590d48","name":"Compare IP","func":"var lastip = msg.lastip.ip;\nvar currentip = msg.payload.ip;\nmsg.currentip = currentip;\nmsg.topic = \"stable\";\nif (lastip !== currentip) {\nmsg.payload.ip = currentip;\nmsg.topic = \"new\";\n}\n\nreturn msg;\n","outputs":"1","noerr":0,"x":1430,"y":440,"wires":[["d8a7f329.2f955","b7b4e50.c01bd98"]]},{"id":"bb58560a.a69138","type":"json","z":"97d46aa8.590d48","name":"","x":866.0001983642578,"y":279.99964141845703,"wires":[["629f442.b044dbc"]]},{"id":"d8a7f329.2f955","type":"template","z":"97d46aa8.590d48","name":"Description","field":"payload","fieldType":"msg","syntax":"mustache","template":"Your {{topic}} Public IP: http://{{payload.ip}}","x":1630,"y":300,"wires":[["19717e68.89302a"]]},{"id":"19717e68.89302a","type":"switch","z":"97d46aa8.590d48","name":"","property":"topic","rules":[{"t":"eq","v":"stable"},{"t":"else"}],"checkall":"false","outputs":2,"x":1771.0000610351562,"y":336.9996032714844,"wires":[["6acc0be8.7f5754"],["b4e6d397.28aa18","706307c1.fece5"]]},{"id":"b4e6d397.28aa18","type":"function","z":"97d46aa8.590d48","name":"prepare","func":"var newFile = {};\nnewFile.filename = msg.filename;\nnewFile.payload = {ip: msg.currentip};\n\nreturn newFile;","outputs":"1","x":1929.000244140625,"y":340.9996032714844,"wires":[["1855c00f.80d9e"]]},{"id":"e1d46089.0c4e2","type":"change","z":"97d46aa8.590d48","name":"null","action":"replace","property":"lastip","from":"","to":"null","reg":false,"x":868.0002059936523,"y":341.24964904785156,"wires":[["5294426b.6081fc"]]},{"id":"706307c1.fece5","type":"debug","z":"97d46aa8.590d48","name":"New IP","active":true,"console":"false","complete":"false","x":1920,"y":380,"wires":[]},{"id":"5294426b.6081fc","type":"http request","z":"97d46aa8.590d48","name":"Server","method":"GET","url":"http://ipecho.net/plain","x":1190.0001831054688,"y":339.99964141845703,"wires":[["4227092b.cd95d8"]]},{"id":"4227092b.cd95d8","type":"function","z":"97d46aa8.590d48","name":"payload.ip","func":"var regObj = new RegExp(\"(?:(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9]).){3}(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])\");\nvar str = msg.payload;\nvar myIp = {};\nmyIp = str.match(regObj);\nmsg.payload = {ip : myIp[0]};\nreturn msg;","outputs":1,"x":1330,"y":360,"wires":[["1ba01446.2b255c"]]},{"id":"aa88ab39.414a2","type":"comment","z":"97d46aa8.590d48","name":"Filename","info":"use the \"payload\" property to define a custom file name to hold\nthe public Ip address.\nThis flow uses the json format and will create a file when\nit is not found or when the public ip address changes.","x":58.27288055419922,"y":268.2723617553711,"wires":[]},{"id":"91d1d111.28e81","type":"comment","z":"97d46aa8.590d48","name":"Is there a filename defined?","info":"If it is blank, inject the default file name into the flow.","x":360.77296447753906,"y":278.2723922729492,"wires":[]},{"id":"42a28d47.bc7604","type":"comment","z":"97d46aa8.590d48","name":"Valid file?","info":"By checking the length of the payload we can determine if\nthe file exists or not.","x":722.0229072570801,"y":268.27235317230225,"wires":[]},{"id":"46d4b380.85036c","type":"comment","z":"97d46aa8.590d48","name":"New file check","info":"If the file does not exist, set the lastip property\nto something that will not match when we check a service for\nour public ip.","x":882.0229072570801,"y":385.7723560333252,"wires":[]},{"id":"bcc46803.2a6528","type":"comment","z":"97d46aa8.590d48","name":"good file","info":"convert the string to json and move it to the\nmsg.lastip property","x":865.7729110717773,"y":234.52235317230225,"wires":[]},{"id":"a6b81bf8.f15cc","type":"comment","z":"97d46aa8.590d48","name":"Check IP","info":"Use a web service to check your ip address.\nThen use a function to extract the ip from the result.\nTested with these Services:\nhttp://checkip.dyndns.org/\nhttp://echoip.com/\nhttp://ipecho.net/plain\nhttp://bot.whatismyipaddress.com/\n","x":1202.022850036621,"y":289.0223617553711,"wires":[]},{"id":"77d394c.90d166c","type":"comment","z":"97d46aa8.590d48","name":"Compare","info":"compare the results from the WEB with file","x":1494.5229110717773,"y":387.0223617553711,"wires":[]},{"id":"6c5da0ab.67b8d","type":"comment","z":"97d46aa8.590d48","name":"Text Description","info":"Add some words around the result to tell you whats going on.","x":1620,"y":160,"wires":[]},{"id":"5f3b0214.fd53bc","type":"comment","z":"97d46aa8.590d48","name":"Results","info":"The results will flow out the top if they are unchanged\nor flow out the bottom when they have changed.\nwe also write that to our file for next time.\nThis would be the ideal place to email or tweet on change.","x":1768.2728691101074,"y":387.0223627090454,"wires":[]},{"id":"a7827a39.8403e","type":"comment","z":"97d46aa8.590d48","name":"No?","info":"Then use the default defined here.","x":433.2728805541992,"y":394.5223388671875,"wires":[]},{"id":"47849ab.88549e4","type":"comment","z":"97d46aa8.590d48","name":"Save if different","info":"This ensures we remember the ip thru power cycles ;-)","x":2145.7728729248047,"y":395.7723627090454,"wires":[]},{"id":"4b839521.176adc","type":"blynk-ws-out-notify","z":"97d46aa8.590d48","name":"","client":"445c05cf.41736c","queue":false,"rate":5,"x":2150,"y":540,"wires":[]},{"id":"b020842f.9afc68","type":"ipwhois","z":"97d46aa8.590d48","name":"","x":1840,"y":540,"wires":[["857d45c0.8c1158"]]},{"id":"857d45c0.8c1158","type":"function","z":"97d46aa8.590d48","name":"ISP","func":"msg.payload = \"ISP: \" +msg.payload.descr\nreturn msg;","outputs":1,"noerr":0,"x":1990,"y":540,"wires":[["4b839521.176adc","c1d86cff.e67c2"]]},{"id":"bf341134.86aff8","type":"change","z":"97d46aa8.590d48","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.ip","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1660,"y":540,"wires":[["b020842f.9afc68","592972e2.abef34"]]},{"id":"b7b4e50.c01bd98","type":"switch","z":"97d46aa8.590d48","name":"","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"new","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":1490,"y":540,"wires":[["bf341134.86aff8"]]},{"id":"c1d86cff.e67c2","type":"blynk-ws-out-write","z":"97d46aa8.590d48","name":"isp","pin":"8","pinmode":0,"client":"445c05cf.41736c","x":2150,"y":600,"wires":[]},{"id":"592972e2.abef34","type":"blynk-ws-out-write","z":"97d46aa8.590d48","name":"ip","pin":"9","pinmode":0,"client":"445c05cf.41736c","x":1830,"y":480,"wires":[]},{"id":"60b278c6.b6e098","type":"mqtt in","z":"bfb81e59.ff7c6","name":"","topic":"shellies/#","qos":"2","datatype":"auto","broker":"a12977.e4f5b688","x":80,"y":40,"wires":[["ce0efd22.525fa"]]},{"id":"ce0efd22.525fa","type":"debug","z":"bfb81e59.ff7c6","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":230,"y":40,"wires":[]},{"id":"b3538198.767e3","type":"mqtt in","z":"bfb81e59.ff7c6","name":"garage closed","topic":"shellies/shellyuni-483FDA82C328/input/1","qos":"2","datatype":"auto","broker":"a12977.e4f5b688","x":90,"y":100,"wires":[["cdfcb02a.22f6f"]]},{"id":"910cccb5.38d94","type":"mqtt in","z":"bfb81e59.ff7c6","name":"garage open","topic":"shellies/shellyuni-483FDA82C328/input/0","qos":"2","datatype":"auto","broker":"a12977.e4f5b688","x":90,"y":160,"wires":[["718a74bb.f6710c"]]},{"id":"49bc7c32.889304","type":"mqtt out","z":"bfb81e59.ff7c6","name":"open","topic":"shellies/shellyuni-483FDA6F317E/relay/0/command","qos":"","retain":"","broker":"a12977.e4f5b688","x":510,"y":620,"wires":[]},{"id":"d7fad0e1.d4a84","type":"mqtt out","z":"bfb81e59.ff7c6","name":"close","topic":"shellies/shellyuni-483FDA6F317E/relay/1/command","qos":"","retain":"","broker":"a12977.e4f5b688","x":510,"y":680,"wires":[]},{"id":"f8964a5d.6eb948","type":"inject","z":"bfb81e59.ff7c6","name":"open","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":620,"wires":[["81c46e20.51a87"]]},{"id":"81c46e20.51a87","type":"trigger","z":"bfb81e59.ff7c6","op1":"on","op2":"off","op1type":"str","op2type":"str","duration":"500","extend":false,"units":"ms","reset":"","bytopic":"all","name":"","x":340,"y":620,"wires":[["49bc7c32.889304"]]},{"id":"16a4b443.11001c","type":"trigger","z":"bfb81e59.ff7c6","op1":"on","op2":"off","op1type":"str","op2type":"str","duration":"500","extend":false,"units":"ms","reset":"","bytopic":"all","name":"","x":340,"y":680,"wires":[["d7fad0e1.d4a84"]]},{"id":"f6f753f1.e2316","type":"inject","z":"bfb81e59.ff7c6","name":"close","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":680,"wires":[["16a4b443.11001c"]]},{"id":"f833fcd8.93e3","type":"inject","z":"bfb81e59.ff7c6","name":"","topic":"","payload":"","payloadType":"date","repeat":"1","crontab":"","once":true,"onceDelay":0.1,"x":90,"y":380,"wires":[["84d58917.e824b8","6cc4005e.31f1f8"]]},{"id":"cdfcb02a.22f6f","type":"change","z":"bfb81e59.ff7c6","name":"closed","rules":[{"t":"change","p":"payload","pt":"msg","from":"1","fromt":"str","to":"true","tot":"bool"},{"t":"change","p":"payload","pt":"msg","from":"0","fromt":"str","to":"false","tot":"bool"},{"t":"set","p":"garageclosed","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":250,"y":100,"wires":[[]]},{"id":"718a74bb.f6710c","type":"change","z":"bfb81e59.ff7c6","name":"open","rules":[{"t":"change","p":"payload","pt":"msg","from":"1","fromt":"str","to":"true","tot":"bool"},{"t":"change","p":"payload","pt":"msg","from":"0","fromt":"str","to":"false","tot":"bool"},{"t":"set","p":"garageopen","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":250,"y":160,"wires":[[]]},{"id":"84d58917.e824b8","type":"function","z":"bfb81e59.ff7c6","name":"limitswitch","func":"var open = flow.get(\"garageopen\")\nvar closed = flow.get(\"garageclosed\")\n\nif (open === true) {\nmsg.payload = \"open\"\nflow.set(\"lastpos\", \"open\")\nnode.send(msg)\n}\n\nif (closed === true) {\nmsg.payload = \"closed\"\nflow.set(\"lastpos\", \"closed\")\nnode.send(msg)\n}\n","outputs":1,"noerr":0,"x":270,"y":380,"wires":[["fe5c12ab.76ec4"]]},{"id":"fe5c12ab.76ec4","type":"timeouttrigger","z":"bfb81e59.ff7c6","ontimeouttype":"str","ontimeoutval":"stuck","duration":"60","units":"s","name":"","x":410,"y":380,"wires":[["b9e1c24d.f956e"]]},{"id":"5637f495.d03fec","type":"switch","z":"bfb81e59.ff7c6","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"stuck","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":710,"y":420,"wires":[["5518287e.9324b"]]},{"id":"b9e1c24d.f956e","type":"rbe","z":"bfb81e59.ff7c6","name":"","func":"rbe","gap":"","start":"","inout":"out","property":"payload","x":550,"y":380,"wires":[["5637f495.d03fec","5f47bb89.6a343c"]]},{"id":"6cc4005e.31f1f8","type":"function","z":"bfb81e59.ff7c6","name":"moving","func":"var open = flow.get(\"garageopen\")\nvar closed = flow.get(\"garageclosed\")\n\nif (open !== true && closed !== true) {\nmsg.payload = \"moving from \" + flow.get(\"lastpos\")\nnode.send(msg)\n}\n","outputs":1,"noerr":0,"x":260,"y":340,"wires":[["16534a54.37eb56"]]},{"id":"16534a54.37eb56","type":"rbe","z":"bfb81e59.ff7c6","name":"","func":"rbe","gap":"","start":"","inout":"out","property":"payload","x":550,"y":340,"wires":[["1780a68f.d5ff01"]]},{"id":"fe5e9def.6e611","type":"blynk-ws-in-write","z":"bfb81e59.ff7c6","name":"open","pin":"10","pin_all":0,"client":"445c05cf.41736c","x":90,"y":500,"wires":[["81c46e20.51a87"]]},{"id":"c3ff5ba0.f5661","type":"blynk-ws-in-write","z":"bfb81e59.ff7c6","name":"close","pin":"11","pin_all":0,"client":"445c05cf.41736c","x":90,"y":560,"wires":[["16a4b443.11001c"]]},{"id":"1780a68f.d5ff01","type":"blynk-ws-out-write","z":"bfb81e59.ff7c6","name":"status","pin":"12","pinmode":0,"client":"445c05cf.41736c","x":830,"y":340,"wires":[]},{"id":"69152922.662ee","type":"blynk-ws-out-notify","z":"bfb81e59.ff7c6","name":"","client":"445c05cf.41736c","queue":false,"rate":5,"x":1010,"y":420,"wires":[]},{"id":"5518287e.9324b","type":"change","z":"bfb81e59.ff7c6","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"garasjeporten er stuck","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":860,"y":420,"wires":[["69152922.662ee"]]},{"id":"5f47bb89.6a343c","type":"function","z":"bfb81e59.ff7c6","name":"","func":"if (msg.payload == \"stuck\") {\nmsg.payload = msg.payload + \" from \" + flow.get(\"lastpos\")\n}\nelse {\n msg.payload = msg.payload\n}\nreturn msg;","outputs":1,"noerr":0,"x":690,"y":360,"wires":[["1780a68f.d5ff01"]]},{"id":"5e2d03b6.fb1acc","type":"PID","z":"6dc4c6ac.83d2b8","name":"","setpoint":21,"pb":"30","ti":9999,"td":0,"integral_default":0.5,"smooth_factor":3,"max_interval":600,"enable":1,"disabled_op":"1","x":1430,"y":40,"wires":[["fe9f83b7.9a2a6"]]},{"id":"ee907d.30e8bf8","type":"function","z":"6dc4c6ac.83d2b8","name":"heat/cool","func":"\n/* A function designed to be used with node-red-contrib-pid in applications where both\n * heating and cooling are available to control the system.\n * The node is given a power value in msg.payload in the range 0 to 1, such as is produced by \n * node-red-contrib-pid and splits this into a heat power (o/p 1) and cool power (o/p 2) where\n * each is in the range 0 to 1. These can then be fed directly into an output device, if this\n * is continuously variable, or they may be passed to node-red-contrib-timeprop nodes to generate\n * time proportioned on/off outputs.\n * There are two particular issues to be dealt with in a heat/cool application. Firstly is the fact\n * that the cooling device may be more or less powerful than the heating device. It is necessary\n * therefore to be able to adjust the gain of the system separately for heating and cooling. Secondly\n * is the highly non-linear response of some devices, notably refrigerant systems, that can have a\n * large effect initially, then this tails off. To compensate for this it is useful to have an \n * overlap range where both heat and cool are slightly on.\n *\n * To allow for these requirements two variables can be set below. The value of the power input value\n * where the heating starts to come on is determined by the variable heatMin. Above this value the\n * heating will rise till it is fully on with an input of 1.\n * The cooling is fully on when value of the power input is 0, and falls till the cooling is fully\n * off at an input of coolMin.\n *\n * If the heating and cooling systems are of similar power then set heatMin and coolMin both to 0.5\n * in which case input values of 0.5 to 1.0 will map to heating outputs of 0.0 to 1.0,\n * and 0.5 down to 0.0 will map to cooling 0.0 to 1.0.\n * If, for example, the cooling system is more powerful than heating then they can both be set\n * to something like 0.7 which increases the gain in the heating region and reduces it\n * in the cooling region, to compensate for the different powers in the heating/cooling systems.\n * If some overlap is desired (so that both heat and cool are on slightly near the crossover\n * point) then overlap the two settings so that, for example, heatMin might be 0.45 and coolMin\n * might be 0.55\n */\n\nflow.set(String(msg.topic), Math. round(msg.payload*100))\n \n// set these as described above\nvar heatMin = 0.5; // the value of input corresponding to 0 heat o/p\nvar coolMin = 0.5; // the value of input corresponding to 0 cool o/p\n \nvar power = msg.payload;\nvar heat = (power - heatMin)/(1 - heatMin);\n// limit to range 0 to 1\nheat = Math.min(Math.max(heat, 0), 1);\nvar cool = (coolMin - power) / coolMin;\n// limit to range 0 to 1\ncool = Math.min(Math.max(cool, 0), 1);\n\nmsg.payload = [{payload: heat}, {payload: cool}];\nreturn msg;\n","outputs":2,"noerr":0,"x":2140,"y":40,"wires":[[],[]]},{"id":"7eab19cf.fda108","type":"change","z":"6dc4c6ac.83d2b8","name":"503","rules":[{"t":"set","p":"topic","pt":"msg","to":"503","tot":"str"},{"t":"set","p":"503output","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1690,"y":40,"wires":[["2513cac2.2e69a6"]]},{"id":"c64ede7c.d3a6a","type":"link in","z":"6dc4c6ac.83d2b8","name":"","links":["54c14458.59eedc"],"x":1215,"y":40,"wires":[["f3cf8f49.ca6148"]]},{"id":"2513cac2.2e69a6","type":"debug","z":"6dc4c6ac.83d2b8","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":1830,"y":40,"wires":[]},{"id":"fe9f83b7.9a2a6","type":"range","z":"6dc4c6ac.83d2b8","minin":"0","maxin":"1","minout":"0","maxout":"255","action":"clamp","round":true,"property":"payload","name":"","x":1560,"y":40,"wires":[["7eab19cf.fda108"]]},{"id":"f3cf8f49.ca6148","type":"switch","z":"6dc4c6ac.83d2b8","name":"","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"201","vt":"str"},{"t":"eq","v":"202","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":1310,"y":40,"wires":[["5e2d03b6.fb1acc"],[]]},{"id":"41ef6903.b0d8d8","type":"modbus-read","z":"6dc4c6ac.83d2b8","name":"Digital out 500","topic":"","showStatusActivities":false,"logIOActivities":false,"showErrors":false,"unitid":"5","dataType":"Coil","adr":"0","quantity":"16","rate":"500","rateUnit":"ms","delayOnStart":false,"startDelayTime":"","server":"6b19cfc5.22db6","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":false,"x":110,"y":40,"wires":[["8599cee8.1a0e7"],["d73a2727.3bcb98"]]},{"id":"d73a2727.3bcb98","type":"modbus-response","z":"6dc4c6ac.83d2b8","name":"","registerShowMax":20,"x":310,"y":80,"wires":[]},{"id":"9ea49dd0.d8d0f","type":"modbus-flex-write","z":"6dc4c6ac.83d2b8","name":"Digtal Out","showStatusActivities":false,"showErrors":false,"server":"6b19cfc5.22db6","emptyMsgOnFail":false,"keepMsgProperties":false,"x":420,"y":140,"wires":[[],["19d7aed0.bf3471"]]},{"id":"19d7aed0.bf3471","type":"modbus-response","z":"6dc4c6ac.83d2b8","name":"","registerShowMax":20,"x":610,"y":160,"wires":[]},{"id":"8599cee8.1a0e7","type":"function","z":"6dc4c6ac.83d2b8","name":"Store input","func":"var inp = msg.payload\nvar portrange = 500\n\nfor (var i = 0; i < inp.length; i++) {\n if (inp[i] === true) {\n flow.set((String(i+portrange)), 1)\n }\n else {\n flow.set((String(i+portrange)), 0)\n }\n}\n\nreturn msg;","outputs":1,"noerr":0,"x":290,"y":40,"wires":[[]]},{"id":"3252e5ba.b8baaa","type":"function","z":"6dc4c6ac.83d2b8","name":"Send DO","func":"\nvar outp =[];\nvar portrange = 500\nvar totaloutputs = 16\n\nfor (var i = 0; i < totaloutputs; i++) {\n if (flow.get(String(i+portrange)+\"output\")=== 1) {\n outp.push(true)\n }\n else {\n outp.push(false)\n }\n}\n\n\nmsg.payload = {value: outp,\n'fc': 15, 'unitid': 5, 'address':0, 'quantity':totaloutputs}\n\nreturn msg;","outputs":1,"noerr":0,"x":280,"y":140,"wires":[["9ea49dd0.d8d0f"]]},{"id":"8b0d17c5.4c89e8","type":"inject","z":"6dc4c6ac.83d2b8","name":"","topic":"","payload":"","payloadType":"date","repeat":"0.5","crontab":"","once":true,"onceDelay":0.1,"x":110,"y":100,"wires":[["3252e5ba.b8baaa"]]},{"id":"d1577588.219748","type":"modbus-read","z":"6dc4c6ac.83d2b8","name":"Analog in 200","topic":"","showStatusActivities":false,"logIOActivities":false,"showErrors":false,"unitid":"2","dataType":"HoldingRegister","adr":"0","quantity":"8","rate":"500","rateUnit":"ms","delayOnStart":false,"startDelayTime":"","server":"6b19cfc5.22db6","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":false,"x":110,"y":420,"wires":[["c7df38bb.734a58"],["94c5e696.973048"]]},{"id":"94c5e696.973048","type":"modbus-response","z":"6dc4c6ac.83d2b8","name":"","registerShowMax":20,"x":310,"y":460,"wires":[]},{"id":"c7df38bb.734a58","type":"function","z":"6dc4c6ac.83d2b8","name":"Split input","func":"var inp = msg.payload\nvar portrange = 200\n\nfor (i = 0; i < inp.length; i++) {\n msg.payload = inp[i]\n msg.topic = i + portrange\n node.send(msg)\n}\n","outputs":1,"noerr":0,"x":280,"y":420,"wires":[["d4b673dd.9ea8f"]]},{"id":"1576aecb.071c91","type":"modbus-read","z":"6dc4c6ac.83d2b8","name":"PT100 400","topic":"","showStatusActivities":false,"logIOActivities":false,"showErrors":false,"unitid":"4","dataType":"HoldingRegister","adr":"32","quantity":"8","rate":"600","rateUnit":"ms","delayOnStart":false,"startDelayTime":"","server":"6b19cfc5.22db6","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":false,"x":100,"y":340,"wires":[["5b45ed60.785ca4"],["d39ee7c3.e24438"]]},{"id":"d39ee7c3.e24438","type":"modbus-response","z":"6dc4c6ac.83d2b8","name":"","registerShowMax":20,"x":310,"y":360,"wires":[]},{"id":"5b45ed60.785ca4","type":"function","z":"6dc4c6ac.83d2b8","name":"Split input","func":"var inp = msg.payload\nvar portrange = 400\n\nfor (i = 0; i < inp.length; i++) {\n msg.payload = inp[i]\n msg.topic = i + portrange\n node.send(msg)\n}\n","outputs":1,"noerr":0,"x":280,"y":320,"wires":[["aca07636.8cbe28"]]},{"id":"d8d01682.693928","type":"link out","z":"6dc4c6ac.83d2b8","name":"","links":["cc96708e.f3e01"],"x":515,"y":420,"wires":[]},{"id":"aca07636.8cbe28","type":"link out","z":"6dc4c6ac.83d2b8","name":"","links":["cc96708e.f3e01"],"x":395,"y":320,"wires":[]},{"id":"e7f85caf.89fd3","type":"modbus-read","z":"6dc4c6ac.83d2b8","name":"Analog out 300","topic":"","showStatusActivities":false,"logIOActivities":false,"showErrors":false,"unitid":"3","dataType":"HoldingRegister","adr":"48","quantity":"8","rate":"500","rateUnit":"ms","delayOnStart":false,"startDelayTime":"","server":"6b19cfc5.22db6","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":false,"x":120,"y":200,"wires":[["63e8643.e2cbe9c"],["3024065a.219fea"]]},{"id":"3024065a.219fea","type":"modbus-response","z":"6dc4c6ac.83d2b8","name":"","registerShowMax":20,"x":310,"y":220,"wires":[]},{"id":"87e63099.e5e5f","type":"inject","z":"6dc4c6ac.83d2b8","name":"","topic":"","payload":"","payloadType":"date","repeat":"0.6","crontab":"","once":true,"onceDelay":0.1,"x":110,"y":260,"wires":[["66f9125d.86c96c"]]},{"id":"fd22355f.c4de68","type":"modbus-flex-write","z":"6dc4c6ac.83d2b8","name":"Analog output","showStatusActivities":false,"showErrors":false,"server":"6b19cfc5.22db6","emptyMsgOnFail":false,"keepMsgProperties":false,"x":440,"y":280,"wires":[[],["bf86632f.4356b"]]},{"id":"bf86632f.4356b","type":"modbus-response","z":"6dc4c6ac.83d2b8","name":"","registerShowMax":20,"x":630,"y":300,"wires":[]},{"id":"63e8643.e2cbe9c","type":"function","z":"6dc4c6ac.83d2b8","name":"Split input","func":"var inp = msg.payload\nvar portrange = 300\n\nfor (i = 0; i < inp.length; i++) {\n msg.payload = inp[i]\n msg.payload = (msg.payload / 4095) * 255\n msg.payload = Math.round(msg.payload)\n msg.topic = i + portrange\n flow.set(String(msg.topic), msg.payload)\n node.send(msg)\n}\n","outputs":1,"noerr":0,"x":280,"y":180,"wires":[[]]},{"id":"66f9125d.86c96c","type":"function","z":"6dc4c6ac.83d2b8","name":"Send AO","func":"\nvar outp =[];\nvar portrange = 300\nvar totaloutputs = 8\n\nfor (var i = 0; i < totaloutputs; i++) {\n if (isNaN(flow.get(String(i+portrange)+\"output\")) === false) {\n var a = (flow.get(String(i+portrange)+\"output\")/255)*4095\n a= Math.round(a)\n outp.push(a)\n }\n else {\n outp.push(0)\n }\n}\n\n\nmsg.payload = {value: outp,\n'fc': 16, 'unitid': 3, 'address':48, 'quantity':totaloutputs}\n\nreturn msg;","outputs":1,"noerr":0,"x":280,"y":280,"wires":[["fd22355f.c4de68"]]},{"id":"c6839720.edfc38","type":"function","z":"6dc4c6ac.83d2b8","name":"parse","func":"node.status({fill:\"green\",shape:\"dot\",text:\"connected\"});\n\nvar inp = msg.payload\nvar s =[];\nvar u = [];\nvar r = [];\nvar d = [];\nvar out = {};\n\nconst numberSorter = (([a, b], [c, d]) => a - c || d - b);\n\nif (inp.indexOf('!') != -1 || inp.indexOf('?') != -1 || inp.indexOf('/') != -1 ) {\n inp = inp.split(/(?=[?!;/])/g)\n\n for (var i = 0; i < inp.length; i++) {\n if (inp[i].indexOf('!') != -1) {\n inp[i] = inp[i].slice(inp[i].indexOf('!')+1)\n u.push (inp[i])\n }\n if (inp[i].indexOf('?') != -1) {\n inp[i] = inp[i].slice(inp[i].indexOf('?')+1)\n s.push (inp[i])\n }\n if (inp[i].indexOf('/') != -1) {\n inp[i] = inp[i].slice(inp[i].indexOf('/')+1)\n r.push (inp[i]+\",\"+\"99\")\n d.push (inp[i])\n }\n } \n\n for (i = 0; i < u.length; i++) {\n u[i] = u[i].split(\",\").map(Number);\n }\n for (i = 0; i < r.length; i++) {\n r[i] = r[i].split(\",\").map(Number);\n \n }\n for (i = 0; i < s.length; i++) {\n s[i] = s[i].split(\",\").map(Number);\n }\nu.sort(numberSorter)\n if (u.length > 0 ) {\n node.send([{payload:u}, null])\n }\nr.sort(numberSorter)\n if (r.length > 0 ) {\n //for (i = 0; i < r.length; i++) {\n \n out = r\n node.send([{payload:out}, null])\n }\ns.sort(numberSorter)\nsetTimeout(reply, 200);\n\n} else {\n if (inp.indexOf('*') != -1) {\n out = \"*;\"\n node.send([null, {payload: out}])\n }\n}\n\nfunction reply() {\n for (i = 0; i < s.length; i++) {\n if (isNaN(flow.get(String(s[i]))) === false) {\n s[i] = \"?\" + s[i] + \"=\" + flow.get(String(s[i]))\n }\n else {\n s[i] = \"?\" + s[i]\n }\n }\n\n for ( i = 0; i < u.length; i++) {\n u[i] = \"!\" + u[i]\n }\n for ( i = 0; i < d.length; i++) {\n d[i] = \"/\" + d[i]\n }\n\n u = u.join('')\n s = s.join('')\n out = s+u+d+\";\"\n node.send([null, {payload: out}])\n}\n\n\nmsg.topic = \"tick\"\nmsg.payload = Date.now()\nreturn [ msg, null];\n \n \n\n","outputs":2,"noerr":0,"x":310,"y":800,"wires":[["197116ed.5a3f49"],["bea6c539.232428"]]},{"id":"197116ed.5a3f49","type":"function","z":"6dc4c6ac.83d2b8","name":"config","func":"\nvar u = msg.payload || []\nvar dcpins = flow.get(\"dcpins\") || []\nvar deadTime = 400; // number of milliseconds the valve (or whatever) takes to actuate, 30 seconds\nvar invert = false; \n\ndcpins = Array.from(new Set(dcpins))\ndcpins.sort(function(a, b){return a-b});\n\nfor (var i = 0; i < u.length; i++) {\n var config = u[i][1]\n var pin = u[i][0]\n \n if (config === 1) { //digital out\n flow.set(String(pin)+\"config\", config)\n msg.topic = pin\n msg.payload = u[i][2]\n flow.set(String(msg.topic)+\"output\", msg.payload) //store digital input to pick it up by modbus\n node.send(msg);\n }\n\n if (config === 4) { //dutycycle\n flow.set(String(pin)+\"config\", config)\n flow.set(String(pin)+\"dcpower\", u[i][2]/100)\n flow.set(String(pin)+\"dctime\", u[i][3])\n dcpins.push(u[i][0]);\n }\n \n if (config === 5) { //hysteresis\n flow.set(String(pin)+\"config\", config)\n flow.set(String(u[i][2])+\"config\", config)\n flow.set(String(pin)+\"pin\", u[i][2])\n flow.set(String(pin)+\"setpoint\", u[i][3])\n flow.set(String(pin)+\"setpoint2\", u[i][4])\n flow.set(String(u[i][2])+\"pin\", pin)\n var cooling\n if (u[i][3] < u[i][4]) {\n cooling = true\n } else {\n cooling = false\n }\n flow.set(String(pin)+\"cooling\", cooling)\n flow.set(String(pin)+\"delay\", u[i][5]*1000)\n }\n\n if (config == 6 ) { //PID\n flow.set(String(pin)+\"config\", config)\n flow.set(String(u[i][2])+\"config\", config)\n flow.set(String(u[i][2])+\"pin\", pin)\n flow.set(String(pin)+\"pin\", u[i][2])\n flow.set(String(pin)+\"pid\", u[i][2])\n flow.set(String(pin)+\"setpoint\", u[i][3])\n flow.set(String(pin)+\"prop_band\", u[i][4] /100)\n flow.set(String(pin)+\"t_integral\", u[i][5] /100)\n flow.set(String(pin)+\"t_derivative\", u[i][6]/ 100)\n flow.set(String(pin)+\"direction\", u[i][7])\n flow.set(String(pin)+\"calctime\", u[i][8]*1000)\n flow.set(String(pin)+\"outtime\", u[i][9])\n flow.set(String(pin)+\"maxout\", u[i][11])\n msg.payload = [u[i][0],u[i][1],u[i][2],u[i][3],u[i][4],u[i][5],u[i][6],u[i][7],u[i][8],u[i][9],u[i][10],u[i][11]]//flow.get(String(u[i][2]))\n msg.topic = u[i][0]\n msg.enable = 1\n node.send(msg)\n }\n \n if (config === 7) { //pwm\n flow.set(String(pin)+\"config\", config)\n //flow.set(String(pin), u[i][2])\n msg.topic = pin\n //msg.payload = flow.get(String(pin))\n msg.payload = u[i][2]\n flow.set(String(msg.topic)+\"output\", msg.payload)\n flow.set(String(msg.topic), msg.payload)\n node.send(msg);\n }\n if (config === 8) { //analoginput\n flow.set(String(pin)+\"pollrate\", u[i][2])\n flow.set(String(pin)+\"awgweight\", u[i][3])\n msg.topic = pin\n msg.payload = [pin, 8, u[i][2], u[i][3]]\n node.send(msg);\n }\n if (config === 99) { //disabled\n previousconfig = flow.get(String(pin)+\"config\") || 0\n flow.set(String(pin)+\"config\", config)\n \n if (previousconfig === 1) {\n msg.topic = pin\n msg.payload = 0\n flow.set(String(msg.topic)+\"output\", msg.payload)\n node.send(msg)\n }\n if (previousconfig === 4) {\n for (i = 0; i < flow.get(\"dcpins\").length; i++) {\n \n if (pin === dcpins[i]) {\n dcpins.splice([i], 1)\n flow.set(String(pin)+\"dcdisabled\", true)\n msg.topic = pin\n msg.payload = 0\n node.send(msg)\n }\n }\n flow.set(String(pin)+\"config\", 99)\n flow.set(String(pin)+\"dcpower\", 0)\n flow.set(String(pin)+\"dctime\", 0)\n }\n \n if (previousconfig === 5) { //hysteresis\n flow.set(String(pin)+\"config\", config)\n //flow.set(String(pin)+\"pin\", 0)\n flow.set(String(pin)+\"setpoint\", 0)\n flow.set(String(pin)+\"setpoint2\", 0)\n flow.set(String(pin)+\"ondelay\", 0)\n msg.topic = pin\n msg.payload = 0\n node.send(msg);\n }\n \n \n if (previousconfig === 6) {\n flow.set(String(pin)+\"config\", 99)\n flow.set(String(u[i][2])+\"config\", 0)\n flow.set(String(u[i][2])+\"pin\", 0)\n flow.set(String(pin)+\"pin\", 0)\n flow.set(String(pin)+\"pid\", 0)\n flow.set(String(pin)+\"setpoint\", 0)\n flow.set(String(pin)+\"prop_band\", 0)\n flow.set(String(pin)+\"t_integral\", 0)\n flow.set(String(pin)+\"t_derivative\",0)\n flow.set(String(pin)+\"direction\", 0)\n flow.set(String(pin)+\"calctime\", 0)\n flow.set(String(pin)+\"outtime\", 0)\n flow.set(String(pin)+\"maxout\", 0)\n msg.topic = pin\n msg.enable = 0\n msg.payload = [msg.payload[0][0], msg.payload[0][1]]\n node.send(msg)\n }\n if (previousconfig === 7) { //pwm\n flow.set(String(pin)+\"config\", 99)\n flow.set(String(pin)+\"output\", 0)\n msg.topic = pin\n msg.payload = flow.get(String(pin))\n node.send(msg);\n }\n if (previousconfig === 8) { //analoginput\n flow.set(String(pin)+\"pollrate\", 0)\n flow.set(String(pin)+\"awgweight\", 0)\n }\n }\n}\n\ndcpins = Array.from(new Set(dcpins))\ndcpins.sort(function(a, b){return a-b});\n\nif (dcpins !== flow.get(\"dcpins\")) {\n flow.set(\"dcpins\", dcpins)\n}\n\nif (msg.topic === \"tick\") {\n for (i = 0; i < dcpins.length; i++) {\n msg.topic = dcpins[i]\n var power = flow.get(String(dcpins[i])+\"dcpower\");\n var dctime = flow.get(String(dcpins[i])+\"dctime\");\n var inn = msg.payload\n // yes, payload is timestamp, calc current wave value between 0 and 1\n var wave = inn % dctime/dctime; // fraction of way through cycle\n var direction;\n // determine direction of travel and convert to triangular wave\n if (wave < 0.5) {\n direction = 1; // on the way up\n wave = wave*2;\n } else {\n direction = -1; // on the way down\n wave = (1 - wave)*2;\n }\n var requestedPower = power || 0;\n // if a dead_time has been supplied for this o/p then adjust power accordingly\n if (deadTime > 0 && requestedPower > 0.0 && requestedPower < 1.0) {\n var dtop = deadTime/dctime;\n power = (1.0-2.0*dtop)*requestedPower + dtop;\n } else {\n power = requestedPower;\n }\n // cope with end cases in case values outside 0..1\n var opState;\n if (power <= 0.0) {\n opState = 0; // no heat\n } else if (power >= 1.0) {\n opState = 1; // full heat\n } else {\n // only allow power to come on on the way down and off on the way up, to reduce short pulses\n if (power >= wave && direction === -1) {\n opState = 1;\n } else if (power <= wave && direction === 1) {\n opState = 0;\n } else {\n // otherwise leave it as it is\n opState = flow.get(String(dcpins[i])+'opState') || 0;\n } \n }\n flow.set(String(dcpins[i])+'opState', opState);\n \n var out = invert ? (1-opState) : opState;\n if ((out !== flow.get(String(dcpins[i])+\"previousout\")) || (flow.get(String(dcpins[i])+\"dcdisabled\") === true)) {\n flow.set(String(dcpins[i])+\"previousout\", out)\n flow.set(String(dcpins[i])+\"dcdisabled\", false)\n flow.set(String(dcpins[i]), out)\n msg.payload = out\n msg.topic = dcpins[i]\n node.send(msg)\n }\n}\n}\n\n \n\n\n\n\n\n","outputs":1,"noerr":0,"x":450,"y":780,"wires":[["71ed0fc1.2674d"]]},{"id":"3ba727c9.6fecc8","type":"tcp in","z":"6dc4c6ac.83d2b8","name":"","server":"server","host":"","port":"5000","datamode":"stream","datatype":"utf8","newline":"","topic":"","base64":false,"x":180,"y":800,"wires":[["c6839720.edfc38"]]},{"id":"bea6c539.232428","type":"tcp out","z":"6dc4c6ac.83d2b8","host":"","port":"","beserver":"reply","base64":false,"end":false,"name":"","x":450,"y":820,"wires":[]},{"id":"60db6701.40c848","type":"switch","z":"6dc4c6ac.83d2b8","name":"out","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"1","vt":"str"},{"t":"eq","v":"2","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":710,"y":760,"wires":[[],[]]},{"id":"645492c.c0dd96c","type":"function","z":"6dc4c6ac.83d2b8","name":"input","func":"if (typeof(msg.payload) !== \"undefined\") {\n\n var pin = msg.topic;\n var value = msg.payload;\n flow.set(String(pin),value)\n\n if (flow.get(String(pin)+\"config\") === 5 && pin >= 100 ){ //hysteresis\n var outpin = flow.get(String(pin)+\"pin\") || 0\n var setpoint = flow.get(String(outpin)+\"setpoint\") || 0\n var setpoint2 = flow.get(String(outpin)+\"setpoint2\") || 0\n var config = flow.get(String(outpin)+\"config\") || 99\n var cooling = flow.get(String(outpin)+\"cooling\") || false\n var delay = flow.get(String(outpin)+\"delay\")\n var out = flow.get(String(outpin)+\"out\")\n \n \n if (value < setpoint) {\n if (cooling === true) {\n out = false\n } else {\n out = true\n }\n }\n if (value > setpoint2) {\n if (cooling === true) {\n out = true\n } else {\n out = false\n }\n }\n \n if (value === -12700) {\n out = false\n }\n \n if (config == 99) {\n out = false\n }\n if (out !== flow.get(String(outpin)+\"out\")) {\n flow.set(String(outpin)+\"out\", out)\n if (out === false) {\n context.set(String(outpin)+\"status\", Number(out))\n msg.topic = outpin\n msg.payload = Number(flow.get(String(outpin)+\"out\"))\n node.send(msg);\n }\n \n if (out === true && config !== 99 && value !== -12700) {\n setTimeout(start, delay)\n }\n }\n setTimeout(mismatch, 2000)\n}\n//PID\n if (flow.get(String(pin)+\"config\") === 6) {\n outpin = flow.get(String(pin)+\"pin\") || 0\n //var config = flow.get(String(outpin)+\"config\") || 99\n var pidsetpoint = flow.get(String(outpin)+\"setpoint\");\n var prop_band = flow.get(String(outpin)+\"prop_band\");\n var t_integral = flow.get(String(outpin)+\"t_integral\");\n var t_derivative = flow.get(String(outpin)+\"t_derivative\");\n \n if (flow.get(String(outpin)+\"config\") === 99 || flow.get(String(pin)) === -12700) {\n msg.topic = pin\n var maxout = flow.get(String(pin)+\"maxout\");\n flow.set(String(pin)+\"oldmaxout\", maxout)\n flow.set(String(pin)+\"maxout\", 0)\n msg.enable = 0\n msg.disabled_op = 0\n node.send(msg)\n }\n \n else {\n var oldmaxout = flow.get(String(pin)+\"oldmaxout\");\n flow.set(String(pin)+\"maxout\", oldmaxout)\n msg.enable = 1\n msg.topic = pin\n msg.payload = flow.get(String(pin))\n msg.setpoint = pidsetpoint\n msg.prop_band = prop_band\n msg.t_integral = t_integral\n msg.t_derivative = t_derivative\n node.send(msg)\n }\n }\n}\n\nfunction start() {\n if (config !== 99 && value !== -12700) {\n context.set(String(outpin)+\"status\", Number(flow.get(String(outpin)+\"out\")))\n msg.topic = outpin\n msg.payload = Number(flow.get(String(outpin)+\"out\"))\n node.send(msg);\n }\n \n}\n\nfunction mismatch() {\n if (context.get(String(outpin)+\"status\") !== flow.get(String(outpin)) ) {\n context.set(String(outpin)+\"status\", Number(flow.get(String(outpin)+\"out\")))\n if (Number(flow.get(String(outpin)+\"out\")) === 1 && config !== 99 && value !== -12700) {\n setTimeout(start, delay)\n }\n if (Number(flow.get(String(outpin)+\"out\")) === 0) {\n msg.payload = Number(flow.get(String(outpin)+\"out\"))\n msg.topic = outpin\n node.send(msg)\n }\n }\n}","outputs":1,"noerr":0,"x":450,"y":740,"wires":[["54c14458.59eedc"]]},{"id":"54c14458.59eedc","type":"link out","z":"6dc4c6ac.83d2b8","name":"input","links":["89ef5759.fc2d28","c64ede7c.d3a6a"],"x":535,"y":740,"wires":[]},{"id":"71ed0fc1.2674d","type":"link out","z":"6dc4c6ac.83d2b8","name":"config","links":["89ef5759.fc2d28"],"x":535,"y":780,"wires":[]},{"id":"89ef5759.fc2d28","type":"link in","z":"6dc4c6ac.83d2b8","name":"outputs","links":["71ed0fc1.2674d","54c14458.59eedc","58d6778.cbf3088","bdc1e45b.bcdfc8"],"x":615,"y":760,"wires":[["60db6701.40c848"]]},{"id":"cc96708e.f3e01","type":"link in","z":"6dc4c6ac.83d2b8","name":"","links":["aca07636.8cbe28","d8d01682.693928"],"x":355,"y":740,"wires":[["645492c.c0dd96c"]]},{"id":"d4b673dd.9ea8f","type":"smooth","z":"6dc4c6ac.83d2b8","name":"","property":"payload","action":"mean","count":"10","round":"0","mult":"multi","reduce":false,"x":420,"y":420,"wires":[["d8d01682.693928"]]}]
Add Comment
Please, Sign In to add comment