GEM driver for Yamaha AV receivers that speak the YNCA (Yamaha Network Control Architecture) TCP protocol on port 50000. Covers the RX-V, RX-A (Aventage), and many CX / NX preamp models from roughly 2011 through 2019. Supports up to four named zones (MAIN, ZONE2, ZONE3, ZONE4) with per-zone power, volume, mute, and input.
For newer Yamaha receivers (RX-V6A, RX-A2A, RX-V4A and later) that ship MusicCast only and no longer expose YNCA, use the yamaha_musiccast driver instead.
Prerequisites
- A Yamaha receiver with YNCA-compatible firmware. Most RX-V / Aventage models from model year 2011 onwards expose YNCA on port 50000. If a
telnet <receiver_ip> 50000 connects and stays open, you're good.
- Network Standby enabled. Setup → Network → Network Standby = On. Without this, the receiver's Ethernet stack drops the moment it goes into standby and the driver loses control after the first
power_off.
- A static IP or DHCP reservation for the receiver. YNCA does not handle IP changes gracefully.
- No competing TCP session. The receiver accepts only one TCP client at a time — close the Yamaha AV Controller / MusicCast Controller apps on phones and tablets before troubleshooting.
Setup steps
- Enable Network Standby on the receiver. Menu → Setup → Network → Network Standby → On.
- Pin the receiver's IP. Either set a static IP from the receiver menu or create a DHCP reservation on the router.
- Add the device in GEM. Devices → Add → driver
yamaha_ynca. Enter the receiver IP. Leave port on 50000.
- Verify protocol. Open the device's Script Console and run:
await gem.command({device: <device_id>, action: 'get_status', args: {address: 'MAIN'}})
You should see PWR / VOL / MUTE / INP responses come back within a second or two.
- Wire up zones. Create one GEM zone per receiver zone you want to control. Set
zone.address to the literal subunit name: MAIN, ZONE2, ZONE3, or ZONE4. Most receivers physically only have MAIN + ZONE2; consult the model spec before configuring ZONE3 / ZONE4.
- Optional — wire AV sources. Create AV sources keyed to the receiver's input codes (
HDMI1, NET RADIO, etc.) so the UI can switch inputs by name.
Attributes
Device — required
| Name | Type | Description |
|---|
ip | string | LAN IP or hostname of the receiver. |
Device — optional
| Name | Type | Default | Description |
|---|
port | int | 50000 | YNCA TCP port. Almost always the factory default. |
status_interval | int (ms) | 30000 | How often to re-query PWR / VOL / MUTE / INP on every configured zone. YNCA also pushes unsolicited updates on user changes, so this is a backstop. |
command_throttle | int (ms) | 100 | Minimum gap between outbound commands. Older firmware drops commands stacked tighter than ~100 ms. |
min_volume_db | float | -80.5 | Lower bound used when mapping GEM 0-100 volume to YNCA dB. |
max_volume_db | float | +16.5 | Upper bound used when mapping GEM 0-100 volume to YNCA dB. Lower this on shared installs where guests can run a control UI. |
Zone — address
| Field | Description |
|---|
address | Subunit name as a literal string. Accepts MAIN, ZONE2, ZONE3, ZONE4 (with or without underscore / space). Plain integers 1-4 are also accepted as aliases. |
Commands
| Name | Args | Description |
|---|
on | address | Power on (PWR=On). |
off | address | Power off / standby (PWR=Standby). |
power_on / power_off | address | Aliases. |
set_volume | address, level | Set volume on the GEM 0-100 scale; linearly mapped to YNCA dB. |
set_volume_db | address, db | Set absolute YNCA dB (-80.5 to +16.5, 0.5 dB steps). |
volume_up / volume_down | address | Step by 0.5 dB. |
mute_on / mute_off | address | Mute / unmute. |
mute_toggle | address | Toggle. Resolved client-side from cached mute_state — YNCA has no native protocol toggle. |
set_input | address, input | Switch input by YNCA input code (HDMI1, NET RADIO, SPOTIFY, etc.). |
get_status | address | Query PWR / VOL / MUTE / INP for one zone. |
get_zones | — | Probe MAIN / ZONE2 / ZONE3 / ZONE4 in turn. Subunits that respond are reported as present. |
HDMI1–HDMI7, AV1–AV7, AUDIO1–AUDIO5, AUX, PHONO, TUNER, USB, SERVER, NET RADIO, SPOTIFY, AIRPLAY, BLUETOOTH, MUSIC CAST LINK. The exact list depends on the model — set_input to an unsupported code returns @RESTRICTED on the wire.
Zone state attributes
| Attribute | Values |
|---|
state | on / off (mapped from PWR=On / PWR=Standby) |
volume | 0-100, mapped from the YNCA dB report |
mute_state | on / off |
input | YNCA input code as a string |
Known limitations
- One TCP client. The receiver allows only one YNCA session. If Yamaha's own app is open on a phone, the GEM driver is silently kicked.
- Volume mapping is linear in dB. YNCA's perceptual response is not linear — small changes near the top of the scale are loud, small changes near the bottom are subtle. Most installs prefer a lower
max_volume_db so that the GEM 0-100 slider reaches a comfortable max well before clipping.
- DSP / surround modes (
SOUNDPRG, STRAIGHT, PUREDIRECT) are not exposed as commands in this MVP. The protocol supports them — see @MAIN:SOUNDPRG=? — but they are not yet wired up to GEM zone attributes.
- Tuner / NetRadio metadata (
@TUN:FREQ=…, @NETRADIO:META=…) is not yet exposed.
- HDMI control / video routing is not yet wired through.
Troubleshooting
- Connection refused on port 50000. Confirm Network Standby is enabled and that no other Yamaha controller app is connected. On newer-than-2020 receivers YNCA may simply not be exposed — switch to the
yamaha_musiccast driver.
- Commands send but state never updates.
response_terminator defaults to \r\n. If the receiver is wired through a serial-over-IP gateway that strips the LF, set response_terminator to \r on the device row.
@RESTRICTED on every command. Either the receiver is powered off and the addressed zone is asleep (PWR=On will wake it), or the input/value sent is not supported on the model. Check the receiver's "Network" menu in the OSD to confirm YNCA is enabled.
@UNDEFINED after probing ZONE3 / ZONE4. Normal — the receiver responds @UNDEFINED to commands targeting subunits it doesn't have. Only configure zones for subunits the receiver physically supports.
- Volume slider scale wrong. Check
min_volume_db / max_volume_db on the device. The driver maps 0-100 linearly into that range; if your install caps the receiver below +16.5 dB physically, lower max_volume_db so the slider tracks reality.
Honest caveats
- Without real hardware on the bench, the response parser was tuned against the YNCA reference (
@SUB:FUNC=Value form, @UNDEFINED / @RESTRICTED error tokens). If the receiver firmware ships a slightly different framing (some early models suffix \r only), set response_terminator accordingly.
- The volume dB ↔ GEM 0-100 mapping is linear and clamped to the configured min/max. Receivers report VOL in 0.5 dB steps; the driver rounds to that granularity on outbound
set_volume to avoid the receiver echoing back a slightly different value than was sent.
- Older RX-V firmware (~2011) is known to drop commands stacked tighter than 100 ms — that's why
command_throttle defaults to 100. If you're on very recent firmware you may be able to lower it, but the gain is marginal.