Legrand Nuvo multi-room audio support

There’s a new v2.0.0-beta.1 release of the integration which contains some breaking changes I’ve listed here: Releases · sprocket-9/hacs-nuvo-serial · GitHub

It will require to download the beta in HACS then delete/reinstall the integration in HA before the new device/entity hierarchy will show correctly - just installing this beta version over the existing version will not work it seems.

The reinstall should recreate the existing entity_ids though, so no lovelace configuration changes are needed. Any automations using page_on/off or all_off will need tweaked to use the switch/button entity instead, as these service names have been removed.

If anyone is up for trying it, to get beta releases showing up in HACS I had to follow this: https://hacs.xyz/docs/faq/beta/

Do flag up any issues you find :slight_smile:

I’ve been meaning to post this for awhile, but I’ve been working on enhancing the original code that was published for the “9600 baud” Nuvos. It supports my Essentia D currently,and creates number entities for bass and treble, switches for group sourcing and volume reset, as well as a binary sensor for override.

I was also able to make the code listen for updates instead of polling the Nuvo, but currently I just put them in memory, as I have yet to figure out how to push the updates to HA.

Anyway, @staxza, I could probably get this to work with your Simplese as it’s very similar. You should be able to hook up a USB to RS232 converter, but it looks like the serial port on the Simplese is a headphone jack? If so I doubt it would be difficult to make a cable exposing the 3 pins needed.

If you do have it connected to RS232 already, could you send me the output of *VER?

1 Like

Hi Brian. Sorry, just trying to understand. I have a Nuvo NV-E6DMS (Essentia D). So have you modified sprocker-9’s code to work with your Essentia D? I guess the simple question is what do I need to do to get my Essentia D integrated to HA?

Hi Steve. I just modified the original code that was published back a couple of years ago. I think sproket-9 took the same code and really did an amazing job turning it into something great for use with the higher end Nuvos. This is much less complex and much less well written, and I do not claim to be a programmer at all! However, I was able to add a callback this week, so it now does update immediately when a button is pressed on the keypads, as well as a version check for the Essentia D or Simplese.

I’ve never published anything to github before but I’ll try to get it out there today. I was on HA 2022.4 until this morning as I was being lazy facing all of the breaking changes. I’ll make sure it works or fix it for 2022.9 and try to put it out there today. I’ll keep you updated.

Here is my first try at ever publishing anything. This should control Nuvo Essentia D and possible Simplese amplifiers. Hopefully it will work for somebody who could make use of it. Here is the link on Github. Let me know if there are any questions or problems.

Great work, Brian! Thank you! Great effort for your first GitHub release. Much better instructions than 95% of the releases I’ve seen.

We’re on holidays for a week so unlikely to get a chance to test until the end of next week. I’ll report my experience once I do.

Hey Brian. How have you used the integration? I’d love some inspiration if you’ve got any screenshots of your dashboards or similar. I’m thinking I’ll have a dedicated tablet somewhere in the family room for the family to control sources and zones as well as run it on our phones. That’s as far as I’ve thought it through.

Great job on getting this released! I know the effort it takes to keep hammering away at something and getting your head around all the HA developer docs is a steep learning curve :+1:

1 Like

The snapshot only seems to work on the zones that are switched on

Bit of a delayed reply :grinning: There was indeed a bug in restoring a zone that was Off when snapshot. It’s fixed now and will be in the next release of the integration.

EXPERIMENTAL! support for media_player.join/unjoin services to group zones together. Designed to work with mini-media-player’s speaker groups but that card requires changes to support these new services before it will work with the Nuvo - more details to follow if and when that happens.

The changes to mini-media-player (MMP) went in a while back but I never did document how it works, so here’s a few notes from memory on how I implemented speakergroups for the Nuvo:

  • Only one global speaker group is supported as the HA join/unjoin API is very simple
  • Uses Nuvo groups under the hood
  • Uses the concept of a zone media_player being a group_controller
  • Source changes by group_controller are synced to group_members
  • Volume/Mute changes by group_controller are synced to group_members
  • Volume changes to a group_member zone are local to that zone
    • A subsequent change to the volume of the group_controller will change the local zone volume:
      • Change using a volume slider which calls set_volume_level will resync volumes
      • Change using volume up/down button will also up/down local volume, so local offset from group_controller will remain
  • Power on/off changes by group_controller are synced to group_members
  • If the group_controller LEAVES a group, the group is DISBANDED and all group_member zones are switched OFF
  • MMP LEAVE and UNGROUP buttons do the same thing for the group_controller
  • MMP LEAVE for a group_member removes the zone from the group and switches it OFF
  • MMP speaker_group.supports_master option is supported and MUST be TRUE (which is the default)
  • MMP speaker_group.sync_volume option is not supported, but is implicitly TRUE in the nuvo speakergroups implementation
  • MMP speaker_group.entities.volume_offset option is not supported
  • MMP platform option: use media_player

Think that’s about it. So it’s kind of a hybrid approach of Nuvo Groups and Party mode designed to be driven by MMP, but the media_player.join/unjoin services will work too as this is what MMP uses under the hood.

The MMP docs envisage a speaker_group object being under each MMP card, allowing any zone to be chosen as the group_controller. This probably makes sense if you have zone keypads and want to dynamically use a real zone as the group_controller.

My own method is:

  • Define only one MMP card which contains a speaker_group object
  • The main entity: being an unused non-physical Nuvo zone which I’ve named media_player.group_controller for convenience.
  • The real physical zones are listed under the speaker_group.entities: key to allow selection as group_members.
  • This set up allows the “virtual” media_player.group controller to be used for source and global volume changes, with local zone volume changes done via their own existing MMP card.

I’ve been using it for over a year and works well enough for my needs. Yep it is a very opinionated way to implement it, but that’s necessary when you have to come up with something that works for the Nuvo, the HA join/unjoin services and MMP frontend :man_shrugging:

Give it a whirl if you’re feeling adventurous :slight_smile:

2 Likes

Hi sprocket-9. I asked Brian the same question but I’ll ask it of you and anyone else on this thread. I’d love to see some screenshots of how you implement this at your home, if you wouldn’t mind. Not only do I lack your programming skills, I similarly lack the knowledge and inspiration to implement it to its fullest potential. I found this thread with the simple ambition to have a cheap tablet with a dashboard the family can use to choose sources and zones and control volume/bass/treble for the Nuvo Essentia E6DM. We also have 4 speakers in one area so ideally combining 2 zones as a single group would be great.

Hopefully it will work well for you. sproket-9 has put together, in my opinion, an awesome way to use the Nuvos. The mini media player entity with the pulldown card works great and allows you to modify the settings. I might try to document it on the github page with the appropriate entities if he doesn’t mind me copying his idea. Since we have those pesky DIP switches, I have an automation that runs on HA startup to re-set any settings I want to keep, so in case the Nuvo loses power and it reverts back to the DIP switches, you can push any changes back to it automatically. Something that would automatically save those to a database and put them back would be nice, but way over my head at the moment.

In HA, automations is where the Nuvo, and the paging service in particular, is really cool in my opinion. I know smart speakers are all the rage today, but the Nuvo excels at this and even puts you back to what you were listening to beforehand. I have a sound card on one zone dedicated to the Pandora integration and also use it to play any alerts, etc. I have the security system going through HA, and even an HA automation to have the Nuvo play one heck of a siren if needed haha! Much better than a small smart speaker! I also have scripts where I can press a button to play Pandora in a few rooms at a preset volume, for one example. The possibilities are really endless. Our Nuvos lack all the cool features but you can still make them do quite a bit with the help of HA.

Back to the dashboard, In a few rooms I have Amazon Fire tablets on their stands that are always on, and a dedicated page per room with “quick entries” that include stuff like the Nuvo. Although we still use IR remotes a lot too really for just simple stuff. The tablets are probably overkill really though. Don’t know I would bother with that again.

On the keypad side, a couple things I thought I might try to add to the integration in the future in an “All Off Recall.” Since the All Off button is just right there, sometimes, someone might hit it by accident (ok, maybe ME). I think it would be nice if you could just press it again and have it restore all zones to their power state before the button was pressed.
Another option I thought of would be to use the 6 source buttons to fire off automations if they were pressed when the zone is off. They can’t be used when the zone is on of course, but could be used, for example, to turn on zones and start a media player, or for something totally not related, like press source 1 button to turn off the room lights after you turned off the zone.

Thank you! This is nothing compared to the complex Grand series that you have managed, somehow, to totally integrate every feature. That is way way over my head. It’s been fun learning though, and I think I only restarted HA a couple thousand times testing everytime I changed a line of code haha.

I might try to document it on the github page with the appropriate entities if he doesn’t mind me copying his idea

I don’t mind at all, copy and use whatever you need.

It’s been fun learning though, and I think I only restarted HA a couple thousand times testing everytime I changed a line of code haha.

Yeah that restart and check the log for the latest ERROR messages loop really gets to be a drag sometimes :laughing:

I was on HA 2022.4 until this morning as I was being lazy facing all of the breaking changes. I’ll make sure it works or fix it for 2022.9 and try to put it out there today.

Don’t know if you’re already doing this but if you develop your component within a clone of the HA core repository, they’ve set up a LOAD of git pre-commit hooks which tests you code for compliance, does auto fixes and gives deprecation HA api warnings etc. It’s extremely useful but also a bit annoying at times as it’s very stringent!

1 Like

Hi Stevan,

Brian has given some good tips and looks to be planning on adding some dashboard layout in his component README soon.

To give you a flavour of what I use see the README for my component: hacs-nuvo-serial/README.md at main · sprocket-9/hacs-nuvo-serial · GitHub

HA allows so many options for dashboard layout, it’s extremely flexible - just start off basic and try small tweaks to find what works for you. I soon moved away from using the graphical layout and used hand edited .yaml files. This gives even more flexibility but also adds to the complexity :man_shrugging: Look into dashboards and views in the HA documentation - a view is like a tab on a dashboard where you could have a view per room/Nuvo zone for example.

1 Like

Don’t know if you’re already doing this but if you develop your component within a clone of the HA core repository, they’ve set up a LOAD of git pre-commit hooks which tests you code for compliance, does auto fixes and gives deprecation HA api warnings etc. It’s extremely useful but also a bit annoying at times as it’s very stringent!

Thanks for letting me know about that. I had no idea that even existed!

Thanks also for letting me use your mini-media-player example. I put one up with the (much less) entities that are specific to the “simple” integration so that might help someone out.

I had never even heard of speaker groups until I saw your post about them but I think that is really nice! Unfortunately I can’t use your integration, but you mentioned making a virtual non physical zone and adding the speaker groups there. Does your integration create it’s own media player entity called zone_controller or is that something you somehow got the MPP to do for you?

I know Stevan had mentioned wanting a group and I thought something like that would be nice to add but I’m a little lost. I’m thinking about making a virtual entity like you mentioned and adding the speaker members/zones there. I thought that I might could add a switch to all of the “real” zones so that one keypad could be the master controller, assuming it already joined in the speaker group. Switching it on in one zone would switch off all the others. These Nuvos have about as much intelligence as a basic remote control so it would all have to be done in software. That might make it a lot easier for me actually, as I can see how juggling it with all of the Nuvo’s own features and making them work together took a lot of effort!

I’ve had a closer look and it wasn’t an entirely accurate description I gave. The Grand Concerto has 16 physical zones, 8 on the system unit and 8 on an optional expander unit. I don’t have the expander, but the additional 8 expander zones can be enabled in the GC and controlled just like any of the on board zones. It’s one of these I’m using for the “virtual zone” and I named it group_controller so HA picks up the name and makes a media_player.group_controller - the name is purely for convenience so I can recognise it amongst the sea of dashboard yaml! There’s nothing special about it.

I don’t use the nuvo keypads, so my use of the virtual zone is because I don’t need a real zone and it’s associated keypad to be the controller, I can do it all through software, and also means I can have volume offset from the controller on the real zones if I want to.

If you always want a keypad zone to be the controller then it’s not really necessary to add a virtual zone, just handle the grouping in keypad zone’s media_player.

If you do want a virtual and your Nuvo doesn’t have the additional expander zones concept, I suppose you could just create a physical+1 media_player, name it group_controller and have special handling not to send any of the received commands in that media_player to the system unit.

You can also use both approaches as I have for flexibility.

Whichever media_player you choose as controller, propagate the source/volume/mute/ changes received by it to the other media_players to in your group.

HA’s concept of speaker grouping is very simple, it’s just a simple list of media_player entity_ids returned by the media_player.group_members property. The management and meaning behind this list is entirely down to you.

MMP uses this list to lookup which of the entities specified in speaker_group are group members. MMP overlays a bit of extra special meaning on the first element in this list - it will use this as the controller (or Master as it calls it) so make sure your controller entity_id is the first element and the controller entity_id is the main entity named at the top of MMP card.

Override media_player.join/unjoin to manage the group_members list. MMP calls these services when you press its various speaker group buttons.

Hope that helps and doesn’t sound complete gibberish :slight_smile:

2 Likes

I’ve had a closer look and it wasn’t an entirely accurate description I gave. The Grand Concerto has 16 physical zones, 8 on the system unit and 8 on an optional expander unit. I don’t have the expander, but the additional 8 expander zones can be enabled in the GC and controlled just like any of the on board zones. It’s one of these I’m using for the “virtual zone” and I named it group_controller so HA picks up the name and makes a media_player.group_controller - the name is purely for convenience so I can recognise it amongst the sea of dashboard yaml! There’s nothing special about it.

Ahhh, ok, that makes sense! If I had a Grand Concerto what you had described would have made much more sense to begin with. That’s a nice feature those have. I guess it could even go the other way, you could have a zone 9 keypad, for instance, that would be just a virtual zone.

If you do want a virtual and your Nuvo doesn’t have the additional expander zones concept, I suppose you could just create a physical+1 media_player, name it group_controller and have special handling not to send any of the received commands in that media_player to the system unit.
You can also use both approaches as I have for flexibility.

These Nuvos have no concept of a virtual zone, or really even grouping, except for one DIP switch for a single source group, but all it does is keep those zones on the same source. Other than that it’s like “6 amps in a box” and works just like six totally separate pieces with the same sources and the common mute/all off. So, that would be the only way you could do it. I like your idea, just make a group_controller entity and then you could add the speaker groups to it.

I like your idea of the keypad zones too. I guess the big thing to watch for would be to make sure someone couldn’t do something to cause an infinite loop like two zones updating each other over and over. I could see it being quite a mess if you had one group controller that has another group controller added to it.

MMP uses this list to lookup which of the entities specified in speaker_group are group members. MMP overlays a bit of extra special meaning on the first element in this list - it will use this as the controller (or Master as it calls it) so make sure your controller entity_id is the first element and the controller entity_id is the main entity named at the top of MMP card.

Thanks for this valuable bit of info! I created the functions to kind of see what they do and yes, they seem pretty simple. Behind the scenes doesn’t seem quite so simple though. I’ll play around with it and sew what I can come up with. This looks like one of these things where testing all the “what if” scenarios could take longer than anything else. I’m certainly impressed with your ability to somehow make all of this work even using the Nuvo groups!

Hope that helps and doesn’t sound complete gibberish :slight_smile:

It helps very much! I get the concept now. Thanks for taking the time to explain it so well.

1 Like

Hey Brian. I had a first look last night at setting up the integration with my NV-E6DM and realised that the expectation is that HA is running on the same RPi with serial to USB converter. I have HA running on a VM on Unraid and the serial to USB converter on a separate RPi. Is there a way to do that? I.e. specify an IP and port in the config to point to the RPi?

Hey Brian. I had a first look last night at setting up the integration with my NV-E6DM and realised that the expectation is that HA is running on the same RPi with serial to USB converter. I have HA running on a VM on Unraid and the serial to USB converter on a separate RPi. Is there a way to do that? I.e. specify an IP and port in the config to point to the RPi?

Sproket-9 has some good info on his integration with how to make it work with ser2net. I have never tried this but I imagine that it should work with this integration as well. That might be worth a try. If that doesn’t work, socat might. I have used it when doing some testing to simulate a Nuvo and it has a few options for that kind of thing. I’ve been working on the integration some and have speaker groups working and a few other things. I’ll put up a new version soon.

1 Like