Optoma Projector
Control any Optoma commercial installation or home-cinema projector that exposes the RS-232 command surface over LAN (which covers virtually every model shipped since 2015 — ZH / ZK / EH / UHD / GT / HD series and most of the commercial ProAV lineup).
The driver speaks the standard Optoma text command protocol (~00<cmd> <val>\r) directly to the projector on TCP port 23. No cloud, no vendor SDK, no license required.
Prerequisites
- Network Standby enabled. In the projector OSD:
Setup → Power → Network Standby → On. Without this, the projector's LAN port powers down when the projector is off, and control is only possible while it is already on. - LAN control enabled. In the projector OSD:
Setup → Network → LAN Control— pick the option that mentions "RS232 by IP" or "Extron IP" (label varies by firmware). This exposes the RS-232 command surface on the network port. - Static IP or DHCP reservation on the projector. Note the address from
Setup → Network → LAN Settings. - Confirmed control port. Most models ship on TCP 23. Some ZK / UHD installation models use 3023. The setup screen usually shows the current value.
Setup steps
- Enter the projector menu and enable Network Standby and LAN control per Prerequisites.
- Note the projector's IP address and confirm the control port under
Setup → Network. - In GEM, go to Admin → Devices and add a new device.
- Choose driver optoma_projector.
- Fill in:
- Projector IP — the LAN IP from the projector's Network Settings.
- Control Port — leave 23 unless the projector's Network menu says otherwise.
- Save. Within a few seconds the device should show as connected and populate
model_name,firmware_version,lamp_hours,power_state, andinput.
Attribute reference
Required
| Attribute | Type | Description |
|---|---|---|
ip | string | LAN IP of the projector. |
Optional (connection & tuning)
| Attribute | Type | Default | Description |
|---|---|---|---|
port | int | 23 | TCP port. Some installation-series models use 3023 — confirm in the projector's Network menu. |
projector_id | string | 00 | Two-digit projector address. 00 is the wildcard and matches any projector. Only change when multiple projectors share a single RS-232 link and each has been assigned a unique ID via the OSD. |
volume_max | int | 100 | The projector's native maximum volume value. Installation-series units use 0-100 natively; entry-level home projectors use 0-32. When set to 32, GEM's 0-100 volume slider scales down to the 0-32 wire range. |
status_interval | int | 30000 | Milliseconds between status polls. |
Diagnostic (populated by the driver)
| Attribute | Type | Description |
|---|---|---|
model_name | string | Auto-populated from the model-name query on first connect. |
firmware_version | string | Auto-populated from the firmware query on first connect. |
lamp_hours | int | Cumulative lamp / light-source hours reported by the projector. History-enabled so long-term wear is tracked. |
power_state | string | on / off — reflects the projector's own report, not just GEM's last command. |
input | string | Current input keyword (e.g. hdmi1, hdbaset). |
volume | int | Volume in the GEM 0-100 scale. |
mute_state | string | on / off. |
Zone address
Not used. Each device row is a single projector. If you want to link volume / mute to an AV zone, set volume_device_id on the AV zone to the projector device's id — the driver will fan mute / volume updates to that zone automatically.
Commands
Power: power_on, power_off, get_power.
Source: set_input (with input arg), plus one-shot shortcuts hdmi1, hdmi2, hdmi3, hdbaset, displayport, vga1, vga2, and get_input.
Audio: volume (0-100), volume_up, volume_down, mute_on, mute_off, mute_toggle.
Image: blank_on / blank_off (AV mute — blanks video, leaves audio alone), freeze_on / freeze_off, brightness, contrast, set_aspect.
OSD & diagnostics: menu_toggle, get_lamp_hours, get_model, get_firmware.
Known limitations
- Warm-up window. Optoma projectors reject control commands during the 30-90 s power-on cycle with an
F(fail) reply. The driver logs a warning and picks the state back up on the next status poll — expect a brief mismatch between commanded and reported state afterpower_on. - Response ambiguity. Optoma projectors reply to queries with just
Ok<value>— the query code is not echoed. The driver maintains a FIFO of pending queries to bind each response back to its query. If the projector volunteers unsolicited data (rare), the FIFO stays consistent because unmatched responses are dropped. - AV mute vs audio mute.
blank_onuses the projector's video mute (command 30). It stops the picture but leaves audio active. Usemute_onif you want silence. - Input coverage. The source list covers HDMI 1/2/3, HDBaseT, DisplayPort, VGA 1/2, Video, S-Video, BNC, DVI, and Component. Newer specialty inputs (Wi-Fi display, USB reader) are model-specific and not exposed as named shortcuts yet — send the raw source code via
set_inputif you need one. - No test-pattern controls. The driver does not expose
pattern,keystone, orcolor-tempcommands. These are model-specific and best driven from the OSD.
Troubleshooting
Connection refused / drops the moment the projector goes into standby.
Network Standby is off. Enable it under Setup → Power → Network Standby → On. Some models call it "Direct Power On" or bury it under Setup → Options → Standby Mode → Eco/Active.
Commands succeed, but power/source status stays empty.
The projector may be on a non-standard port (3023 vs 23) or need the LAN Control mode set to RS232 by IP specifically. Toggle both and disconnect / reconnect the device row.
Set commands return F while the projector is warming up.
Expected. Optoma rejects control during the 30-90 s warm-up. The driver picks state back up on the next poll.
Volume slider jumps in large steps.
volume_max defaults to 100 but your model uses 0-32 native. Set volume_max = 32 in the device attributes and the driver will scale 0-100 GEM values into the 0-32 wire range.
Multiple projectors on the same link (RS-232 daisy chain).
Set each projector's Projector ID in the OSD (Advanced → Projector ID), then set the corresponding projector_id attribute on each GEM device row so commands don't broadcast.