IKEA Symfonisk rotary remote more responsive

I bought the rotary remote thing yesterday and managed to get it in HA with the Zigbee Home Automation integration and a Conbee II.
It was very disappointing with the slowness of the rotation.
I tried using the events directly instead of the device, but I found it only made it marginally better

So I managed to make it faster/more responsive using Node red.
Perhaps it’s fine when you use volume up/down, but using volume set I noticed multiple messages got sent to HA with the same information because the call service had not yet been carried out.
Example:
volume_level: "{{ state_attr('media_player.yamaha_receiver', 'volume_level') |float +0.02}}"
Needs the call service to have been carried out before the next event to happen, otherwise it will send the same value twice.

So I figured I could use a flow variable as an intermediate variable that way the call service does not have to be carried out for the next message to know what the volume will be soon.

To make the code run as fast as possible I only use one function node and nothing else.

if(msg.payload.event.device_id == "f594d0a16628c130b023f476a35c0091" && msg.payload.event.command == "move"){
    var states = global.get('homeassistant.homeAssistant.states');
    var vol = states["media_player.yamaha_receiver"].attributes.volume_level;
    
    if(flow.get("vol") != vol && flow.get("vol") != "" && typeof flow.get("vol") !== 'undefined' ){
        vol = flow.get("vol");
    }
    
    if(msg.payload.event.args[0] == 0){
        msg.volume_level = vol + 0.02
    }else{
        msg.volume_level = vol - 0.02
    }
    flow.set("vol", msg.volume_level);
    return msg;
}              

The only thing that needs to be changed is the device_id and media_player.
You get the device_id from the debug node, just rotate once and look in the debug window.

[{"id":"d9c31b63.61df68","type":"function","z":"a787a77.9c16458","name":"","func":"if(msg.payload.event.device_id == \"f594d0a16628c130b023f476a35c0091\" && msg.payload.event.command == \"move\"){\n    var states = global.get('homeassistant.homeAssistant.states');\n    var vol = states[\"media_player.yamaha_receiver\"].attributes.volume_level;\n    \n    if(flow.get(\"vol\") != vol && flow.get(\"vol\") != \"\" && typeof flow.get(\"vol\") !== 'undefined' ){\n        vol = flow.get(\"vol\");\n    }\n    \n    if(msg.payload.event.args[0] == 0){\n        msg.volume_level = vol + 0.02\n    }else{\n        msg.volume_level = vol - 0.02\n    }\n    flow.set(\"vol\", msg.volume_level);\n    return msg;\n}              ","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":300,"y":100,"wires":[["57751245.69af1c"]]},{"id":"d6bc8910.db2678","type":"server-events","z":"a787a77.9c16458","name":"","server":"4bbca37b.1700ec","event_type":"zha_event","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":true,"x":120,"y":100,"wires":[["d9c31b63.61df68","c850a2b7.f6dfc"]]},{"id":"57751245.69af1c","type":"api-call-service","z":"a787a77.9c16458","name":"","server":"4bbca37b.1700ec","version":1,"debugenabled":false,"service_domain":"media_player","service":"volume_set","entityId":"media_player.yamaha_receiver","data":"{        \"volume_level\": {{volume_level}}    }","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":510,"y":100,"wires":[[]]},{"id":"c850a2b7.f6dfc","type":"debug","z":"a787a77.9c16458","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":310,"y":200,"wires":[]},{"id":"4bbca37b.1700ec","type":"server","name":"Home Assistant","legacy":false,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true}]

Hey there trying something similar with a Rotation Smart Knob to Set vol +/-
could you help me setting it Up cause im Not familiar with node Red yet.
Can you maybe Export your Note?

Sorry I forgot about this post.

Do you mean you have the tuya knob? As far as I have understood, it’s limited in speed so you can’t really get more out of it.

Yup its the tuya knob with rotate and Press
Integrated through Zigbee2MQTT

Ok got myself a symfonisk on my way home :sweat_smile::v:t3: would you mind exporting your node?

Guess the Volume steps are adjustable too like AVR and Device ID?

It has become a bit more complex since this thread started.

I now have the ability to control DVD player, rew/ff on chromecast, control a different room and so on…

[{"id":"17cef50e.849dcb","type":"api-call-service","z":"a787a77.9c16458","name":"media_seek","server":"4bbca37b.1700ec","version":5,"debugenabled":false,"domain":"media_player","service":"media_seek","areaId":[],"deviceId":[],"entityId":["media_player.chromecast_vardagsrum"],"data":"","dataType":"json","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":810,"y":100,"wires":[["4d74cd83.6d2184"]]},{"id":"d9c31b63.61df68","type":"function","z":"a787a77.9c16458","name":"","func":"node.log(\"Log message\");\nnode.debug(\"Variable\", msg.payload.event.device_id);\nif(msg.payload.event.device_id == \"f594d0a16628c130b023f476a35c0091\" && msg.payload.event.command == \"move\"){\n    var states = global.get('homeassistant.homeAssistant.states');\n    if (states[\"media_player.chromecast_vardagsrum\"].state != \"paused\"){\n        var vol_black = states[\"media_player.yamaha_receiver\"].attributes.volume_level;\n        \n        if(flow.get(\"vol_black\") != \"\" && typeof flow.get(\"vol_black\") !== 'undefined' ){\n            vol_black = flow.get(\"vol_black\");\n        }else{\n            vol_black = 0.5\n        }\n        \n        if(msg.payload.event.args[0] == 0){\n            msg.volume_level = vol_black + 0.02\n            if (msg.volume_level > 1){\n                msg.volume_level = 1;\n            }\n        }else{\n            msg.volume_level = vol_black - 0.02\n        }\n        if(!isNaN(msg.volume_level)){\n            flow.set(\"vol_black\", msg.volume_level);\n        }\n        return [msg, null, null, null, null];\n    }else{\n        var pos = states[\"media_player.chromecast_vardagsrum\"].attributes.media_position;\n        if(msg.payload.event.args[0] == 0){\n            pos = pos + 10;\n        }else{\n            pos = Math.max(pos - 10,0);\n        }\n        \n        \n        //msg.pos = parseFloat(msg.data.attributes.media_position+10);\n        msg.payload = {\n            data:{\n                \"entity_id\": \"media_player.chromecast_vardagsrum\",\n                \"seek_position\": pos,\n            }\n        }\n        \n        return [null, msg, null, null, null];\n    }\n}else if(msg.payload.event.device_id == \"f594d0a16628c130b023f476a35c0091\" && msg.payload.event.command == \"toggle\"){\n    return [null, null, msg, null, null];\n}else if(msg.payload.event.device_id == \"f594d0a16628c130b023f476a35c0091\" && msg.payload.event.command == \"step\"){\n    if(msg.payload.event.args[0] == 0 && msg.payload.event.args[1] == 1 && msg.payload.event.args[2] == 0 ){\n        return [null, null, null, msg, null];   \n    }else if(msg.payload.event.args[0] == 1 && msg.payload.event.args[1] == 1 && msg.payload.event.args[2] == 0 ){\n        return [null, null, null, null, msg];   \n    }\n}                     ","outputs":5,"noerr":0,"initialize":"","finalize":"","libs":[],"x":600,"y":100,"wires":[["57751245.69af1c"],["17cef50e.849dcb"],["c0602dcfb008ebba"],["13c4934d.0520dd"],["da40739d2f4a3248"]]},{"id":"4d74cd83.6d2184","type":"function","z":"a787a77.9c16458","name":"{}","func":"msg = {};\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":950,"y":100,"wires":[["77334a5c.9bf214"]]},{"id":"a350be847fc3e1ca","type":"function","z":"a787a77.9c16458","name":"","func":"\n\nif(msg.payload.event.device_id == \"d1bc3a6a786d78efb2cc3ca826a4a625\"){\n    msg.white = flow.get(\"white\");\n    \n    if (msg.white == \"black\"){\n        msg.payload.event.device_id = \"f594d0a16628c130b023f476a35c0091\";\n    }\n}\n    \nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":460,"y":100,"wires":[["d9c31b63.61df68"]]},{"id":"57751245.69af1c","type":"api-call-service","z":"a787a77.9c16458","name":"","server":"4bbca37b.1700ec","version":5,"debugenabled":false,"domain":"media_player","service":"volume_set","areaId":[],"deviceId":[],"entityId":["media_player.yamaha_receiver"],"data":"{        \"volume_level\": {{volume_level}}    }","dataType":"json","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":870,"y":40,"wires":[[]]},{"id":"c0602dcfb008ebba","type":"api-current-state","z":"a787a77.9c16458","name":"","server":"4bbca37b.1700ec","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"media_player.yamaha_receiver","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"}],"for":0,"forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":920,"y":240,"wires":[["00c4807eb0d3d061"]]},{"id":"13c4934d.0520dd","type":"api-call-service","z":"a787a77.9c16458","name":"","server":"4bbca37b.1700ec","version":5,"debugenabled":false,"domain":"media_player","service":"turn_off","areaId":[],"deviceId":[],"entityId":["media_player.yamaha_receiver","media_player.philips_tv","media_player.chromecast_vardagsrum"],"data":"","dataType":"json","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":860,"y":160,"wires":[["5afeac0d.6118c4"]]},{"id":"da40739d2f4a3248","type":"delay","z":"a787a77.9c16458","name":"","pauseType":"delay","timeout":"500","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":830,"y":380,"wires":[["44ab579e286207d6"]]},{"id":"77334a5c.9bf214","type":"delay","z":"a787a77.9c16458","name":"","pauseType":"delay","timeout":"3","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"outputs":1,"x":1120,"y":100,"wires":[["4d86cad9.5065c4"]]},{"id":"c7099de63cb8116f","type":"delay","z":"a787a77.9c16458","name":"","pauseType":"rate","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"0.25","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":true,"allowrate":false,"outputs":1,"x":310,"y":100,"wires":[["a350be847fc3e1ca"]]},{"id":"00c4807eb0d3d061","type":"switch","z":"a787a77.9c16458","name":"","property":"data.attributes.source","propertyType":"msg","rules":[{"t":"eq","v":"HDMI3","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":1190,"y":240,"wires":[["2d1495dca042b3ee"],["e317296f.17bce8"]]},{"id":"5afeac0d.6118c4","type":"delay","z":"a787a77.9c16458","name":"","pauseType":"delay","timeout":"10","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"outputs":1,"x":1120,"y":160,"wires":[["5fb4dea2.84c66"]]},{"id":"44ab579e286207d6","type":"change","z":"a787a77.9c16458","name":"","rules":[{"t":"set","p":"black","pt":"flow","to":"white","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1000,"y":380,"wires":[["cf3ae26de7ca2d98"]]},{"id":"4d86cad9.5065c4","type":"ha-wait-until","z":"a787a77.9c16458","name":"","server":"4bbca37b.1700ec","version":1,"outputs":1,"entityId":"media_player.chromecast_vardagsrum","entityIdFilterType":"exact","property":"state","comparator":"is","value":"playing","valueType":"str","timeout":0,"timeoutType":"num","timeoutUnits":"seconds","entityLocation":"","entityLocationType":"none","checkCurrentState":true,"blockInputOverrides":true,"x":1260,"y":100,"wires":[["957d3925.e0d4d8"]]},{"id":"d6bc8910.db2678","type":"server-events","z":"a787a77.9c16458","name":"","server":"4bbca37b.1700ec","version":1,"event_type":"zha_event","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":true,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"$outputData(\"eventData\").event_type","valueType":"jsonata"},{"property":"event_type","propertyType":"msg","value":"$outputData(\"eventData\").event_type","valueType":"jsonata"}],"x":130,"y":100,"wires":[["c7099de63cb8116f"]]},{"id":"2d1495dca042b3ee","type":"switch","z":"a787a77.9c16458","name":"","property":"DVD","propertyType":"flow","rules":[{"t":"eq","v":"pause","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":1350,"y":240,"wires":[["bd3f48d6019a3a78"],["19c9592ed81ae504"]]},{"id":"e317296f.17bce8","type":"api-call-service","z":"a787a77.9c16458","name":"","server":"4bbca37b.1700ec","version":5,"debugenabled":false,"domain":"media_player","service":"media_play_pause","areaId":[],"deviceId":[],"entityId":["media_player.chromecast_vardagsrum"],"data":"","dataType":"json","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1510,"y":320,"wires":[[]]},{"id":"5fb4dea2.84c66","type":"api-call-service","z":"a787a77.9c16458","name":"","server":"4bbca37b.1700ec","version":5,"debugenabled":false,"domain":"light","service":"turn_off","areaId":[],"deviceId":[],"entityId":["light.taklampan"],"data":"","dataType":"json","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1290,"y":160,"wires":[[]]},{"id":"cf3ae26de7ca2d98","type":"delay","z":"a787a77.9c16458","name":"","pauseType":"delay","timeout":"10","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1180,"y":380,"wires":[["00805e1b3ca012a9"]]},{"id":"957d3925.e0d4d8","type":"api-call-service","z":"a787a77.9c16458","name":"rew","server":"4bbca37b.1700ec","version":5,"debugenabled":false,"domain":"media_player","service":"media_pause","areaId":[],"deviceId":[],"entityId":["media_player.chromecast_vardagsrum"],"data":"","dataType":"json","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1390,"y":100,"wires":[[]]},{"id":"bd3f48d6019a3a78","type":"api-call-service","z":"a787a77.9c16458","name":"play","server":"4bbca37b.1700ec","version":5,"debugenabled":false,"domain":"remote","service":"send_command","areaId":[],"deviceId":[],"entityId":["remote.broadlink_4_remote"],"data":"{\t  \"device\": \"DVD\",\t  \"command\": \"play\"\t}","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1510,"y":200,"wires":[["e1a6c18a92beb08c"]]},{"id":"19c9592ed81ae504","type":"api-call-service","z":"a787a77.9c16458","name":"pause","server":"4bbca37b.1700ec","version":5,"debugenabled":false,"domain":"remote","service":"send_command","areaId":[],"deviceId":[],"entityId":["remote.broadlink_4_remote"],"data":"{\t  \"device\": \"DVD\",\t  \"command\": \"pause\"\t}","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1510,"y":260,"wires":[["808bdfaab03ac2a0"]]},{"id":"00805e1b3ca012a9","type":"change","z":"a787a77.9c16458","name":"","rules":[{"t":"set","p":"black","pt":"flow","to":"","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1360,"y":380,"wires":[[]]},{"id":"e1a6c18a92beb08c","type":"change","z":"a787a77.9c16458","name":"play","rules":[{"t":"set","p":"DVD","pt":"flow","to":"play","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1690,"y":200,"wires":[[]]},{"id":"808bdfaab03ac2a0","type":"change","z":"a787a77.9c16458","name":"pause","rules":[{"t":"set","p":"DVD","pt":"flow","to":"pause","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1690,"y":260,"wires":[[]]},{"id":"de1498ed6519868e","type":"server-state-changed","z":"a787a77.9c16458","name":"","server":"4bbca37b.1700ec","version":4,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"media_player.yamaha_receiver","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":false,"for":"0","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":220,"y":200,"wires":[["3d7004f641ef8567"]]},{"id":"3d7004f641ef8567","type":"change","z":"a787a77.9c16458","name":"","rules":[{"t":"set","p":"vol_black","pt":"flow","to":"data.new_state.attributes.volume_level","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":510,"y":200,"wires":[[]]},{"id":"4bbca37b.1700ec","type":"server","name":"Home Assistant","version":2,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":30}]

The first function node is the one that switches the black knob to “emulate” being white. The black one is in the living room and the white is in the kitchen. So triple press means switch for 10 seconds (fifth output of the second function node).
If you don´t need this then you can just remove the nodes from the fifth output and the first function node.

The state changed node below takes manual (IR or physical) volume changes and updates the value in the sequence.