Home Assistant custom component integration to control a Nuvo Grand Concerto/Essentia G using a serial connection.
Auto discovers zone and source settings from a Nuvo Grand Concerto/Essentia G amplifier, create HA Entities for each settings, allowing control through the Home Assistant web interface.
Amplifier controls exposed:
Provide support for any Nuvo amplifier other than the Grand Concerto/Essentia G.
Interface or control any Nuvonet source component.
Provide a way to send metadata or menus to zone keypads.
Communication between the Nuvo and Home Assistant uses Local Push for state changes, meaning no polling of the Nuvo occurs, so the web interface is fast and responsive. Also as the underlying library nuvo-serial monitors the serial port for activity, any changes to the Nuvo made through zone keypads will be immediately reflected in Home Assistant.
Connection to the Nuvo amplifier is via the "Programming and Serial Control" RS-232 9-pin female connector, either cabled direct to the device running Home Assistant or remotely over a network using a serial-to-network device.
Direct connection to the device running Home Assistant, either through a serial-to-serial cable if the device has a serial port, or a USB-to-RS-232 9-pin male cable.
NOTE when using a usb to serial cable, the device name assigned e.g /dev/ttyUSB1 may change when the machine is rebooted and multiple devices on the USB bus are enumerated in a different order. Obviously if this happens Home Assistant will be using the old device name for the serial port and will not be able to contact the Nuvo. To prevent this it's a good idea to assign a fixed device name to the USB cable e.g. /dev/nuvo
Systems and syntax will vary depending on OS etc, but a good Linux-based overview is here.
It essentially comes to down to:
/etc/udev/rules.d/99-usb-serial.rules
SUBSYSTEM=="tty", ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2303", SYMLINK+="nuvo"
/dev/nuvo
/dev/nuvo
as Port url in the Integration configurationConnecting to the Nuvo over a network is possible using a hardware serial-to-network adapter or software such as ser2net.
The port url should then be in the form: socket://host:port
e.g.
A possible ser2net configuration connecting TCP port 10003 to the nuvo device on /dev/ttyUSB1:
Old syntax:
10003:raw:0:/dev/ttyUSB1:57600 8DATABITS NONE 1STOPBIT
ser2net.yaml syntax:
connection: &nuvo
accepter: tcp,10003
enable: on
options:
kickolduser: true
connector: serialdev,
/dev/ttyUSB1,
57600n81,local
Port URL: socket://192.168.5.1:10003
Install using the Home Assistant Community Store HACS.
Once HACS is installed, search the available Integrations for Nuvo multi-zone amplifier (serial) and install to make the integration available for install to Home Assistant.
In Home Assistant home page go to Configuration->Integrations->Add Integration-> Nuvo multi-zone amplifier (serial)
Configure through the GUI:
Port: the url of the serial port e.g /dev/ttyUSB1
Model: Grand Concerto
or Essentia G
The existing physical zones and source names are automatically discovered and displayed for optional modification.
An Entity will now be created for each:
Entity | Integration Type |
---|---|
Zone | Media Player |
Zone balance | Number |
Zone bass | Number |
Zone treble | Number |
Zone loudness compensation | Switch |
Zone Volume Max | Number |
Zone Volume Initial | Number |
Zone Volume Page | Number |
Zone Volume Party | Number |
Zone Volume Reset | Switch |
Source Gain | Number |
Switch off all zones.
Activate Paging feature for all zones. This uses the in-built Nuvo paging feature to switch all zones to use fixed source 6 at a pre-configured paging volume.
Deactivate Paging feature, restoring all zone to pre-page state.
Make the media player zone the party host.
Release the media player zone from being the party host.
Take a snapshot of the media player zone. Useful for implementing a custom paging feature using automations.
Restores the last snapshot of the media player zone.
The following services simulate pressing the media buttons on a zone's keypad. Useful for testing automations without having to physically press the keypad button.
Simulate pressing zone keypad Next button.
Simulate pressing zone keypad Prev button.
Simulate pressing zone keypad Play/Pause button.
In addition to the media player integration built-in triggers provided by Home Assistant, this integration also provides device triggers for zone keypad Prev, Next and Play/Pause buttons. A press of one of these buttons will cause a device automation trigger to fire. E.g. Triggers for the zone named "Kitchen" can be found in the Automations trigger interface named:
NOTE: The Nuvo only emits keypad button event messages (and thus the Home Assistant keypad triggers will only fire) when the currently selected Source for a Zone is configured as a Non-Nuvonet source. As of now there is no way to configure the source type through the Home Assistant integration. Use the nuvo-serial Python library or the Windows-based Nuvo Configurator software.
Everything in this section is optional and shows a heavily opinionated method of configuring Lovelace to display the Nuvo entities. While it may not be to everyones taste, it should at least give some inspiration for configuration possibilites.
The core Media Player integration (and therefore any Lovelace media control card representing a media player entity) does not provide a way to control a media device's EQ settings. Each EQ setting is modeled using the Number integration. The advantage of this is the ability to use the native number ranges exposed by the Nuvo for each control rather than a card showing a generic 0-X scale.
While Home Assistant will auto-create Lovelace media control and number cards for each Nuvo entity, a more polished look can be achieved using third-party cards mini-media-player and lovelace-slider-entity-row, both cards are installable through HACS.
This example Lovelace configuration displays the EQ settings in a Conditional card that is only displayed when the zone is switched on and an input_boolean entity is True. This input_boolean is toggled by tapping the mini-media-player representing the zone. In order to achieve this, an additional input_boolean entity per-zone needs manually created (it's purely to control the frontend EQ Conditional card, it doesn't represent anything on the Nuvo itself).
e.g. In configuration.yaml:
input_boolean:
eq_office:
name: Office EQ
initial: off
eq_kitchen:
name: Kitchen EQ
initial: off
Will create the entities:
input_boolean.eq_office
input_boolean.eq_kitchen
As shown the yaml section below, the tap action on each mini-media-player will call the input_boolean.toggle service.
Example section in ui-lovelace.yaml:
views:
- title: MusicZones
cards:
- type: vertical-stack
cards:
- type: entities
entities:
- type: custom:mini-media-player
entity: media_player.office
group: true
hide:
controls: false
info: true
power_state: false
play_pause: true
prev: true
next: true
icon: mdi:speaker-wireless
volume_stateless: true
tap_action:
action: call-service
service: input_boolean.toggle
service_data:
entity_id: input_boolean.eq_office
- type: custom:slider-entity-row
entity: media_player.office
full_row: true
step: 1
hide_state: false
hide_when_off: true
- type: conditional
conditions:
- entity: media_player.office
state: "on"
- entity: input_boolean.eq_office
state: "on"
card:
type: entities
entities:
- type: custom:slider-entity-row
entity: number.office_bass
name: Bass
icon: mdi:music-clef-bass
hide_state: false
hide_when_off: true
full_row: false
- type: custom:slider-entity-row
entity: number.office_treble
full_row: false
name: Treble
icon: mdi:music-clef-treble
hide_state: false
hide_when_off: true
- type: custom:slider-entity-row
entity: number.office_balance
full_row: false
name: Balance
hide_state: false
hide_when_off: true
- entity: switch.office_loudcmp
name: LoudComp
show_state: true
- type: custom:slider-entity-row
entity: number.office_volume_max
full_row: false
name: Volume Max
hide_state: false
hide_when_off: true
icon: mdi:tune
- type: custom:slider-entity-row
entity: number.office_volume_initial
full_row: false
name: Volume Initial
hide_state: false
hide_when_off: true
icon: mdi:tune
- type: custom:slider-entity-row
entity: number.office_volume_page
full_row: false
name: Volume Page
hide_state: false
hide_when_off: true
icon: mdi:tune
- type: custom:slider-entity-row
entity: number.office_volume_party
full_row: false
name: Volume Party
hide_state: false
hide_when_off: true
icon: mdi:tune
- entity: switch.office_volume_reset
name: Volume Reset
show_state: true
- type: entities
entities:
- type: custom:mini-media-player
entity: media_player.kitchen
group: true
hide:
controls: false
info: true
power_state: false
play_pause: true
prev: true
next: true
icon: mdi:speaker-wireless
volume_stateless: true
tap_action:
action: call-service
service: input_boolean.toggle
service_data:
entity_id: input_boolean.eq_kitchen
- type: custom:slider-entity-row
entity: media_player.kitchen
full_row: true
step: 1
hide_state: false
hide_when_off: true
- type: conditional
conditions:
- entity: media_player.kitchen
state: "on"
- entity: input_boolean.eq_kitchen
state: "on"
card:
type: entities
entities:
- type: custom:slider-entity-row
entity: number.kitchen_bass
name: Bass
icon: mdi:music-clef-bass
hide_state: false
hide_when_off: true
full_row: false
- type: custom:slider-entity-row
entity: number.kitchen_treble
full_row: false
name: Treble
icon: mdi:music-clef-treble
hide_state: false
hide_when_off: true
- type: custom:slider-entity-row
entity: number.kitchen_balance
full_row: false
name: Balance
hide_state: false
hide_when_off: true
- entity: switch.kitchen_loudcmp
name: LoudComp
show_state: true
- type: custom:slider-entity-row
entity: number.kitchen_volume_max
full_row: false
name: Volume Max
hide_state: false
hide_when_off: true
icon: mdi:tune
- type: custom:slider-entity-row
entity: number.kitchen_volume_initial
full_row: false
name: Volume Initial
hide_state: false
hide_when_off: true
icon: mdi:tune
- type: custom:slider-entity-row
entity: number.kitchen_volume_page
full_row: false
name: Volume Page
hide_state: false
hide_when_off: true
icon: mdi:tune
- type: custom:slider-entity-row
entity: number.kitchen_volume_party
full_row: false
name: Volume Party
hide_state: false
hide_when_off: true
icon: mdi:tune
- entity: switch.kitchen_volume_reset
name: Volume Reset
show_state: true
This configuration will display the cards below, with the EQ settings card toggled by tapping on the media player, in any area not containing a control: