janbar / noson

C++ library for accessing SONOS devices.
GNU General Public License v3.0
27 stars 9 forks source link

How to handle the changes on the zones #5

Closed daniwebCH closed 6 years ago

daniwebCH commented 6 years ago

Hi Janbar, first at all thanks for your work!

I'm trying to handle my sonos via the knx installation of my home. So far looks like working, my major problem is to handle when the groups/zones are changing. I tried to supervise the connectedZonePtr->GetZoneName but this is not changing after initialization. When I got a CB event from the System, I also tried to get again the GetZoneList() and scan, but no one is set as disconnected (for the moment I decided to keep all devices not p grouped in a zone when I start my application).

I have to admit that I know good ansi C (development of embedded systems since 20 years) but the C++ special features are not my specialty, this maybe limits a bit my understanding of your library.

There are my questions: 1) I do not know how to handle the groups/zones changes, could you give me a hint? 2) Shall I avoid to perform some calls on the callback context?

Thanks a lot Daniele

janbar commented 6 years ago

You can find a sample how I handle the change in my repository noson-app:

In this app, the class Sonos owns the callback function "topologyEventCB(void* handle)" at line https://github.com/janbar/noson-app/blob/ed98c09fa1196381f4e6f1ad612a33a1b5458ad8/backend/modules/NosonApp/sonos.h#L208 . Always in this app, in the constructor of the instance of Sonos at line https://github.com/janbar/noson-app/blob/ed98c09fa1196381f4e6f1ad612a33a1b5458ad8/backend/modules/NosonApp/sonos.cpp#L78 , I initialize the Sonos::System passing the pointer of the callback function to catch any event emit by the topology service.

janbar commented 6 years ago

So you have to initialize your sonos::System(handle, callback), passing the pointer of your handle and the pointer of the callback to receive topology events. A topology event is emit by the Sonos player when grouping change, or a zone is added/removed. In the app, on those events I call sonos::System.GetZoneList() to retrieve the fresh list of zones, and then I reconnect to a zone (if possible the same as before the change) by calling sonos::System.ConnectZone(const ZonePtr& zone, void* CBHandle, EventCB eventCB) , where eventCB is the callback to catch events relate the zone player: see the sample of callback from the app: https://github.com/janbar/noson-app/blob/ed98c09fa1196381f4e6f1ad612a33a1b5458ad8/backend/modules/NosonApp/sonos.cpp#L495 .

janbar commented 6 years ago

To be more clear, your connectedZonePtr won't change after a topology change. In fact it controls the supervisor of the connected zone: and so that could be a simple device or a group. After a topology event you should drop out all connected zones and reconnect the new(s). You can check for a zone with same name as before the change, else if none because it has been broken by grouping or ungrouping, get the first from the list.

janbar commented 6 years ago

When you connect to a zone, you pass a callback to catch zone (player) events. Some events relates the zone itself (rendering) and others are global. So if you connect all zones (i.e to show a dashboard) you have to handle global events only once: that could be for the zone having the current focus.

daniwebCH commented 6 years ago

Hi Janbar,

thanks for the answer, I think now is working ;-) Sorry that I took time to post it, not nice to keep an issue open to long, especially if it is not really an issue ;-)

Thanks