How to make a button that send msg once on click and sends msg repeated at set interval on button hold?

At the moment I have two basic buttons. One sends 'G DOWN 0' on click, the other sends 'G UP 0" on click, to a tcp request. This works well, however I need a fast tune ability to hold button and send repeatedly for a scroll effect until button is released, then msg send is stopped. Have googled, but not finding what I am looking for to adapt etc. Any advice from the experts please?

Thankyou

There are a few examples around the forum. Here is one such example: Adding `output` function to buttons designed in `template` node - #54 by Steve-Mcl

Thankyou Steve, I adapted that for a frequency tuner for radio, and working well.
Is it possible to make the interval rate reduce the longer the button is held ?

regards

Adrian Fewster

I assume you mean is it possible to speed up the messages the longer the button is held?
Yes, of course, anything is possible.

chrome_gjQ37wuTZi

You can tweak the template to your liking. The part of the code that is controlling repeat in this update is this...

        var repeatButtons = $(BUTTON_CLASS + "[data-buttontype='repeater']") 
        repeatButtons.on('mousedown',function(e) {
            var btn = $(this);
            if(this.running) return; //already in operation
            var topic = btn.data("topic");//get the topic from attribute data-topic="xxxxx"
            var payload = btn.data("payload");//get the payload from attribute data-payload="xxxxx"
            var interval = btn.data("interval");//get the desired repeat duration
            if(isNumeric(interval) == false || interval < 1) interval = 300;//prevent zero & non numeric timeout value
            const queueSend = (msg, delay, iteration) => {
                if(!this.running) { return }
                $scope.send(msg)
                if(iteration == 5) { delay = delay/2 }//half the delay (speed up after 5 pulses)
                setTimeout(() => {
                    msg.iteration = iteration;
                    if(this.running) {
                        queueSend(msg, delay, iteration+1)
                    }
                },delay) 
            }
            this.running = true;
            queueSend({"topic":topic,"payload":payload},interval,1 )
        }).on('mouseup blur focusout',function(e) {
            this.running = false;
        });

If you want it to go faster after 10 messages, then you could change this

    if(iteration == 5) { delay = delay/2 }//half the delay (speed up after 5 pulses)

to this...

    if(iteration == 5) { delay = delay/2 }//half the delay (speed up after 5 pulses)
    else if(iteration == 10) { delay = delay/2 }//half it again after 10 pulses! 

Demo flow...

[{"id":"f4fac1e9.e93e4","type":"ui_template","z":"a7b009fd18302719","group":"be17d3d4.a92a6","name":"CSS only ","order":7,"width":0,"height":0,"format":"<style id=\"remote-buttons\">\n    :root {\n      --dashboard-unit-width: 48px;\n      --dashboard-unit-height: 48px;\n    }\n    .nr-dashboard-template {\n        padding: 0px;\n    }\n    .remote-button:not([disabled]):hover{\n         background-color: #232323 !important;\n    }\n\n    /*   This is the normal button definition  */\n    .remote-button{\n        background-color: black !important;\n        color: #cccccc !important;\n        height: var(--dashboard-unit-height);\n        width: 100%;\n        border-radius: 10px;\n        font-size:1.0em;\n        font-weight:normal;\n        margin: 0;\n        min-height: 36px;\n        min-width: unset;\n        line-height: unset;\n    }\n    /*  This is a sub-set which is invoked by */\n    /*  <md-button class=\"md-button remote-button bigger\"> */\n    /*  note the (space) \"bigger\" at the end.  */\n    .remote-button.bigger{\n        font-weight:bold;\n        font-size:1.5em;\n    }\n    /*  This is for buttons with a lot of text.  `font-size:0.7em` */\n    /*  makes the font 70% normal size  */\n    .remote-button.small{\n        font-size:0.7em;\n    }\n    /*  This is for buttons with just icons, to upsize the size */\n    /*  of the icon with the line: */\n    /*  <i class=\"fa fa-fw fa-plus remote-icon\"> in the other node  */\n    .remote-icon{\n        font-size:2.0em;\n    }\n    /*  This is the same as the other one, but it makes the icon smaller  */\n    .remote-iconS{\n        font-size:0.5em;\n    }\n\n    .remote-button.black{\n        background-color: black !important;\n        color: #cccccc !important;\n    }\n\n    .remote-button.red{\n        background-color: red !important;\n        color: #cccccc !important;\n    }\n    .remote-button.red:not([disabled]):hover{\n         background-color: orange !important;\n    }\n</style>","storeOutMessages":true,"fwdInMessages":true,"templateScope":"global","x":692,"y":128,"wires":[[]]},{"id":"bc691572.02ce88","type":"ui_template","z":"a7b009fd18302719","group":"a381801e.309e1","name":"NetFlix","order":20,"width":"1","height":"1","format":"<div>\n    <md-button \n        class=\"md-button remote-button\"\n        data-topic=\"netflix\"\n        data-payload=\"netflix\"\n        aria-label=\"Netflix\"\n    >\n        <img\n            class=\"remote-icon\"\n            style=\"width: 36px; padding-top: 2px\"\n            src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAE2klEQVR4Xu3bW4hVVRzH8c8ZE/GCtywry5qcarrhpbKLmoVl9FZ0s2zS0DIJrIceSl+EwIgIDCQCp4t2L4guBJUgTmnlXYtUirIpU9EZxyayqWbmxPKcARFn1hKDaW/7v64fM/v3Pf/1X2v/91oFx3kUjnP//gdwLBnQxMB2Hk75G81sreTNFO0CbioyKkX7Nwvnsz9FeyTNMWXAbip78kPKP29n++uMmkNzTL+AlzAtpgvjBSof48cU7b8O4Ckqp7G8B2elPMB2pl7KazFtZgA8wVkTWHI+V8dMhfE/eec0bolpMwWgNxtq6IeeMWM4sIzRU/i2K22mABTZPoUvB3BFAgD7mHcOC3IFoJKNkxmdAqCNTc9y2XxaO9NnLgPCUjKTnys4IwXCNm4Yxye5ARCMXEvduUxMAdBC7TDuyxWAPjTUMBAnJEBo/Jjqu2g4kjZzU6DDxJ2s7s/lCQA0cX8Vi3MFoIoNkxiTAqCV5UOZlCsABYoz2VnBsAQI7VsYM4HNh2szOwWCkUnUVSUWwwM8eQaP5gpAP/ZMZQgqYllQpP4Dqu+l5VBtpjMgGJnK2n5cFgMQxhu4+TzezRWAatZOTATQyttDuT1XACpon8meAqckZEFLPSPGsLNDm/kpEIxcT93ZicXwLx45ladzBWAAu6aUMiDadWpn8xBGh2U0QMhFBgQjd7OuL5cmTIOwMxxfxapcATifNVczNgVAO8+dxOxcAaigbSaNBU5OgNC0lTPH81tupkAwfSN1w9OL4bRTWZorAAPYMYXTEzIgVMDlQ5iUKwDB+D1s7J3WMise4LyXmZeJ7wKhLR6aorFf9yK+HJfYNG3n8cUMzxWAHrTO4NcCJ8Zg4ada6tqoSdB275eh1AwoF8MVw7kmxVQdn2xjcoq2Wz+NHQ2Awbx9G7em7Ax/5Ys3uDJXALBkVqlTdF2Csb+WcuCPUpO1y8hMBgQAD7CsyCsxU2H8az77nAkxbaYA1DC7D79gUMxYK989zzkxXaYAzGV6I89gTsxYGH+fbbuo7kqbOQD7uKh4MMPjsZvP3otMg8wBCLYbS6+9V8URaK6lVxu9OtNmEkAD0wu8mADAWj7f0AWsTALYSZ9epR7ggBiEFjYvYWSuMiCY2ceiIg/GAITxt9jR1MkbZSYzIJhqYmQ7m1IA/Ejdx530FDILoFwMV0tomRXZvZihxSM0WLMOYAZqU7JgOeu/45LDtZkGsId+PdildMqsy2hm9etHOHuQaQDlafAcZsUAoHUpzX8w+FBt5gHsZUwF6xMA+IZPVx52KDPzAMpL4vpiwsmSNr6vZUSuMqAMYFaRMBWi8SFbdnBBhzAXGdBIf6WdYd8Ygb2sfIfxuQJQLoZhOQzLYpdR5PcXqGildxDmIgOCkQbGFggbo2isY9V6xuUKQNjl7WOjLl58Osi08PUSLs4VgHIWPFhgUTQFSi9I9U2cmZspEEyX7yCFYnhwfncV9dR9xMRcASgXw9AomR4DUGRPLUOKjOi2O0NH82EktMVDUzRmrLHU/Tl4UiQWK1j7LbfnCkC5GIam6YUxAL+z5lXuyBWAcjGcUyi1z2PR9hVV13bXtbn5DOyZeHGywKa5h50I7czdfga18VDMfRivYOGg7ro4mfKA/3VN9Azff93AsT7fcQ/gH8HaMl8q26yhAAAAAElFTkSuQmCC\">\n        />\n    </md-button>\n</div>\n","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":682,"y":428,"wires":[[]]},{"id":"57de4e.f4cfb1b4","type":"ui_template","z":"a7b009fd18302719","group":"a381801e.309e1","name":"Home","order":21,"width":"1","height":"1","format":"<div>\n   <md-button class=\"md-button remote-button\" \n        data-topic=\"home\"\n        data-payload=\"home\" \n        aria-label=\"home\"\n    >\n    <i class=\"fa fa-home remote-icon\"> </i>\n   </md-button>\n</div>\n","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":802,"y":428,"wires":[[]]},{"id":"a6df6e36.1d16b","type":"ui_template","z":"a7b009fd18302719","group":"a381801e.309e1","name":"Vid","order":22,"width":"1","height":"1","format":"<div>\n   <md-button class=\"md-button remote-button small\" \n        data-topic=\"video\"\n        data-payload=\"video\" \n    >Video\n   </md-button>\n</div>\n","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":922,"y":428,"wires":[[]]},{"id":"2a646eff.3f7cf2","type":"ui_template","z":"a7b009fd18302719","group":"a381801e.309e1","name":"1","order":2,"width":1,"height":1,"format":"<div>\n   <md-button class=\"md-button remote-button bigger\"\n    data-topic=\"1\"\n    data-payload=\"1\">1\n   </md-button>\n</div>\n","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":682,"y":188,"wires":[[]]},{"id":"ef0701c1.ddb63","type":"ui_template","z":"a7b009fd18302719","group":"a381801e.309e1","name":"2","order":3,"width":1,"height":1,"format":"<div>\n   <md-button class=\"md-button remote-button bigger\"\n    data-topic=\"2\"\n    data-payload=\"2\">2\n   </md-button>\n</div>\n","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":802,"y":188,"wires":[[]]},{"id":"a8296eda.ec9d6","type":"ui_template","z":"a7b009fd18302719","group":"a381801e.309e1","name":"3","order":4,"width":1,"height":1,"format":"<div>\n   <md-button class=\"md-button remote-button bigger\"\n    data-topic=\"3\"\n    data-payload=\"3\">3\n   </md-button>\n</div>\n","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":922,"y":188,"wires":[[]]},{"id":"cf65f510.c80d68","type":"ui_template","z":"a7b009fd18302719","group":"a381801e.309e1","name":"4","order":5,"width":1,"height":1,"format":"<div>\n   <md-button class=\"md-button remote-button bigger\"\n    data-topic=\"4\"\n    data-payload=\"4\">4\n   </md-button>\n</div>\n","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":682,"y":228,"wires":[[]]},{"id":"84949bc8.2bd298","type":"ui_template","z":"a7b009fd18302719","group":"a381801e.309e1","name":"5","order":6,"width":1,"height":1,"format":"<div>\n   <md-button class=\"md-button remote-button bigger\"\n    data-topic=\"5\"\n    data-payload=\"5\">5\n   </md-button>\n</div>\n","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":802,"y":228,"wires":[[]]},{"id":"b341d1f1.adf42","type":"ui_template","z":"a7b009fd18302719","group":"a381801e.309e1","name":"6","order":7,"width":1,"height":1,"format":"<div>\n   <md-button class=\"md-button remote-button bigger\"\n    data-topic=\"6\"\n    data-payload=\"6\">6\n   </md-button>\n</div>\n","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":922,"y":228,"wires":[[]]},{"id":"76507e83.940e6","type":"ui_template","z":"a7b009fd18302719","group":"a381801e.309e1","name":"7","order":8,"width":1,"height":1,"format":"<div>\n   <md-button class=\"md-button remote-button bigger\"\n    data-topic=\"7\"\n    data-payload=\"7\">7\n   </md-button>\n</div>\n","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":682,"y":268,"wires":[[]]},{"id":"fbafce7d.80576","type":"ui_template","z":"a7b009fd18302719","group":"a381801e.309e1","name":"8","order":9,"width":1,"height":1,"format":"<div>\n   <md-button class=\"md-button remote-button bigger\"\n    data-topic=\"8\"\n    data-payload=\"8\">8\n   </md-button>\n</div>\n","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":802,"y":268,"wires":[[]]},{"id":"684b5568.bf5c6c","type":"ui_template","z":"a7b009fd18302719","group":"a381801e.309e1","name":"9","order":10,"width":1,"height":1,"format":"<div>\n   <md-button class=\"md-button remote-button bigger\"\n    data-topic=\"9\"\n    data-payload=\"9\">9\n   </md-button>\n</div>\n","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":922,"y":268,"wires":[[]]},{"id":"114192b6.67ea7d","type":"ui_template","z":"a7b009fd18302719","group":"a381801e.309e1","name":"0","order":12,"width":1,"height":1,"format":"<div>\n   <md-button class=\"md-button remote-button bigger\"\n    data-topic=\"0\"\n    data-payload=\"0\">0\n   </md-button>\n</div>\n","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":802,"y":308,"wires":[[]]},{"id":"84c69bfc.13faa8","type":"ui_template","z":"a7b009fd18302719","group":"a381801e.309e1","name":"info","order":11,"width":1,"height":1,"format":"<div>\n   <md-button class=\"md-button remote-button\"\n    data-topic=\"info\"\n    data-payload=\"info\"\n    aria-label=\"info\"\n   >\n      <i class=\"fa fa-info-circle remote-icon\"></i>\n   </md-button>\n</div>\n","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":682,"y":308,"wires":[[]]},{"id":"25910d61.070c82","type":"ui_template","z":"a7b009fd18302719","group":"a381801e.309e1","name":"prev","order":13,"width":1,"height":1,"format":"<div>\n   <md-button class=\"md-button remote-button\"\n    data-topic=\"prev\"\n    data-payload=\"prev\"\n    aria-label=\"previous\"\n   >\n      <i class=\"fa fa-rotate-left remote-icon\"></i>\n   </md-button>\n</div>\n","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":922,"y":308,"wires":[[]]},{"id":"787787b2.c80b88","type":"ui_template","z":"a7b009fd18302719","group":"a381801e.309e1","name":"Ch +","order":16,"width":1,"height":1,"format":"<div>\n   <md-button class=\"md-button remote-button\" \n        data-topic=\"channel/up\"\n        data-payload=\"up\" \n        aria-label=\"channel up\"\n    >\n    <i class=\"fa fa-chevron-up remote-icon\"></i>\n   </md-button>\n</div>\n\n\n","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":922,"y":348,"wires":[[]]},{"id":"7eb81447.3ea8dc","type":"ui_template","z":"a7b009fd18302719","group":"a381801e.309e1","name":"mute","order":15,"width":1,"height":1,"format":"<div>\n   <md-button class=\"md-button remote-button\" \n              data-payload=\"1\" \n              data-buttontype=\"toggle\"\n              data-topic=\"mute\"\n              data-icon0=\"volume_off\"\n              data-icon1=\"volume_mute\"\n              aria-label=\"volume mute\"\n              >\n      <i class=\"material-icons md-48\">volume_mute</i>\n   </md-button>\n</div>\n","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":802,"y":348,"wires":[[]],"info":"  class=\"material-icons\"> volume_off"},{"id":"6eeb00d0.da35b","type":"ui_template","z":"a7b009fd18302719","group":"a381801e.309e1","name":"vol +  *","order":14,"width":1,"height":1,"format":"<div>\n   <md-button class=\"md-button remote-button\" \n        data-buttontype=\"repeater\"\n        data-interval=\"200\"\n        data-topic=\"volume/plus\"\n        data-payload=\"volume/plus\"\n        aria-label=\"volume plus\"\n    >\n    <span class=\"fa fa-plus remote-icon\"> </span>\n   </md-button>\n</div>\n\n\n","storeOutMessages":true,"fwdInMessages":false,"templateScope":"local","x":682,"y":348,"wires":[[]],"info":"<div id=\"regular_plus\">\n   <md-button class=\"md-button remote-button\">\n      <i class=\"fa fa-plus remote-icon\"></i>\n   </md-button>\n</div>"},{"id":"c58bb5ab.ebc658","type":"ui_template","z":"a7b009fd18302719","group":"a381801e.309e1","name":"vol -  *","order":17,"width":1,"height":1,"format":"<div>\n   <md-button class=\"md-button remote-button\"\n        data-buttontype=\"repeater\"\n        data-interval=\"200\"\n        data-topic=\"volume/minus\"\n        data-payload=\"volume/minus\"\n        aria-label=\"volume minus\"\n    >\n    <span style=\"color:{{msg.colour}}\" class=\"fa fa-minus remote-icon\"> </span>\n   </md-button>\n</div>\n\n","storeOutMessages":true,"fwdInMessages":false,"templateScope":"local","x":682,"y":388,"wires":[[]],"info":"<div id=\"regular_plus\">\n   <md-button class=\"md-button remote-button\">\n      <i class=\"fa fa-minus remote-icon\"></i>\n   </md-button>\n</div>\n"},{"id":"782351a7.0f3f6","type":"ui_template","z":"a7b009fd18302719","group":"a381801e.309e1","name":"ch list","order":18,"width":1,"height":1,"format":"<div>\n   <md-button class=\"md-button remote-button\"\n    data-topic=\"channel/list\"\n    data-payload=\"list\"\n    aria-label=\"channel list\"\n   >\n      <i class=\"fa fa-list-alt remote-icon\"></i>\n   </md-button>\n</div>\n","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":802,"y":388,"wires":[[]]},{"id":"18ff979.4cf7768","type":"ui_template","z":"a7b009fd18302719","group":"a381801e.309e1","name":"Ch -","order":19,"width":1,"height":1,"format":"<div>\n   <md-button class=\"md-button remote-button\" \n        data-topic=\"channel/down\"\n        data-payload=\"down\" \n        aria-label=\"channel down\"\n    >\n    <i class=\"fa fa-chevron-down remote-icon\"></i>\n   </md-button>\n</div>\n\n\n","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":922,"y":388,"wires":[[]]},{"id":"6b43ca3e.3b35a4","type":"inject","z":"a7b009fd18302719","name":"","repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"mute","payload":"1","payloadType":"num","x":642,"y":488,"wires":[["c322da00.abb3a8"]]},{"id":"54ff0f5c.2703e","type":"inject","z":"a7b009fd18302719","name":"","repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"mute","payload":"0","payloadType":"num","x":642,"y":528,"wires":[["c322da00.abb3a8"]]},{"id":"c322da00.abb3a8","type":"ui_template","z":"a7b009fd18302719","group":"a381801e.309e1","name":"script for all buttons with class remote-button","order":23,"width":"1","height":"1","format":"<div>\n<!--diliberately emtpy - only need the script below -->\n</div>\n\n<script>\n\n(function($scope) {\n//debugger\n\n    //cause a small delay while things load \n    //ideally this would be an init event or on all parts of document loaded\n    //(may not be necessary!)\n    setTimeout(function() {\n        //debugger\n        $scope.init();\n    },100);\n    \n    var BUTTON_CLASS = \".remote-button\";\n\n    /** \n     * Initialise all buttons with class BUTTON_CLASS\n    */\n    $scope.init = function () {\n        //debugger\n        console.log(\"$scope.init called. Adding event handlers to all buttons with class '\" + BUTTON_CLASS + \"'.\");\n        var clickButtons = $(BUTTON_CLASS + \":not([data-buttontype='repeater'])\") \n        clickButtons.click(function(e){\n            //debugger\n            var btn = $(this)\n            var type = btn.data(\"buttontype\");//get the button type from attribute data-buttontype=\"xxxxx\"\n            var topic = btn.data(\"topic\");//get the topic from attribute data-topic=\"xxxxx\"\n            var payload = btn.data(\"payload\");//get the payload from attribute data-payload=\"xxxxx\"\n            \n            if(type == \"toggle\"){\n                var newPayload = payload == 1 ? 0 : 1;\n                setButtonState(btn,newPayload)\n                $scope.send({\"topic\":topic,\"payload\":newPayload})\n            } else {\n                $scope.send({\"topic\":topic,\"payload\":payload})\n            }\n        }); \n\n        var repeatButtons = $(BUTTON_CLASS + \"[data-buttontype='repeater']\") \n        repeatButtons.on('mousedown',function(e) {\n            var btn = $(this);\n            if(this.running) return; //already in operation\n            var topic = btn.data(\"topic\");//get the topic from attribute data-topic=\"xxxxx\"\n            var payload = btn.data(\"payload\");//get the payload from attribute data-payload=\"xxxxx\"\n            var interval = btn.data(\"interval\");//get the desired repeat duration\n            if(isNumeric(interval) == false || interval < 1) interval = 300;//prevent zero & non numeric timeout value\n            const queueSend = (msg, delay, iteration) => {\n                if(!this.running) { return }\n                $scope.send(msg)\n                if(iteration == 5) { delay = delay/2 }//half the delay (speed up after 5 pulses)\n                setTimeout(() => {\n                    msg.iteration = iteration;\n                    if(this.running) {\n                        queueSend(msg, delay, iteration+1)\n                    }\n                },delay) \n            }\n            this.running = true;\n            queueSend({\"topic\":topic,\"payload\":payload},interval,1 )\n        }).on('mouseup blur focusout',function(e) {\n            this.running = false;\n        });\n           \n    };\n    \n    //watch for node-red msgs\n    $scope.$watch('msg', function(msg) {\n        //debugger\n        if(!msg){ //if no msg \n            console.log(\"$scope.$watch('msg', ...) - msg is empty\");\n            return;\n        }\n        if(!msg.topic){ //if no topic set found\n            console.log(\"msg.topic is empty - cannot match this to any button\")\n            return; //stop processing!\n        }\n        var buttonSelector = \".remote-button[data-topic='\" + msg.topic + \"']\" \n        var $btn = $(buttonSelector);//get the button\n        \n        if(!$btn.length){ //if no button found\n            console.log(buttonSelector + \" not found - cannot set state\")\n            return; //stop processing!\n        }\n        \n        if($btn.length > 1){ //if MORE than one button found\n            console.log(buttonSelector + \" found more than 1 button - is this intended? Do you have the same data-topic set on multiple buttons?\")\n        }\n        \n        if($btn.data(\"buttontype\") === \"toggle\"){\n            if(msg.payload == \"1\"){\n                setButtonState($btn, 1);\n            } else if(msg.payload == \"0\"){\n                setButtonState($btn, 0);\n            } else {\n               console.log(\"Invalid toggle value in msg.payload, cannot set \" + buttonSelector + \". Ensure msg.payload is either 0 or 1\") \n            }\n        }\n\n    }); \n    \n    /** \n    * helper function to set the correct icon & update the \"data-payload\" memory \n    */\n    function setButtonState($btn, state){\n        \n        $btn.data(\"payload\", state);//set data-payload to new state value (used as a memory)\n        \n        //determine the opposite state\n        var oppositeState;\n        if(state == \"1\" || state === 1){\n            state = 1; //normalise to a number\n            oppositeState = 0;\n        } else {\n            state = 0; //normalise to a number\n            oppositeState = 1;\n        }\n        \n        var $icon = $btn.find(\"i\"); //get the <i> element\n        if(!$icon.length){\n            $icon = $btn.find(\"span\"); //get the <span> element instead!\n        }\n        if(!$icon.length){\n            console.log(\"<i> or <span> not found inside button - cant toggle the icon!\")\n            return;//exit this function - nothing to toggle!\n        }\n        \n        //get the old icon and new icon names\n        var oldIcon = $btn.data(\"icon\" + oppositeState); //get icon1 or icon2 depending on oppositeState\n        var newIcon = $btn.data(\"icon\" + state); //get icon1 or icon2 depending on newPayload\n       \n        //if we have newIcon and an actual DOM element ($icon) - update it...\n        if(newIcon && $icon.length){\n            if(newIcon.includes(\"fa-\")){ \n                $icon.removeClass(oldIcon).addClass(newIcon);  // fontawesome\n            } else { \n                $icon.text(newIcon); // MDI\n            }\n        }\n    }\n        \n    /** \n    * helper function to determine a value is REALLY a number \n    */\n    function isNumeric(n){\n        if(n === \"\") return false;\n        if(n === true || n === false) return false;\n        return !isNaN(parseFloat(n)) && isFinite(n);\n    }\n   \n\n})(scope);\n</script>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":false,"templateScope":"local","className":"","x":802,"y":588,"wires":[["a90df8f.7eac108"]]},{"id":"a90df8f.7eac108","type":"debug","z":"a7b009fd18302719","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":882,"y":528,"wires":[]},{"id":"b5beb822.d8e4d8","type":"ui_template","z":"a7b009fd18302719","group":"a381801e.309e1","name":"lock","order":23,"width":"1","height":"1","format":"<div>\n   <md-button class=\"md-button remote-button bigger\" \n              data-payload=\"0\" \n              data-buttontype=\"toggle\"\n              data-topic=\"lock\"\n              data-icon0=\"fa-unlock\"\n              data-icon1=\"fa-lock\"\n              aria-label=\"lock\"\n              >\n      <span class=\"fa fa-unlock\" aria-hidden=\"true\"> </span>\n   </md-button>\n</div>","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":802,"y":468,"wires":[[]]},{"id":"be17d3d4.a92a6","type":"ui_group","name":"HOME","tab":"6af80cca.442cb4","order":1,"disp":true,"width":3,"collapse":false},{"id":"a381801e.309e1","type":"ui_group","name":"Full_Remote2","tab":"9e72c753.ebf048","order":3,"disp":false,"width":"3","collapse":false},{"id":"6af80cca.442cb4","type":"ui_tab","name":"TEST","icon":"dashboard","order":3,"disabled":false,"hidden":false},{"id":"9e72c753.ebf048","type":"ui_tab","name":"HDMI_TV_control","icon":"dashboard","order":7,"disabled":false,"hidden":false}]

I tried below, but did not see a noticiable increase in speed, and also the scroll continued after mouse release.

regards

Adrian Fewster

What did you try? Did you change the function code in your existing template? did you import the new demo flow (and keep your old flow)?

I did change the appropriate section, I think what is happening is that the target rigctld tcp server cannot keep up.

I will look at that.

Thankyou

regards

Adrian Fewster