As an FYI (because it was probably my fault as I submitted this as a fix for an issue that impacted Deep Harmony, so I should probably say something ;))
node-roon-api-source-control have undergone a significant change in behaviour to improve tracking of controls around restarts of Roon and extensions.
If you are the author of an extension that can support two or more of one or the other of these controls, then these changes are breaking changes (however the old behavior was not valid anyway). If you are the author of an extension that only supports a single instance of a source or volume control, then these should not be breaking changes and most likely your code will continue to function with no further change.
What has changed
Previously, when creating an instance of a control via the new_device method, a control key was assigned such that the key value would increment for each new source or volume control. Following a restart (or repairing) of either Roon or an extension it is common for an extension to re-create its controls, however if those control were created in a different order, then they would end up with different keys. Similarly, if they were created following re-pairing then again, they would be created with different keys. The keys used were out of your control and for some extensions that may mean it is very difficult to predict creation order for all time and maintain it, especially if other related devices could be added/created by a user.
The change is therefore to allow an extension to manage their own control_keys by setting a control_key property on the state object passed to new_device() and if needed the extension is free to persist those control_keys in its own settings to ensure device are correctly re-created later, for eg over a restart.
As I understand it, within Roon source and volume control are tracked by a combination of the extension pairing token (UUID) and the control_key (and the control type - source or volume). When you re-create a control with a previously used control_key that has not been explicitly destroyed, then I think you are not really creating a new control and at best perhaps just re-enabling it with a new state.
I am assuming the control_keys persistently map to a physical device (or virtual in the case of Logitech Harmony activities) and as such there needs to be something unique and persistent about the device to map to. A hardware serial number obtained over a device’s web api is a good choice as may be its MAC address if that is available. Basically choose anything that you can discover about a device that will never change. On the other hand an IP address assigned by DHCP is a bad choice as that can change over device or router restarts. A fixed IP address may be a workable choice, but non ideal if this forces a user to have to reconfigure device to fixed IP addresses which may be beyond the common tech knowledge of many end users and hence be difficult to support. If it is a device that is discovered via SSDP, the UDN is an ideal choice, or even the serial number field from the device.xml.
For storing in settings, then I suggest creating a value whos key is a device’s hardware identifier - ie its serial number, UDN, etc and store the control_key against that.
To ensure I never use a key twice I also persist a next value for each control_key type (source or volume) in settings.
I may later post source for a class to simply wrap this lot up (once I have extracted this out of Deep Harmony) if anyone will find that helpful. In the meantime I hope the above makes sense, if not Ill try answer any questions, however…
Disclaimer, I have nothing to do with Roon, I just happened to be the author of SDK changes to fix this problem in Deep Harmony and submitted them to Roon via Git. The final SDK changes were quite different, but functionally near enough the same for Deep Harmony to work correctly without further change. The above is as I understand it, but there are others who have been making excellent extensions for far longer than I and who probably know a lot more about how all this works :).
Just to re-iterate, if your extension will only ever support a single instance of a source or volume control, you can pretty much ignore this. Your existing code will just always end up with a control_key of ‘1’.