|
[{"id":"6ec7b365.ffb2f4","type":"function","z":"fc0d5395.fce918","name":"add direction","func":"msg.payload = msg.direction + msg.payload; \nreturn msg;","outputs":1,"noerr":0,"x":1050,"y":420,"wires":[["e99bc2ff.97b23","7fe8b5a2.5f2f0c"]]},{"id":"dabb1e36.1c9a88","type":"inject","z":"fc0d5395.fce918","name":"daily at midnight","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"01 00 * * *","once":false,"onceDelay":0.1,"x":210,"y":160,"wires":[["2859837e.e639a4"]]},{"id":"2859837e.e639a4","type":"http request","z":"fc0d5395.fce918","name":"Get Tide Data","method":"GET","ret":"txt","url":"http://www.ukho.gov.uk/easytide/EasyTide/ShowPrediction.aspx?PortID=0068A&PredictionLength=2","tls":"","x":420,"y":160,"wires":[["172ffaad.1b739d"]]},{"id":"6790a535.f844f4","type":"html","z":"fc0d5395.fce918","name":"parse HWLW labels","property":"payload","outproperty":"payload","tag":".HWLWTableHWLWCell","ret":"text","as":"single","x":690,"y":200,"wires":[["c8a3ffec.f2a848"]]},{"id":"f4e6ba0f.6fbf08","type":"html","z":"fc0d5395.fce918","name":"parse tide times","property":"payload","outproperty":"payload","tag":".HWLWTableCell","ret":"text","as":"single","x":960,"y":240,"wires":[["8d24c477.0542b8"]]},{"id":"28fa46df.150bc2","type":"change","z":"fc0d5395.fce918","name":"save models","rules":[{"t":"set","p":"models","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1410,"y":240,"wires":[[]]},{"id":"3bdc762b.27bbda","type":"inject","z":"fc0d5395.fce918","name":"5 mins","topic":"","payload":"","payloadType":"date","repeat":"300","crontab":"","once":false,"onceDelay":0.1,"x":180,"y":420,"wires":[["c2b6ac46.cb641"]]},{"id":"c522d3ca.1c6ba","type":"function","z":"fc0d5395.fce918","name":"calculate LED and direction","func":"// number of LEDs we have\nmsg.LEDs = 8;\n\n// msg.payload contains an angle in degrees of where we \n// currently are on the sine wave\nvar sine = Math.sin(msg.payload * Math.PI / 180); // -1 to +1\nsine = (sine + 1)/2; // 0 to 1\n// how many pixels are covered by water (blue) at this point?\nvar pixel = Math.round(sine * msg.LEDs); // 0 .. LEDs\n\n// see if tide is going out or coming in\n// by looking at cos of the angle - if it's negative,\n// sine is on way down (i.e. going out), \n// otherwise if cos is +ve, sine is on way up (coming in)\nvar cos = Math.cos(msg.payload * Math.PI / 180);\n\nif (cos < 0) \n msg.direction = 0; // outwards\nelse\n msg.direction = 1; // inwards\n\nmsg.payload = pixel;\nreturn msg;","outputs":1,"noerr":0,"x":580,"y":420,"wires":[["71fd553a.e3e95c","d0d3a9f3.12ad48","b2772b4c.cd4758"]]},{"id":"71fd553a.e3e95c","type":"function","z":"fc0d5395.fce918","name":"compile colours","func":"// msg.payload is how many blue pixels to show\n\nvar LED = [];\n\n// paint them all green\nfor (var i = 0; i<msg.LEDs; i++)\n LED.push('000400');\n\n// paint the right number blue\nfor (var i = 0; i<msg.payload; i++)\n LED[i] = '000004';\n \n// create the string of colours\nmsg.payload = LED.join('');\n//msg.payload = LED.slice().reverse().join('');\n// (in case you need it the other way round!)\n\nreturn msg;","outputs":1,"noerr":0,"x":860,"y":420,"wires":[["6ec7b365.ffb2f4"]]},{"id":"d0d3a9f3.12ad48","type":"debug","z":"fc0d5395.fce918","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":850,"y":480,"wires":[]},{"id":"b2772b4c.cd4758","type":"debug","z":"fc0d5395.fce918","name":"","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"direction","x":860,"y":360,"wires":[]},{"id":"e99bc2ff.97b23","type":"rbe","z":"fc0d5395.fce918","name":"","func":"rbe","gap":"","start":"","inout":"out","property":"payload","x":1210,"y":420,"wires":[["c67e7ad7.3e79a8","d2f74f20.1c843"]]},{"id":"7fe8b5a2.5f2f0c","type":"debug","z":"fc0d5395.fce918","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1190,"y":480,"wires":[]},{"id":"172ffaad.1b739d","type":"change","z":"fc0d5395.fce918","name":"save HTML","rules":[{"t":"set","p":"HTML","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":610,"y":160,"wires":[["6790a535.f844f4"]]},{"id":"c8a3ffec.f2a848","type":"change","z":"fc0d5395.fce918","name":"save / restore data","rules":[{"t":"set","p":"labels","pt":"msg","to":"payload","tot":"msg"},{"t":"set","p":"payload","pt":"msg","to":"HTML","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":910,"y":200,"wires":[["f4e6ba0f.6fbf08"]]},{"id":"3d51a548.9c5432","type":"debug","z":"fc0d5395.fce918","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1410,"y":280,"wires":[]},{"id":"c67e7ad7.3e79a8","type":"change","z":"fc0d5395.fce918","name":"store last sent","rules":[{"t":"set","p":"last_sent","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1420,"y":380,"wires":[[]]},{"id":"f3899839.d4fd","type":"change","z":"fc0d5395.fce918","name":"get last sent","rules":[{"t":"set","p":"payload","pt":"msg","to":"last_sent","tot":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":970,"y":600,"wires":[["fcfa90bc.a0e178"]]},{"id":"fcfa90bc.a0e178","type":"function","z":"fc0d5395.fce918","name":"fix msg","func":"msg = {payload: msg.payload};\nreturn msg;","outputs":1,"noerr":0,"x":1140,"y":600,"wires":[["5f79229.1f6dedc","d2f74f20.1c843"]]},{"id":"5f79229.1f6dedc","type":"debug","z":"fc0d5395.fce918","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1330,"y":600,"wires":[]},{"id":"b6b62985.9ef9e8","type":"comment","z":"fc0d5395.fce918","name":"© Crown Copyright and/or database rights. ","info":"Reproduced by permission of the Controller of Her Majesty’s Stationery Office and the UK Hydrographic Office (www.GOV.uk/UKHO).","x":410,"y":240,"wires":[]},{"id":"c3fbe664.ad6318","type":"comment","z":"fc0d5395.fce918","name":"Replace the port ID ...","info":"Find the Port ID of your choice at http://www.ukho.gov.uk/easytide/EasyTide/SelectPort.aspx\nReplace \"PortID=0048\" in the http link below with the PortID of your port.\n\n","x":420,"y":200,"wires":[]},{"id":"d2f74f20.1c843","type":"ibmiot out","z":"fc0d5395.fce918","authentication":"boundService","apiKey":"","outputType":"cmd","deviceId":"yyy","deviceType":"xxx","eventCommandType":"command","format":"text","data":"{}","qos":0,"name":"send to device","service":"registered","x":1520,"y":480,"wires":[]},{"id":"bbfd829c.8f2f2","type":"ibmiot in","z":"fc0d5395.fce918","authentication":"boundService","apiKey":"","inputType":"evt","logicalInterface":"","ruleId":"","deviceId":"yyy","applicationId":"","deviceType":"xxx","eventType":"status","commandType":"","format":"text","name":"birth certificate","service":"registered","allDevices":"","allApplications":"","allDeviceTypes":false,"allLogicalInterfaces":"","allEvents":false,"allCommands":"","allFormats":"","qos":0,"x":800,"y":600,"wires":[["f3899839.d4fd"]]},{"id":"377d36b7.57b712","type":"comment","z":"fc0d5395.fce918","name":"update Device Type and Device ID","info":"","x":840,"y":660,"wires":[]},{"id":"8d24c477.0542b8","type":"function","z":"fc0d5395.fce918","name":"build array of models","func":"// are we on daylight saving time? (true/false)\nvar DST = false;\n\n\n// need to know the start time\n// the wavelength (or half the wavelength)\n// and whether it's low-high or high-low (phase)\n\n// copy out the times but not the wave heights (heights are e.g. \"4.3 m\"))\nvar times = [];\nfor (var i=0; i<msg.payload.length; i++) {\n if (!msg.payload[i].match(/m$/)) \n times.push(msg.payload[i]);\n}\n \nnode.warn(times);\n\nvar models = [];\n\n// just look at the first 4 entries: that must cover more than 24 hours\n// then get one more, so there's always a \"next\" one to look at, even if we never use it\n// so we don't run off the end of the array of models\nfor (var i=0; i<5;i++) {\n var time1 = parse_time(times[i]);\n var time2 = parse_time(times[i+1]);\n \n if (time2 < time1) {\n // we've wrapped to tomorrow\n time2 += 24;\n }\n \n // get the \"wavelength\" from low to high (about 6 hours)\n var cycle = Math.abs(time2 - time1);\n \n \n // see if the start time is less than the previous start time\n // (only if we've got at least one model already)\n // this is so we have an \"end stop\" that we never reach\n if (i>0 && time1 < models[i-1].start) {\n // we've wrapped to tomorrow\n time1 += 24;\n }\n //node.warn(time1+\" and \"+time2);\n \n \n var phase = 90; // high to low\n if (msg.labels[i] == \"LW\") {\n // low to high\n phase = -90;\n }\n\n if (DST)\n time1 += 1;\n \n models[i] = {start: time1, cycle: cycle, phase: phase};\n}\n\nmsg.payload = models;\nreturn msg;\n\n\n// convert a hh:mm time string into decimal time hh.mmm\nfunction parse_time(time) {\n var components = time.match(/(.*):(.*)/);\n var hours = Number(components[1]);\n var mins = Number(components[2]);\n return hours + mins / 60;\n}","outputs":1,"noerr":0,"x":1180,"y":240,"wires":[["28fa46df.150bc2","3d51a548.9c5432"]]},{"id":"c2b6ac46.cb641","type":"function","z":"fc0d5395.fce918","name":"compute tide","func":"// get current time\nvar now = new Date();\nvar time = now.getHours() + now.getMinutes()/60;\n\n// if we're on daylight saving, add that to shift it one hour to the right\ntime += now.getTimezoneOffset()/60;\n\nvar models = flow.get(\"models\");\nvar current = flow.get(\"current\");\n\n// find the correct current model to use\n// if there either isn't a current one, or the next one available could be in play\n// make the next one available the current one\n// there will always be one more than we need in a day, so there will always be\n// a models[0], and the last one will have a start time > 24, so it will never become\n// valid, so we'll stick with the last one of the previous day until the new day's\n// models come along\n//node.warn(\"model 0 start is \"+models[0].start);\n\nwhile (!current || models[0].start <= time) {\n // if we've just reset, mark this model as special\n if (!current)\n models[0].first = true;\n \n current = models.shift();\n flow.set(\"current\", current);\n node.warn(\"new current...\");\n node.warn(current);\n}\n\n// see if we're still running on last night's final model\n// that can't happen if we've just been reset, so should then use the first model of\n// the day, and extrapolate backwards\nif (!current.first && time < current.start) {\n time += 24;\n}\n\n// use cycle time to calculate deg/hour, 180 deg in cycle time (about 6h)\nvar deg_hour = 180 / current.cycle; // about 30\n\n// find out how far we are through the sine cycle\n// +90 if this is high tide, so it's at the top of the sine wave\n// -90 if low tide, so it's bottom of the sine wave\nvar angle = (time - current.start) * deg_hour + current.phase;\n\nmsg.payload = angle;\nreturn msg;","outputs":1,"noerr":0,"x":350,"y":420,"wires":[["c522d3ca.1c6ba"]]},{"id":"b8366923.3ab128","type":"comment","z":"fc0d5395.fce918","name":"update Device Type and Device ID","info":"","x":1580,"y":540,"wires":[]}] |