RoonLabs / node-roon-api-volume-control

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

new_device cannot be called twice in a session

maru-sama opened this issue · comments

As mentioned in #2 there is another issue with registering of new controls.
Apparently the roon server does not accept a second call to "new_device"

RoonApiVolumeControl.prototype.new_device = function(o) {

The first time it is called it succeeds. If you then destroy this subscription and call new_device again the new control is not registered. Together with #2 this results to the following.

does not work since it should be (at least I think)

this._svc.send_continue_all('subscribe_controls', "Changed", { controls_removed: [ o.state.control_key ] });

If changed like this roon server successfully de-registers the control

  • Calling new_device again fails (I am not sure why)
    The extension sends the request to the server but it is apparently ignored resulting in no volume control.

I tried this for testing with a simplified version of the meridian extension.

Reproducing is quite simple, just modify the configuration which then results in a new setup call.

I spend more time looking at this and wonder if you are even supposed to call new_device again if you "only" reconnect the same control. The meridian extension does it but I wonder if it makes more sense to only register it once during startup and on a reconnect just update the values instead of destroying and re-creating it.

I fixed the other issue in commit 73ce294. I don't have meridian hardware, so when I run the extension it gets stuck in a loop of destroying and re-creating the volume control object. That appears to work, can you test this one with commit 73ce294 as well?

Sorry if I was not clear enough. This is not meridian related I just used the core facing code for testing. If you call new_device and then assign the control to a zone it works if you then call destroy on the control and call new_device again the room core does not seem to register it. Just try it. Create a control assign to a zone so it picks up volume changes and then destroy it and call new_device again. This new device will not be assigned to the zone and you will see that the zone is stuck to fixed volume. Since I do not know what's happening on the core side it is hard to debug. Are the controls assigned to the zone by the control_key in some way?

Use this gist for testing https://gist.github.com/maru-sama/4c50cfa09963ddc0140f9c14e1b28f49
I removed everything meridian related. Just setup the extension and select a serial port then assign it to any zone. When you change the volume it will work. Go to the extension again and change the serial port. this will result in a destroy()->new_device() try to chang the volume again you will notice that the volume control is gone.

There does seem to be a bug in the Roon core side code in that when a volume control is removed the value in the device setup page for an audio device it's attached to isn't correctly removed.

That said, the behavior where removing a volume control and then adding a new one doesn't automatically attach the new volume control to any audio devices the old one was attached to is intended. There's no way for the Roon core to know that the new volume control is actually an updated version of the old volume control, so we can't do that automatically.

So how is the volume control assigned to the audio device the FIRST time new_device is called (during startup of the extension). Is the control_key part of this? I am asking since I want to handle disconnects correctly. So take the following example.

  • The extension starts up connects to the receiver and creates the control which is automatically assigned to the device.
  • The receiver is turned off/not reachable and therefore the extension wants to inform Roon about it. My first idea was to just remove the control/device again so you can clearly see that the receiver is not reachable right now. But as you said the extension is not automatically assigned to the device the second time new_device is called. So for now I am NOT destroying the control on the client side and use a proxy object so the roon requests get "handled".

My question now is what's different between the FIRST new_device call and the SECOND new_device call? The only difference I see is the control_key number but there must be something else otherwise the extension would be assigned to the device again.

The link between an audio device + the volume control in the core is based on the extension's token + the control_key. Together, those are used as a key. If either changes, the link is broken.

I have been testing a change to both volume and source to allow the client the option of managing the keys, thus allowing the client to potentially persist the keys and guarantee to re-create on a new session with the same control keys.

Closing old issue.