[{"id":"5905d21e.2bc55c","type":"tab","label":"Sailing Performance Dashboard","disabled":false,"info":""},{"id":"b4f3630c.1ea2","type":"json","z":"5905d21e.2bc55c","name":"","property":"payload","action":"","pretty":false,"x":490,"y":500,"wires":[["44b57282.348e1c","8d80b0bf.8e214"]]},{"id":"8d80b0bf.8e214","type":"function","z":"5905d21e.2bc55c","name":"SPD to Signal K","func":"function pushAngleValue(values, path, d) { // Convert from deg to rad\n if (typeof d !== 'undefined') {\n values.push( { \"path\": path, \"value\": d * (Math.PI / 180) } );\n }\n}\n\nfunction pushDistanceValue(values, path, d) { // Convert miles to m\n if (typeof d !== 'undefined') {\n values.push( { \"path\": path, \"value\": 1852 * d} );\n }\n}\n\nfunction pushSpeedValue(values, path, k) { // Convert kts to m/s\n if (typeof k !== 'undefined') {\n values.push( { \"path\": path, \"value\": k * 0.514444 } );\n }\n}\n\nfunction pushStringValue(values, path, s) {\n if (typeof s !== 'undefined') {\n values.push({ \"path\": path, \"value\": s} );\n }\n}\n\nfunction pushAnyValue(values, path, s) {\n if (typeof s !== 'undefined') {\n values.push( { \"path\": path, \"value\": s} );\n }\n}\n\nvalues = [];\npushAngleValue(values, \"environment.wind.angleApparent\", msg.payload.AWA);\npushAngleValue(values, \"environment.wind.angleTrueWater\", msg.payload.TWA);\npushAngleValue(values, \"environment.wind.angleTrueGround\", msg.payload.GEOWIND);\npushStringValue(values,\"environment.wind.shift\", msg.payload.windshift);\npushSpeedValue(values,\"environment.wind.speedApparent\", msg.payload.AWS); \npushSpeedValue(values,\"environment.wind.speedTrue\", msg.payload.TWS);\npushSpeedValue(values,\"environment.wind.speedTrue.average\", msg.payload[\"TWS-avg\"]);\npushSpeedValue(values,\"environment.wind.speedTrue.trend\", msg.payload[\"TWS-trend\"]);\npushSpeedValue(values,\"environment.wind.speedOverGround\", msg.payload[\"GEOWIND-TWS\"]);\npushSpeedValue(values,\"environment.wind.speedOverGround.average\", msg.payload[\"GEOWIND-TWS-avg\"]);\npushSpeedValue(values,\"environment.wind.speedOverGround.trend\", msg.payload[\"GEOWIND-TWS-trend\"]); \npushAngleValue(values,\"environment.wind.upwash\", msg.payload.Upwash);\npushStringValue(values,\"environment.wind.bow\", msg.payload.BOW);\npushAnyValue(values,\"environment.depth.average\", msg.payload[\"Depth-avg\"]);\npushAnyValue(values,\"environment.depth.change\", msg.payload[\"Depth-change\"]);\npushSpeedValue(values,\"environment.current.drift\", msg.payload[\"Current-kts\"]);\npushAngleValue(values,\"environment.current.setTrue\", msg.payload[\"Current-degrees-relative\"]);\npushAnyValue(values,\"environment.heave\", msg.payload[\"Heave-vertical\"]);\npushAngleValue(values,\"steering.rudderAngle\", msg.payload[\"Rudder-angle\"]);\npushAngleValue(values,\"navigation.destination.twa\", msg.payload[\"TWA-to-WP\"]);\npushStringValue(values,\"navigation.destination.waypoint\", msg.payload.Waypoint); \npushDistanceValue(values,\"navigation.destination.distance\", msg.payload.DTW);\npushAnyValue(values,\"navigation.destination.enroute\", msg.payload[\"Est-Time en Route\"]);\npushAngleValue(values,\"navigation.destination.bearing\", msg.payload.BTW);\npushSpeedValue(values,\"navigation.destination.vmg\", msg.payload[\"VMG-to-WP\"]);\npushAnyValue(values,\"navigation.waypoint.polarspeedRatio\", msg.payload[\"Performance-to-WP\"]); \npushAngleValue(values,\"navigation.courseOverGroundTrue\", msg.payload[\"COG\"]);\npushAngleValue(values,\"navigation.headingTrue\", msg.payload[\"HDG-corrected\"]); \npushSpeedValue(values,\"navigation.speedOverGround\", msg.payload.SOG);\npushSpeedValue(values,\"navigation.speedOverGround.forward\", msg.payload[\"SOG-forward\"]);\npushSpeedValue(values,\"navigation.speedThroughWater\", msg.payload[\"STW-corrected\"]); \npushSpeedValue(values,\"navigation.speed-shortage\", msg.payload[\"Speed-shortage\"]);\npushDistanceValue(values,\"navigation.racing.layline.distance\", msg.payload[\"Distance-layline\"]); \npushAnyValue(values,\"navigation.racing.layline.time\", msg.payload[\"Time-layline\"]); \npushAngleValue(values,\"navigation.attitude.heel.best\", msg.payload[\"Best-heel\"]); \npushAngleValue(values,\"navigation.attitude.heel\", msg.payload[\"Actual-heel\"]); \npushAngleValue(values,\"navigation.attitude.pitch\", msg.payload[\"Actual-pitch\"]); \npushAngleValue(values,\"navigation.attitude.yaw\", msg.payload[\"Actual-yaw\"]); \npushAnyValue(values,\"navigation.rateOfTurn\", msg.payload[\"Rate-of-Turn\"]);\npushAnyValue(values,\"navigation.courseRhumbline.crossTrackError\", msg.payload.XTE); \npushSpeedValue(values,\"performance.velocityMadeGood\", msg.payload.VMG);\npushAngleValue(values,\"performance.beatAngle\", msg.payload[\"Upwind-angle\"]);\npushAngleValue(values,\"performance.beatAngle.error\", msg.payload[\"UA-error\"]); \npushAngleValue(values,\"performance.gybeAngle\", msg.payload[\"Downwind-angle\"]); \npushAngleValue(values,\"performance.gybeAngle.error\", msg.payload[\"DA-error\"]); \npushAngleValue(values,\"performance.targetAngle\", msg.payload[\"Best-angle\"]);\npushAngleValue(values,\"performance.targetAngle.error\", msg.payload[\"Best-angle-error\"]);\npushAngleValue(values,\"performance.leeway.expected\", msg.payload[\"Expected-leeway\"]);\npushAngleValue(values,\"performance.leeway\", msg.payload[\"Actual-leeway\"]);\npushAnyValue(values,\"performance.polarSpeedRatio\", msg.payload[\"Performance-incl-current\"]);\npushAnyValue(values,\"performance.polarSpeedRatio.waterspeed\", msg.payload[\"Performance-waterspeed\"]); \npushAnyValue(values,\"performance.polarspeedRatio.windward\", msg.payload[\"Performance-to-windward\"]); \npushSpeedValue(values,\"performance.polarSpeed\",msg.payload[\"Target-speed\"]);\npushSpeedValue(values,\"performance.velocityMadeGood.target\", msg.payload[\"Target-VMG\"]); \npushStringValue(values,\"performance.Trim-advice1\", msg.payload[\"Trim-advice1\"]); \npushStringValue(values,\"performance.Trim-advice2\", msg.payload[\"Trim-advice2\"]); \npushStringValue(values,\"performance.Trim-advice3\", msg.payload[\"Trim-advice3\"]); \npushAngleValue(values,\"spd.Off Course\", msg.payload[\"Off Course\"]);\npushAnyValue(values,\"spd.Speed-sideways\", msg.payload[\"Speed-sideways\"]);\npushSpeedValue(values,\"spd.Speed from current\", msg.payload[\"Speed from current\"]); \n// TODO\npushAnyValue(values, \"spd.Current-from-degrees\", \"\");\npushAngleValue(values,\"spd.Current-to-degrees\", msg.payload[\"Current-to-degrees\"]);\n// TODO\npushAnyValue(values, \"spd.Current-impact\", \"\");\npushStringValue(values,\"spd.Wind-message\", msg.payload[\"Wind-message\"]);\npushStringValue(values,\"spd.Current-message\", msg.payload[\"Current-message\"]); \npushSpeedValue(values,\"spd.Performance-SOG\", msg.payload[\"Performance-SOG\"]); \npushAnyValue(values,\"spd.GPS-RMC-time\", msg.payload[\"GPS-RMC-time\"]);\npushStringValue(values,\"spd.Direction-to-steer\", msg.payload[\"Direction-to-steer\"]);\npushAnyValue(values,\"spd.controls.Current-limit-degrees\", msg.payload[\"Current-limit-degrees\"]);\npushAnyValue(values,\"spd.controls.Current-limit-kts\", msg.payload[\"Current-limit-kts\"]);\npushAnyValue(values,\"spd.controls.Shift-limit\", msg.payload[\"Shift-limit\"]); \npushAnyValue(values,\"spd.controls.Records-filter\", msg.payload[\"Records-filter\"]);\npushAnyValue(values,\"spd.controls.AppWind-filter\", msg.payload[\"App Wind-filter\"]);\n\npushAnyValue(values,\"spd.controls.Replay-speed\", msg.payload[\"Replay-speed\"]);\npushAnyValue(values,\"spd.controls.Log-nr\", msg.payload[\"Log-nr\"]); \npushAnyValue(values,\"spd.controls.Records-processed\", msg.payload[\"Records-processed\"]);\npushAnyValue(values,\"spd.controls.Performance-filter\", msg.payload[\"Performance-filter\"]); \npushStringValue(values,\"spd.controls.Speed-source\", msg.payload[\"Speed-source\"]);\n\nreturn { payload: {\n \"updates\": [\n {\n \"values\": values\n }\n ]\n }\n}\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":660,"y":500,"wires":[["5b15d1e7ae204937","aa48fb5ebbe65b4c"]]},{"id":"afc09c64.dd2c9","type":"websocket in","z":"5905d21e.2bc55c","name":"","server":"","client":"c19e9b7a.5af818","x":140,"y":520,"wires":[["65ab04c1932bf8d0"]]},{"id":"65ab04c1932bf8d0","type":"switch","z":"5905d21e.2bc55c","name":"","property":"payload","propertyType":"msg","rules":[{"t":"regex","v":"^{","vt":"str","case":false},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":350,"y":520,"wires":[["b4f3630c.1ea2"],["b7be7380b3d8fceb","d21adc0e42df6fe0"]]},{"id":"44b57282.348e1c","type":"debug","z":"5905d21e.2bc55c","name":"SailingPD json","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":660,"y":580,"wires":[]},{"id":"aa48fb5ebbe65b4c","type":"debug","z":"5905d21e.2bc55c","name":"SignalK delta","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":890,"y":580,"wires":[]},{"id":"5b15d1e7ae204937","type":"signalk-send-delta","z":"5905d21e.2bc55c","name":"","x":910,"y":500,"wires":[]},{"id":"b7be7380b3d8fceb","type":"debug","z":"5905d21e.2bc55c","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":470,"y":580,"wires":[]},{"id":"c77198ae04cf2542","type":"websocket out","z":"5905d21e.2bc55c","name":"","server":"","client":"c19e9b7a.5af818","x":840,"y":680,"wires":[]},{"id":"17ea4fa8d301655d","type":"ui_button","z":"5905d21e.2bc55c","name":"","group":"b569de3d08052257","order":1,"width":"3","height":"1","passthru":false,"label":"Quit","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"quit","payloadType":"str","topic":"topic","topicType":"msg","x":550,"y":660,"wires":[["c77198ae04cf2542"]]},{"id":"4eaa739d9b42bbcb","type":"ui_button","z":"5905d21e.2bc55c","name":"","group":"b569de3d08052257","order":2,"width":"3","height":"1","passthru":false,"label":"Files","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"files","payloadType":"str","topic":"topic","topicType":"msg","x":550,"y":700,"wires":[["c77198ae04cf2542"]]},{"id":"9b9f537be94cf9df","type":"ui_button","z":"5905d21e.2bc55c","name":"","group":"b569de3d08052257","order":3,"width":"2","height":"1","passthru":false,"label":"NMEA","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"nmea","payloadType":"str","topic":"topic","topicType":"msg","x":550,"y":740,"wires":[["c77198ae04cf2542"]]},{"id":"3bf38500aaeb6474","type":"ui_button","z":"5905d21e.2bc55c","name":"","group":"b569de3d08052257","order":5,"width":"2","height":"1","passthru":false,"label":"NEWLOG","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"newlog","payloadType":"str","topic":"topic","topicType":"msg","x":560,"y":780,"wires":[["c77198ae04cf2542"]]},{"id":"99102adba67750f6","type":"ui_button","z":"5905d21e.2bc55c","name":"","group":"b569de3d08052257","order":8,"width":"2","height":"1","passthru":false,"label":">>","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"shiftthresup","payloadType":"str","topic":"topic","topicType":"msg","x":550,"y":820,"wires":[["c77198ae04cf2542"]]},{"id":"15204c6e9ad486f9","type":"ui_button","z":"5905d21e.2bc55c","name":"","group":"b569de3d08052257","order":6,"width":"2","height":"1","passthru":false,"label":"<<","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"shiftthresdn","payloadType":"str","topic":"topic","topicType":"msg","x":550,"y":860,"wires":[["c77198ae04cf2542"]]},{"id":"ffee142e81126b78","type":"ui_text","z":"5905d21e.2bc55c","group":"b569de3d08052257","order":7,"width":"2","height":"1","name":"","label":"Shift-limit","format":"{{msg.payload}}","layout":"row-center","className":"","x":420,"y":840,"wires":[]},{"id":"1a4868a059ce2e1d","type":"ui_button","z":"5905d21e.2bc55c","name":"","group":"b569de3d08052257","order":11,"width":"2","height":"1","passthru":false,"label":">>","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"currthresup","payloadType":"str","topic":"topic","topicType":"msg","x":550,"y":940,"wires":[["c77198ae04cf2542"]]},{"id":"6dd71126703978ac","type":"ui_button","z":"5905d21e.2bc55c","name":"","group":"b569de3d08052257","order":9,"width":"2","height":"1","passthru":false,"label":"<<","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"currthresdn","payloadType":"str","topic":"topic","topicType":"msg","x":550,"y":900,"wires":[["c77198ae04cf2542"]]},{"id":"05f28a7b59160afe","type":"ui_text","z":"5905d21e.2bc55c","group":"b569de3d08052257","order":10,"width":"2","height":"1","name":"","label":"Curr-limit","format":"{{msg.payload}}","layout":"row-spread","className":"","x":420,"y":920,"wires":[]},{"id":"18e86843fc247527","type":"ui_button","z":"5905d21e.2bc55c","name":"","group":"b569de3d08052257","order":14,"width":"2","height":"1","passthru":false,"label":">>","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"filterup","payloadType":"str","topic":"topic","topicType":"msg","x":550,"y":980,"wires":[["c77198ae04cf2542"]]},{"id":"8aec15738c819ad1","type":"ui_button","z":"5905d21e.2bc55c","name":"","group":"b569de3d08052257","order":12,"width":"2","height":"1","passthru":false,"label":"<<","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"filterdn","payloadType":"str","topic":"topic","topicType":"msg","x":550,"y":1020,"wires":[["c77198ae04cf2542"]]},{"id":"b180b9eaabac062f","type":"ui_text","z":"5905d21e.2bc55c","group":"b569de3d08052257","order":13,"width":"2","height":"1","name":"","label":"Filter","format":"{{msg.payload}}","layout":"row-spread","className":"","x":430,"y":1000,"wires":[]},{"id":"bf81b3a7d0b058e4","type":"ui_button","z":"5905d21e.2bc55c","name":"","group":"b569de3d08052257","order":17,"width":"2","height":"1","passthru":false,"label":">>","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"perffilterup","payloadType":"str","topic":"topic","topicType":"msg","x":550,"y":1060,"wires":[["c77198ae04cf2542"]]},{"id":"78599d57b2aa1689","type":"ui_button","z":"5905d21e.2bc55c","name":"","group":"b569de3d08052257","order":15,"width":"2","height":"1","passthru":false,"label":"<<","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"perffilterdn","payloadType":"str","topic":"topic","topicType":"msg","x":550,"y":1100,"wires":[["c77198ae04cf2542"]]},{"id":"ec9ce7f3a2821628","type":"ui_text","z":"5905d21e.2bc55c","group":"b569de3d08052257","order":16,"width":"2","height":"1","name":"","label":"PerfFilter","format":"{{msg.payload}}","layout":"row-spread","className":"","x":420,"y":1080,"wires":[]},{"id":"07c8a27cc2efda84","type":"ui_text","z":"5905d21e.2bc55c","group":"b569de3d08052257","order":19,"width":"2","height":"1","name":"","label":"AWFilter","format":"{{msg.payload}}","layout":"row-spread","className":"","x":420,"y":1160,"wires":[]},{"id":"cadb53fddea89941","type":"ui_button","z":"5905d21e.2bc55c","name":"","group":"b569de3d08052257","order":20,"width":"2","height":"1","passthru":false,"label":">>","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"AWfilterup","payloadType":"str","topic":"topic","topicType":"msg","x":550,"y":1140,"wires":[["c77198ae04cf2542"]]},{"id":"20391f678b3606bf","type":"ui_button","z":"5905d21e.2bc55c","name":"","group":"b569de3d08052257","order":18,"width":"2","height":"1","passthru":false,"label":"<<","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"AWfilterdn","payloadType":"str","topic":"topic","topicType":"msg","x":550,"y":1180,"wires":[["c77198ae04cf2542"]]},{"id":"85c015501ecc8e60","type":"template","z":"5905d21e.2bc55c","name":"html","field":"payload","fieldType":"msg","format":"html","syntax":"mustache","template":"{{#payload}}\n{{msg}}

\n{{/payload}}\n","output":"str","x":710,"y":400,"wires":[["757e82edb073a13f"]]},{"id":"757e82edb073a13f","type":"ui_template","z":"5905d21e.2bc55c","group":"2dee2e04.7cf00a","name":"SPD output","order":1,"width":0,"height":0,"format":"

","storeOutMessages":false,"fwdInMessages":false,"resendOnRefresh":false,"templateScope":"local","className":"","x":870,"y":400,"wires":[[]]},{"id":"d21adc0e42df6fe0","type":"function","z":"5905d21e.2bc55c","name":"Add output","func":"var msg_obj = {msg: msg.payload};\nvar arr_msgs = flow.get(\"spdout\", 'memoryOnly');\n\nif (arr_msgs===undefined ) {\n // Create an empty array if it does not exist yet\n arr_msgs = [];\n}\narr_msgs.push(msg_obj);\n\nif (arr_msgs.length > 20) {\n arr_msgs.shift();\n}\nflow.set(\"spdout\",arr_msgs, 'memoryOnly');\nmsg.payload = arr_msgs;\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":550,"y":400,"wires":[["85c015501ecc8e60"]]},{"id":"078409c014510183","type":"signalk-subscribe","z":"5905d21e.2bc55c","name":"spd.controls.Shift-limit","mode":"sendChanges","flatten":true,"context":"vessels.self","path":"spd.controls.Shift-limit","source":"signalk-node-red","period":1000,"x":240,"y":840,"wires":[["ffee142e81126b78"]]},{"id":"c973bbd98d1e5434","type":"signalk-subscribe","z":"5905d21e.2bc55c","name":"spd.controls.Current-limit-kts","mode":"sendAll","flatten":true,"context":"vessels.self","path":"spd.controls.Current-limit-kts","source":"signalk-node-red","period":1000,"x":220,"y":920,"wires":[["05f28a7b59160afe"]]},{"id":"0de039806a936f5f","type":"signalk-subscribe","z":"5905d21e.2bc55c","name":"spd.controls.Records-filter","mode":"sendChanges","flatten":true,"context":"vessels.self","path":"spd.controls.Records-filter","source":"signalk-node-red","period":1000,"x":230,"y":1000,"wires":[["b180b9eaabac062f"]]},{"id":"f1c7399499ca35ba","type":"signalk-subscribe","z":"5905d21e.2bc55c","name":"spd.controls.Performance-filter","mode":"sendChanges","flatten":true,"context":"vessels.self","path":"spd.controls.Performance-filter","source":"signalk-node-red","period":1000,"x":220,"y":1080,"wires":[["ec9ce7f3a2821628"]]},{"id":"c04550b00f5ed061","type":"signalk-subscribe","z":"5905d21e.2bc55c","name":"spd.controls.AppWind-filter","mode":"sendChanges","flatten":true,"context":"vessels.self","path":"spd.controls.AppWind-filter","source":"signalk-node-red","period":1000,"x":230,"y":1160,"wires":[["07c8a27cc2efda84"]]},{"id":"4baec59369324f93","type":"ui_text","z":"5905d21e.2bc55c","group":"b569de3d08052257","order":4,"width":"2","height":"1","name":"","label":"Lognr","format":"{{msg.payload}}","layout":"row-center","className":"","x":430,"y":760,"wires":[]},{"id":"14ea6f605624aefa","type":"signalk-subscribe","z":"5905d21e.2bc55c","name":"spd.controls.Log-nr","mode":"sendChanges","flatten":true,"context":"vessels.self","path":"spd.controls.Log-nr","source":"signalk-node-red","period":1000,"x":250,"y":760,"wires":[["4baec59369324f93"]]},{"id":"dabdfa88828872fe","type":"comment","z":"5905d21e.2bc55c","name":"Receive SailingPD values through websocket","info":"","x":190,"y":460,"wires":[]},{"id":"8786e9359b46efcf","type":"comment","z":"5905d21e.2bc55c","name":"Receive SailingPD output through websocket (optional, see comment)","info":"Put web in headless.txt to receive this info\nPut printer in headless.txt to receive the info in the terminal","x":730,"y":340,"wires":[]},{"id":"c21cbe2d60933f95","type":"comment","z":"5905d21e.2bc55c","name":"SailingPD node red dashboard (optional)","info":"","x":300,"y":660,"wires":[]},{"id":"c19e9b7a.5af818","type":"websocket-client","path":"ws://_sailingpd:9090/ws","tls":"","wholemsg":"false","hb":"0"},{"id":"b569de3d08052257","type":"ui_group","name":"Controls","tab":"ce6845d44e38b8dd","order":1,"disp":true,"width":"7","collapse":false,"className":""},{"id":"2dee2e04.7cf00a","type":"ui_group","name":"SPD Output","tab":"ce6845d44e38b8dd","order":2,"disp":true,"width":"20","collapse":true,"className":""},{"id":"ce6845d44e38b8dd","type":"ui_tab","name":"Sailing Performance Dashboard","icon":"dashboard","disabled":false,"hidden":false}]