Skip to main content

Zoom Rooms

Controls a Zoom Room through ZR-CSAPI, the control system interface Zoom Rooms serves on TCP port 2244. Joins and leaves meetings, mutes the room microphone and camera, sets speaker volume, and tracks call status so the rest of GEM can react to whether the room is in a meeting.

This is the local control path. It talks directly to the room computer on the LAN — no cloud account, no OAuth, no Zoom Marketplace app.

PC and Mac rooms only

ZR-CSAPI is served by the Zoom Rooms for Windows / macOS application. Appliance-mode rooms — Neat, Poly, Logitech, DTEN, and the Android-based bars — do not serve it and cannot be driven by this driver. Check what the room actually runs before quoting it.

Prerequisites

  • A Zoom Room running on a Windows or Mac computer.
  • The Zoom Rooms Control System API enabled on that room with a passcode set (Zoom Rooms Settings → Meetings → Zoom Rooms Control System API). It is off by default.
  • TCP 2244 reachable from the GEM controller. The room computer's own firewall usually blocks it — that rule is separate from enabling the API, and forgetting it is the single most common commissioning failure.
  • A static IP or DHCP reservation on the room computer.

Setup

  1. Enable the API on the room. In the Zoom Rooms application on the room computer, open Settings → Meetings and turn on the Zoom Rooms Control System API. Set a passcode and note it down.
  2. Open the firewall. Allow inbound TCP 2244 on the room computer for your controller's subnet.
  3. Verify by hand. From a workstation, telnet <room-ip> 2244. The room answers with a banner and a login prompt; type the passcode and press Enter. A successful login is acknowledged, after which zStatus Call Status returns the room's state.
  4. Add the device. In /admin/devices create a device with driver zoom_rooms:
    • ip — the room computer's address
    • port — leave at 2244
    • password — the control system passcode (stored encrypted)
  5. Confirm. Run get_call_status. The device's call_status attribute should populate with NOT_IN_MEETING or IN_MEETING within a second or two, and room_name fills in from the room's own system info.

Attribute reference

Device

AttributeRequiredDefaultDescription
ipyesRoom computer IP — not the scheduling display or the controller tablet
passwordyesControl system passcode. Stored encrypted.
portno2244ZR-CSAPI port
poll_intervalno30000Backstop call-status re-read interval, in ms
default_durationno30Minutes passed to start_meeting when the command carries no duration
call_statusread-onlyNOT_IN_MEETING / CONNECTING_MEETING / IN_MEETING
mute_stateread-onlyRoom microphone, on / off
camera_stateread-onlyon when the room is sending video
volumeread-onlyRoom speaker volume, 0-100
room_nameread-onlyRoom name as configured in Zoom

Zones

This driver does not use zones — one GEM device per room, and state lands on the device.

Commands

CommandArgsNotes
join_meetingmeeting_number, passwordMeeting number is stripped to digits; password optional
start_meetingdurationStarts the room's personal meeting for N minutes
leave_meetingThe room leaves; the meeting continues for everyone else
end_meetingEnds the meeting for all participants
mute_on / mute_off / mute_toggleRoom microphone. Toggle resolves from the cached state.
mute_all / unmute_allEvery participant in the meeting, not just the room
camera_on / camera_offCamera mute
volumevolume0-100
volume_up / volume_downstepDefault step 5, from the cached volume
get_call_statusRe-read call status
get_system_infoRoom name, platform, version
get_bookings / update_bookingsRead, or force a refresh of, the room's calendar bookings
send_commandtextSend a literal ZR-CSAPI line
dial_phonenumberNot implemented — see below

send_command is the escape hatch. ZR-CSAPI exposes far more than this driver wraps (layout control, participant management, sharing), and any documented zCommand / zConfiguration / zStatus line can be sent through it from a macro without a driver change.

What this unlocks

The useful part of this driver is usually not the meeting control — the room's own tablet does that better — it is call_status as an automation input. A room that reports IN_MEETING can drive the rest of the building:

  • Set an in-use indicator outside the door.
  • Lower shades and drop the lights to a preset when a meeting starts, restore them when it ends.
  • Hold back HVAC setbacks and cleaning-crew scenes while the room is occupied.
  • Route the room's DSP to conferencing gain structure on entry and back to program audio on exit.

Build these as attribute triggers on the device's call_status.

Session behavior

The driver opens one long-lived socket, sends the passcode when the room prompts for it, then switches the session to JSON replies. State changes the room pushes are applied as they arrive; the poll loop is a backstop, not the primary path.

Most builds allow one control system session at a time. If a third-party controller is already connected, GEM may take the slot from it or be refused — decide which system owns the room before commissioning both.

Known limitations

  • dial_phone is not implemented. It appears in the command list so it is discoverable, but the Zoom Phone outbound dial verb was not verifiable against the ZR-CSAPI reference, so it returns not yet implemented rather than a guessed wire format. Zoom Phone dialing can be driven through send_command once you have confirmed the verb for your build.
  • Sharing, layout and participant management are not wrapped. Use send_command.
  • No appliance-mode support. Covered above.
  • Not validated against a live room. The command surface follows Zoom's published control system interface, but this driver has not yet been run against physical hardware. Commission with get_call_status and one mute command before wiring it into automation.

Troubleshooting

SymptomCheck
Connection refused on 2244The control system API is disabled, or the room computer's firewall is blocking the port. These are two separate things — confirm both.
Connects, then every command is ignoredThe passcode was rejected. The device log records the login attempt; re-read the passcode from the room settings screen.
Status stops updating after a whileAnother control system took the session slot. Reload the device and disconnect the other controller.
volume_up returns "no cached volume"The driver has not read the volume yet. Run get_system_info, or wait for the session to re-establish.
Nothing works on a Neat / Poly / DTEN roomAppliance-mode rooms serve no ZR-CSAPI. There is no local control path on that hardware.
Meeting joins but with no audioUnrelated to this driver — check the room's own audio device selection in Zoom Rooms settings.