HomeSeer HS4 (JSON API)
The HomeSeer driver bridges devices already paired into a HomeSeer HS4 (or HS3)
system — Z-Wave, Zigbee, and plug-in devices — through to GEM zones. Each
HomeSeer device is addressed by its reference (ref), and HomeSeer events
(scenes) can be triggered by identity. All traffic stays on the LAN; there is no
cloud token and no re-pairing of hardware.
This is the pragmatic path when a site already runs HomeSeer and you want GEM to be the front-of-house UI, automation engine, and AV/lighting integrator without migrating the existing Z-Wave/Zigbee mesh.
The driver talks to http://<homeseer-ip>/JSON?request=.... It never calls the
HomeSeer cloud (MyHS). The controller must be reachable on the LAN.
Prerequisites
- A HomeSeer HS4 or HS3 system reachable on the LAN with the web server enabled (default port 80).
- A reserved/static IP for the HomeSeer host (DHCP reservation on the router).
- A HomeSeer user account only if you have enabled password protection under Setup → Network → Password. Open LAN installs need no credentials.
Setup steps
- Reserve the HomeSeer IP. In the router, give the HomeSeer host a static DHCP lease so its address does not change.
- Create the GEM device. Under System → Devices, add a device with driver
homeseer_hs4. Set:ip— the HomeSeer LAN IP (e.g.192.168.1.20)username/password— only if web password protection is enabledport— leave at80unless you changed the HomeSeer web port
- Enumerate devices. Run the
get_devicescommand. It returns each HomeSeer device with itsref, a composed name (location + name), and its device type. Note therefvalues you want to control. - Create one GEM zone per HomeSeer device. Set
zone.addressto the HomeSeerref(an integer). Choose the zone subsystem (lights, shade, lock, etc.) so GEM verbs map to the intended behavior.
Attribute reference
Device attributes
| Attribute | Required | Description |
|---|---|---|
ip | yes | HomeSeer LAN IP or hostname. |
username | no | HomeSeer account username. Only needed with web password protection. |
password | no | HomeSeer account password. Sent as HTTP Basic auth, stored encrypted. |
port | no | HomeSeer web server port. Default 80. |
status_interval | no | How often (ms) the driver re-reads all device states in one getstatus call. Default 20000. |
Zone attributes
| Attribute | Required | Description |
|---|---|---|
address | yes | HomeSeer device reference (ref), an integer. |
on_value | no | Value sent for the on command. Default 100. Set to 99 for legacy Z-Wave dimmers that cap at 99. |
Zone address format
zone.address is the HomeSeer device reference (ref) — the integer shown
in the HomeSeer Devices grid and in the device-edit URL. Run get_devices to
list every ref and its friendly name.
Commands
| Command | Arguments | Notes |
|---|---|---|
on | address | controldevicebyvalue with the zone's on_value (default 100). |
off | address | controldevicebyvalue with value 0. |
set_level | address, level | Level 0-100. controldevicebyvalue. |
set_value | address, value | Raw HomeSeer value for specialty devices whose value is not a 0-100 level. |
control_by_label | address, label | Control by an exact device ControlPair label (e.g. On, Lock, Dim 50%). |
run_event | event_id or group + name | Run a HomeSeer event (scene) by identity. |
get_devices | — | List all devices with ref, name, and type. |
get_status | address | Read the current status/value for a single ref. |
get_events | — | List HomeSeer events (scenes). |
raw_request | hs_request, params | Send any JSON API request verbatim. params is an optional pre-encoded key=value&... query string. Escape hatch for requests GEM does not map natively. |
State surfaced back to GEM
On each poll the driver writes, per zone:
state—on/off, derived from the device value (> 0⇒ on).brightness— the raw HomeSeer device value. For dimmers this is the 0-99/0-100 level; for non-dimmer refs it simply mirrors the device value.status_text— the HomeSeer status string (e.g.On,Locked,72°).
Controlling devices — values vs. labels
HomeSeer device values are device-specific. The generic on / off / set_level
verbs use controldevicebyvalue, which suits switches and dimmers. When a device
uses non-obvious control values (a thermostat mode, a multi-position specialty
device, a Z-Wave lock that expects a specific value), prefer:
control_by_label— matches the device's own ControlPair label exactly, so you control by what the HomeSeer UI shows (Lock,Unlock,Auto, …).set_value— send the exact numeric value the device expects.
Legacy Z-Wave multilevel dimmers cap at 99. If on leaves such a dimmer one
step short of full, set the zone's on_value to 99.
Known limitations
- No event push. The JSON API is poll-only; GEM re-reads state on the
status_interval. For sub-second reactions (motion → light), drive that logic on the HomeSeer side and have the HomeSeer event call a GEM macro over HTTP. - Color control is not mapped. RGB / color-temperature control is not exposed
as a first-class verb. Use
control_by_labelorset_valueagainst the device's color feature ref, or drive color from a HomeSeer event. - Values are device-defined. GEM cannot know a specialty device's value
semantics;
brightnessmirrors the raw value. Map meaning per-zone in your UI.
Troubleshooting
| Symptom | Check |
|---|---|
get_devices returns an auth error (401) | Web password protection is on but username/password are blank or wrong. Fill them in, or disable password protection for LAN under Setup → Network. |
| Connection times out | Confirm the HomeSeer IP and web port, and that the GEM host can reach the HomeSeer web UI in a browser. |
| Commands return an error string | HomeSeer rejected the value for that ref. Use get_status to inspect the device, then control_by_label with a valid ControlPair label. |
| Zone state never updates | The ref in zone.address does not match a device returned by get_devices, or the device is a grouped root (relationship 2) rather than the controllable feature (relationship 4). Map the feature ref. |
run_event does nothing | The event_id, or the group + name pair, must match a HomeSeer event exactly. Run get_events to confirm the identity. |