Room Controls for Zoom Rooms
The Room Controls feature allows you to control third-party, IP-capable equipment so that the equipment can be controlled by the user through the Zoom Room controller. Admins can create a configuration profile to add outgoing IP control messages from Zoom Room.
Requirements for Room Controls for Zoom Rooms
Note: If you are using room controls for audio/video (A/V) purposes, you can assign separate Network Interface Cards (NICs) on computers in Zoom Rooms with multiple NICs. NICs can be independently selected from room control devices connected to alternate networks, which are connected to the Zoom Rooms-enabled computer. This configuration can keep your audio/video traffic off of the primary network.
Third-party devices controllable by LAN or WLAN
USB-Serial Adapters
- Zoom Rooms:
- Devices based on the Prolific PL2303 chipset, such as Startech or Sabrent
How to enable Room Controls
Before you can upload a JSON configuration profile, the setting will need to be enabled for a Zoom Room.
- Sign in to the Zoom web portal as an admin.
- In the top-right corner, click your profile picture or initials, then click Admin Center.
- In the side menu, click Product configuration
. - Click Rooms, then click Zoom Rooms.
- Click Edit to the right of the Zoom Room name.
- Under Devices, click the Enable Room Controls toggle to enable or disable it.
- (Optional) Select the checkbox to enable Set the "Room Controls" page as the home screen on the Zoom Rooms controller.
Note: This requires Zoom Rooms and Zoom Rooms Controller app version 6.3.0 or higher. - Click Create Profile.
- Enter the JSON configuration for this room.
How to write a Room Controls profile
Getting Started
Before writing a Room Controls Profile, some working knowledge of JSON is needed. The key items to note are that JSON is a key:value pair-based system and that syntax is important to correctly lay out the file. For additional information on the basics of JSON, consult an online intro course.
In any coding language, some courtesy should be extended to the next person who handles your file. While there is no specific requirement around this for Room Controls, it is recommended. To leave a record of the author, version, or other history, the 'about' object can be used and placed above 'adapters'. This is not parsed by Room Controls, but will persist in the portal. An example of how this could be leveraged is below.
{
"about": {
"type": "Medium Conference A",
"version": "v1.2.4",
"design_ref": "\\files\MediumConfA",
"created": "Mon, 21 Oct 2020 16:35:52 GMT"
},
Adapters
Setting up the adapters connects Room Controls to devices. This section is the primary section for configuration. Individual devices inside the nested JSON format should follow a similar format (this example is nested to parallel the code example below):
- Adapters: Adapters define the individual device connections
- Model: Models can be "GenericNetworkAdapter", "IP2CC", and "IP2SL". More details below.
- IP: This is the IP Address + Port of the network device
- NOTE: Room Controls now also supports hostname rather than IP address in current software versions
- UUID: This is only required with Global Caché devices and would follow "GlobalCache_[MAC]"
- Ports: Ports define the device attached to the connection
- ID: This is the name of the device in code. Should follow JSON variable formatting
- Name: This is the friendly name that your users will see on the Interface
- Methods: Methods define the individual UI section
- ID: This is the control type ID that is called in code (specific to the control type)
- Name: This is the user-accessible name shown on the Zoom Rooms Interface
- Command: This is either the full command or the shared parts of the command string depending on the action type
- NOTE: When the action type is 'actions', a % should be placed in the command string as a placeholder for the inserted elements inside of 'params'
- Params: This section is only used with the 'actions' type and contains the elements that can roll up to the parent command.
- ID: This is the programming ID that is called in code
- Name: This will be the user-accessible text on the Room Controls Button
- Value: This is the command section that is inserted in the parent command. An example of this would be using 'POWR000%\\x0D' as the parent command; '0' for Off or '1' for On could be inserted for some Sharp Displays
{
"adapters": [
{
"model": "iTachIP2SL",
"ip": "[IP_ADDRESS]",
"uuid": "GlobalCache_[UNIT_MAC_ADDRESS]",
"ports": [
{
"id": "sl_sharp_tv",
"name": "Sharp Display",
"settings": {
"baud_rate": "38400",
"flow_control": "FLOW_NONE",
"parity": "PARITY_NO"
},
"methods": [
{
"id": "power",
"name": "Power",
"command": "POWR000%\\x0D",
"params": [
{
"id": "displayOn",
"name": "On",
"value": "0001"
},
{
"id": "displayOff",
"name": "Off",
"value": "0000"
}
],
"type": "actions"
},
...
Below 'methods', an additional section can be used: "response_filter". The Response Filter is a beacon that allows the Response Filters defined below to understand which connection to listen for. There are no functions defined in this area. How a Response Filter fits into other sections will be covered inside of those sections.
Styles
Styles control the visual styling of your interface elements. The adjustments aren't extremely extensive, so it isn't very hard to learn.
There are many icons available in the interface. They span everything from air conditioners to speakerphones. The icons below are the current list, but this list is regularly expanding.
| Device | Name | Image |
| air conditioner | icon_air_conditioner |  |
| cable TV | icon_cable_tv |  |
| ceiling mic | icon_ceiling_mic |  |
| curtain | icon_curtain |  |
| DVD Player | icon_dvd_player | |
| Xbox/PS4 System | icon_game_console | |
| HDMI | icon_hdmi | |
| laptop | icon_laptop |  |
| light | icon_light | |
| projector | icon_projector |  |
| rack equipment | icon_rack_equipment |  |
| satellite dish | icon_satellite_dish |  |
| speaker | icon_speaker |  |
| speakerphone | icon_speakerphone |  |
| TV | icon_tv |  |
| power | icon_power |  |
| up | icon_up |  |
| down | icon_down |  |
| cold | icon_cold |  |
| hot | icon_hot |  |
| dry | icon_dry |  |
| wind | icon_wind |  |
There are three primary modifiers within styles: icons (as we discussed above), Main Methods, and Visibility.
Icons are the visualizations of the system. You can use them either to mark a device or to replace the text tied to a button. In the below example, we've defined a device called 'example'.
{
"adapters": [
{
"model": "ExternalControlSystem",
"ip": "tcp://[USER_IP_ADDRESS]:[USER_PORT]",
"ports": [
{
"id": "example",
"name": "Example Device",
"methods": [
...
Once 'example' is defined as a device, we can use this ID inside of styles. For example, setting the main icon for our example device to be a light is easily done.
"styles": [
"example.icon=icon_light",
"example.main_method=power"
]
Zoom also supports Material Design Icons (MDI) which can be found on Google's official MDI site.
To specify one of these icons, follow this format:
- mdi: use this prefix to identify icon as Google MDI icon
- icon_name: customer can search icon from Google Material Icons official site and use '_' to replace '(space)' in the icon name
- style_name: support "outlined", "filled", "rounded", "sharp" and "two_tone"
"example.icon=mdi:local_airport:two_tone"
Please note that that this should be in all lower case. Use an underscore (_) instead of a space in the icon name. If the icon is unable to be downloaded, the default icon will be displayed.
You may also notice that within a single line, we've also defined the Main Method for the device. The Main Method pulls the referenced command that you've defined into the title bar of the device giving it a prominent billing like so:

We've defined the power command as the main method, and so it is shown in the upper bar separate from the other commands.
The third style type is Visibility. Visibility allows the programmer to define a function, but hide that function from the User's Interface completely. It can be defined just as easily:
"example.power.invisible=true"
Following the format of "device.command.invisible=true" allows this command to be completely hidden from the Rooms User.
Rules
Rules are the automation engine of Room Controls. This is the area where things that happen on their own are defined. For example, if I wanted my display to only be active when a meeting is active, I could leverage "meeting_started" and "meeting_ended" (stock Zoom events) to make this occur.
"rules": {
"meeting_started": [
"display.power.on",
"camera.power.wake"
]
),
"meeting_ended": [
"display.power.off"
]
}
This example can be used to reduce power consumption for your system.
If one command per rule isn't enough, these commands can easily be stacked. While they technically fire sequentially, they process quickly enough that we'll consider these events simultaneous. In my above example "camera.power.wake" is added beneath "display.power.on" to activate my camera when my display wakes.
Notes:
- The available stock Zoom commands inside of rules have been expanded as of Zoom Rooms version 5.13.0. Meeting start/end events also now apply to 3rd-party interop meetings, including Microsoft Teams Direct Guest Join Meetings. Other events do not apply to 3rd-party interop meetings in this release.
- Room controls users can specify "events only" in their JSON configuration to hide unnecessary room control interfaces. When this field is specifically defined in the JSON, the Native Room Controls UI will not appear on the Zoom Rooms controller. In deployments using both NRC events and Zoom Apps, the Room Controls button directly launches the Zoom App interface without showing empty room control page.
| Type | Event | String | Notes |
| Meeting |
| Meeting | Meeting Started | zr_meeting_started | |
| Meeting | Meeting Ended | zr_meeting_ended | |
| Meeting | Meeting Started | zr_zoom_meeting_started | This command was added to differentiate between regular meetings and interop meetings, however, the meeting_started and meeting_ended commands are still supported. |
| Meeting | Meeting Ended | zr_zoom_meeting_ended | This command was added to differentiate between regular meetings and interop meetings, however, the meeting_started and meeting_ended commands are still supported. |
| Meeting | Meeting Started | zr_interop_meeting_started | |
| Meeting | Meeting Ended | zr_interop_meeting_ended | |
| Meeting | Incoming Meeting Invite Start | zr_meeting_ring_started | |
| Meeting | Incoming Meeting Invite End | zr_meeting_ring_ended | |
| | Next Meeting Alert Triggered | zr_meeting_item_about_to_start | |
| | Meeting List Item Start | zr_meeting_item_start | |
| | Meeting List Item Stop | zr_meeting_item_stop | |
| Phone |
| Phone | Incoming Phone Call Start | zr_phone_ring_started |
Any type of phone interaction (Zoom Phone, Audio Plan, 3rd Party PBX) will trigger this command
|
| Phone | Incoming Phone Call End | zr_phone_ring_ended |
All phone ring types must be inactive to trigger this event
|
| Phone | Phone Call Started | zr_phone_call_started |
PSTN Invites within an active meeting will not trigger this event
|
| Phone | Phone Call Ended | zr_phone_call_ended |
|
| In-Meeting |
| In-Meeting - Video | Video On (Camera Mute Off) | zr_video_started | |
| In-Meeting - Video | Video Off (Camera Mute On) | zr_video_stopped | |
| In-Meeting - Video | Selected Video Device Changed | zr_video_device_changed | Video device change event is only triggered when the main selected device changes. Multi-camera changes will not trigger this event. |
| In-Meeting - Audio | Mic On (Mic Unmuted) | zr_microphone_unmuted | |
| In-Meeting - Audio | Mic Off (Mic Muted) | zr_microphone_muted | |
| In-Meeting - Audio | Selected Audio Device Changed | zr_audio_device_changed | Audio device change event is only triggered when the main selected device changes. Dante mic channel change will not trigger this event. |
| In-Meeting - Content | Wireless Sharing Started | zr_share_started | Applies to direct share, whiteboard camera share, camera share, zoom apps sharing, and Apple Airplay (for multiple simultaneous shares, only the first command is sent). Digital Signage will not trigger these events. |
| In-Meeting - Content | Wireless Sharing Ended | zr_share_ended | This command is sent when the last of multiple shares ends. Digital Signage will not trigger these events. |
| In-Meeting - Content | HDMI Sharing Started | zr_hdmi_share_started | Digital Signage will not trigger these events. |
| In-Meeting - Content | HDMI Sharing Stopped | zr_hdmi_share_ended | Digital Signage will not trigger these events. |
| In-Meeting - Recording | Recording Started | zr_recording_started | |
| In-Meeting - Recording | Recording Stopped | zr_recording_ended | |
| Elevation | Meeting elevation | zr_elevate_to_meeting | This event triggers when a Zoom Room engaged in a telephony or screen-sharing session elevates the session to a video meeting. |
| Pairing |
| Pairing | User Paired to ZR | zr_user_paired | Each user will trigger a generalized pairing event. |
| Pairing | User Unpaired from ZR | zr_user_unpaired |
All users unpaired will trigger a generalized unpairing event.
|
| Digital Signage |
| Digital Signage | Digital Signage Begins | zr_digital_signage_started | |
| Digital Signage | Digital Signage is dismissed | zr_digital_signage_ended | |
| Whiteboard |
| Whiteboard | Whiteboarding opened | zr_whiteboard_started | Applies to Classic Whiteboard, New Whiteboard, and in-meeting whiteboards |
| Whiteboard | Whiteboarding closed | zr_whiteboard_ended | Applies to Classic Whiteboard, New Whiteboard, and in-meeting whiteboards |
| Whiteboard | Companion Whiteboard is added to the Zoom Room | zr_companion_whiteboard_connected | |
| Whiteboard | Companion Whiteboard is removed from the Zoom Room | zr_companion_whiteboard_disconnected | |
| Admin |
| Operation Time | Operation Time Begins | zr_operation_time_started | |
| Operation Time | Operation Time Ends | zr_operation_time_ended | |
| People Detection | People Detected | zr_people_detected | Only applicable to hardware layer people detection |
| People Detection | No People Detected | zr_people_not_detected | Only applicable to hardware layer people detection |
| Voice Commands | Voice Commands are enabled | zr_voice_command_on | |
| Voice Commands | Voice Commands are disabled | zr_voice_command_off | |
| Zoom Apps | Zoom App is opened | zr_zoom_app_opened | Opening any app will trigger this event, even if an app is already open in the meeting. |
| Zoom Apps | Zoom App is closed | zr_zoom_app_closed | Closing any app will trigger this event, even if another app is still active in the meeting. |
| Admin | Room Controls is Opened | zr_room_controls_opened | |
| Admin | Room Controls is Closed | zr_room_controls_closed | |
| Admin | Zoom Rooms Startup Completed | zr_room_startup_completed | Zoom Room startup, login, and Room Controls loading completed |
Note: Operating Hours for Operation Time events are set in the Zoom Rooms settings page.
It is also simple to add your own for Response Filters. Within the rules section, you can also use the Trigger Events discussed below to drive your own automation with outside inputs.
"rules":{
"operation_time_started":[
"light.power.on"
],
"user_customized_event1":[
"light.power.off"
]
}
In this example, our "user_customized_event1" is turning our controlled light off. This could be driven by an input from a button or maybe a motion sensor going inactive or maybe even a third-party system like a booking system sending the room an update that no users checked in for the meeting. How you can use this feature is primarily limited by your imagination.
Scenes
New in Zoom Rooms 5.13.0, the Scenes function allows Room Controls devotees to finally add Macros (multiple stacked commands on a single button) to their user experiences. This can be helpful for scene recall or dependant devices such as lowering a projector screen as well as powering the projector on.
Like Rules or Adapters, Scenes is a top-tier section in the JSON file. Today, a maximum of 20 scenes can be configured. Within those scenes, a maximum of 50 independent commands are supported.
Once configured, these new scene buttons are available at the top of the room controls window.
To configure scenes, you can reference the code sample below.
Before copying this content, please be aware that '//text' sections are notes for your reference and cannot be included in the final JSON file.
"scenes":[
{
"id":"scene_1", //required
"name":"Turn on all lights", //optional, shown if name and icon are empty
"icon":"icon_light", //optional, see icon list
"commands": [ //required
"light1.power.on",
"light2.power.on"
]
},
{
"id":"scene 2",
"name":"Turn off all lights"
"icon":"icon_light"
"commands": [
"light1.power.off",
"light2.power.off"
]
}
]
Response Filters
Response Filters are a powerful advancement in Room Controls functionality. These filters read messages coming back from defined devices and instantaneously scan for a phrase to match. When this phrase (or expression) is identified on that connection, the Rules Trigger Event (described above) fires.
Each Response Filter is comprised of three elements:
- "name": The name is used in the "ports" section of "methods". When the response filter matches this name in the "ports" area, this begins to span the defined connection
- "filter_regex": The regex (or Regular Expression) is the set of characters that the Response Filter is attempting to match. When the match occurs, the "trigger_event" will activate
- "trigger_event": The Trigger Event is used within the rules section. When the "filter_regex" activates, the automation defined within this Trigger Event in Rules will occur
How to use Room Controls
On the Zoom Rooms controller, simply tap the Room Controls
icon to access these added functions.
When not in a meeting, the Room Controls icon can be found in the main menus.
During a meeting, tapping the icon at the top right of the controller window will display the same Room Controls.
Troubleshooting
Troubleshooting is an important part in any custom configuration. While Room Controls can be simple, it is also flexible enough to be complex when needed. The below sections should help to resolve possible roadblocks.
Room Control Errors
| Error Code | Description |
| No_Config_Error | JSON Profile is not loaded in web portal |
| Json_Syntax_Error | JSON Profile contains a syntax error |
| Json_Config_Error | JSON Profile contains a configuration error |
| IP_Error | There is an issue connecting to a specified IP |
| IP_Is_Public | Public IPs are not allowed at this time |
| DeviceID_Error | One or more Device IDs are incorrectly set |
| MethodID_Error | One or more methods are incorrectly defined |
| ParamID_Error | One or more parameters are incorrectly defined |
| IP2SL_Settings_Error | Serial Port incorrectly configured on GC IP2SL |
| Empty_Device_Error | One or more devices are called without being defined in the JSON Profile |
| Unknown | An unknown error has occurred |
Sample Files
These files have been compiled from various sources and should be used as a starting point only. Some modification is likely required to fit your application.
- Generic Files
- Avocor
- Middle Atlantic
- Shure
- DTEN