Skip to main content

Omnibus VRF (REST)

HTTPS/JSON integration for a Omnibus protocol-adapter gateway's VRF/HVAC port. Omnibus taps a manufacturer's indoor-unit bus and normalizes every indoor unit, then exposes them over a REST API. GEM speaks only HTTPS + JSON to the gateway — there is no serial wiring or bus protocol knowledge in GEM; Omnibus does all of that.

One Omnibus VRF port becomes one GEM device row; each indoor air handler becomes a climate zone addressed by its bus id (for example 20.2.4).

The integration is validated against Samsung DVM-S (the NASA bus). Daikin, Mitsubishi, LG, and Toshiba share the identical REST contract — only the mode / fanSpeed enum sets and the unit address format differ, and the driver reads those from the gateway rather than hardcoding them, so no driver change is needed per brand.

What this integration covers

  • Power — on / off per indoor unit.
  • Mode — the gateway-advertised modes (Samsung: auto, cool, dry, fan, heat), mapped to GEM system_mode; off powers the unit down.
  • Setpoint — single target temperature per unit. Default presentation is °F (writes setpointF, whole degrees); switchable to °C (writes setpointC).
  • Fan speed — the gateway-advertised speeds (Samsung: auto, low, mid, high, turbo). Common GEM synonyms (mediummid, very_strongturbo, …) are bridged automatically.
  • Status polling of on/off, mode, room temperature, setpoint, fan speed, humidity, thermostat demand, and the unit fault code — refreshed from the gateway's cached snapshot on the poll interval.
  • Auto-discovery — the driver enumerates indoor units from the status snapshot and (by default) creates a climate zone per unit. Each zone's name is derived from the gateway-reported unit label (e.g. Livingroom Climatelivingroom_climate), falling back to a device+unit slug when the unit has no name. Zones are deduped by address, so renaming a unit only affects display naming, not which zone it maps to.
  • Gateway health tags on the device row — brand, gateway_mode, dry_run, writes_live, controller, crc_fail, parse_errors, frame counters.

What this integration does NOT cover (yet)

  • Push updates. The status snapshot is a cached, periodically-broadcast view; a change made elsewhere appears at the next poll (within poll_interval), not instantly. The gateway also publishes the same state over MQTT — a future event-driven alternative to polling — but this driver uses the REST poll path.
  • Dry-run / mode control. Whether the port is in sniffer/poll vs control, and whether dry-run is on, is an operator decision on the Omnibus panel. The driver reflects these as read-only device tags and flags writes that can't actuate; it never flips them.
  • Dual heat/cool setpoints. A VRF indoor unit has a single setpoint; the setpoint command accepts a mode argument for climate-UI compatibility but always applies that one setpoint.
  • Hardware-confirmed power/mode/fan on Samsung. Only the setpoint write is hardware-confirmed today; power/mode/fan writes are functional-but-unverified until the operator confirms on real equipment.

Prerequisites

  • The Omnibus gateway reachable from the GEM host over HTTPS.
  • An admin account on the gateway. Every per-port rest/* action — including the read-only status — requires an admin token, so the driver polls and writes with the same admin credentials.
  • The gateway's VRF port configured with the indoor-unit adapter (e.g. Samsung VRF / DVM-S) and seeing decoded bus frames.
  • To actuate writes: the operator must set the port to control mode with dry-run OFF on the Omnibus panel. In sniffer/poll or dry-run, writes are accepted and echoed but nothing transmits.

Setup steps

  1. In GEM, go to System → Devices → Add Device (Open Devices) and pick Omnibus VRF (REST) as the driver.
  2. Enter ip (the gateway host), port (default 443), and the admin username / password.
  3. Leave port_path blank to have the driver auto-select the gateway's VRF/REST port, or set it explicitly. The driver matches your value against both the canonical device path and the /dev/ttyUSBx display path, and URL-encodes it for you.
  4. Choose tls:
    • verify (default) pins the gateway's internal CA, fetched once (unauthenticated, a public/stable credential) from /api/system/ca-cert. Use this on-site, reaching the gateway by a LAN IP or local hostname.
    • insecure skips verification. Use only for a first install / lab, or when reaching the gateway by a hostname not in the certificate's SANs (e.g. a remote tunnel).
  5. Set setpoint_unit (F default, or C).
  6. Save. The driver authenticates, polls status, and auto-creates one climate zone per indoor unit (address = bus id, e.g. 20.2.4). Run the discover command to list the units the gateway reports.
Subsystem placement

Auto-created zones are placed under the Climate subsystem. If your site has no climate subsystem, the driver creates one. The subsystem only affects grouping/presentation, not whether commands work.

TLS and the gateway certificate

The gateway serves HTTPS with a leaf certificate signed by an internal CA. The certificate's SANs cover local hostnames (omnibus-<id>, omnibus-<id>.local) and LAN/overlay IPs — not arbitrary external hostnames.

  • In verify mode the driver downloads the CA once and pins it, then verifies normally. This is the preferred, secure path for on-site deployments addressed by an in-SAN name or IP.
  • If you reach the gateway by an out-of-SAN hostname (such as a remote *.netbird.cloud tunnel used during commissioning), TLS hostname verification will fail even with the CA trusted — use insecure for that connection. Insecure mode is opt-in and logged.

Attribute reference

Device attributes

NameTypeRequiredDescription
ipstringyesLAN IP or hostname of the Omnibus gateway.
usernamestringyesAdmin account (the status action needs an admin token).
passwordstringyesAdmin password (stored encrypted).
portintnoGateway HTTPS port (default 443).
port_pathstringnoVRF port device path. Blank = auto-select the VRF/REST port. Accepts the /dev/ttyUSBx display path or the canonical /dev/serial/by-id/... path.
tlsstringnoverify (default, pin CA) or insecure (skip verification).
setpoint_unitstringnoF (default) writes setpointF; C writes setpointC.
poll_intervalintnoStatus poll cadence in ms (default 3000; floor 1000).
stale_afterintnoMark a unit stale when now - lastSeen exceeds this, in ms (default 120000).
request_timeoutintnoPer-call HTTP timeout in ms (default 5000).
confirm_writesboolnoAfter a write, verify the field reflects the commanded value within ~10 s; flag the zone if not (default false).
auto_create_zonesboolnoCreate a climate zone per discovered indoor unit (default true).
brand, gateway_mode, dry_run, writes_live, controller, crc_fail, parse_errors, frames_seen, frames_decodedRead-only gateway status/health, set from the snapshot. writes_live is true only when gateway_mode = control and dry_run = false.

Zone attributes

NameTypeDescription
addressstringIndoor-unit bus id, e.g. 20.2.4 (required).
statestringon / off.
system_modestringoff when the unit is off, otherwise the running mode (cool / heat / auto / dry / fan).
device_modestringThe unit's actual running mode (modeReal) regardless of power.
setpointintTarget temperature in the configured setpoint_unit.
temperatureintCurrent room temperature in the configured setpoint_unit.
fan_modestringThe current fan speed (auto / low / mid / high / turbo).
humidityintRelative humidity %, if the unit is equipped.
demandbooltrue while the thermostat is calling (thermoOn).
faultstringThe unit's error code; empty when errorCode is 0.
stalebooltrue when the unit stopped broadcasting past stale_after. Tags are retained, not deleted.
system_modes / fan_modesjsonCapability lists published once so the climate UI renders the right buttons.
min / maxintSetpoint bounds (60–90 °F, or 16–32 °C).
room_temp_c / room_temp_f / setpoint_c / setpoint_fnumberBoth-unit mirrors so an operator can pick the display.
mode_real / fan_real / capacity / unit_name / last_seenRead-only diagnostics mirrored from the snapshot.
write_simulatedboolSet true when the last write was accepted but could not actuate (port not in control, or dry-run).
write_unconfirmedboolWith confirm_writes on, true when a commanded change did not read back within the window.

Commands

CommandArgsNotes
on / offaddressPower the unit ({power: true/false}).
system_modeaddress, modeoff powers the unit off; any other (gateway-advertised) mode powers it on and selects that mode. Out-of-range modes are rejected before any call.
fan_modeaddress, modeThe gateway-advertised speeds; common GEM synonyms are bridged.
setpointaddress, setpoint, modeTarget temperature in the configured unit. Writes setpointF (whole °F) or setpointC — never both. mode is accepted for UI compatibility; the unit has a single setpoint. Rapid changes are debounced.
swingaddress, modeoff / vertical / horizontal / both. Samsung: not hardware-confirmed.
get_temperature / get_system_mode / get_fan_modeaddressReturn the last-polled value for the zone.
discoverList the indoor units the gateway currently reports.
get_statusReturn the raw gateway status snapshot.

How state mapping works

  • Temperature units. The gateway returns both °C and °F for every unit. setpoint_unit selects which mirror feeds the canonical setpoint / temperature tags and which field a write targets (setpointF whole-degree, or setpointC). Both *_c and *_f mirrors are always exposed.
  • Off vs. mode. The climate UI treats "off" as a mode. When a unit is off the driver reports system_mode = off while preserving the real selection in device_mode; selecting a non-off mode sends {mode, power: true} so the unit powers on and switches in one write.
  • Writes are serialized and audited. All sets run through a single queue so the gateway is never flooded; each set is logged with the unit, the changes, the gateway's dryRun/queued flags, and the hex it transmitted.
  • Dry-run / non-control is surfaced, not hidden. When the port can't actuate, the gateway still accepts the set and echoes the hex it would send; the driver returns simulated: true and sets the zone's write_simulated tag so operators aren't misled.
  • Auth and recovery. The admin token (12 h sliding TTL, in-memory on the gateway) is cached and refreshed proactively; any 401 triggers a transparent re-login and one retry. The poll loop runs unconditionally with backoff, so a gateway reboot or transient outage recovers automatically.

Troubleshooting

SymptomCheck
Authenticates but no zones appearRun discover, or check the Omnibus panel — the VRF port may be configured but not yet seeing decoded indoor-unit frames.
Writes "succeed" but the unit never changesThe port is in sniffer/poll or dry-run. Check the gateway_mode / dry_run / writes_live device tags and the zone's write_simulated; set the port to control with dry-run OFF on the Omnibus panel.
Connection fails with a TLS / certificate errorYou are likely reaching the gateway by a hostname not in the cert SANs. Use the LAN IP / local hostname with tls = verify, or set tls = insecure for first install.
Repeated "authentication failed" in the logBad admin credentials. The driver backs off (it won't hammer /api/login) and stays in an auth-failed state until corrected.
A zone shows staleThe indoor unit stopped broadcasting (now - lastSeen exceeded stale_after). Check the unit / bus; the zone tags are kept, not deleted.
Setpoint write rejected with a control-mode errorThe gateway returned 409 — the port is not in control mode. This is surfaced as a clear fault and not retried blindly.