Skip to main content

Samsung SmartThings

GEM integrates with the Samsung SmartThings cloud as a controller — every device already paired in the SmartThings mobile app can be promoted to a GEM zone and controlled from macros, schedules, triggers, voice, or the UI. The driver speaks the public SmartThings REST API at https://api.smartthings.com with bearer-token (Personal Access Token, "PAT") auth.

Prerequisites

  • A working Samsung SmartThings account with the mobile app set up, a SmartThings Hub (Aeotex, Aeotec, Samsung WiFi, V3 hub, or Station) or hub-less Wi-Fi devices on the account, and the devices you want to control already paired.
  • Outbound HTTPS (port 443) from the GEM server to api.smartthings.com.
  • A Personal Access Token from https://account.smartthings.com/tokens. PATs are tied to your SmartThings account; rotate yours whenever staff turns over.

Setup

  1. Sign in to https://account.smartthings.com/tokens and click Generate new token.
  2. Give the token a clear name (e.g., gem-<site>) and select the scopes:
    • Devices — Read, Write, Execute
    • Locations — Read
    • Scenes — Read, Execute
  3. Copy the token immediately — Samsung does not show it again. If you lose it, you must mint a new one.
  4. In GEM, System → Devices → Add Device and pick driver smartthings.
  5. Paste the PAT into the access_token attribute. Leave api_base on the default.
  6. Save and Reload the device. GEM logs smartthings connected: <id> <name> devices: <n> when the PAT is accepted.
  7. (Optional) Run the get_locations command — note the locationId and set the location_id attribute to filter device enumeration to one location.
  8. Run get_devices to enumerate paired devices, then create one GEM zone per device. Set zone.address to the SmartThings deviceId UUID.
  9. (Optional) Run get_scenes to enumerate scenes; trigger them with run_scene using the scene UUID as the address.

Attribute reference

AttributeRequiredDefaultDescription
access_tokenyesSmartThings Personal Access Token (Bearer). Treated as a secret.
api_basenohttps://api.smartthings.comAPI endpoint. Only override if Samsung directs you to.
location_idnoRestrict get_devices / get_scenes to a single SmartThings location UUID.
status_intervalno60000Status poll interval in ms. Lower for snappier UI; watch the 250 req/min cap.
request_timeoutno15000Per-request HTTP timeout in ms.

Zone address format

zone.address is the SmartThings deviceId — a UUID returned by get_devices. For scenes, the address is the scene UUID and the only valid command is run_scene.

Commands

The driver maps each GEM verb onto a SmartThings capability+command pair under component=main:

GEM commandCapabilitySmartThings command
on / offswitchon / off
set_levelswitchLevel (or windowShadeLevel for shades)setLevel(level) / setShadeLevel(level)
open / closewindowShade if shade, else doorControlopen / close
stopwindowShadepause
lock / unlocklocklock / unlock
arm_home / arm_away / disarmsecuritySystemarmStay / armAway / disarm
set_temperaturethermostatHeatingSetpoint or thermostatCoolingSetpoint (chosen from zone.system_mode)setHeatingSetpoint / setCoolingSetpoint
set_modethermostatModesetThermostatMode(mode)
set_fan_modethermostatFanModesetThermostatFanMode(mode)
set_volume / mute_on / mute_offaudioVolume / audioMutesetVolume / setMute
play / pausemediaPlaybackplay / pause
set_color_temperaturecolorTemperaturesetColorTemperature(K)
set_hue / set_saturationcolorControlsetHue(%) / setSaturation(%)
run_scenePOST /v1/scenes/{address}/execute
raw_command(caller-supplied)(caller-supplied) — escape hatch for capabilities not in the table above

get_devices, get_locations, get_scenes, and get_status return raw JSON from the SmartThings API for inspection and use in macros.

Status polling

The driver iterates Object.keys(self.zones) every status_interval ms and calls GET /v1/devices/{id}/status. The first matching capability sets zone.state:

switch.switchlock.lockcontactSensor.contactmotionSensor.motiondoorControl.doorwindowShade.windowShadepresenceSensor.presencesecuritySystem.securitySystemStatus.

Additional attributes are surfaced when present: level, battery_level, temperature, humidity, illuminance, color_temperature, volume, mute_state, heating_setpoint, cooling_setpoint, system_mode, fan_mode, power_w, energy_kwh.

Known limitations

  • No push events. PAT clients cannot subscribe to SmartThings event webhooks — state changes are visible only on the next poll. If sub-second responsiveness is required, deploy GEM behind the device's local hub instead.
  • Rate limits. SmartThings caps PATs at 250 requests/minute and 12,000 requests/day. On large accounts (>60 zones) bump status_interval to 90–120s.
  • Token rotation. PATs cannot be refreshed. When one expires or is revoked, generate a new one and paste it into access_token.
  • Capability coverage. Devices with custom capabilities (<vendor>.<capability>) are not routed by the verb table — use raw_command to drive them.

Troubleshooting

SymptomLikely cause
unauthorized — check that the PAT has the required scopesPAT missing one of r:devices:* / w:devices:* / x:devices:*, or the PAT was revoked. Mint a fresh one.
rate limited by SmartThings (429)Too many zones polled too often. Increase status_interval.
Commands report success but the device doesn't changeSome SmartThings capabilities (notably doorControl.open) require user confirmation in the mobile app — that's enforced cloud-side and not visible to the API.
Zone never reaches connectedThe PAT may be valid but for a different SmartThings account. Confirm at account.smartthings.com/tokens that the token belongs to the account that paired the devices.