pjjameso Posted July 14 Posted July 14 I have a simple program that senses when to execute a join function as seen below. My problem is that it works fine but then after a while it loses the saved sonos unit in the program and changes to a random sonos unit. Is this a problem in the program function of IOX or is it a st-sonos issue? Any thoughts on how to correct the issue? Buttkicker - [ID 0032][Parent 0001] If 'Emporia / Bmt UPS' Killowatts >= 0.4000 kW Then Set 'ST-Sonos / Buttkicker' Join Basement Else Set 'ST-Sonos / Buttkicker' Leave
bpwwer Posted July 14 Posted July 14 You're saying the "ST-Sonos / Buttkicker" changes to "ST-Sonos / random speaker" ? IoX programs are using a fixed index that get's mapped to the name for display. The Sonos zone list is re-generated every time a Sonos device sends out a "topology-change" message. My best guess is that something is causing a topology-change which changes the zone list so the index into that zone list is no longer pointing to the same speaker that it was when you created the program. The issue is a combination of how IoX programs work and how Sonos works. I don't think there's any way to fix this without IoX rewriting how programs work or breaking the dynamic behavior of Sonos.
pjjameso Posted July 14 Author Posted July 14 Thanks Bob for the explanation. Of course I have a follow up question, is there a way to delete or disable all the other nodes in the ST-Sonos which would then force a default to the basement node. Or would it try and join to itself, assuming only two nodes?
bpwwer Posted July 15 Posted July 15 I don't have any Sonos devices nor do I fully understand how the plug-in works. I just took over support from the original author. But I believe that the issue isn't with the nodes, but internally with the way Sonos enumerates the zones (or speakers) for use in the join command. If I'm understanding the code correctly, it does something like a network query to discover the zones (speakers) and each device then responds back. So the order is not fixed and just based on the order that the devices respond. My understanding of the Sonos devices is that there isn't any central controller that keeps track of everything and instead, the devices just communicate between themselves. The IoX programming requires that the list be a fixed list. So a list is created using the order the devices responded above and that list is then used when editing the program. The next time you go to edit (or even display) the program, the order of devices in that list may have changed. So initially the basement devices may have been the third device on the list, now it's the second and some other device is third so that's what shows up in the program. I don't think there's any way to work around this, but I can't experiment since I don't have any Sonos devices. I believe the join is something that happens at the sonos device level, and not something that's happening in the plug-in so it's not really related to the nodes created by the plug-in. 1
pjjameso Posted July 15 Author Posted July 15 Thanks Bob for your thoughtful reply. One curious point is with the then statement Set 'ST-Sonos / Buttkicker' Join Basement Is that the buttkicker never changes in the program just the join Sonos device. Wonder why if it is reindexed as you suggest. Appreciated your help, understand that there doesn’t look like a solution.
bpwwer Posted July 15 Posted July 15 If I had some sonos devices, I'd experiment with this and would be able to provide better answers, but I'm mostly just making some assumptions based on what I see in the code. In the code, it looks like it creates a zone list of what I assume are groups of speakers/devices. The order of speakers/devices and membership can change in these zones. A speaker node holds a copy of this zone list and that's what's used when you create the program. If I'm guessing right, your program is requesting that the speaker named Buttkicker is added (then) or removed (else) from the group/zone called Basement. When you created this this program, the zone Basement might have been at index 2 in the zone list and that "2" is what IoX saves in the program. If over time that zone list changes and Basement ends up at index 3, then the next time the program is viewed or executed, it will show/use whatever zone is now at index 2 instead of the Basement zone. I'm not sure the original author of the plug-in would have even realized that this could happen.
pjjameso Posted July 16 Author Posted July 16 The interesting point is the buttkicker has never changed to another device in the then statement. It’s just the device in the join action. Wonder how the set device is locked but the join is not, could it be due to the apostrophe? Maybe I should loan you a couple of Sonos units!
bpwwer Posted July 16 Posted July 16 I've thought about getting some, just haven't been able to justify it since we have an existing whole house audio solution. Each speaker node in the plug-in is running as a somewhat independent entity. So when something changes on the Sonos network (I.E. a speaker is turned off/on, or a join/unjoin happens) a device will send out a message to all the other devices to notify them that a change happened. The plug-in device nodes also see this notification and respond by re-querying to get the most updated information. So when the buttkicker device node in the plug-in sees that notification, it rebuilds it's internal "zone" list. It's that internal "zone" list that is used to provide the options to the IoX programming interface. When you create the program and specify that for the device node buttkicker to join, the plug-in sends it's zone list which is then used to create the drop down list of devices/zones that buttkicker can join. You then select 'basement' from that list and IoX stores the index number for basement. Later the buttkicker plug-in node gets another notification that something has changed so it rebuilds it's internal "zone" list again, but this time basement is at a different index. The IoX program didn't save "basement" just the index and now that index references a different device/zone in the new zone list. When the program executes, it sends what was saved to the plug-in device node. So in this case, it sends a command (JOIN) to the buttkicker node with the index of what it wants to join with. The node code looks up that index in it's zone list to map that index back to the proper (or improper) device and sends the command to the various sonos devices. If that internal zone list never changed, this would all work how you want/expect. Or if IoX was able to save the device name instead of just the index, it would work as expected. I think it may be possible to create an internal zone list that maps to fixed indexes and then try to maintain that, but I'm concerned that it would get fragmented and that might cause issues over time. It would also be a pretty big overhaul to the plug-in code base. I'm reasonably comfortable debugging issues with the existing code base, but re-writing it for something like this is a lot more effort and time (and probably does require having some devices to test with).
Recommended Posts