Skip to content

Instantly share code, notes, and snippets.

@alex-controlx
Created January 13, 2020 03:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alex-controlx/eb24c4815ed772c244836dbbebd8e9d5 to your computer and use it in GitHub Desktop.
Save alex-controlx/eb24c4815ed772c244836dbbebd8e9d5 to your computer and use it in GitHub Desktop.
Testing a PLC program - IO Simulation
[{"id":"fa3843f7.68d0b","type":"tab","label":"Sim Operator","disabled":false,"info":""},{"id":"fea35f7b.4a29a","type":"tab","label":"Hydraulics","disabled":false,"info":""},{"id":"583f4d36.50aae4","type":"eth-ip endpoint","z":"","address":"192.168.98.1","slot":"0","cycletime":"100","name":"","vartable":{"":{"Local:3:O.Data.0":{"type":"BOOL"},"Local:3:O.Data.1":{"type":"BOOL"},"Local:3:O.Data.2":{"type":"BOOL"},"Local:3:O.Data.3":{"type":"BOOL"},"Local:2:I.Data.0":{"type":"BOOL"},"Local:2:I.Data.1":{"type":"BOOL"},"Local:2:I.Data.2":{"type":"BOOL"},"Local:2:I.Data.3":{"type":"BOOL"},"Local:2:I.Data.4":{"type":"BOOL"},"Local:2:I.Data.5":{"type":"BOOL"},"Local:2:I.Data.6":{"type":"BOOL"},"Local:2:I.Data.7":{"type":"BOOL"},"Local:2:I.Data.8":{"type":"BOOL"},"Local:2:I.Data.9":{"type":"BOOL"},"Local:2:I.Data.10":{"type":"BOOL"},"Local:2:I.Data.11":{"type":"BOOL"},"Local:2:I.Data.12":{"type":"BOOL"},"Local:2:I.Data.13":{"type":"BOOL"},"Local:2:I.Data.14":{"type":"BOOL"},"Local:2:I.Data.15":{"type":"BOOL"},"Local:2:I.Data.16":{"type":"BOOL"},"Local:4:I.Ch0Data":{"type":"REAL"}}}},{"id":"1f5894f7.5861bb","type":"ui_group","z":"","name":"Simulated Operator's Panel","tab":"c46bed3b.020d7","order":2,"disp":true,"width":"6","collapse":false},{"id":"c46bed3b.020d7","type":"ui_tab","z":"","name":"Winch Simulation","icon":"dashboard","disabled":false,"hidden":false},{"id":"b6fd3c8b.d23a3","type":"ui_base","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":"Simulation Demo","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":"d6caabb5.09a3d8","type":"ui_group","z":"","name":"Simulation Outputs","tab":"c46bed3b.020d7","order":3,"disp":true,"width":"6","collapse":false},{"id":"8b42adca.7805b","type":"ui_group","z":"","name":"Default","tab":"c46bed3b.020d7","order":1,"disp":false,"width":"6","collapse":false},{"id":"9c85ac7d.87f5b","type":"eth-ip in","z":"fea35f7b.4a29a","endpoint":"583f4d36.50aae4","mode":"single","variable":"Local:3:O.Data.1","program":"","name":"","x":140,"y":220,"wires":[["592948f2.64f108"]]},{"id":"98c654e4.cb8bd8","type":"eth-ip out","z":"fa3843f7.68d0b","endpoint":"583f4d36.50aae4","variable":"Local:2:I.Data.0","program":"","name":"Start PB","x":920,"y":160,"wires":[]},{"id":"70af2a8b.dc7414","type":"inject","z":"fa3843f7.68d0b","name":"","topic":"","payload":"false","payloadType":"bool","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":110,"y":160,"wires":[["f2fa1f2e.42307","983a7d52.37737","3808bcd0.693014"]]},{"id":"f47ce61d.32f088","type":"eth-ip out","z":"fa3843f7.68d0b","endpoint":"583f4d36.50aae4","variable":"Local:2:I.Data.1","program":"","name":"Stop PB","x":920,"y":220,"wires":[]},{"id":"4635604a.9ab74","type":"function","z":"fa3843f7.68d0b","name":"3 pole switch","func":"\"use strict\";\n\nif (msg.payload !== \"all\" && !Number.isInteger(msg.payload)) return;\n\nconst length = 4;\nconst msgs = (msg.payload === \"all\")?\n Array(length).fill(buildMsg(true)):\n Array(length).fill(buildMsg(false));\n\nif (msg.payload > 0) {\n msgs[0] = null;\n msgs[parseInt(msg.payload)] = buildMsg(true);\n}\n\nreturn msgs\n\nfunction buildMsg(value){\n return {payload: value, topic: msg.topic}\n}","outputs":4,"noerr":0,"x":670,"y":420,"wires":[[],["f0ce2063.e9039"],["8d2c03b.a6113"],["3454c985.bd8ea6"]],"outputLabels":["[reserved]","1st option selected","2nd option selected","3rd option selected"]},{"id":"736e5151.471c1","type":"ui_dropdown","z":"fa3843f7.68d0b","name":"","label":"SS1 Operation Type","tooltip":"","place":"Select option","group":"1f5894f7.5861bb","order":4,"width":0,"height":0,"passthru":true,"options":[{"label":"Error (none)","value":0,"type":"num"},{"label":"Auto","value":1,"type":"num"},{"label":"Manual","value":2,"type":"num"},{"label":"Maint","value":3,"type":"num"},{"label":"Error (all)","value":"all","type":"str"}],"payload":"","topic":"","x":460,"y":420,"wires":[["4635604a.9ab74"]]},{"id":"f0ce2063.e9039","type":"eth-ip out","z":"fa3843f7.68d0b","endpoint":"583f4d36.50aae4","variable":"Local:2:I.Data.2","program":"","name":"SS1 Auto Mode","x":940,"y":360,"wires":[]},{"id":"8d2c03b.a6113","type":"eth-ip out","z":"fa3843f7.68d0b","endpoint":"583f4d36.50aae4","variable":"Local:2:I.Data.3","program":"","name":"SS1 Manual Mode","x":950,"y":420,"wires":[]},{"id":"3454c985.bd8ea6","type":"eth-ip out","z":"fa3843f7.68d0b","endpoint":"583f4d36.50aae4","variable":"Local:2:I.Data.4","program":"","name":"SS1 Maintenance Mode","x":970,"y":480,"wires":[]},{"id":"983a7d52.37737","type":"ui_template","z":"fa3843f7.68d0b","group":"1f5894f7.5861bb","name":"STOP","order":2,"width":0,"height":0,"format":"<script>\n this.scope.sendPayload = function(_scope, value) {\n // const topic = \"_topic\";\n \n if (value === \"out\" && _scope.lastValue)\n return _scope.send(buildMsg(false));\n \n if (typeof value !== \"boolean\") return;\n \n _scope.send(buildMsg(value));\n \n function buildMsg(_payload, _topic){\n _scope.lastValue = _payload;\n return {payload: _payload, topic: _topic}\n }\n }\n</script>\n<md-button\n ng-touchstart=\"sendPayload(this, true)\"\n ng-touchend=\"sendPayload(this, false)\"\n ng-mousedown=\"sendPayload(this, true)\"\n ng-mouseup=\"sendPayload(this, false)\"\n ng-mouseleave=\"sendPayload(this, 'out')\">\n PB2 STOP\n</md-button>","storeOutMessages":false,"fwdInMessages":true,"templateScope":"local","x":450,"y":220,"wires":[["f47ce61d.32f088"]]},{"id":"f2fa1f2e.42307","type":"ui_template","z":"fa3843f7.68d0b","group":"1f5894f7.5861bb","name":"START","order":1,"width":0,"height":0,"format":"<script>\n this.scope.sendPayload = function(_scope, value) {\n // const topic = \"_topic\";\n \n if (value === \"out\" && _scope.lastValue)\n return _scope.send(buildMsg(false));\n \n if (typeof value !== \"boolean\") return;\n \n _scope.send(buildMsg(value));\n \n function buildMsg(_payload, _topic){\n _scope.lastValue = _payload;\n return {payload: _payload, topic: _topic}\n }\n }\n</script>\n<md-button\n ng-touchstart=\"sendPayload(this, true)\"\n ng-touchend=\"sendPayload(this, false)\"\n ng-mousedown=\"sendPayload(this, true)\"\n ng-mouseup=\"sendPayload(this, false)\"\n ng-mouseleave=\"sendPayload(this, 'out')\">\n PB1 START\n</md-button>","storeOutMessages":false,"fwdInMessages":true,"templateScope":"local","x":460,"y":160,"wires":[["98c654e4.cb8bd8"]]},{"id":"3808bcd0.693014","type":"ui_template","z":"fa3843f7.68d0b","group":"1f5894f7.5861bb","name":"RESET","order":2,"width":0,"height":0,"format":"<script>\n this.scope.sendPayload = function(_scope, value) {\n // const topic = \"_topic\";\n \n if (value === \"out\" && _scope.lastValue)\n return _scope.send(buildMsg(false));\n \n if (typeof value !== \"boolean\") return;\n \n _scope.send(buildMsg(value));\n \n function buildMsg(_payload, _topic){\n _scope.lastValue = _payload;\n return {payload: _payload, topic: _topic}\n }\n }\n</script>\n<md-button\n ng-touchstart=\"sendPayload(this, true)\"\n ng-touchend=\"sendPayload(this, false)\"\n ng-mousedown=\"sendPayload(this, true)\"\n ng-mouseup=\"sendPayload(this, false)\"\n ng-mouseleave=\"sendPayload(this, 'out')\">\n PB3 RESET\n</md-button>","storeOutMessages":false,"fwdInMessages":true,"templateScope":"local","x":460,"y":280,"wires":[["1faa0141.05bbef"]]},{"id":"1faa0141.05bbef","type":"eth-ip out","z":"fa3843f7.68d0b","endpoint":"583f4d36.50aae4","variable":"Local:2:I.Data.5","program":"","name":"Reset PB","x":920,"y":280,"wires":[]},{"id":"39433b28.779c94","type":"eth-ip out","z":"fea35f7b.4a29a","endpoint":"583f4d36.50aae4","variable":"Local:2:I.Data.10","program":"","name":"","x":950,"y":260,"wires":[]},{"id":"5e4bb611.72e6b8","type":"eth-ip out","z":"fea35f7b.4a29a","endpoint":"583f4d36.50aae4","variable":"Local:2:I.Data.11","program":"","name":"","x":950,"y":320,"wires":[]},{"id":"df1d7c8d.cafc1","type":"eth-ip in","z":"fea35f7b.4a29a","endpoint":"583f4d36.50aae4","mode":"single","variable":"Local:3:O.Data.0","program":"","name":"","x":140,"y":120,"wires":[["9b0fd6b5.d10f68","87f800e6.3ef1a"]]},{"id":"634967fe.42f608","type":"eth-ip out","z":"fea35f7b.4a29a","endpoint":"583f4d36.50aae4","variable":"Local:4:I.Ch0Data","program":"","name":"","x":950,"y":120,"wires":[]},{"id":"83820e82.96962","type":"ui_switch","z":"fa3843f7.68d0b","name":"","label":"SS2 Extend Base","tooltip":"","group":"1f5894f7.5861bb","order":6,"width":0,"height":0,"passthru":true,"decouple":"false","topic":"","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":480,"y":700,"wires":[["17281267.c1b39e"]]},{"id":"17281267.c1b39e","type":"eth-ip out","z":"fa3843f7.68d0b","endpoint":"583f4d36.50aae4","variable":"Local:2:I.Data.6","program":"","name":"","x":940,"y":700,"wires":[]},{"id":"4ab215af.21d83c","type":"inject","z":"fa3843f7.68d0b","name":"","topic":"","payload":"false","payloadType":"bool","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":130,"y":700,"wires":[["83820e82.96962"]]},{"id":"b0e3a181.cea53","type":"function","z":"fea35f7b.4a29a","name":"Hydraulic Cylinder","func":"\"use strict\";\n// Outputs: 1 - position value; 2 - Max position; 3 - Min Position; 4 - at setpoint\n\n// how long does it take to reach from extended to retracted position\nconst time_ms = 5000;\n// length to travel in [mm]\nconst length = 2000;\n// Mid point setpoint, simulates a limit switch position in [mm] from retracted limit \nconst spLength = 500;\n\n\n// ---- DO NOT CHANGE VALUES BELOW ---- \nconst minPosition = 0;\nconst req = {\n stop: 0,\n forwardStart: 1,\n reverseStart: -1\n}\nconst update_ms = 150;\nconst step = length/(time_ms/update_ms);\n\nif (typeof msg._extend !== \"boolean\" && typeof msg._retract !== \"boolean\") return;\nconst dirRequest = getRequest(msg._extend, msg._retract, context.get(\"dirRequest\"));\n\nif (dirRequest === null) return;\n\ncontext.set(\"dirRequest\", dirRequest);\n\n// if (typeof msg.payload !== \"number\") return;\n// const dirRequest = (msg.payload > 0)? 1: (msg.payload < 0)? -1 : 0;\n// if (context.get(\"dirRequest\") === dirRequest) return;\n\n// node.log(`dirRequest=${dirRequest}, interval=${context.get(\"interval\")}`)\nnode.status({text:`Direction = ${dirRequest}`});\n\nif (dirRequest === req.stop) {\n clearInterval(context.get(\"interval\"));\n return;\n}\n\nlet position = context.get(\"position\") || minPosition;\n\nclearInterval(context.get(\"interval\"));\ncontext.set(\"interval\", setInterval(calculateMove, update_ms));\n\nlet out4Sent = false;\nfunction calculateMove() {\n if (dirRequest === req.forwardStart && position >= length) {\n position = length;\n reachedLimit(true)\n } else if (dirRequest === req.reverseStart && position <= minPosition) {\n position = minPosition;\n reachedLimit(false)\n } else {\n if (position === length || position === minPosition) \n node.send([null, buildMsg(false), buildMsg(false), buildMsg(false)]);\n position = position + dirRequest * step;\n context.set(\"position\", position);\n node.send([buildMsg(position)]);\n // calculate and send middle position\n if (position >= (spLength - step/2) && position < (spLength + step/2)) {\n out4Sent = true;\n node.send([null, null, null, buildMsg(true)]);\n } else if (out4Sent) {\n out4Sent = false;\n node.send([null, null, null, buildMsg(false)]);\n }\n }\n}\n\nfunction reachedLimit(value) {\n context.set(\"position\", position);\n clearInterval(context.get(\"interval\"));\n context.set(\"interval\", null);\n node.send([buildMsg(position), buildMsg(value), buildMsg(!value), buildMsg(false)]);\n}\n\nfunction buildMsg(value) {\n return {payload: value, topic: msg.topic}\n}\n\n\nfunction getRequest(_extend, _retract, lastRequest) {\n\n if (_extend === true) return req.forwardStart;\n if (_retract === true) return req.reverseStart;\n if (_extend === false && lastRequest === req.forwardStart) return req.stop;\n if (_retract === false && lastRequest === req.reverseStart) return req.stop;\n \n return null\n // const forwardStart = (msg.payload && msg.topic !== \"_extend\");\n // const forwardStop = (!msg.payload && msg.topic !== \"_extend\");\n \n // const reverseStart = (msg.payload && msg.topic !== \"_retract\");\n // const reverseStop = (!msg.payload && msg.topic !== \"_retract\");\n}","outputs":4,"noerr":0,"x":630,"y":220,"wires":[["deefadf1.a1e69"],["39433b28.779c94"],["5e4bb611.72e6b8"],[]],"outputLabels":["Position Value","Extended","Retracted","In Mid SP"]},{"id":"592948f2.64f108","type":"function","z":"fea35f7b.4a29a","name":"Prepare signal","func":"// must ba a boolean\nif (typeof msg.payload !== \"boolean\" && msg.topic !== \"pressure\") return;\n\nconst prSP = 40;\n\nif (msg.topic === \"pressure\") {\n context.set(\"pressure\", msg.payload)\n \n if (msg.payload <= prSP) return {_extend: false, _retract: false};\n\n} else {\n if (msg.payload) {\n context.set(\"_extend\", true);\n context.set(\"_retract\", false);\n } else {\n context.set(\"_extend\", false);\n context.set(\"_retract\", true);\n }\n}\n\nif (context.get(\"pressure\") > prSP)\n return {_extend: context.get(\"_extend\"), _retract: context.get(\"_retract\")}","outputs":1,"noerr":0,"x":380,"y":220,"wires":[["b0e3a181.cea53"]],"inputLabels":["Boolean value"]},{"id":"deefadf1.a1e69","type":"ui_text","z":"fea35f7b.4a29a","group":"d6caabb5.09a3d8","order":3,"width":0,"height":0,"name":"","label":"Base Position","format":"{{(msg.payload === 0)? 'PARKED': (msg.payload === 2000)? 'EXTENDED' : (msg.payload).toFixed(2)}}","layout":"row-spread","x":940,"y":200,"wires":[]},{"id":"9b0fd6b5.d10f68","type":"ui_text","z":"fea35f7b.4a29a","group":"d6caabb5.09a3d8","order":1,"width":0,"height":0,"name":"","label":"Hyd Motor","format":"{{(msg.payload === true)? \"ON\" : \"OFF\"}}","layout":"row-spread","x":930,"y":60,"wires":[]},{"id":"23e26343.423a8c","type":"ui_text","z":"fea35f7b.4a29a","group":"d6caabb5.09a3d8","order":2,"width":0,"height":0,"name":"","label":"Pressure","format":"{{msg.payload.toFixed(2)}}, bar","layout":"row-spread","x":1140,"y":60,"wires":[]},{"id":"87f800e6.3ef1a","type":"function","z":"fea35f7b.4a29a","name":"Anaolog Value Rise","func":"\"use strict\";\n// Outputs: 1 - current value; 2 - Max value; 3 - Min value\n\n// how long does it take to reach from extended to retracted position\nconst time_ms = 2000;\n// Max Analog Value\nconst analogValue = 50;\n\n\n// ---- DO NOT CHANGE VALUES BELOW ---- \nconst spLength = 500;\nconst minPosition = 0;\nconst req = {\n stop: 0,\n forwardStart: 1,\n reverseStart: -1\n}\nconst update_ms = 100;\nconst step = analogValue/(time_ms/update_ms);\n\nif (typeof msg.payload !== \"boolean\") return;\nconst dirRequest = getRequest(msg.payload, !msg.payload, context.get(\"dirRequest\"));\n\nif (dirRequest === null) return;\n\ncontext.set(\"dirRequest\", dirRequest);\n\n// if (typeof msg.payload !== \"number\") return;\n// const dirRequest = (msg.payload > 0)? 1: (msg.payload < 0)? -1 : 0;\n// if (context.get(\"dirRequest\") === dirRequest) return;\n\n// node.log(`dirRequest=${dirRequest}, interval=${context.get(\"interval\")}`)\nnode.status({text:`Direction = ${dirRequest}`});\n\nif (dirRequest === req.stop) {\n clearInterval(context.get(\"interval\"));\n return;\n}\n\nlet position = context.get(\"position\") || minPosition;\n\nclearInterval(context.get(\"interval\"));\ncontext.set(\"interval\", setInterval(calculateMove, update_ms));\n\nlet out4Sent = false;\nfunction calculateMove() {\n if (dirRequest === req.forwardStart && position >= analogValue) {\n position = analogValue;\n reachedLimit(true)\n } else if (dirRequest === req.reverseStart && position <= minPosition) {\n position = minPosition;\n reachedLimit(false)\n } else {\n if (position === analogValue || position === minPosition) \n node.send([null, buildMsg(false), buildMsg(false), buildMsg(false)]);\n position = position + dirRequest * step;\n context.set(\"position\", position);\n node.send([buildMsg(position)]);\n // calculate and send middle position\n if (position >= (spLength - step/2) && position < (spLength + step/2)) {\n out4Sent = true;\n node.send([null, null, null, buildMsg(true)]);\n } else if (out4Sent) {\n out4Sent = false;\n node.send([null, null, null, buildMsg(false)]);\n }\n }\n}\n\nfunction reachedLimit(value) {\n context.set(\"position\", position);\n clearInterval(context.get(\"interval\"));\n context.set(\"interval\", null);\n node.send([buildMsg(position), buildMsg(value), buildMsg(!value), buildMsg(false)]);\n}\n\nfunction buildMsg(value) {\n return {payload: value, topic: msg.topic}\n}\n\n\nfunction getRequest(_extend, _retract, lastRequest) {\n\n if (_extend === true) return req.forwardStart;\n if (_retract === true) return req.reverseStart;\n if (_extend === false && lastRequest === req.forwardStart) return req.stop;\n if (_retract === false && lastRequest === req.reverseStart) return req.stop;\n \n return null\n}","outputs":3,"noerr":0,"x":630,"y":120,"wires":[["23e26343.423a8c","634967fe.42f608","274475fa.39477a","274475fa.39477a"],[],[]],"outputLabels":["Position Value","Extended","Retracted","In Mid SP"]},{"id":"274475fa.39477a","type":"function","z":"fea35f7b.4a29a","name":"topic","func":"msg.topic = \"pressure\";\nreturn msg;","outputs":1,"noerr":0,"x":350,"y":160,"wires":[["592948f2.64f108","592948f2.64f108"]]},{"id":"9d1d94f5.e5cb58","type":"ui_slider","z":"fa3843f7.68d0b","name":"","label":"Joystik","tooltip":"Wind In <===> Wind Out","group":"1f5894f7.5861bb","order":5,"width":0,"height":0,"passthru":true,"outs":"end","topic":"","min":"-1","max":"1","step":1,"x":430,"y":540,"wires":[["19cb8c52.06d494","2ec1fd55.008d32"]]},{"id":"19cb8c52.06d494","type":"function","z":"fa3843f7.68d0b","name":"Greater 0","func":"msg.payload = (msg.payload > 0)\nreturn msg;","outputs":1,"noerr":0,"x":660,"y":600,"wires":[["f08aab81.574178"]]},{"id":"2ec1fd55.008d32","type":"function","z":"fa3843f7.68d0b","name":"Less 0","func":"msg.payload = (msg.payload < 0)\nreturn msg;","outputs":1,"noerr":0,"x":650,"y":540,"wires":[["e6623556.5d0708"]]},{"id":"e6623556.5d0708","type":"eth-ip out","z":"fa3843f7.68d0b","endpoint":"583f4d36.50aae4","variable":"Local:2:I.Data.7","program":"","name":"","x":940,"y":540,"wires":[]},{"id":"f08aab81.574178","type":"eth-ip out","z":"fa3843f7.68d0b","endpoint":"583f4d36.50aae4","variable":"Local:2:I.Data.8","program":"","name":"","x":940,"y":600,"wires":[]},{"id":"d1acec7c.47745","type":"eth-ip in","z":"fea35f7b.4a29a","endpoint":"583f4d36.50aae4","mode":"single","variable":"Local:3:O.Data.2","program":"","name":"","x":140,"y":400,"wires":[["6d7bc8c7.0a2988"]]},{"id":"726503e6.6029bc","type":"eth-ip in","z":"fea35f7b.4a29a","endpoint":"583f4d36.50aae4","mode":"single","variable":"Local:3:O.Data.3","program":"","name":"","x":140,"y":460,"wires":[["bd07a1e1.0d84f"]]},{"id":"6d7bc8c7.0a2988","type":"function","z":"fea35f7b.4a29a","name":"","func":"return {_windIn: msg.payload};","outputs":1,"noerr":0,"x":310,"y":400,"wires":[["5e913c98.17cdc4"]]},{"id":"bd07a1e1.0d84f","type":"function","z":"fea35f7b.4a29a","name":"","func":"return {_windOut: msg.payload};","outputs":1,"noerr":0,"x":310,"y":460,"wires":[["5e913c98.17cdc4"]]},{"id":"46c89a41.6e00f4","type":"ui_text","z":"fea35f7b.4a29a","group":"d6caabb5.09a3d8","order":4,"width":0,"height":0,"name":"","label":"Winding Status","format":"{{msg.payload}}","layout":"row-spread","x":940,"y":400,"wires":[]},{"id":"5e913c98.17cdc4","type":"function","z":"fea35f7b.4a29a","name":"","func":"if (typeof msg._windIn === \"boolean\") context.set(\"_windIn\", msg._windIn);\nif (typeof msg._windOut === \"boolean\") context.set(\"_windOut\", msg._windOut);\n\nif (context.get(\"_windIn\") && !context.get(\"_windOut\")) return {payload: \"IN\"};\nif (!context.get(\"_windIn\") && context.get(\"_windOut\")) return {payload: \"OUT\"};\nif (!context.get(\"_windIn\") && !context.get(\"_windOut\")) return {payload: \"Stanby\"};\nif (context.get(\"_windIn\") && context.get(\"_windOut\")) return {payload: \"ERROR\"};","outputs":1,"noerr":0,"x":590,"y":400,"wires":[["46c89a41.6e00f4"]]},{"id":"220e4c49.a59074","type":"ui_switch","z":"fa3843f7.68d0b","name":"","label":"Enable Simulation","tooltip":"","group":"8b42adca.7805b","order":0,"width":0,"height":0,"passthru":true,"decouple":"false","topic":"","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":490,"y":60,"wires":[["3b41a772.5b3ce8"]]},{"id":"b833543c.1807d8","type":"inject","z":"fa3843f7.68d0b","name":"","topic":"","payload":"true","payloadType":"bool","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":110,"y":60,"wires":[["220e4c49.a59074"]]},{"id":"d7009b84.4c4f08","type":"function","z":"fa3843f7.68d0b","name":"Send 2","func":"if (msg.payload === true) return {payload: 2};","outputs":1,"noerr":0,"x":120,"y":420,"wires":[["736e5151.471c1"]]},{"id":"654ccd71.41c774","type":"function","z":"fa3843f7.68d0b","name":"Send 0","func":"if (msg.payload === true) return {payload: 0};","outputs":1,"noerr":0,"x":120,"y":540,"wires":[["9d1d94f5.e5cb58"]]},{"id":"3b41a772.5b3ce8","type":"function","z":"fa3843f7.68d0b","name":"Send 2","func":"if (msg.payload === true) return [{payload: true}, null];\nelse if (msg.payload === false) return [null, {payload: false}];","outputs":2,"noerr":0,"x":700,"y":60,"wires":[["d7009b84.4c4f08","654ccd71.41c774"],["98c654e4.cb8bd8","f47ce61d.32f088","1faa0141.05bbef","f0ce2063.e9039","8d2c03b.a6113","3454c985.bd8ea6","e6623556.5d0708","f08aab81.574178","17281267.c1b39e","d349fdb.ba81"]]},{"id":"d349fdb.ba81","type":"link out","z":"fa3843f7.68d0b","name":"","links":["1c713ae3.111985"],"x":995,"y":60,"wires":[]},{"id":"1c713ae3.111985","type":"link in","z":"fea35f7b.4a29a","name":"","links":["d349fdb.ba81"],"x":715,"y":320,"wires":[["39433b28.779c94","5e4bb611.72e6b8"]]}]
@QvixoteRoux
Copy link

Hi

I am trying to test this code for a raspberry, but there are some modules missing, my guess is that the controls you used for the GUI are from another dependency or package as all nodes related to the GUI are showing errors

@alex-controlx
Copy link
Author

Hi @QvixoteRoux yes I used Dashboard module, which you can get from https://flows.nodered.org/node/node-red-dashboard

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment