Patrick Weber
Patrick Weber

Reputation: 65

Node-Red UI_Template send msg

to control my robot via Node-Red dashboard, I need some kind of joystick control for UI (not a hardware joystick).

Luckily I found nippleJS which does exactly what I was looking for. Also I was able to get it running with ui_template node.

Now I get stuck. How can I send the coordinates back to node-red node? I know that I can't reach any context and I only get a msg object. But I'm unable to change it (msg undefined).

Here is my current flow. To run it you must load nipplejs and set the path accordingly. I hope someone out there can show me a way how to send data back to node-red

[{"id":"ff5f827f.796e","type":"ui_template","z":"9738c4ac.01e748","group":"9550e4e.ea6f618","name":"","order":0,"width":"6","height":"6","format":"\n<script src=\"/myjs/nippleJS/nipplejs.min.js\" ></script>\n\n<div data-type=\"semi\" id=\"zone_joystick\" style=\"position:absolute; width:200px; height:200px; background-color:grey;\"></div>\n\n<script>\n\n\n           (function(scope){ \n\n                scope.$watch('msg', function(msg) {\n                createJoystick();\n           \n                });\n            })(scope);\n\n\nfunction createJoystick(){\n    var semi = nipplejs.create({\n        zone: document.getElementById('zone_joystick'),\n        mode: 'semi',\n        catchDistance: 150,\n        color: 'white'\n    });\n\t\n\n\tsemi.on('move', function(evt, nipple_obj) {\n\t   debug(nipple_obj);\n\t});\n\t\n\t}\n\nfunction debug(obj) {\n  setTimeout(function() {\n    var test = obj.position.x;\n    console.log(test);\n  }, 0);\n}\t\n\t\n\t\t\n\n</script>","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":286,"y":708,"wires":[["17f18c51.494204","3e99bf46.a8532"]]},{"id":"b2219879.075b28","type":"inject","z":"9738c4ac.01e748","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":117,"y":675,"wires":[["ff5f827f.796e"]]},{"id":"17f18c51.494204","type":"ui_text","z":"9738c4ac.01e748","group":"9550e4e.ea6f618","order":0,"width":"3","height":"2","name":"","label":"text","format":"{{msg.payload}}","layout":"row-spread","x":468,"y":736,"wires":[]},{"id":"3e99bf46.a8532","type":"debug","z":"9738c4ac.01e748","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":314,"y":769,"wires":[]},{"id":"9550e4e.ea6f618","type":"ui_group","z":"","name":"Joystick","tab":"ccfc45fa.de7cb8","order":1,"disp":true,"width":"6","collapse":false},{"id":"ccfc45fa.de7cb8","type":"ui_tab","z":"","name":"Bubbles","icon":"dashboard"}]

For those who don't want to import the flow, here is the Script I use. As you see in function debug, I can print the values to console. I need this value back.

<script src="/myjs/nippleJS/nipplejs.min.js" ></script>

<div data-type="semi" id="zone_joystick" style="position:absolute; width:200px; height:200px; background-color:grey;"></div>

<script>


           (function(scope){ 

                scope.$watch('msg', function(msg) {
                createJoystick();
           
                });
            })(scope);


function createJoystick(){
    var semi = nipplejs.create({
        zone: document.getElementById('zone_joystick'),
        mode: 'semi',
        catchDistance: 150,
        color: 'white'
    });
	

	semi.on('move', function(evt, nipple_obj) {
	   debug(nipple_obj);
	   
	});
	
	}

function debug(obj) {
  setTimeout(function() {
    var test = obj.position.x;
    console.log(test);
  }, 0);
}	
	
		

</script>

Thank you for your support, Patrick.

Upvotes: 1

Views: 3871

Answers (2)

Patrick Weber
Patrick Weber

Reputation: 65

Just in case someone else wants to use nippleJS, here is my workling code

[{"id":"d1cb92a5.0e9b2","type":"inject","z":"cf477024.84de6","name":"Trigger UI Templates","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":163,"y":209,"wires":[["93a7c595.e3b868","8b092d1b.0e2ed"]]},{"id":"8b092d1b.0e2ed","type":"ui_template","z":"cf477024.84de6","group":"52892a0c.d9c5b4","name":"Joystick","order":0,"width":"6","height":"6","format":"<script src=\"/myjs/nippleJS/nipplejs.min.js\" ></script>\n\n<div data-type=\"dynamic\" id=\"zone_joystick\" style=\"position:absolute; width:200px; height:200px; background-color:grey;\"></div>\n\n<script>\n\n\n(function(scope){ \n\n    function createJoystick(){\n        var dynamic = nipplejs.create({\n            zone: document.getElementById('zone_joystick'),\n            mode: 'dynamic',\n            catchDistance: 150,\n            color: 'white'\n        });\n        dynamic.on('move', function(evt, nipple_obj) {\n            setTimeout(function() {\n                var posx = nipple_obj.position.x;\n                var posy = nipple_obj.position.y;\n                var centerx = nipple_obj.instance.position.x;\n                var centery = nipple_obj.instance.position.y;\n                // use scope.send to trigger a message in the runtime flow\n                scope.send({payload:{x: posx, y:posy, centerx:centerx, centery:centery}});\n            }, 0);\n\n        });\n    }\n\n\n    scope.$watch('msg', function(msg) {\n        createJoystick();\n\n    });\n})(scope);\n\n</script>","storeOutMessages":false,"fwdInMessages":false,"templateScope":"local","x":434,"y":212,"wires":[["65da6852.c65ac8","fbdf3963.9c2858"]]},{"id":"fbdf3963.9c2858","type":"function","z":"cf477024.84de6","name":"","func":"\nvar x = {payload:msg.payload.centerx - msg.payload.x};\nvar y = {payload:msg.payload.centery - msg.payload.y};\n\nreturn [x, y];","outputs":2,"noerr":0,"x":578,"y":216,"wires":[["26f05e22.8d3a12"],["2d78681b.d82be8"]]},{"id":"26f05e22.8d3a12","type":"ui_text","z":"cf477024.84de6","group":"52892a0c.d9c5b4","order":0,"width":"3","height":"1","name":"","label":"X","format":"{{msg.payload}}","layout":"row-spread","x":710,"y":227,"wires":[]},{"id":"2d78681b.d82be8","type":"ui_text","z":"cf477024.84de6","group":"52892a0c.d9c5b4","order":0,"width":"3","height":"2","name":"","label":"Y","format":"{{msg.payload}}","layout":"row-spread","x":719,"y":275,"wires":[]},{"id":"65da6852.c65ac8","type":"debug","z":"cf477024.84de6","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":571,"y":257,"wires":[]},{"id":"52892a0c.d9c5b4","type":"ui_group","z":"","name":"Default","tab":"56c2703a.7a819","disp":true,"width":"6","collapse":false},{"id":"56c2703a.7a819","type":"ui_tab","z":"","name":"Manual","icon":"dashboard"}]

Thanks again knolleary

Upvotes: 0

knolleary
knolleary

Reputation: 10117

The scope object has a send function that can be used to send a message from the ui_template node within the runtime.

You need to structure your code so the callback for the move event is in scope of the scope variable. For example, replace your code inside the <script> block with:

(function(scope){ 

    function createJoystick(){
        var semi = nipplejs.create({
            zone: document.getElementById('zone_joystick'),
            mode: 'semi',
            catchDistance: 150,
            color: 'white'
        });
        semi.on('move', function(evt, nipple_obj) {
            setTimeout(function() {
                var test = obj.position.x;
                // use scope.send to trigger a message in the runtime flow
                scope.send({payload:test});
            }, 0);

        });
    }


    scope.$watch('msg', function(msg) {
        createJoystick();

    });
})(scope);

Upvotes: 2

Related Questions