一键导入
understanding-profiles
// Understanding and defining SmartThings capabilities, device profiles, preferences, and embedded device configurations for Edge Drivers
// Understanding and defining SmartThings capabilities, device profiles, preferences, and embedded device configurations for Edge Drivers
Setting up the development environment, deploying Edge Drivers to hubs, and sharing drivers with other users via channels and invites
Running luacheck for Lua linting and following code style conventions in Edge Driver development
Running and writing integration tests for SmartThings Edge Drivers using the Python test harness and Lua integration test framework
Understanding the SmartThings Edge Driver Lua libraries - driver lifecycle, message dispatchers, default handlers, and protocol message objects
| name | understanding-profiles |
| description | Understanding and defining SmartThings capabilities, device profiles, preferences, and embedded device configurations for Edge Drivers |
Capabilities are the fundamental abstraction in SmartThings. They define what a device can do and what state it can report. Each capability consists of:
switch has attribute switch with values on/off)on(), off(), setLevel(level))A capability definition specifies data types, units, and constraints for its attributes and commands.
| Type | Example | Description |
|---|---|---|
| string | "locked" | May have enum or pattern constraints |
| integer | 5 | Whole number, may have min/max |
| number | 5.5 | Fractional values allowed |
| boolean | true | true or false |
| object | {x: 12} | Map of name-value pairs |
| array | ["heat","cool"] | List of single type |
switch - on/off controlswitchLevel - dimming (0-100)temperatureMeasurement - temperature readingbattery - battery percentagecontactSensor - open/closedmotionSensor - active/inactivelock - locked/unlockedthermostatMode, thermostatHeatingSetpoint, thermostatCoolingSetpointcolorTemperature, colorControlrefresh - request device state updatefirmwareUpdate - OTA firmware managementhealthCheck - device connectivity monitoringFull reference: https://developer.smartthings.com/docs/devices/capabilities/capabilities-reference
Standard capabilities live under the smartthings namespace but are referenced without a namespace prefix:
- id: switch
version: 1
- id: temperatureMeasurement
version: 1
Custom capabilities use the format namespace.capabilityName:
- id: perfectlife6617.customGarageDoor
version: 1
A namespace is auto-generated per developer account (e.g., perfectlife6617). Custom capabilities are created via the SmartThings CLI:
smartthings capabilities:create -i capability.json
Custom capabilities require a Capability Presentation to render properly in the app.
Device profiles define which capabilities a device exposes, organized into components. They live in profiles/ directories within driver packages.
zwave-lock)name: base-lock
components:
- id: main
capabilities:
- id: lock
version: 1
- id: lockCodes
version: 1
- id: battery
version: 1
- id: refresh
version: 1
categories:
- name: SmartLock
zigbee-fan)name: fan-light
components:
- id: main
label: Fan
capabilities:
- id: switch
version: 1
- id: fanSpeed
version: 1
config:
values:
- key: "fanSpeed.value"
range: [0, 3]
- id: firmwareUpdate
version: 1
- id: refresh
version: 1
categories:
- name: Fan
- id: light
label: Light
capabilities:
- id: switch
version: 1
- id: switchLevel
version: 1
config:
values:
- key: "level.value"
range: [0, 100]
- id: refresh
version: 1
categories:
- name: Light
zigbee-contact)name: multi-sensor
components:
- id: main
capabilities:
- id: contactSensor
version: 1
- id: temperatureMeasurement
version: 1
- id: threeAxis
version: 1
- id: accelerationSensor
version: 1
- id: battery
version: 1
- id: firmwareUpdate
version: 1
- id: refresh
version: 1
categories:
- name: MultiFunctionalSensor
preferences:
- preferenceId: tempOffset
explicit: true
- preferenceId: certifiedpreferences.garageSensor
explicit: true
id: maincategories determines the device icon in the app (e.g., SmartLock, Fan, Light, Thermostat, MultiFunctionalSensor)version: 1 is always used (only version supported)Embedded device configs let you customize the SmartThings app UI directly in the profile YAML, without creating a separate Device Presentation. Only supported by Edge Drivers.
- id: colorTemperature
config:
values:
- key: "colorTemperature.value"
range: [2600, 6200]
- id: thermostatOperatingState
version: 1
config:
values:
- key: "thermostatOperatingState.value"
enabledValues:
- heating
- cooling
- fan only
- idle
- id: thermostatMode
config:
values:
- key: thermostatMode.value
enabledValues:
- off
- heat
- eco
- key: setThermostatMode
enabledValues:
- off
- heat
- id: alarm
config:
values:
- key: alarm.value
enabledValues:
- off
- siren
- key: "{{enumCommands}}"
enabledValues:
- off
- siren
When you package the driver, the platform auto-generates a Device Presentation from these configs.
Preferences let users configure device behavior from Settings in the SmartThings app.
Explicit (shared/reusable): Defined externally, referenced by ID in the profile:
preferences:
- preferenceId: tempOffset
explicit: true
Standard explicit preferences include: tempOffset, humidityOffset, motionSensitivity, reportingInterval, reverse, presetPosition, username, password.
tempOffset and humidityOffset are automatically applied by the platform to attribute values - no driver code needed.
Embedded (inline in profile): Defined directly in the profile YAML:
preferences:
- title: "IP Address"
name: ipAddress
description: "IP address of the Pi-Hole"
required: true
preferenceType: string
definition:
minLength: 7
maxLength: 15
stringType: text
default: localhost
| Type | Definition Fields |
|---|---|
| boolean | default |
| integer | minimum, maximum, default |
| number | minimum, maximum, default |
| string | stringType (text/paragraph/password), minLength, maxLength, default |
| enumeration | options (key-value map), default (must match a key) |
Query current value:
local offset = device.preferences.tempOffset
local level = command.args.level + device.preferences.levelOffset
Handle preference changes via infoChanged lifecycle:
local function device_info_changed(driver, device, event, args)
if args.old_st_store.preferences.sensitivityLevel ~= device.preferences.sensitivityLevel then
device:send(<message_to_control_device>)
end
end
For sleepy Z-Wave devices, use device:set_update_preferences_fn(fn) which fires on wakeup.
The config.yml file is the driver package manifest. It lives at the root of each driver directory.
name: 'Zigbee Thermostat'
defaultProfile: 'thermostat-battery-powerSource'
packageKey: 'zigbee-thermostat'
permissions:
zigbee: {}
description: "SmartThings driver for Zigbee thermostat devices"
vendorSupportInformation: "https://support.smartthings.com"
| Field | Description |
|---|---|
name | Human-readable driver name |
packageKey | Unique package identifier |
permissions | Protocol access: zigbee: {}, zwave: {}, lan: {}, matter: {} |
description | Driver description |
defaultProfile | Profile name used when no fingerprint match specifies one |
vendorSupportInformation | Support URL |
Fingerprints map physical devices to profiles. They live in fingerprints.yml at the driver root.
zigbeeManufacturer:
- id: "LUMI/lumi.motion.ac02"
deviceLabel: Aqara Motion Sensor P1
manufacturer: LUMI
model: lumi.motion.ac02
deviceProfileName: motion-illuminance-battery-aqara
- id: "SmartThings/motionv5"
deviceLabel: Motion Sensor
manufacturer: SmartThings
model: motionv5
deviceProfileName: motion-temp-battery
zigbeeGeneric:
- id: kickstarter/motion/1
deviceLabel: SmartThings Motion Sensor
zigbeeProfiles:
- 0xFC01
deviceIdentifiers:
- 0x013A
deviceProfileName: smartsense-motion
| Field | Description |
|---|---|
id | Unique identifier for the fingerprint |
deviceLabel | Default label shown to users |
manufacturer | Device manufacturer string |
model | Device model string |
deviceProfileName | Which profile from profiles/ to use |
zigbeeProfiles | (zigbeeGeneric) Zigbee profile IDs |
deviceIdentifiers | (zigbeeGeneric) Zigbee device type IDs |
Z-Wave fingerprints use manufacturerId, productType, and productId instead.
driver/
├── config.yml # Package manifest, declares defaultProfile
├── fingerprints.yml # Maps hardware → profile by deviceProfileName
├── profiles/
│ ├── basic-device.yml # Profile A
│ └── advanced-device.yml # Profile B
└── src/
└── init.lua # Driver logic
Flow:
fingerprints.yml entriesdeviceProfileName selects which profile to usedefaultProfile from config.yml is usedconfig in the profile customizes the app UI