RTI AD-4x / AD-8x (HTTP)
GEM driver rti_ad8x_http controls an RTI AD-4x / AD-8x multi-zone audio distribution amplifier over the local HTTP control interface (rti_*.cgi) served at port 80.
Functionally equivalent to the rti_ad8 TCP driver — pick this one where the TCP control port becomes unresponsive after extended uptime. The web UI keeps responding on units where the TCP socket has wedged.
What it does
- Per-zone power, mute, volume, and source select via GET requests to
rti_zp0/zp1.cgi,rti_zm0/zm1.cgi,rti_zvs.cgi,rti_zi.cgi. - Periodic poll of
rti_status.cgito reconcile state — the amp does not push updates. - Optimistic state push on each command so the UI updates without waiting for the next poll.
- Transparent re-login when the amp serves the login page in place of a CGI response (silent session expiry).
Prerequisites
- AD-4x or AD-8x amplifier on the LAN with HTTP control enabled (port 80 by default).
- Web-UI password — the one set on the amp's
rti.shtmllogin page. Leave the GEM attribute blank to use the factory default (rti).
Setup steps
- Confirm
http://<amp-ip>/rti.shtmlloads the RTI login page. - Create the device with driver
rti_ad8x_http, enter the IP, and set the web-UI password. - Add a GEM Zone for each amplifier output. Set
zone.addressto1..4(AD-4x) or1..8(AD-8x) — this is the value the amp expects in thez=query parameter. - On connect, the driver logs in, polls
rti_status.cgi, and refreshes everystatus_intervalms (default 5000).
Attribute reference
Device
| Name | Required | Description |
|---|---|---|
ip | yes | LAN IP of the amplifier. |
password | no | Web-UI password. Sent to /rti_login.cgi?pw=… on each session. Defaults to rti. Stored as a secure attribute. |
port | no | HTTP port. Defaults to 80. |
status_interval | no | Poll interval (ms) for rti_status.cgi. Defaults to 5000. |
volume_min | no | Soft floor on GEM volume (0..100). Requests below this are clamped before being sent. Defaults to 0 (no floor). |
volume_max | no | Soft ceiling on GEM volume (0..100). Useful for capping how loud a zone can be driven. Defaults to 100 (no cap). |
debug_log_status | no | When true, dumps the first status response body per connect to the log for parser tuning. |
Zone
No required zone attributes. Set zone.address to the 1-based output number.
Commands
| Name | Args | Notes |
|---|---|---|
zone_on / zone_off | address | Powers the zone on or off. |
mute_on / mute_off | address | Mute control. |
volume | address, volume | Volume 0-100 in GEM units; converted to wire dB internally. |
volume_up / volume_down | address | ±5 GEM units from the cached current value. |
set_input | address, input | Route a physical amp input (1-based) to a zone. Writes the value to zone.input. Implicitly powers the zone on. |
all_zones_on / all_zones_off | — | Power all zones (sequential fan-out, one HTTP request per zone). |
mute_all / unmute_all | — | Mute / unmute all zones (sequential fan-out). |
request_status | — | Trigger an immediate status poll. |
passthrough | path | Send a raw GET to the amp. path is the URI after the host, e.g. rti_zp1.cgi?z=1. |
Volume scale
GEM exposes 0..100; the wire is dB attenuation -78..0 (0 = loudest, -78 = quietest). The driver converts in both directions. The rti_status.cgi body reports volume as an unsigned attenuation (e.g. "vol":"56" = -56 dB); the driver inverts the sign before mapping to GEM units.
Use volume_min / volume_max to cap or floor the GEM-side range — these are soft caps on the write path only, so a value set above the cap from the front panel still surfaces accurately on the next status poll.
Known limitations
- The amp does not push state — all reads happen via the polling interval. Lower
status_intervalfor tighter UI sync at the cost of more LAN traffic. rti_status.cgireturns near-JSON with SSI comments inlined ({"zone": <!--#zn1-->{...}}). The driver strips comments before parsing and infers zone numbers from the array index, since the JSON itself does not carry them.- Sessions are held by client IP — no cookie is set by most firmware. The driver re-logs in transparently when the amp serves the login page back in place of a CGI response.
- Success and failure both return HTTP 200. The driver disambiguates on body content (
<!-- ok -->for success, an HTMLParameter Errorpage for failure). set_inputimplicitly powers the target zone on — observed on AD-8x firmware. Setting a source on a powered-off zone will showpwr=1on the next status poll.
:::info zone.input vs zone.source
The driver writes the amp's physical input number (1..N) to zone.input. It never writes zone.source — that attribute is reserved for GEM's av_source foreign key and is owned by the AV-routing macros. Writing the raw amp input into zone.source would be rejected by the av-source-change handler as an invalid av source.
:::
Troubleshooting
| Symptom | Check |
|---|---|
| Login fails / status returns HTML. | Confirm the password attribute matches the rti.shtml web UI password exactly. The driver re-logs in on 401/403 but a wrong password will loop. |
| Volume slider feels backwards or compressed. | Older firmware uses a -62..0 range instead of -79..0. The driver assumes the newer range; expect proportionally lower GEM volume on legacy firmware. |
| Zone state diverges from the web UI. | Lower status_interval; the amp does not push state, GEM only sees changes after the next poll. |
Commands rejected with parameter error. | Confirm zone.address is the 1-based output number (1-4 on AD-4x, 1-8 on AD-8x), not a padded string. |
:::tip TCP vs HTTP
If the existing rti_ad8 TCP driver works reliably for you, stick with it — TCP is lower-overhead. Switch to rti_ad8x_http if you see the amp's TCP control port stop responding after weeks of uptime while the web UI continues to work.
:::