smartthings

package module
v1.0.7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 5, 2025 License: MIT Imports: 27 Imported by: 0

README

smartthings-go

Go Reference Coverage Go Report Card

A comprehensive Go client library for the Samsung SmartThings API.

Installation

go get github.com/tj-smith47/smartthings-go

Quick Start

package main

import (
    "context"
    "fmt"
    "log"

    st "github.com/tj-smith47/smartthings-go"
)

func main() {
    // Create a client with your SmartThings API token
    client, err := st.NewClient("your-api-token")
    if err != nil {
        log.Fatal(err)
    }

    ctx := context.Background()

    // List all devices
    devices, err := client.ListDevices(ctx)
    if err != nil {
        log.Fatal(err)
    }

    for _, device := range devices {
        fmt.Printf("Device: %s (%s)\n", device.Label, device.DeviceID)
    }
}

Features

  • Full SmartThings API v1 support
  • OAuth 2.0 authentication with automatic token refresh
  • Device management - list, get, update, delete, execute commands
  • Locations & Rooms - CRUD operations for organization
  • Scenes - list and execute scenes
  • Automation Rules - CRUD operations for rules
  • Schedules - cron-based scheduling
  • Subscriptions - webhook management
  • Capabilities - capability introspection
  • Pagination support for large datasets
  • Automatic retry with configurable backoff
  • Response caching for capabilities and device profiles
  • SSDP discovery for local SmartThings hubs and Samsung TVs
  • TV control (power, volume, input, apps, picture/sound modes)
  • Generalized appliance status extraction for any Samsung CE device
  • Auto-discovery of device capabilities

Authentication Methods

Personal Access Token

Get a token from SmartThings Tokens:

client, err := st.NewClient("your-personal-access-token")
OAuth 2.0

For apps that need to access other users' devices:

// 1. Configure OAuth
config := &st.OAuthConfig{
    ClientID:     "your-client-id",
    ClientSecret: "your-client-secret",
    RedirectURL:  "https://your-app.com/callback",
    Scopes:       st.DefaultScopes(), // r:devices:*, x:devices:*, r:locations:*
}

// 2. Create token store (file-based or in-memory)
store := st.NewFileTokenStore("/path/to/tokens.json")

// 3. Create OAuth client
client, err := st.NewOAuthClient(config, store)
if err != nil {
    log.Fatal(err)
}

// 4. Check if user needs to authenticate
if client.NeedsReauthentication() {
    state := generateSecureRandomState()
    authURL := client.GetAuthorizationURL(state)
    // Redirect user to authURL...
}

// 5. In your callback handler, exchange the code
func handleCallback(code string) error {
    return client.ExchangeCode(ctx, code)
}

// 6. Use the client - tokens refresh automatically
devices, err := client.ListDevices(ctx)
Token Storage Options

The library provides multiple token storage backends:

// File-based storage (persists across restarts)
store := st.NewFileTokenStore("/path/to/tokens.json")

// In-memory storage (for testing or short-lived processes)
store := st.NewMemoryTokenStore()

// Custom storage (implement TokenStore interface)
type TokenStore interface {
    Load() (*TokenData, error)
    Save(data *TokenData) error
}

// Example: Redis-based storage
type RedisTokenStore struct {
    client *redis.Client
    key    string
}

func (r *RedisTokenStore) Load() (*st.TokenData, error) {
    data, err := r.client.Get(ctx, r.key).Bytes()
    if err != nil {
        return nil, err
    }
    var tokens st.TokenData
    return &tokens, json.Unmarshal(data, &tokens)
}

func (r *RedisTokenStore) Save(data *st.TokenData) error {
    bytes, _ := json.Marshal(data)
    return r.client.Set(ctx, r.key, bytes, 0).Err()
}

Token Refresh Behavior:

  • Tokens are automatically refreshed when expired
  • Refresh happens transparently during API calls
  • Access tokens expire after ~24 hours
  • Refresh tokens are long-lived (~30 days)
  • If refresh fails, NeedsReauthentication() returns true

API Usage

Client Options
// Basic client
client, err := st.NewClient("your-token")

// With options
client, err := st.NewClient("your-token",
    st.WithTimeout(60 * time.Second),
    st.WithRetry(st.DefaultRetryConfig()),
    st.WithCache(st.DefaultCacheConfig()), // Enable response caching
    st.WithBaseURL("https://custom-api.example.com"),
)

// Custom retry configuration
client, err := st.NewClient("your-token",
    st.WithRetry(&st.RetryConfig{
        MaxRetries:     3,
        InitialBackoff: 100 * time.Millisecond,
        MaxBackoff:     5 * time.Second,
        Multiplier:     2.0, // Exponential backoff
    }),
)

// Custom cache configuration
client, err := st.NewClient("your-token",
    st.WithCache(&st.CacheConfig{
        TTL:     15 * time.Minute, // Cache TTL
        MaxSize: 1000,             // Max cached items
    }),
)

Cached Endpoints:

  • Capability definitions (rarely change)
  • Device profiles (rarely change)
  • Capability presentations (rarely change)

Not Cached:

  • Device status (changes frequently)
  • Device lists (membership changes)
  • Commands/actions (side effects)
Device Operations
// List all devices
devices, err := client.ListDevices(ctx)

// List with pagination and filtering
paged, err := client.ListDevicesWithOptions(ctx, &st.ListDevicesOptions{
    Capability: []string{"switch"},
    LocationID: []string{"location-id"},
    Max:        100,
    Page:       0,
})

// Get all devices with automatic pagination
allDevices, err := client.ListAllDevices(ctx)

// Get a specific device
device, err := client.GetDevice(ctx, "device-id")

// Get device status (main component)
status, err := client.GetDeviceStatus(ctx, "device-id")

// Get device health
health, err := client.GetDeviceHealth(ctx, "device-id")

// Update device label
updated, err := client.UpdateDevice(ctx, "device-id", &st.DeviceUpdate{Label: "New Name"})

// Delete device
err := client.DeleteDevice(ctx, "device-id")

// Execute a command
err := client.ExecuteCommand(ctx, "device-id", st.NewCommand("switch", "on"))

// Execute multiple commands
err := client.ExecuteCommands(ctx, "device-id", []st.Command{
    st.NewCommand("switch", "on"),
    st.NewCommand("audioVolume", "setVolume", 50),
})
Locations & Rooms
// List locations
locations, err := client.ListLocations(ctx)

// Create a location
loc, err := client.CreateLocation(ctx, &st.LocationCreate{
    Name:        "Home",
    CountryCode: "US",
    TimeZoneID:  "America/New_York",
})

// List rooms in a location
rooms, err := client.ListRooms(ctx, locationID)

// Create a room
room, err := client.CreateRoom(ctx, locationID, &st.RoomCreate{Name: "Living Room"})
Scenes
// List scenes
scenes, err := client.ListScenes(ctx, locationID)

// Execute a scene
err := client.ExecuteScene(ctx, sceneID)
Automation Rules
// List rules
rules, err := client.ListRules(ctx, locationID)

// Create a rule
rule, err := client.CreateRule(ctx, locationID, &st.RuleCreate{
    Name: "Turn on lights at sunset",
    Actions: []st.RuleAction{
        // Rule definition...
    },
})

// Execute a rule manually
err := client.ExecuteRule(ctx, ruleID)
Subscriptions (Webhooks)
// List subscriptions
subs, err := client.ListSubscriptions(ctx, installedAppID)

// Create a device subscription
sub, err := client.CreateSubscription(ctx, installedAppID, &st.SubscriptionCreate{
    SourceType: "DEVICE",
    Device: &st.DeviceSubscription{
        DeviceID:   "device-id",
        Capability: "switch",
        Attribute:  "switch",
    },
})

// Delete all subscriptions
err := client.DeleteAllSubscriptions(ctx, installedAppID)
Webhook Handling

When building SmartApps, you'll receive webhook callbacks from SmartThings. The library provides utilities for validating and processing these callbacks:

// Validate webhook signature (HMAC-SHA256)
valid := st.ValidateWebhookSignature(requestBody, signatureHeader, appSecret)
if !valid {
    return errors.New("invalid webhook signature")
}

// Parse webhook event
var event st.WebhookEvent
if err := json.Unmarshal(requestBody, &event); err != nil {
    return err
}

// Handle based on lifecycle phase
switch event.Lifecycle {
case "PING":
    // Respond with challenge for initial registration
    response := st.PingResponse{PingData: event.PingData}

case "CONFIGURATION":
    // Return app configuration UI

case "INSTALL":
    // App installed - create subscriptions
    for _, device := range event.InstalledApp.Config.Devices {
        client.CreateSubscription(ctx, event.InstalledApp.InstalledAppID, ...)
    }

case "UPDATE":
    // App configuration updated

case "EVENT":
    // Device event received
    for _, evt := range event.Events {
        if evt.EventType == "DEVICE_EVENT" {
            fmt.Printf("Device %s: %s = %v\n",
                evt.DeviceEvent.DeviceID,
                evt.DeviceEvent.Attribute,
                evt.DeviceEvent.Value)
        }
    }

case "UNINSTALL":
    // App uninstalled - clean up
}

Webhook Security:

  • Always validate the X-ST-SIGNATURE header using HMAC-SHA256
  • Use HTTPS for your webhook endpoint
  • Respond within 20 seconds to avoid timeout
  • Return 200 OK for successful processing
Capabilities
// List all capabilities
caps, err := client.ListCapabilities(ctx)

// List capabilities by namespace (standard vs custom)
caps, err := client.ListCapabilitiesWithOptions(ctx, &st.ListCapabilitiesOptions{
    Namespace: st.CapabilityNamespaceSmartThings, // "st" for standard, "custom" for custom
})

// Get capability definition
cap, err := client.GetCapability(ctx, "switch", 1)
Apps & Installed Apps

For SmartApp development:

// List your registered apps
apps, err := client.ListApps(ctx)

// Get app details
app, err := client.GetApp(ctx, appID)

// List installations of your app
installs, err := client.ListInstalledApps(ctx, locationID)

// Get specific installation
install, err := client.GetInstalledApp(ctx, installedAppID)

// Get current (authorized) configuration
config, err := client.GetCurrentInstalledAppConfig(ctx, installedAppID)
if config != nil {
    // Access config values
    for name, entries := range config.Config {
        for _, entry := range entries {
            if entry.DeviceConfig != nil {
                fmt.Printf("Device: %s\n", entry.DeviceConfig.DeviceID)
            }
        }
    }
}

// List all configurations
configs, err := client.ListInstalledAppConfigs(ctx, installedAppID)

// Get specific configuration by ID
config, err := client.GetInstalledAppConfig(ctx, installedAppID, configID)

// Delete installation
err := client.DeleteInstalledApp(ctx, installedAppID)
Schedules

Create scheduled automations:

// List schedules for an installed app
schedules, err := client.ListSchedules(ctx, installedAppID)

// Create a scheduled trigger (cron expression)
schedule, err := client.CreateSchedule(ctx, installedAppID, &st.ScheduleRequest{
    Name: "daily-morning",
    Cron: &st.CronSchedule{
        Expression: "0 7 * * *", // Daily at 7 AM
        Timezone:   "America/New_York",
    },
})

// Delete a schedule
err := client.DeleteSchedule(ctx, installedAppID, scheduleName)
Notifications

Send push notifications to SmartThings app users:

// Send a push notification
resp, err := client.CreateNotification(ctx, &st.NotificationRequest{
    LocationID: locationID,
    Type:       st.NotificationTypeAlert,
    Messages: map[string]st.NotificationMessage{
        "en": {
            Title: "Washer Complete",
            Body:  "Your laundry is done!",
        },
    },
})
TV Control
// Get TV status
status, err := client.FetchTVStatus(ctx, tvDeviceID)
fmt.Printf("Power: %s, Volume: %d\n", status.Power, status.Volume)

// Control TV
client.SetTVPower(ctx, tvDeviceID, true)
client.SetTVVolume(ctx, tvDeviceID, 25)
client.SetTVMute(ctx, tvDeviceID, true)
client.SetTVInput(ctx, tvDeviceID, "HDMI1")

// Remote control
client.SendTVKey(ctx, tvDeviceID, "UP")
client.SendTVKey(ctx, tvDeviceID, "ENTER")

// Media control
client.TVPlay(ctx, tvDeviceID)
client.TVPause(ctx, tvDeviceID)

// Apps
client.LaunchTVApp(ctx, tvDeviceID, "Netflix")

// Picture/Sound modes
client.SetPictureMode(ctx, tvDeviceID, "Movie")
client.SetSoundMode(ctx, tvDeviceID, "Standard")
Appliance Status
// Generic extraction works with ANY Samsung appliance (recommended)
status, _ := client.GetDeviceStatus(ctx, deviceID)
appStatus := st.ExtractGenericApplianceStatus(status)
if appStatus.State == "running" {
    fmt.Printf("Running: %d mins remaining\n", *appStatus.RemainingMins)
}
// Discover what capabilities a device has
fmt.Printf("Capabilities: %v\n", appStatus.DiscoveredCapabilities)

// Type-specific extraction for washer/dryer/dishwasher
laundryStatus := st.ExtractLaundryStatus(status, st.ApplianceWasher)
if laundryStatus != nil && laundryStatus.State == "running" {
    fmt.Printf("Washing: %d mins remaining\n", *laundryStatus.RemainingMins)
}

// Get range status
rangeStatus := st.ExtractRangeStatus(status)
if rangeStatus.OvenActive {
    fmt.Printf("Oven: %d°F (target: %d°F)\n",
        *rangeStatus.OvenTemp, *rangeStatus.OvenTargetTemp)
}

Supported Appliances:

  • Washers, Dryers, Dishwashers
  • Ranges/Ovens, Microwaves
  • Refrigerators
  • Air Conditioners, Air Purifiers
  • Robot Vacuums
  • Any Samsung CE device with standard capabilities
Helper Functions
status, _ := client.GetDeviceStatus(ctx, deviceID)

// Extract values from nested paths
power, ok := st.GetString(status, "switch", "switch", "value")
volume, ok := st.GetInt(status, "audioVolume", "volume", "value")
temp, ok := st.GetFloat(status, "temperatureMeasurement", "temperature", "value")

// Check string equality
isOn := st.GetStringEquals(status, "on", "switch", "switch", "value")

// Temperature conversion
fahrenheit := st.CelsiusToFahrenheit(celsius)
Local Network Discovery
// Discover SmartThings hubs on the local network via SSDP
discovery := st.NewDiscovery(5 * time.Second)
hubs, err := discovery.FindHubs(ctx)
for _, hub := range hubs {
    fmt.Printf("Found hub at %s:%d\n", hub.IP, hub.Port)
}

// Discover Samsung TVs
tvs, err := discovery.FindTVs(ctx)
for _, tv := range tvs {
    fmt.Printf("Found TV: %s at %s:%d\n", tv.Name, tv.IP, tv.Port)
}

// Discover both hubs and TVs at once
allDevices, err := discovery.DiscoverAll(ctx)

Error Handling

status, err := client.GetDeviceStatus(ctx, deviceID)
if err != nil {
    if st.IsUnauthorized(err) {
        // Token is invalid or expired
    } else if st.IsNotFound(err) {
        // Device doesn't exist
    } else if st.IsRateLimited(err) {
        // Too many requests
    } else if st.IsDeviceOffline(err) {
        // Device is offline
    } else if st.IsTimeout(err) {
        // Request timed out
    } else {
        var apiErr *st.APIError
        if errors.As(err, &apiErr) {
            fmt.Printf("API Error %d: %s\n", apiErr.StatusCode, apiErr.Message)
        }
    }
}

Testing

The library provides a SmartThingsClient interface for mocking:

type SmartThingsClient interface {
    ListDevices(ctx context.Context) ([]Device, error)
    GetDevice(ctx context.Context, deviceID string) (*Device, error)
    // ... all other methods
}

// Both Client and OAuthClient implement this interface
var _ SmartThingsClient = (*Client)(nil)
var _ SmartThingsClient = (*OAuthClient)(nil)

Concurrency

The library is designed to be safe for concurrent use:

// Client is safe to share across goroutines
client, _ := st.NewClient("your-token")

// Concurrent device polling
var wg sync.WaitGroup
for _, deviceID := range deviceIDs {
    wg.Go(func() {
        status, err := client.GetDeviceStatus(ctx, deviceID)
        // Process status...
    })
}
wg.Wait()

Thread Safety Notes:

  • All client methods are goroutine-safe
  • Token refresh is synchronized (one refresh at a time)
  • Cache operations are protected by mutex
  • Token storage implementations should be thread-safe

Rate Limiting

SmartThings API has rate limits. The library handles this automatically with configurable retry:

client, _ := st.NewClient("your-token",
    st.WithRetry(&st.RetryConfig{
        MaxRetries:     5,
        InitialBackoff: 1 * time.Second,
    }),
)

When rate limited:

  • Library retries with exponential backoff
  • IsRateLimited(err) returns true for rate limit errors
  • Consider spreading requests over time for bulk operations
Enhanced Rate Limit Handling

Get detailed rate limit information:

// RateLimitError includes Retry-After duration
var rle *st.RateLimitError
if errors.As(err, &rle) {
    fmt.Printf("Retry after: %v\n", rle.RetryAfter)
}

// Wait for rate limit to reset
if err := client.WaitForRateLimit(ctx); err != nil {
    return err // Context canceled
}

// Preemptive throttling
if client.ShouldThrottle(10) { // Threshold of 10 remaining
    time.Sleep(time.Second)
}

// Automatic throttling for bulk operations
throttler := st.NewRateLimitThrottler(client, 10, 100*time.Millisecond)
for _, deviceID := range devices {
    throttler.Wait(ctx)
    client.ExecuteCommand(ctx, deviceID, cmd)
}

Batch Operations

Execute commands on multiple devices concurrently:

// Same command to multiple devices
cmd := st.Command{Capability: "switch", Command: "on"}
results := client.ExecuteCommandBatch(ctx, []string{"device1", "device2", "device3"}, cmd, nil)

for _, r := range results {
    if r.Error != nil {
        log.Printf("Device %s failed: %v", r.DeviceID, r.Error)
    }
}

// Different commands to different devices
batch := []st.BatchCommand{
    {DeviceID: "light1", Commands: []st.Command{{Capability: "switch", Command: "on"}}},
    {DeviceID: "light2", Commands: []st.Command{{Capability: "switchLevel", Command: "setLevel", Arguments: []any{50}}}},
}
results := client.ExecuteCommandsBatch(ctx, batch, &st.BatchConfig{
    MaxConcurrent: 5,   // Limit concurrent API calls
    StopOnError:   false, // Continue on errors
})

// Fetch status for multiple devices
statusResults := client.GetDeviceStatusBatch(ctx, deviceIDs, nil)

Structured Logging

Enable structured logging with Go's log/slog:

import "log/slog"

// Option 1: Add logger to existing client
logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
client, _ := st.NewClient("token", st.WithLogger(logger))

// Option 2: Create client with request/response logging
logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
    Level: slog.LevelDebug,
}))
client, _ := st.NewLoggingClient("token", logger)

// Manual logging helpers
client.LogDeviceCommand(ctx, deviceID, "switch", "on", nil)
client.LogRateLimit(ctx, st.RateLimitInfo{Remaining: 50})

// Webhook event logging
st.LogWebhookEvent(logger, ctx, event, nil)

Performance

HTTP/2 Support

The library automatically uses HTTP/2 for connections to the SmartThings API, providing:

  • Multiplexed requests over a single connection
  • Header compression
  • Reduced latency for concurrent requests
Connection Pooling

Default transport settings (optimized for typical usage):

// These are the default settings - no configuration needed
Transport: &http.Transport{
    MaxIdleConns:        100,  // Total idle connections across all hosts
    MaxIdleConnsPerHost: 10,   // Idle connections per host
    IdleConnTimeout:     90s,  // Close idle connections after 90s
    ForceAttemptHTTP2:   true, // Use HTTP/2 when available
}

For high-throughput applications, customize with WithHTTPClient:

transport := &http.Transport{
    MaxIdleConns:        200,
    MaxIdleConnsPerHost: 50,  // More connections for parallel requests
    IdleConnTimeout:     120 * time.Second,
    ForceAttemptHTTP2:   true,
}

client, _ := st.NewClient("token",
    st.WithHTTPClient(&http.Client{
        Transport: transport,
        Timeout:   60 * time.Second,
    }),
)
Best Practices
  1. Reuse the client - Create one client and share it across goroutines
  2. Use iterators for large lists - Automatic pagination without loading all items
  3. Enable caching - Reduces API calls for capabilities and device profiles
  4. Batch commands - Use ExecuteCommands for multiple commands to one device

SmartThings API Reference

Disclaimer

Generated entirely by Claude Opus 4.5 over many iterations 🤖

License

MIT License - see LICENSE for details.

Documentation

Overview

Package smartthings provides a Go client library for the Samsung SmartThings API.

This library provides comprehensive access to the SmartThings public API, including device management, location/room organization, scene execution, automation rules, and webhook subscriptions.

Authentication

The library supports two authentication methods:

Personal Access Token (PAT) - Simple, good for personal projects:

client, err := smartthings.NewClient("your-personal-access-token")
if err != nil {
    log.Fatal(err)
}

OAuth 2.0 - Required for published apps, supports user authorization:

config := &smartthings.OAuthConfig{
    ClientID:     "your-client-id",
    ClientSecret: "your-client-secret",
    RedirectURL:  "https://your-app.com/callback",
    Scopes:       smartthings.DefaultScopes(),
}
store := smartthings.NewFileTokenStore("/path/to/tokens.json")
client, err := smartthings.NewOAuthClient(config, store)

Basic Usage

List all devices:

devices, err := client.ListDevices(ctx)
for _, device := range devices {
    fmt.Printf("Device: %s (%s)\n", device.Label, device.DeviceID)
}

Get device status:

status, err := client.GetDeviceStatus(ctx, deviceID)
power, ok := smartthings.GetString(status, "switch", "switch", "value")

Execute a command:

err := client.ExecuteCommand(ctx, deviceID, smartthings.NewCommand("switch", "on"))

Pagination

For large device lists, use pagination:

paged, err := client.ListDevicesWithOptions(ctx, &smartthings.ListDevicesOptions{
    Max:  100,
    Page: 0,
    Capability: []string{"switch"},
})
fmt.Printf("Got %d of %d devices\n", len(paged.Items), paged.PageInfo.TotalResults)

Or automatically fetch all pages:

allDevices, err := client.ListAllDevices(ctx)

Retry Configuration

Enable automatic retry for transient failures:

client, err := smartthings.NewClient("token",
    smartthings.WithRetry(smartthings.DefaultRetryConfig()),
)

Error Handling

Check for specific error types:

status, err := client.GetDeviceStatus(ctx, deviceID)
if err != nil {
    if smartthings.IsUnauthorized(err) {
        // Token is invalid or expired
    } else if smartthings.IsNotFound(err) {
        // Device doesn't exist
    } else if smartthings.IsRateLimited(err) {
        // Too many requests
    }
}

API Coverage

The library supports the following SmartThings API endpoints:

  • Devices: List, get, update, delete, execute commands, health status
  • Locations: CRUD operations for locations
  • Rooms: CRUD operations for rooms within locations
  • Scenes: List and execute scenes
  • Rules: CRUD operations for automation rules
  • Schedules: CRUD operations for cron-based schedules
  • Subscriptions: Webhook subscription management
  • Installed Apps: List, get, delete installed apps
  • Capabilities: List and get capability definitions

Samsung-Specific Features

The library includes specialized support for Samsung devices:

  • TV control (power, volume, input, apps, picture/sound modes)
  • Appliance status extraction (washer, dryer, dishwasher, range, refrigerator)

Third-Party Device Support

The library also supports third-party devices that integrate with SmartThings:

  • Brilliant Home Control switches and dimmers

For more information, see https://developer.smartthings.com/docs/api/public/

Index

Examples

Constants

View Source
const (
	ApplianceDryer          = "dryer"
	ApplianceWasher         = "washer"
	ApplianceDishwasher     = "dishwasher"
	ApplianceRange          = "range"
	ApplianceRefrigerator   = "refrigerator"
	ApplianceMicrowave      = "microwave"
	ApplianceAirConditioner = "airconditioner"
	ApplianceRobotVacuum    = "robotvacuum"
	ApplianceAirPurifier    = "airpurifier"
	ApplianceOven           = "oven"
)

Appliance type constants for extraction.

View Source
const (
	// DefaultBaseURL is the SmartThings API base URL.
	DefaultBaseURL = "https://api.smartthings.com/v1"

	// DefaultTimeout is the default HTTP request timeout.
	DefaultTimeout = 30 * time.Second
)
View Source
const (
	// TVLocalDefaultPort is the default port for Samsung TV local API (non-secure).
	TVLocalDefaultPort = 8001

	// TVLocalSecurePort is the secure port for Samsung TV local API.
	TVLocalSecurePort = 8002

	// TVLocalAPIPath is the WebSocket path for Samsung TV remote control.
	TVLocalAPIPath = "/api/v2/channels/samsung.remote.control"
)
View Source
const (
	TVKeyPower     = "KEY_POWER"
	TVKeyPowerOff  = "KEY_POWEROFF"
	TVKeyHome      = "KEY_HOME"
	TVKeyMenu      = "KEY_MENU"
	TVKeyUp        = "KEY_UP"
	TVKeyDown      = "KEY_DOWN"
	TVKeyLeft      = "KEY_LEFT"
	TVKeyRight     = "KEY_RIGHT"
	TVKeyEnter     = "KEY_ENTER"
	TVKeyReturn    = "KEY_RETURN"
	TVKeyBack      = "KEY_RETURN"
	TVKeyExit      = "KEY_EXIT"
	TVKeyVolumeUp  = "KEY_VOLUP"
	TVKeyVolumeDn  = "KEY_VOLDOWN"
	TVKeyMute      = "KEY_MUTE"
	TVKeyChannelUp = "KEY_CHUP"
	TVKeyChannelDn = "KEY_CHDOWN"
	TVKeyPlay      = "KEY_PLAY"
	TVKeyPause     = "KEY_PAUSE"
	TVKeyStop      = "KEY_STOP"
	TVKeyRewind    = "KEY_REWIND"
	TVKeyFF        = "KEY_FF"
	TVKeySource    = "KEY_SOURCE"
	TVKeyInfo      = "KEY_INFO"
	TVKeyGuide     = "KEY_GUIDE"
	TVKeyTools     = "KEY_TOOLS"
	TVKey0         = "KEY_0"
	TVKey1         = "KEY_1"
	TVKey2         = "KEY_2"
	TVKey3         = "KEY_3"
	TVKey4         = "KEY_4"
	TVKey5         = "KEY_5"
	TVKey6         = "KEY_6"
	TVKey7         = "KEY_7"
	TVKey8         = "KEY_8"
	TVKey9         = "KEY_9"
)

Common TV key codes

View Source
const (
	// HubLocalDefaultPort is the default port for SmartThings Hub local API.
	HubLocalDefaultPort = 39500
)
View Source
const WebhookSignatureHeader = "X-ST-Signature"

Webhook signature header name used by SmartThings.

Variables

View Source
var (
	// Authentication errors
	ErrUnauthorized = errors.New("smartthings: unauthorized (invalid or expired token)")
	ErrEmptyToken   = errors.New("smartthings: API token cannot be empty")

	// Resource errors
	ErrNotFound      = errors.New("smartthings: resource not found")
	ErrDeviceOffline = errors.New("smartthings: device is offline")

	// Rate limiting
	ErrRateLimited = errors.New("smartthings: rate limited (too many requests)")

	// Device validation errors
	ErrEmptyDeviceID    = errors.New("smartthings: device ID cannot be empty")
	ErrEmptyComponentID = errors.New("smartthings: component ID cannot be empty")

	// TV/media validation errors
	ErrEmptyInputID   = errors.New("smartthings: input ID cannot be empty")
	ErrEmptyKey       = errors.New("smartthings: key cannot be empty")
	ErrEmptyAppID     = errors.New("smartthings: app ID cannot be empty")
	ErrEmptyMode      = errors.New("smartthings: mode cannot be empty")
	ErrInvalidChannel = errors.New("smartthings: channel must be non-negative")

	// Location validation errors
	ErrEmptyLocationID   = errors.New("smartthings: location ID cannot be empty")
	ErrEmptyLocationName = errors.New("smartthings: location name cannot be empty")

	// Room validation errors
	ErrEmptyRoomID   = errors.New("smartthings: room ID cannot be empty")
	ErrEmptyRoomName = errors.New("smartthings: room name cannot be empty")

	// Scene validation errors
	ErrEmptySceneID = errors.New("smartthings: scene ID cannot be empty")

	// Rule validation errors
	ErrEmptyRuleID   = errors.New("smartthings: rule ID cannot be empty")
	ErrEmptyRuleName = errors.New("smartthings: rule name cannot be empty")

	// Schedule validation errors
	ErrEmptyScheduleName = errors.New("smartthings: schedule name cannot be empty")

	// InstalledApp/Subscription validation errors
	ErrEmptyInstalledAppID = errors.New("smartthings: installed app ID cannot be empty")
	ErrEmptySubscriptionID = errors.New("smartthings: subscription ID cannot be empty")
	ErrInvalidSubscription = errors.New("smartthings: invalid subscription configuration")

	// Capability validation errors
	ErrEmptyCapabilityID = errors.New("smartthings: capability ID cannot be empty")

	// Mode validation errors
	ErrEmptyModeID = errors.New("smartthings: mode ID cannot be empty")

	// App validation errors
	ErrEmptyAppName = errors.New("smartthings: app name cannot be empty")

	// Device profile validation errors
	ErrEmptyProfileID   = errors.New("smartthings: profile ID cannot be empty")
	ErrEmptyProfileName = errors.New("smartthings: profile name cannot be empty")

	// Channel validation errors
	ErrEmptyChannelID   = errors.New("smartthings: channel ID cannot be empty")
	ErrEmptyChannelName = errors.New("smartthings: channel name cannot be empty")

	// Driver validation errors
	ErrEmptyDriverID      = errors.New("smartthings: driver ID cannot be empty")
	ErrEmptyDriverVersion = errors.New("smartthings: driver version cannot be empty")

	// Hub validation errors
	ErrEmptyHubID = errors.New("smartthings: hub ID cannot be empty")

	// Device preference validation errors
	ErrEmptyPreferenceID   = errors.New("smartthings: preference ID cannot be empty")
	ErrEmptyPreferenceName = errors.New("smartthings: preference name cannot be empty")
	ErrEmptyLocaleTag      = errors.New("smartthings: locale tag cannot be empty")

	// Driver archive validation errors
	ErrEmptyDriverArchive = errors.New("smartthings: driver archive cannot be empty")

	// Schema app/invitation validation errors
	ErrEmptySchemaAppID  = errors.New("smartthings: schema app ID cannot be empty")
	ErrEmptyInvitationID = errors.New("smartthings: invitation ID cannot be empty")

	// Notification validation errors
	ErrEmptyNotificationRequest  = errors.New("smartthings: notification request cannot be nil")
	ErrEmptyNotificationType     = errors.New("smartthings: notification type cannot be empty")
	ErrEmptyNotificationMessages = errors.New("smartthings: notification messages cannot be empty")

	// Organization validation errors
	ErrEmptyOrganizationID = errors.New("smartthings: organization ID cannot be empty")

	// Presentation validation errors
	ErrEmptyPresentationID     = errors.New("smartthings: presentation ID cannot be empty")
	ErrEmptyPresentationConfig = errors.New("smartthings: presentation config cannot be nil")

	// Schema validation errors
	ErrEmptySchemaAppName        = errors.New("smartthings: schema app name cannot be empty")
	ErrEmptyInstalledSchemaAppID = errors.New("smartthings: installed schema app ID cannot be empty")

	// Service subscription validation errors
	ErrEmptyServiceSubscriptionRequest = errors.New("smartthings: service subscription request cannot be nil")
	ErrEmptyServiceCapability          = errors.New("smartthings: service capability cannot be empty")
	ErrEmptyServiceCapabilities        = errors.New("smartthings: service capabilities cannot be empty")

	// Virtual device validation errors
	ErrEmptyVirtualDeviceName = errors.New("smartthings: virtual device name cannot be empty")
	ErrEmptyPrototype         = errors.New("smartthings: prototype cannot be empty")
	ErrEmptyEvents            = errors.New("smartthings: events cannot be empty")
)

Sentinel errors returned by the SmartThings client. All errors are defined here for easy discovery and consistent organization.

View Source
var (
	ErrInvalidSignature = errors.New("smartthings: invalid webhook signature")
	ErrMissingSignature = errors.New("smartthings: missing webhook signature header")
	ErrEmptyBody        = errors.New("smartthings: empty webhook body")
)

Webhook validation errors.

Functions

func CelsiusToFahrenheit

func CelsiusToFahrenheit(celsius float64) int

CelsiusToFahrenheit converts Celsius to Fahrenheit. Returns 0 if the input is NaN, Inf, or would overflow int range. For typical home appliance temperatures (-50°C to 500°C), this function is safe and accurate.

func DefaultScopes

func DefaultScopes() []string

DefaultScopes returns the default OAuth scopes for SmartThings

func DiscoverCapabilities added in v1.0.2

func DiscoverCapabilities(status Status) []string

DiscoverCapabilities returns all capability names found in a device status. Useful for debugging and discovering what capabilities a device supports.

func FahrenheitToCelsius

func FahrenheitToCelsius(fahrenheit int) float64

FahrenheitToCelsius converts Fahrenheit to Celsius.

func FindOperatingStateCapabilities added in v1.0.2

func FindOperatingStateCapabilities(status Status) map[string]map[string]any

FindOperatingStateCapabilities discovers all *OperatingState capabilities in a status. Returns a map of capability name to capability data.

func GetApplianceState

func GetApplianceState(status Status, applianceType string) string

GetApplianceState determines the display state for an appliance based on its status. Returns a human-readable state string.

func GetArray

func GetArray(data map[string]any, keys ...string) ([]any, bool)

GetArray navigates a nested map and returns a []any value.

Example:

// Extract: status["mediaInputSource"]["supportedInputSources"]["value"]
inputs, ok := GetArray(status, "mediaInputSource", "supportedInputSources", "value")

func GetAuthorizationURL

func GetAuthorizationURL(cfg *OAuthConfig, state string) string

GetAuthorizationURL returns the URL to redirect users to for OAuth authorization

func GetBool

func GetBool(data map[string]any, keys ...string) (bool, bool)

GetBool navigates a nested map and returns a bool value.

Example:

// Extract: status["switch"]["switch"]["value"] == true
isOn, ok := GetBool(status, "switch", "switch", "value")

func GetCurrentPictureMode

func GetCurrentPictureMode(status Status) string

GetCurrentPictureMode extracts the current picture mode from a device status.

func GetCurrentSoundMode

func GetCurrentSoundMode(status Status) string

GetCurrentSoundMode extracts the current sound mode from a device status.

func GetFloat

func GetFloat(data map[string]any, keys ...string) (float64, bool)

GetFloat navigates a nested map and returns a float64 value.

Example:

// Extract: status["temperatureMeasurement"]["temperature"]["value"]
temp, ok := GetFloat(status, "temperatureMeasurement", "temperature", "value")

func GetInt

func GetInt(data map[string]any, keys ...string) (int, bool)

GetInt navigates a nested map and returns an int value. Handles JSON's float64 representation of numbers. Returns false if the value is outside the valid int range.

Example:

// Extract: status["audioVolume"]["volume"]["value"]
volume, ok := GetInt(status, "audioVolume", "volume", "value")

func GetMap

func GetMap(data map[string]any, keys ...string) (map[string]any, bool)

GetMap navigates a nested map and returns a map[string]any value.

Example:

// Extract: status["main"]
main, ok := GetMap(status, "main")

func GetPictureModes

func GetPictureModes(status Status) []string

GetPictureModes extracts available picture modes from a device status.

func GetSoundModes

func GetSoundModes(status Status) []string

GetSoundModes extracts available sound modes from a device status.

func GetString

func GetString(data map[string]any, keys ...string) (string, bool)

GetString navigates a nested map and returns a string value. Returns the value and true if found, or empty string and false if not.

Example:

// Extract: status["switch"]["switch"]["value"]
power, ok := GetString(status, "switch", "switch", "value")

func GetStringEquals

func GetStringEquals(data map[string]any, expected string, keys ...string) bool

GetStringEquals checks if a nested string value equals the expected value.

Example:

// Check: status["switch"]["switch"]["value"] == "on"
isOn := GetStringEquals(status, "on", "switch", "switch", "value")

func IsApplianceRunning

func IsApplianceRunning(status Status, applianceType string) bool

IsApplianceRunning checks if an appliance is actively doing something.

func IsDeviceOffline

func IsDeviceOffline(err error) bool

IsDeviceOffline returns true if the error indicates the device is offline.

func IsNotFound

func IsNotFound(err error) bool

IsNotFound returns true if the error indicates the resource was not found.

func IsRateLimited

func IsRateLimited(err error) bool

IsRateLimited returns true if the error indicates rate limiting.

func IsTimeout

func IsTimeout(err error) bool

IsTimeout returns true if the error indicates a timeout.

func IsUnauthorized

func IsUnauthorized(err error) bool

IsUnauthorized returns true if the error indicates an authentication failure.

func LogWebhookEvent added in v1.0.1

func LogWebhookEvent(logger *slog.Logger, ctx context.Context, event *WebhookEvent, err error)

LogWebhookEvent logs an incoming webhook event.

func PingResponse

func PingResponse(challenge string) map[string]any

PingResponse creates the response for a PING lifecycle event.

func ToIntSlice added in v1.0.5

func ToIntSlice(arr []any) []int

ToIntSlice converts a []any to []int, filtering out non-numeric values. Handles both int and float64 (JSON number representation).

Example:

arr, _ := GetArray(status, "supportedTemperatures", "value")
temps := ToIntSlice(arr) // []int{34, 36, 38, 40, 42, 44}

func ToStringSlice added in v1.0.5

func ToStringSlice(arr []any) []string

ToStringSlice converts a []any to []string, filtering out non-string values. Useful for extracting supported options lists from Samsung API responses.

Example:

arr, _ := GetArray(status, "samsungce.washerCycle", "supportedWasherCycle", "value")
cycles := ToStringSlice(arr) // []string{"normal", "delicate", "heavy"}

func ValidateWebhookSignature

func ValidateWebhookSignature(secret string, body []byte, signature string) bool

ValidateWebhookSignature verifies the HMAC-SHA256 signature of a webhook request. The signature is computed as: base64(hmac-sha256(secret, body)) Uses constant-time comparison to prevent timing attacks.

Example
package main

import (
	"fmt"

	st "github.com/tj-smith47/smartthings-go"
)

func main() {
	secret := "your-webhook-secret"
	body := []byte(`{"lifecycle":"EVENT","eventData":{}}`)
	signature := "base64-hmac-signature"

	if st.ValidateWebhookSignature(secret, body, signature) {
		fmt.Println("Valid webhook signature")
	} else {
		fmt.Println("Invalid webhook signature")
	}
}

Types

type APIError

type APIError struct {
	StatusCode int
	Message    string
	RequestID  string
}

APIError represents an error response from the SmartThings API.

func (*APIError) Error

func (e *APIError) Error() string

Error implements the error interface.

type AirQualityData added in v1.0.1

type AirQualityData struct {
	AirQualityIndex int `json:"airQualityIndex,omitempty"`
	O3Amount        int `json:"o3Amount,omitempty"`
	O3Index         int `json:"o3Index,omitempty"`
	NO2Amount       int `json:"no2Amount,omitempty"`
	NO2Index        int `json:"no2Index,omitempty"`
	SO2Amount       int `json:"so2Amount,omitempty"`
	SO2Index        int `json:"so2Index,omitempty"`
	COAmount        int `json:"coAmount,omitempty"`
	COIndex         int `json:"coIndex,omitempty"`
	PM10Amount      int `json:"pm10Amount,omitempty"`
	PM10Index       int `json:"pm10Index,omitempty"`
	PM25Amount      int `json:"pm25Amount,omitempty"`
	PM25Index       int `json:"pm25Index,omitempty"`
}

AirQualityData contains air quality information.

type AirQualityForecast added in v1.0.1

type AirQualityForecast struct {
	Daily []DailyAirQualityForecast `json:"daily,omitempty"`
}

AirQualityForecast contains air quality forecast information.

type App

type App struct {
	AppID           string          `json:"appId"`
	AppName         string          `json:"appName"`
	AppType         AppType         `json:"appType"`
	Classifications []string        `json:"classifications,omitempty"`
	DisplayName     string          `json:"displayName,omitempty"`
	Description     string          `json:"description,omitempty"`
	IconImage       *IconImage      `json:"iconImage,omitempty"`
	SingleInstance  bool            `json:"singleInstance,omitempty"`
	WebhookSmartApp *WebhookAppInfo `json:"webhookSmartApp,omitempty"`
	LambdaSmartApp  *LambdaAppInfo  `json:"lambdaSmartApp,omitempty"`
	CreatedDate     string          `json:"createdDate,omitempty"`
	LastUpdatedDate string          `json:"lastUpdatedDate,omitempty"`
}

App represents a SmartThings SmartApp.

type AppCreate

type AppCreate struct {
	AppName         string          `json:"appName"`
	AppType         AppType         `json:"appType"`
	Classifications []string        `json:"classifications,omitempty"`
	DisplayName     string          `json:"displayName,omitempty"`
	Description     string          `json:"description,omitempty"`
	SingleInstance  bool            `json:"singleInstance,omitempty"`
	IconImage       *IconImage      `json:"iconImage,omitempty"`
	WebhookSmartApp *WebhookAppInfo `json:"webhookSmartApp,omitempty"`
	LambdaSmartApp  *LambdaAppInfo  `json:"lambdaSmartApp,omitempty"`
}

AppCreate is the request body for creating a new SmartApp.

type AppOAuth

type AppOAuth struct {
	ClientName   string   `json:"clientName"`
	Scope        []string `json:"scope"`
	RedirectUris []string `json:"redirectUris,omitempty"`
}

AppOAuth represents OAuth settings for a SmartApp.

type AppOAuthGenerated

type AppOAuthGenerated struct {
	ClientID     string `json:"oauthClientId"`
	ClientSecret string `json:"oauthClientSecret"`
}

AppOAuthGenerated contains newly generated OAuth credentials.

type AppType

type AppType string

AppType represents the type of SmartApp.

const (
	AppTypeWebhook AppType = "WEBHOOK_SMART_APP"
	AppTypeLambda  AppType = "LAMBDA_SMART_APP"
)

App type constants.

type AppUpdate

type AppUpdate struct {
	DisplayName     string          `json:"displayName,omitempty"`
	Description     string          `json:"description,omitempty"`
	SingleInstance  bool            `json:"singleInstance,omitempty"`
	IconImage       *IconImage      `json:"iconImage,omitempty"`
	Classifications []string        `json:"classifications,omitempty"`
	WebhookSmartApp *WebhookAppInfo `json:"webhookSmartApp,omitempty"`
	LambdaSmartApp  *LambdaAppInfo  `json:"lambdaSmartApp,omitempty"`
}

AppUpdate is the request body for updating a SmartApp.

type ApplianceStatus

type ApplianceStatus struct {
	State          string  `json:"state"`                     // "run", "stop", "pause", etc.
	RemainingMins  *int    `json:"remaining_mins,omitempty"`  // Minutes remaining
	CompletionTime *string `json:"completion_time,omitempty"` // ISO8601 completion time
	CycleProgress  *int    `json:"cycle_progress,omitempty"`  // Percentage 0-100
}

ApplianceStatus represents the status of a Samsung appliance (washer, dryer, dishwasher).

func ExtractLaundryStatus

func ExtractLaundryStatus(status Status, applianceType string) *ApplianceStatus

ExtractLaundryStatus extracts status from a laundry appliance (washer, dryer, dishwasher). The applianceType should be "dryer", "washer", or "dishwasher".

Example
package main

import (
	"fmt"

	st "github.com/tj-smith47/smartthings-go"
)

func main() {
	// Given a device status from GetDeviceFullStatus
	status := st.Status{
		"samsungce.washerOperatingState": map[string]any{
			"machineState": map[string]any{"value": "running"},
			"remainingTime": map[string]any{
				"value": float64(45),
				"unit":  "min",
			},
			"progress": map[string]any{"value": float64(60)},
		},
	}

	laundry := st.ExtractLaundryStatus(status, st.ApplianceWasher)
	if laundry != nil {
		fmt.Printf("State: %s, Remaining: %d mins\n", laundry.State, *laundry.RemainingMins)
	}
}
Output:

State: running, Remaining: 45 mins

type AttributeSchema

type AttributeSchema struct {
	Type       string                 `json:"type,omitempty"` // "string", "integer", "number", "boolean", "object", "array"
	Properties map[string]interface{} `json:"properties,omitempty"`
	Required   []string               `json:"required,omitempty"`
	Minimum    *float64               `json:"minimum,omitempty"`
	Maximum    *float64               `json:"maximum,omitempty"`
	Enum       []interface{}          `json:"enum,omitempty"`
}

AttributeSchema describes the schema for an attribute value.

type BatchCommand added in v1.0.1

type BatchCommand struct {
	DeviceID string    // Target device ID
	Commands []Command // Commands to execute on this device
}

BatchCommand represents a command to be executed on a specific device.

type BatchConfig added in v1.0.1

type BatchConfig struct {
	// MaxConcurrent is the maximum number of concurrent API calls.
	// Defaults to 10 if not specified.
	MaxConcurrent int

	// StopOnError determines whether to stop processing remaining commands
	// when an error occurs. Default is false (continue processing all).
	StopOnError bool
}

BatchConfig configures batch execution behavior.

func DefaultBatchConfig added in v1.0.1

func DefaultBatchConfig() *BatchConfig

DefaultBatchConfig returns sensible defaults for batch operations.

type BatchResult added in v1.0.1

type BatchResult struct {
	DeviceID string // The device ID
	Error    error  // Error if execution failed, nil on success
}

BatchResult contains the result of executing commands on a single device.

type BatchStatusResult added in v1.0.1

type BatchStatusResult struct {
	DeviceID   string            // The device ID
	Components map[string]Status // Status per component (nil on error)
	Error      error             // Error if fetch failed
}

BatchStatusResult contains device status fetch results.

type BrilliantDeviceStatus

type BrilliantDeviceStatus struct {
	ID         string `json:"id"`
	Name       string `json:"name"`
	IsOn       bool   `json:"is_on"`
	Type       string `json:"type"`       // "switch", "dimmer"
	Brightness *int   `json:"brightness"` // 0-100 for dimmers
}

BrilliantDeviceStatus represents the status of a Brilliant smart switch.

func ExtractBrilliantStatus

func ExtractBrilliantStatus(deviceID, name string, status Status) *BrilliantDeviceStatus

ExtractBrilliantStatus extracts status from a Brilliant smart switch/dimmer.

type Cache added in v1.0.1

type Cache interface {
	// Get retrieves a value from the cache.
	// Returns the value and true if found and not expired, or nil and false otherwise.
	Get(key string) (any, bool)

	// Set stores a value in the cache with the given TTL.
	// If TTL is 0 or negative, the entry never expires.
	Set(key string, value any, ttl time.Duration)

	// Delete removes a value from the cache.
	Delete(key string)

	// Clear removes all values from the cache.
	Clear()
}

Cache defines an interface for caching API responses. Implementations must be safe for concurrent access.

type CacheConfig added in v1.0.1

type CacheConfig struct {
	// Cache is the cache implementation to use.
	Cache Cache

	// CapabilityTTL is how long to cache capability definitions.
	// Defaults to 1 hour if zero.
	CapabilityTTL time.Duration

	// DeviceProfileTTL is how long to cache device profiles.
	// Defaults to 1 hour if zero.
	DeviceProfileTTL time.Duration
}

CacheConfig configures the caching behavior for a Client.

func DefaultCacheConfig added in v1.0.1

func DefaultCacheConfig() *CacheConfig

DefaultCacheConfig returns a CacheConfig with sensible defaults.

type Capability

type Capability struct {
	ID         string                         `json:"id"`
	Version    int                            `json:"version"`
	Status     string                         `json:"status"` // "live", "proposed", "deprecated"
	Name       string                         `json:"name,omitempty"`
	Attributes map[string]CapabilityAttribute `json:"attributes,omitempty"`
	Commands   map[string]CapabilityCommand   `json:"commands,omitempty"`
}

Capability represents a SmartThings capability definition.

type CapabilityAttribute

type CapabilityAttribute struct {
	Schema       AttributeSchema `json:"schema,omitempty"`
	Setter       string          `json:"setter,omitempty"`
	EnumCommands []string        `json:"enumCommands,omitempty"`
}

CapabilityAttribute describes a capability attribute.

type CapabilityCommand

type CapabilityCommand struct {
	Name      string                      `json:"name,omitempty"`
	Arguments []CapabilityCommandArgument `json:"arguments,omitempty"`
}

CapabilityCommand describes a capability command.

type CapabilityCommandArgument

type CapabilityCommandArgument struct {
	Name     string          `json:"name"`
	Optional bool            `json:"optional,omitempty"`
	Schema   AttributeSchema `json:"schema,omitempty"`
}

CapabilityCommandArgument describes a command argument.

type CapabilityNamespace added in v1.0.1

type CapabilityNamespace string

CapabilityNamespace represents the namespace of a capability.

const (
	CapabilityNamespaceSmartThings CapabilityNamespace = "st"
	CapabilityNamespaceCustom      CapabilityNamespace = "custom"
)

Capability namespace constants.

type CapabilityRef

type CapabilityRef struct {
	ID      string `json:"id"`
	Version int    `json:"version,omitempty"`
}

CapabilityRef references a capability with its version.

type CapabilityReference

type CapabilityReference struct {
	ID      string `json:"id"`
	Version int    `json:"version"`
	Status  string `json:"status,omitempty"`
}

CapabilityReference is a lightweight reference to a capability.

type CapabilitySubscription

type CapabilitySubscription struct {
	LocationID      string      `json:"locationId"`
	Capability      string      `json:"capability"`
	Attribute       string      `json:"attribute,omitempty"`
	StateChangeOnly bool        `json:"stateChangeOnly,omitempty"`
	Value           interface{} `json:"value,omitempty"`
	Modes           []string    `json:"modes,omitempty"`
}

CapabilitySubscription specifies a capability-level subscription.

type CapabilityVisibleCondition added in v1.0.1

type CapabilityVisibleCondition struct {
	Capability string `json:"capability,omitempty"`
	Attribute  string `json:"attribute,omitempty"`
	Value      any    `json:"value,omitempty"`
	Operator   string `json:"operator,omitempty"`
}

CapabilityVisibleCondition defines when a capability is visible.

type Channel added in v1.0.1

type Channel struct {
	ChannelID         string      `json:"channelId"`
	Name              string      `json:"name"`
	Description       string      `json:"description,omitempty"`
	TermsOfServiceURL string      `json:"termsOfServiceUrl,omitempty"`
	Type              ChannelType `json:"type,omitempty"`
	CreatedDate       string      `json:"createdDate,omitempty"`
	LastModifiedDate  string      `json:"lastModifiedDate,omitempty"`
}

Channel represents a SmartThings driver channel.

type ChannelCreate added in v1.0.1

type ChannelCreate struct {
	Name              string      `json:"name"`
	Description       string      `json:"description,omitempty"`
	TermsOfServiceURL string      `json:"termsOfServiceUrl,omitempty"`
	Type              ChannelType `json:"type,omitempty"`
}

ChannelCreate is the request body for creating a channel.

type ChannelListOptions added in v1.0.1

type ChannelListOptions struct {
	SubscriberType  SubscriberType // Filter by subscriber type
	SubscriberID    string         // Filter by subscriber ID (e.g., hub ID)
	IncludeReadOnly bool           // Include read-only channels
}

ChannelListOptions contains options for listing channels.

type ChannelType added in v1.0.1

type ChannelType string

ChannelType represents the type of a driver channel.

const (
	// ChannelTypeDriver is a channel containing Edge drivers.
	ChannelTypeDriver ChannelType = "DRIVER"
)

type ChannelUpdate added in v1.0.1

type ChannelUpdate struct {
	Name              string `json:"name,omitempty"`
	Description       string `json:"description,omitempty"`
	TermsOfServiceURL string `json:"termsOfServiceUrl,omitempty"`
}

ChannelUpdate is the request body for updating a channel.

type ChildDevice

type ChildDevice struct {
	DeviceID string `json:"deviceId"`
}

ChildDevice represents a reference to a child device.

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is a SmartThings API client.

func NewClient

func NewClient(token string, opts ...Option) (*Client, error)

NewClient creates a new SmartThings API client. Returns ErrEmptyToken if token is empty.

Example
package main

import (
	"context"
	"fmt"
	"log"

	st "github.com/tj-smith47/smartthings-go"
)

func main() {
	// Create a client with a Personal Access Token
	client, err := st.NewClient("your-api-token")
	if err != nil {
		log.Fatal(err)
	}

	ctx := context.Background()
	devices, err := client.ListDevices(ctx)
	if err != nil {
		log.Fatal(err)
	}

	for _, device := range devices {
		fmt.Printf("Device: %s\n", device.Label)
	}
}
Example (WithOptions)
package main

import (
	"log"
	"time"

	st "github.com/tj-smith47/smartthings-go"
)

func main() {
	// Create a client with custom options
	client, err := st.NewClient("your-api-token",
		st.WithTimeout(30*time.Second),
		st.WithRetry(&st.RetryConfig{
			MaxRetries:     3,
			InitialBackoff: 100 * time.Millisecond,
			MaxBackoff:     5 * time.Second,
		}),
		st.WithCache(st.DefaultCacheConfig()),
	)
	if err != nil {
		log.Fatal(err)
	}

	_ = client
}

func NewLoggingClient added in v1.0.1

func NewLoggingClient(token string, logger *slog.Logger, opts ...Option) (*Client, error)

NewLoggingClient creates a client with request/response logging enabled. This is a convenience function that wraps the HTTP transport with logging.

Example:

logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelDebug}))
client, err := st.NewLoggingClient("token", logger)

func (*Client) Apps added in v1.0.1

func (c *Client) Apps(ctx context.Context) iter.Seq2[App, error]

Apps returns an iterator over all apps.

func (*Client) AssignDriver added in v1.0.1

func (c *Client) AssignDriver(ctx context.Context, channelID, driverID, version string) (*DriverChannelDetails, error)

AssignDriver assigns a driver version to a channel.

func (*Client) AssignedDrivers added in v1.0.1

func (c *Client) AssignedDrivers(ctx context.Context, channelID string) iter.Seq2[DriverChannelDetails, error]

AssignedDrivers returns an iterator over all drivers assigned to a channel.

func (*Client) Capabilities added in v1.0.1

func (c *Client) Capabilities(ctx context.Context) iter.Seq2[CapabilityReference, error]

Capabilities returns an iterator over all capabilities.

func (*Client) Channels added in v1.0.1

func (c *Client) Channels(ctx context.Context, opts *ChannelListOptions) iter.Seq2[Channel, error]

Channels returns an iterator over all channels.

func (*Client) CreateApp

func (c *Client) CreateApp(ctx context.Context, app *AppCreate) (*App, error)

CreateApp registers a new SmartApp.

func (*Client) CreateChannel added in v1.0.1

func (c *Client) CreateChannel(ctx context.Context, channel *ChannelCreate) (*Channel, error)

CreateChannel creates a new driver channel.

func (*Client) CreateDevicePreference added in v1.0.1

func (c *Client) CreateDevicePreference(ctx context.Context, pref *DevicePreferenceCreate) (*DevicePreference, error)

CreateDevicePreference creates a new device preference.

func (*Client) CreateDeviceProfile

func (c *Client) CreateDeviceProfile(ctx context.Context, profile *DeviceProfileCreate) (*DeviceProfileFull, error)

CreateDeviceProfile creates a new device profile.

func (*Client) CreateLocation

func (c *Client) CreateLocation(ctx context.Context, location *LocationCreate) (*Location, error)

CreateLocation creates a new location.

func (*Client) CreateNotification added in v1.0.1

func (c *Client) CreateNotification(ctx context.Context, req *NotificationRequest) (*NotificationResponse, error)

CreateNotification sends a push notification to mobile apps at a location.

func (*Client) CreatePreferenceTranslations added in v1.0.1

func (c *Client) CreatePreferenceTranslations(ctx context.Context, preferenceID string, localization *PreferenceLocalization) (*PreferenceLocalization, error)

CreatePreferenceTranslations creates translations for a device preference.

func (*Client) CreatePresentationConfig added in v1.0.1

func (c *Client) CreatePresentationConfig(ctx context.Context, config *PresentationDeviceConfigCreate) (*PresentationDeviceConfig, error)

CreatePresentationConfig creates a new device presentation configuration.

func (*Client) CreateRoom

func (c *Client) CreateRoom(ctx context.Context, locationID string, room *RoomCreate) (*Room, error)

CreateRoom creates a new room in a location.

func (*Client) CreateRule

func (c *Client) CreateRule(ctx context.Context, locationID string, rule *RuleCreate) (*Rule, error)

CreateRule creates a new rule.

func (*Client) CreateSchedule

func (c *Client) CreateSchedule(ctx context.Context, installedAppID string, schedule *ScheduleCreate) (*Schedule, error)

CreateSchedule creates a new schedule.

func (*Client) CreateSchemaApp added in v1.0.1

func (c *Client) CreateSchemaApp(ctx context.Context, req *SchemaAppRequest, organizationID string) (*SchemaCreateResponse, error)

CreateSchemaApp creates a new ST Schema connector.

func (*Client) CreateSchemaAppInvitation added in v1.0.1

func (c *Client) CreateSchemaAppInvitation(ctx context.Context, invitation *SchemaAppInvitationCreate) (*SchemaAppInvitationID, error)

CreateSchemaAppInvitation creates an invitation for a Schema app.

func (*Client) CreateServiceSubscription added in v1.0.1

func (c *Client) CreateServiceSubscription(ctx context.Context, req *ServiceSubscriptionRequest, installedAppID, locationID string) (*ServiceNewSubscription, error)

CreateServiceSubscription creates a new service subscription.

func (*Client) CreateStandardVirtualDevice added in v1.0.1

func (c *Client) CreateStandardVirtualDevice(ctx context.Context, req *VirtualDeviceStandardCreateRequest) (*Device, error)

CreateStandardVirtualDevice creates a new virtual device from a standard prototype. Common prototypes include: VIRTUAL_SWITCH, VIRTUAL_DIMMER, VIRTUAL_LOCK, etc.

func (*Client) CreateSubscription

func (c *Client) CreateSubscription(ctx context.Context, installedAppID string, sub *SubscriptionCreate) (*Subscription, error)

CreateSubscription creates a new subscription.

func (*Client) CreateVirtualDevice added in v1.0.1

func (c *Client) CreateVirtualDevice(ctx context.Context, req *VirtualDeviceCreateRequest) (*Device, error)

CreateVirtualDevice creates a new virtual device from a device profile.

func (*Client) CreateVirtualDeviceEvents added in v1.0.1

func (c *Client) CreateVirtualDeviceEvents(ctx context.Context, deviceID string, events []VirtualDeviceEvent) (*VirtualDeviceEventsResponse, error)

CreateVirtualDeviceEvents creates events on a virtual device. This is used to simulate state changes on virtual devices.

func (*Client) DeleteAllServiceSubscriptions added in v1.0.1

func (c *Client) DeleteAllServiceSubscriptions(ctx context.Context, installedAppID, locationID string) error

DeleteAllServiceSubscriptions deletes all service subscriptions.

func (*Client) DeleteAllSubscriptions

func (c *Client) DeleteAllSubscriptions(ctx context.Context, installedAppID string) error

DeleteAllSubscriptions deletes all subscriptions for an installed app.

func (*Client) DeleteApp

func (c *Client) DeleteApp(ctx context.Context, appID string) error

DeleteApp removes a SmartApp.

func (*Client) DeleteChannel added in v1.0.1

func (c *Client) DeleteChannel(ctx context.Context, channelID string) error

DeleteChannel deletes a channel.

func (*Client) DeleteDevice

func (c *Client) DeleteDevice(ctx context.Context, deviceID string) error

DeleteDevice deletes a device.

func (*Client) DeleteDeviceProfile

func (c *Client) DeleteDeviceProfile(ctx context.Context, profileID string) error

DeleteDeviceProfile removes a device profile.

func (*Client) DeleteDriver added in v1.0.1

func (c *Client) DeleteDriver(ctx context.Context, driverID string) error

DeleteDriver deletes a driver.

func (*Client) DeleteInstalledApp

func (c *Client) DeleteInstalledApp(ctx context.Context, installedAppID string) error

DeleteInstalledApp uninstalls an app.

func (*Client) DeleteInstalledSchemaApp added in v1.0.1

func (c *Client) DeleteInstalledSchemaApp(ctx context.Context, isaID string) error

DeleteInstalledSchemaApp deletes an installed Schema app instance and its devices.

func (*Client) DeleteLocation

func (c *Client) DeleteLocation(ctx context.Context, locationID string) error

DeleteLocation deletes a location.

func (*Client) DeleteRoom

func (c *Client) DeleteRoom(ctx context.Context, locationID, roomID string) error

DeleteRoom deletes a room.

func (*Client) DeleteRule

func (c *Client) DeleteRule(ctx context.Context, ruleID string) error

DeleteRule deletes a rule.

func (*Client) DeleteSchedule

func (c *Client) DeleteSchedule(ctx context.Context, installedAppID, scheduleName string) error

DeleteSchedule deletes a schedule.

func (*Client) DeleteSchemaApp added in v1.0.1

func (c *Client) DeleteSchemaApp(ctx context.Context, appID string) error

DeleteSchemaApp deletes a ST Schema connector.

func (*Client) DeleteServiceSubscription added in v1.0.1

func (c *Client) DeleteServiceSubscription(ctx context.Context, subscriptionID, installedAppID, locationID string) error

DeleteServiceSubscription deletes a service subscription.

func (*Client) DeleteSubscription

func (c *Client) DeleteSubscription(ctx context.Context, installedAppID, subscriptionID string) error

DeleteSubscription deletes a specific subscription.

func (*Client) DeviceEvents added in v1.0.1

func (c *Client) DeviceEvents(ctx context.Context, deviceID string, opts *HistoryOptions) iter.Seq2[DeviceEvent, error]

DeviceEvents returns an iterator over device events with automatic pagination.

func (*Client) DevicePreferences added in v1.0.1

func (c *Client) DevicePreferences(ctx context.Context, namespace string) iter.Seq2[DevicePreference, error]

DevicePreferences returns an iterator over all device preferences.

func (*Client) DeviceProfiles added in v1.0.1

func (c *Client) DeviceProfiles(ctx context.Context) iter.Seq2[DeviceProfileFull, error]

DeviceProfiles returns an iterator over all device profiles.

func (*Client) Devices added in v1.0.1

func (c *Client) Devices(ctx context.Context) iter.Seq2[Device, error]

Devices returns an iterator over all devices with automatic pagination. Stops iteration early if an error occurs or context is cancelled.

Example
package main

import (
	"context"
	"fmt"
	"log"

	st "github.com/tj-smith47/smartthings-go"
)

func main() {
	client, _ := st.NewClient("your-api-token")
	ctx := context.Background()

	// Iterate over all devices using the iterator pattern
	for device, err := range client.Devices(ctx) {
		if err != nil {
			log.Fatal(err)
		}
		fmt.Printf("Device: %s (%s)\n", device.Label, device.DeviceID)
	}
}

func (*Client) DevicesWithOptions added in v1.0.1

func (c *Client) DevicesWithOptions(ctx context.Context, opts *ListDevicesOptions) iter.Seq2[Device, error]

DevicesWithOptions returns a device iterator with custom filtering options. The iterator automatically handles pagination, fetching additional pages as needed.

Example
package main

import (
	"context"
	"fmt"
	"log"

	st "github.com/tj-smith47/smartthings-go"
)

func main() {
	client, _ := st.NewClient("your-api-token")
	ctx := context.Background()

	// Filter devices by capability and location
	opts := &st.ListDevicesOptions{
		Capability: []string{"switch"},
		LocationID: []string{"your-location-id"},
	}

	for device, err := range client.DevicesWithOptions(ctx, opts) {
		if err != nil {
			log.Fatal(err)
		}
		fmt.Printf("Switch: %s\n", device.Label)
	}
}

func (*Client) DiscoverHubForLocalConnection added in v1.0.5

func (c *Client) DiscoverHubForLocalConnection(ctx context.Context) (*HubLocalConnectionInfo, error)

DiscoverHubForLocalConnection finds the first available hub and returns connection info for the local WebSocket API.

func (*Client) Drivers added in v1.0.1

Drivers returns an iterator over all edge drivers.

func (*Client) EnrollHub added in v1.0.1

func (c *Client) EnrollHub(ctx context.Context, channelID, hubID string) error

EnrollHub enrolls a hub in a channel, allowing it to receive drivers from the channel.

func (*Client) EnrolledChannels added in v1.0.1

func (c *Client) EnrolledChannels(ctx context.Context, hubID string) iter.Seq2[EnrolledChannel, error]

EnrolledChannels returns an iterator over all enrolled channels for a hub.

func (*Client) ExecuteCommand

func (c *Client) ExecuteCommand(ctx context.Context, deviceID string, cmd Command) error

ExecuteCommand sends a single command to a device.

func (*Client) ExecuteCommandBatch added in v1.0.1

func (c *Client) ExecuteCommandBatch(ctx context.Context, deviceIDs []string, cmd Command, cfg *BatchConfig) []BatchResult

ExecuteCommandBatch is a convenience wrapper for executing the same command on multiple devices.

Example:

cmd := Command{Component: "main", Capability: "switch", Command: "on"}
results := client.ExecuteCommandBatch(ctx, []string{"device1", "device2", "device3"}, cmd, nil)

func (*Client) ExecuteCommands

func (c *Client) ExecuteCommands(ctx context.Context, deviceID string, cmds []Command) error

ExecuteCommands sends multiple commands to a device.

Example
package main

import (
	"context"
	"log"

	st "github.com/tj-smith47/smartthings-go"
)

func main() {
	client, _ := st.NewClient("your-api-token")
	ctx := context.Background()

	// Turn on a light
	err := client.ExecuteCommands(ctx, "device-id", []st.Command{
		{
			Component:  "main",
			Capability: "switch",
			Command:    "on",
		},
	})
	if err != nil {
		log.Fatal(err)
	}
}
Example (Dimmer)
package main

import (
	"context"
	"log"

	st "github.com/tj-smith47/smartthings-go"
)

func main() {
	client, _ := st.NewClient("your-api-token")
	ctx := context.Background()

	// Set dimmer level to 50%
	err := client.ExecuteCommands(ctx, "device-id", []st.Command{
		{
			Component:  "main",
			Capability: "switchLevel",
			Command:    "setLevel",
			Arguments:  []any{50},
		},
	})
	if err != nil {
		log.Fatal(err)
	}
}

func (*Client) ExecuteCommandsBatch added in v1.0.1

func (c *Client) ExecuteCommandsBatch(ctx context.Context, batch []BatchCommand, cfg *BatchConfig) []BatchResult

ExecuteCommandsBatch executes commands on multiple devices concurrently. It uses a worker pool to limit concurrent API calls and respects rate limits.

Example:

batch := []BatchCommand{
    {DeviceID: "device1", Commands: []Command{{Component: "main", Capability: "switch", Command: "on"}}},
    {DeviceID: "device2", Commands: []Command{{Component: "main", Capability: "switch", Command: "off"}}},
}
results := client.ExecuteCommandsBatch(ctx, batch, nil)
for _, r := range results {
    if r.Error != nil {
        log.Printf("Device %s failed: %v", r.DeviceID, r.Error)
    }
}

func (*Client) ExecuteComponentCommand added in v1.0.5

func (c *Client) ExecuteComponentCommand(ctx context.Context, deviceID, component, capability, command string, args ...any) error

ExecuteComponentCommand sends a command to a specific component of a device. This is a convenience method that combines NewComponentCommand and ExecuteCommand.

Example usage for refrigerator cooler temperature:

err := client.ExecuteComponentCommand(ctx, deviceID, "cooler", "thermostatCoolingSetpoint", "setCoolingSetpoint", 3)

Example usage for icemaker switch:

err := client.ExecuteComponentCommand(ctx, deviceID, "icemaker", "switch", "on")

func (*Client) ExecuteRule

func (c *Client) ExecuteRule(ctx context.Context, ruleID string) error

ExecuteRule manually executes a rule.

func (*Client) ExecuteScene

func (c *Client) ExecuteScene(ctx context.Context, sceneID string) error

ExecuteScene executes a scene.

Example
package main

import (
	"context"
	"fmt"
	"log"

	st "github.com/tj-smith47/smartthings-go"
)

func main() {
	client, _ := st.NewClient("your-api-token")
	ctx := context.Background()

	err := client.ExecuteScene(ctx, "scene-id")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Scene executed")
}

func (*Client) FetchTVInputs

func (c *Client) FetchTVInputs(ctx context.Context, deviceID string) ([]TVInput, error)

FetchTVInputs fetches and returns available TV inputs from the API.

func (*Client) FetchTVStatus

func (c *Client) FetchTVStatus(ctx context.Context, deviceID string) (*TVStatus, error)

FetchTVStatus fetches and parses the current TV status from the API.

func (*Client) GenerateAppOAuth

func (c *Client) GenerateAppOAuth(ctx context.Context, appID string) (*AppOAuthGenerated, error)

GenerateAppOAuth generates new OAuth client credentials for a SmartApp. This will invalidate any existing credentials.

func (*Client) GeneratePresentation added in v1.0.1

func (c *Client) GeneratePresentation(ctx context.Context, profileID string) (*PresentationDeviceConfig, error)

GeneratePresentation generates a device configuration from a device profile.

func (*Client) GetApp

func (c *Client) GetApp(ctx context.Context, appID string) (*App, error)

GetApp returns a single SmartApp by ID.

func (*Client) GetAppOAuth

func (c *Client) GetAppOAuth(ctx context.Context, appID string) (*AppOAuth, error)

GetAppOAuth returns the OAuth settings for a SmartApp.

func (*Client) GetCapability

func (c *Client) GetCapability(ctx context.Context, capabilityID string, version int) (*Capability, error)

GetCapability returns a specific capability definition. If version is 0, returns the latest version. Results are cached if caching is enabled.

func (*Client) GetChannel added in v1.0.1

func (c *Client) GetChannel(ctx context.Context, channelID string) (*Channel, error)

GetChannel returns a single channel by ID.

func (*Client) GetComponentStatus

func (c *Client) GetComponentStatus(ctx context.Context, deviceID, componentID string) (Status, error)

GetComponentStatus returns the status of a specific component.

func (*Client) GetCurrentInstalledAppConfig added in v1.0.1

func (c *Client) GetCurrentInstalledAppConfig(ctx context.Context, installedAppID string) (*InstalledAppConfiguration, error)

GetCurrentInstalledAppConfig returns the current (latest authorized) configuration. Returns nil if no authorized configuration exists.

func (*Client) GetCurrentMode

func (c *Client) GetCurrentMode(ctx context.Context, locationID string) (*Mode, error)

GetCurrentMode returns the currently active mode for a location.

func (*Client) GetDevice

func (c *Client) GetDevice(ctx context.Context, deviceID string) (*Device, error)

GetDevice returns a single device by ID.

func (*Client) GetDeviceEvents

func (c *Client) GetDeviceEvents(ctx context.Context, deviceID string, opts *HistoryOptions) (*PagedEvents, error)

GetDeviceEvents returns the event history for a device.

func (*Client) GetDeviceFullStatus

func (c *Client) GetDeviceFullStatus(ctx context.Context, deviceID string) (map[string]Status, error)

GetDeviceFullStatus returns the status of all components of a device. The returned map contains component IDs as keys and their status as values.

Example
package main

import (
	"context"
	"fmt"
	"log"

	st "github.com/tj-smith47/smartthings-go"
)

func main() {
	client, _ := st.NewClient("your-api-token")
	ctx := context.Background()

	// Returns map[componentID]Status
	components, err := client.GetDeviceFullStatus(ctx, "device-id")
	if err != nil {
		log.Fatal(err)
	}

	// Access the "main" component status
	if main, ok := components["main"]; ok {
		if sw, ok := st.GetMap(main, "switch"); ok {
			if attr, ok := st.GetMap(sw, "switch"); ok {
				if value, ok := st.GetString(attr, "value"); ok {
					fmt.Printf("Switch is: %s\n", value)
				}
			}
		}
	}
}

func (*Client) GetDeviceHealth

func (c *Client) GetDeviceHealth(ctx context.Context, deviceID string) (*DeviceHealth, error)

GetDeviceHealth returns the health status of a device.

func (*Client) GetDevicePreference added in v1.0.1

func (c *Client) GetDevicePreference(ctx context.Context, preferenceID string) (*DevicePreference, error)

GetDevicePreference returns a single device preference by ID.

func (*Client) GetDevicePresentation added in v1.0.1

func (c *Client) GetDevicePresentation(ctx context.Context, presentationID, manufacturerName string) (*PresentationDevicePresentation, error)

GetDevicePresentation returns the full device presentation for rendering.

func (*Client) GetDeviceProfile

func (c *Client) GetDeviceProfile(ctx context.Context, profileID string) (*DeviceProfileFull, error)

GetDeviceProfile returns a single device profile by ID. Results are cached if caching is enabled.

func (*Client) GetDeviceStates

func (c *Client) GetDeviceStates(ctx context.Context, deviceID string, opts *HistoryOptions) (*PagedStates, error)

GetDeviceStates returns historical state snapshots for a device.

func (*Client) GetDeviceStatus

func (c *Client) GetDeviceStatus(ctx context.Context, deviceID string) (Status, error)

GetDeviceStatus returns the status of the main component of a device.

func (*Client) GetDeviceStatusAllComponents

func (c *Client) GetDeviceStatusAllComponents(ctx context.Context, deviceID string) (Status, error)

GetDeviceStatusAllComponents returns a merged status from all components. This is useful for devices like refrigerators where data is split across components.

func (*Client) GetDeviceStatusBatch added in v1.0.1

func (c *Client) GetDeviceStatusBatch(ctx context.Context, deviceIDs []string, cfg *BatchConfig) []BatchStatusResult

GetDeviceStatusBatch fetches status for multiple devices concurrently.

Example:

results := client.GetDeviceStatusBatch(ctx, []string{"device1", "device2"}, nil)
for _, r := range results {
    if r.Error == nil {
        fmt.Printf("Device %s: %v\n", r.DeviceID, r.Components)
    }
}

func (*Client) GetDriver added in v1.0.1

func (c *Client) GetDriver(ctx context.Context, driverID string) (*EdgeDriver, error)

GetDriver returns a single driver by ID.

func (*Client) GetDriverChannelMetaInfo added in v1.0.1

func (c *Client) GetDriverChannelMetaInfo(ctx context.Context, channelID, driverID string) (*EdgeDriver, error)

GetDriverChannelMetaInfo returns metadata for a specific driver in a channel.

func (*Client) GetDriverRevision added in v1.0.1

func (c *Client) GetDriverRevision(ctx context.Context, driverID, version string) (*EdgeDriver, error)

GetDriverRevision returns a specific version of a driver.

func (*Client) GetHub added in v1.0.1

func (c *Client) GetHub(ctx context.Context, hubID string) (*Hub, error)

GetHub returns a hub by ID. This uses the standard devices endpoint since /hubdevices/{id} is not available.

func (*Client) GetHubCharacteristics added in v1.0.1

func (c *Client) GetHubCharacteristics(ctx context.Context, hubID string) (HubCharacteristics, error)

GetHubCharacteristics returns detailed characteristics for a hub.

func (*Client) GetHubLocalConnectionInfo added in v1.0.5

func (c *Client) GetHubLocalConnectionInfo(ctx context.Context, hubID string) (*HubLocalConnectionInfo, error)

GetHubLocalConnectionInfo retrieves the information needed to connect to a hub's local WebSocket API. Returns the hub ID, name, local IP, and port.

func (*Client) GetHubWithLocalIP added in v1.0.5

func (c *Client) GetHubWithLocalIP(ctx context.Context, hubID string) (*Hub, *HubData, error)

GetHubWithLocalIP returns a hub with its local IP address by fetching the device details. The hub device ID can be found by listing devices and filtering for type "HUB". The local IP is in device.hub.hubData.localIP, NOT in the device status.

func (*Client) GetInstalledApp

func (c *Client) GetInstalledApp(ctx context.Context, installedAppID string) (*InstalledApp, error)

GetInstalledApp returns a single installed app by ID.

func (*Client) GetInstalledAppConfig added in v1.0.1

func (c *Client) GetInstalledAppConfig(ctx context.Context, installedAppID, configID string) (*InstalledAppConfiguration, error)

GetInstalledAppConfig returns a specific configuration by ID.

func (*Client) GetInstalledDriver added in v1.0.1

func (c *Client) GetInstalledDriver(ctx context.Context, hubID, driverID string) (*InstalledDriver, error)

GetInstalledDriver returns a specific installed driver on a hub.

func (*Client) GetInstalledSchemaApp added in v1.0.1

func (c *Client) GetInstalledSchemaApp(ctx context.Context, isaID string) (*InstalledSchemaApp, error)

GetInstalledSchemaApp returns a single installed Schema app instance.

func (*Client) GetLocation

func (c *Client) GetLocation(ctx context.Context, locationID string) (*Location, error)

GetLocation returns a single location by ID.

func (*Client) GetLocationServiceInfo added in v1.0.1

func (c *Client) GetLocationServiceInfo(ctx context.Context, locationID string) (*ServiceLocationInfo, error)

GetLocationServiceInfo returns service information for a location.

func (*Client) GetMode

func (c *Client) GetMode(ctx context.Context, locationID, modeID string) (*Mode, error)

GetMode returns a single mode by ID.

func (*Client) GetOrganization added in v1.0.1

func (c *Client) GetOrganization(ctx context.Context, organizationID string) (*Organization, error)

GetOrganization returns a single organization by ID.

func (*Client) GetPreferenceTranslations added in v1.0.1

func (c *Client) GetPreferenceTranslations(ctx context.Context, preferenceID, locale string) (*PreferenceLocalization, error)

GetPreferenceTranslations returns translations for a specific locale.

func (*Client) GetPresentationConfig added in v1.0.1

func (c *Client) GetPresentationConfig(ctx context.Context, presentationID, manufacturerName string) (*PresentationDeviceConfig, error)

GetPresentationConfig returns a device configuration by presentation ID.

func (*Client) GetRoom

func (c *Client) GetRoom(ctx context.Context, locationID, roomID string) (*Room, error)

GetRoom returns a single room by ID.

func (*Client) GetRule

func (c *Client) GetRule(ctx context.Context, ruleID string) (*Rule, error)

GetRule returns a single rule by ID.

func (*Client) GetScene

func (c *Client) GetScene(ctx context.Context, sceneID string) (*Scene, error)

GetScene returns a single scene by ID.

func (*Client) GetSchedule

func (c *Client) GetSchedule(ctx context.Context, installedAppID, scheduleName string) (*Schedule, error)

GetSchedule returns a single schedule by name.

func (*Client) GetSchemaApp added in v1.0.1

func (c *Client) GetSchemaApp(ctx context.Context, appID string) (*SchemaApp, error)

GetSchemaApp returns a single Schema app by ID.

func (*Client) GetSchemaAppPage added in v1.0.1

func (c *Client) GetSchemaAppPage(ctx context.Context, appID, locationID string) (*SchemaPage, error)

GetSchemaAppPage returns the page configuration for an installed Schema app.

func (*Client) GetServiceCapabilitiesData added in v1.0.1

func (c *Client) GetServiceCapabilitiesData(ctx context.Context, capabilities []ServiceCapability, locationID string) (*ServiceCapabilityData, error)

GetServiceCapabilitiesData returns data for multiple service capabilities.

func (*Client) GetServiceCapabilitiesList added in v1.0.1

func (c *Client) GetServiceCapabilitiesList(ctx context.Context, locationID string) ([]ServiceCapability, error)

GetServiceCapabilitiesList returns available service capabilities for a location.

func (*Client) GetServiceCapability added in v1.0.1

func (c *Client) GetServiceCapability(ctx context.Context, capability ServiceCapability, locationID string) (*ServiceCapabilityData, error)

GetServiceCapability returns data for a single service capability.

func (*Client) InstallDriver added in v1.0.1

func (c *Client) InstallDriver(ctx context.Context, driverID, hubID, channelID string) error

InstallDriver installs a driver from a channel onto a hub.

func (*Client) InstalledApps added in v1.0.1

func (c *Client) InstalledApps(ctx context.Context, locationID string) iter.Seq2[InstalledApp, error]

InstalledApps returns an iterator over all installed apps for a location.

func (*Client) InstalledDrivers added in v1.0.1

func (c *Client) InstalledDrivers(ctx context.Context, hubID, deviceID string) iter.Seq2[InstalledDriver, error]

InstalledDrivers returns an iterator over all installed drivers on a hub.

func (*Client) InstalledSchemaApps added in v1.0.1

func (c *Client) InstalledSchemaApps(ctx context.Context, locationID string) iter.Seq2[InstalledSchemaApp, error]

InstalledSchemaApps returns an iterator over all installed ST Schema apps for a location.

func (*Client) InvalidateCache added in v1.0.1

func (c *Client) InvalidateCache(resourceType string, ids ...string)

InvalidateCache removes a specific entry from the cache.

func (*Client) InvalidateCapabilityCache added in v1.0.1

func (c *Client) InvalidateCapabilityCache()

InvalidateCapabilityCache removes all cached capability entries.

func (*Client) LaunchTVApp

func (c *Client) LaunchTVApp(ctx context.Context, deviceID, appID string) error

LaunchTVApp launches an app on the TV.

func (*Client) ListAllDevices

func (c *Client) ListAllDevices(ctx context.Context) ([]Device, error)

ListAllDevices retrieves all devices by automatically handling pagination.

func (*Client) ListApps

func (c *Client) ListApps(ctx context.Context) ([]App, error)

ListApps returns all SmartApps for the authenticated account.

func (*Client) ListAssignedDrivers added in v1.0.1

func (c *Client) ListAssignedDrivers(ctx context.Context, channelID string) ([]DriverChannelDetails, error)

ListAssignedDrivers returns all drivers assigned to a channel.

func (*Client) ListCapabilities

func (c *Client) ListCapabilities(ctx context.Context) ([]CapabilityReference, error)

ListCapabilities returns all available capabilities.

func (*Client) ListCapabilitiesWithOptions added in v1.0.1

func (c *Client) ListCapabilitiesWithOptions(ctx context.Context, opts *ListCapabilitiesOptions) ([]CapabilityReference, error)

ListCapabilitiesWithOptions returns capabilities with filtering options.

func (*Client) ListChannels added in v1.0.1

func (c *Client) ListChannels(ctx context.Context, opts *ChannelListOptions) ([]Channel, error)

ListChannels returns all channels accessible to the user.

func (*Client) ListDefaultDrivers added in v1.0.1

func (c *Client) ListDefaultDrivers(ctx context.Context) ([]EdgeDriver, error)

ListDefaultDrivers returns all SmartThings default drivers.

func (*Client) ListDevicePreferences added in v1.0.1

func (c *Client) ListDevicePreferences(ctx context.Context, namespace string) ([]DevicePreference, error)

ListDevicePreferences returns all device preferences, optionally filtered by namespace.

func (*Client) ListDeviceProfiles

func (c *Client) ListDeviceProfiles(ctx context.Context) ([]DeviceProfileFull, error)

ListDeviceProfiles returns all device profiles for the authenticated account.

func (*Client) ListDevices

func (c *Client) ListDevices(ctx context.Context) ([]Device, error)

ListDevices returns all devices associated with the account. For pagination support, use ListDevicesWithOptions instead.

func (*Client) ListDevicesWithOptions

func (c *Client) ListDevicesWithOptions(ctx context.Context, opts *ListDevicesOptions) (*PagedDevices, error)

ListDevicesWithOptions returns devices with pagination and filtering options.

func (*Client) ListDrivers added in v1.0.1

func (c *Client) ListDrivers(ctx context.Context) ([]EdgeDriverSummary, error)

ListDrivers returns all drivers owned by the user.

func (*Client) ListEnrolledChannels added in v1.0.1

func (c *Client) ListEnrolledChannels(ctx context.Context, hubID string) ([]EnrolledChannel, error)

ListEnrolledChannels returns all driver channels a hub is enrolled in.

func (*Client) ListHubs added in v1.0.5

func (c *Client) ListHubs(ctx context.Context) ([]Hub, error)

ListHubs returns all hubs associated with the account. This works by listing all devices and filtering for those with type "HUB".

func (*Client) ListInstalledAppConfigs added in v1.0.1

func (c *Client) ListInstalledAppConfigs(ctx context.Context, installedAppID string) ([]InstalledAppConfigItem, error)

ListInstalledAppConfigs returns all configurations for an installed app.

func (*Client) ListInstalledApps

func (c *Client) ListInstalledApps(ctx context.Context, locationID string) ([]InstalledApp, error)

ListInstalledApps returns all installed apps for a location. If locationID is empty, returns installed apps for all locations.

func (*Client) ListInstalledDrivers added in v1.0.1

func (c *Client) ListInstalledDrivers(ctx context.Context, hubID string, deviceID string) ([]InstalledDriver, error)

ListInstalledDrivers returns all drivers installed on a hub. If deviceID is provided, only returns drivers associated with that device.

func (*Client) ListInstalledSchemaApps added in v1.0.1

func (c *Client) ListInstalledSchemaApps(ctx context.Context, locationID string) ([]InstalledSchemaApp, error)

ListInstalledSchemaApps returns all installed Schema app instances.

func (*Client) ListLocations

func (c *Client) ListLocations(ctx context.Context) ([]Location, error)

ListLocations returns all locations associated with the account.

func (*Client) ListModes

func (c *Client) ListModes(ctx context.Context, locationID string) ([]Mode, error)

ListModes returns all modes for a location.

func (*Client) ListOrganizations added in v1.0.1

func (c *Client) ListOrganizations(ctx context.Context) ([]Organization, error)

ListOrganizations returns all organizations for the user.

func (*Client) ListPreferenceTranslations added in v1.0.1

func (c *Client) ListPreferenceTranslations(ctx context.Context, preferenceID string) ([]LocaleReference, error)

ListPreferenceTranslations returns all available locales for a preference.

func (*Client) ListRooms

func (c *Client) ListRooms(ctx context.Context, locationID string) ([]Room, error)

ListRooms returns all rooms in a location.

func (*Client) ListRules

func (c *Client) ListRules(ctx context.Context, locationID string) ([]Rule, error)

ListRules returns all rules for a location.

func (*Client) ListScenes

func (c *Client) ListScenes(ctx context.Context, locationID string) ([]Scene, error)

ListScenes returns all scenes for a location. If locationID is empty, returns scenes for all locations.

Example
package main

import (
	"context"
	"fmt"
	"log"

	st "github.com/tj-smith47/smartthings-go"
)

func main() {
	client, _ := st.NewClient("your-api-token")
	ctx := context.Background()

	scenes, err := client.ListScenes(ctx, "location-id")
	if err != nil {
		log.Fatal(err)
	}

	for _, scene := range scenes {
		fmt.Printf("Scene: %s\n", scene.SceneName)
	}
}

func (*Client) ListSchedules

func (c *Client) ListSchedules(ctx context.Context, installedAppID string) ([]Schedule, error)

ListSchedules returns all schedules for an installed app.

func (*Client) ListSchemaAppInvitations added in v1.0.1

func (c *Client) ListSchemaAppInvitations(ctx context.Context, schemaAppID string) ([]SchemaAppInvitation, error)

ListSchemaAppInvitations returns all invitations for a Schema app.

func (*Client) ListSchemaApps added in v1.0.1

func (c *Client) ListSchemaApps(ctx context.Context, includeAllOrganizations bool) ([]SchemaApp, error)

ListSchemaApps returns all ST Schema connectors for the user.

func (*Client) ListSubscriptions

func (c *Client) ListSubscriptions(ctx context.Context, installedAppID string) ([]Subscription, error)

ListSubscriptions returns all subscriptions for an installed app.

func (*Client) ListVirtualDevices added in v1.0.1

func (c *Client) ListVirtualDevices(ctx context.Context, opts *VirtualDeviceListOptions) ([]Device, error)

ListVirtualDevices returns all virtual devices.

func (*Client) Locations added in v1.0.1

func (c *Client) Locations(ctx context.Context) iter.Seq2[Location, error]

Locations returns an iterator over all locations.

func (*Client) LogDeviceCommand added in v1.0.1

func (c *Client) LogDeviceCommand(ctx context.Context, deviceID string, capability, command string, err error)

LogDeviceCommand logs a device command execution.

func (*Client) LogRateLimit added in v1.0.1

func (c *Client) LogRateLimit(ctx context.Context, info RateLimitInfo)

LogRateLimit logs rate limit information at info level. Useful for monitoring API usage.

func (*Client) LogRequest added in v1.0.1

func (c *Client) LogRequest(ctx context.Context, method, path string)

LogRequest logs an API request. This is the low-level logging method used internally and can be used for custom request logging.

func (*Client) LogResponse added in v1.0.1

func (c *Client) LogResponse(ctx context.Context, method, path string, statusCode int, duration time.Duration, err error)

LogResponse logs an API response. This is the low-level logging method used internally and can be used for custom response logging.

func (*Client) Modes added in v1.0.1

func (c *Client) Modes(ctx context.Context, locationID string) iter.Seq2[Mode, error]

Modes returns an iterator over all modes for a location.

func (*Client) Organizations added in v1.0.1

func (c *Client) Organizations(ctx context.Context) iter.Seq2[Organization, error]

Organizations returns an iterator over all organizations.

func (*Client) RateLimitInfo

func (c *Client) RateLimitInfo() *RateLimitInfo

RateLimitInfo returns the most recent rate limit information from API responses. Returns nil if no rate limit headers have been received yet.

func (*Client) RateLimitResetTime added in v1.0.1

func (c *Client) RateLimitResetTime() time.Time

RateLimitResetTime returns the time when the rate limit window resets. Returns zero time if no rate limit info is available.

func (*Client) RegenerateSchemaAppOAuth added in v1.0.1

func (c *Client) RegenerateSchemaAppOAuth(ctx context.Context, appID string) (*SchemaCreateResponse, error)

RegenerateSchemaAppOAuth regenerates OAuth client credentials for a Schema app.

func (*Client) RemainingRequests added in v1.0.1

func (c *Client) RemainingRequests() int

RemainingRequests returns the number of remaining requests in the current rate limit window. Returns -1 if no rate limit info is available.

func (*Client) RevokeSchemaAppInvitation added in v1.0.1

func (c *Client) RevokeSchemaAppInvitation(ctx context.Context, invitationID string) error

RevokeSchemaAppInvitation revokes an invitation.

func (*Client) Rooms added in v1.0.1

func (c *Client) Rooms(ctx context.Context, locationID string) iter.Seq2[Room, error]

Rooms returns an iterator over all rooms in a location.

func (*Client) Rules added in v1.0.1

func (c *Client) Rules(ctx context.Context, locationID string) iter.Seq2[Rule, error]

Rules returns an iterator over all rules for a location.

func (*Client) Scenes added in v1.0.1

func (c *Client) Scenes(ctx context.Context, locationID string) iter.Seq2[Scene, error]

Scenes returns an iterator over all scenes for a location.

func (*Client) Schedules added in v1.0.1

func (c *Client) Schedules(ctx context.Context, installedAppID string) iter.Seq2[Schedule, error]

Schedules returns an iterator over all schedules for an installed app.

func (*Client) SchemaAppInvitations added in v1.0.1

func (c *Client) SchemaAppInvitations(ctx context.Context, schemaAppID string) iter.Seq2[SchemaAppInvitation, error]

SchemaAppInvitations returns an iterator over all invitations for a schema app.

func (*Client) SchemaApps added in v1.0.1

func (c *Client) SchemaApps(ctx context.Context, includeAllOrganizations bool) iter.Seq2[SchemaApp, error]

SchemaApps returns an iterator over all ST Schema apps.

func (*Client) SendTVKey

func (c *Client) SendTVKey(ctx context.Context, deviceID, key string) error

SendTVKey sends a remote control key press to the TV. Common keys: UP, DOWN, LEFT, RIGHT, ENTER, BACK, HOME, MENU, EXIT

func (*Client) SetCurrentMode

func (c *Client) SetCurrentMode(ctx context.Context, locationID, modeID string) (*Mode, error)

SetCurrentMode changes the active mode for a location.

func (*Client) SetPictureMode

func (c *Client) SetPictureMode(ctx context.Context, deviceID, mode string) error

SetPictureMode sets the TV picture mode.

func (*Client) SetSoundMode

func (c *Client) SetSoundMode(ctx context.Context, deviceID, mode string) error

SetSoundMode sets the TV sound mode.

func (*Client) SetTVChannel

func (c *Client) SetTVChannel(ctx context.Context, deviceID string, channel int) error

SetTVChannel sets the TV channel directly.

func (*Client) SetTVInput

func (c *Client) SetTVInput(ctx context.Context, deviceID, inputID string) error

SetTVInput sets the TV input source.

func (*Client) SetTVMute

func (c *Client) SetTVMute(ctx context.Context, deviceID string, muted bool) error

SetTVMute sets the TV mute state.

func (*Client) SetTVPower

func (c *Client) SetTVPower(ctx context.Context, deviceID string, on bool) error

SetTVPower turns the TV on or off.

func (*Client) SetTVVolume

func (c *Client) SetTVVolume(ctx context.Context, deviceID string, volume int) error

SetTVVolume sets the TV volume (0-100).

func (*Client) SetToken

func (c *Client) SetToken(token string)

SetToken updates the client's bearer token. This is useful for OAuth clients that need to refresh tokens.

func (*Client) ShouldThrottle added in v1.0.1

func (c *Client) ShouldThrottle(threshold int) bool

ShouldThrottle returns true if the rate limit remaining is below the given threshold. This enables preemptive throttling before hitting rate limits.

Example:

if client.ShouldThrottle(10) {
    // Remaining requests below threshold, slow down
    time.Sleep(time.Second)
}

func (*Client) Subscriptions added in v1.0.1

func (c *Client) Subscriptions(ctx context.Context, installedAppID string) iter.Seq2[Subscription, error]

Subscriptions returns an iterator over all subscriptions for an installed app.

func (*Client) SwitchDriver added in v1.0.1

func (c *Client) SwitchDriver(ctx context.Context, driverID, hubID, deviceID string, forceUpdate bool) error

SwitchDriver changes the driver for a device on a hub. If forceUpdate is true, forces the driver switch even if versions match.

func (*Client) TVChannelDown

func (c *Client) TVChannelDown(ctx context.Context, deviceID string) error

TVChannelDown decreases the TV channel.

func (*Client) TVChannelUp

func (c *Client) TVChannelUp(ctx context.Context, deviceID string) error

TVChannelUp increases the TV channel.

func (*Client) TVPause

func (c *Client) TVPause(ctx context.Context, deviceID string) error

TVPause sends a pause command to the TV.

func (*Client) TVPlay

func (c *Client) TVPlay(ctx context.Context, deviceID string) error

TVPlay sends a play command to the TV.

func (*Client) TVStop

func (c *Client) TVStop(ctx context.Context, deviceID string) error

TVStop sends a stop command to the TV.

func (*Client) TVVolumeDown

func (c *Client) TVVolumeDown(ctx context.Context, deviceID string) error

TVVolumeDown decreases the TV volume.

func (*Client) TVVolumeUp

func (c *Client) TVVolumeUp(ctx context.Context, deviceID string) error

TVVolumeUp increases the TV volume.

func (*Client) Token

func (c *Client) Token() string

Token returns the current bearer token.

func (*Client) UnassignDriver added in v1.0.1

func (c *Client) UnassignDriver(ctx context.Context, channelID, driverID string) error

UnassignDriver removes a driver from a channel.

func (*Client) UnenrollHub added in v1.0.1

func (c *Client) UnenrollHub(ctx context.Context, channelID, hubID string) error

UnenrollHub removes a hub from a channel.

func (*Client) UninstallDriver added in v1.0.1

func (c *Client) UninstallDriver(ctx context.Context, driverID, hubID string) error

UninstallDriver removes a driver from a hub.

func (*Client) UpdateApp

func (c *Client) UpdateApp(ctx context.Context, appID string, update *AppUpdate) (*App, error)

UpdateApp updates an existing SmartApp.

func (*Client) UpdateAppOAuth

func (c *Client) UpdateAppOAuth(ctx context.Context, appID string, oauth *AppOAuth) (*AppOAuth, error)

UpdateAppOAuth updates the OAuth settings for a SmartApp.

func (*Client) UpdateChannel added in v1.0.1

func (c *Client) UpdateChannel(ctx context.Context, channelID string, update *ChannelUpdate) (*Channel, error)

UpdateChannel updates an existing channel.

func (*Client) UpdateDevice

func (c *Client) UpdateDevice(ctx context.Context, deviceID string, update *DeviceUpdate) (*Device, error)

UpdateDevice updates a device (currently only the label can be updated).

func (*Client) UpdateDevicePreference added in v1.0.1

func (c *Client) UpdateDevicePreference(ctx context.Context, preferenceID string, pref *DevicePreference) (*DevicePreference, error)

UpdateDevicePreference updates an existing device preference.

func (*Client) UpdateDeviceProfile

func (c *Client) UpdateDeviceProfile(ctx context.Context, profileID string, update *DeviceProfileUpdate) (*DeviceProfileFull, error)

UpdateDeviceProfile updates an existing device profile.

func (*Client) UpdateLocation

func (c *Client) UpdateLocation(ctx context.Context, locationID string, update *LocationUpdate) (*Location, error)

UpdateLocation updates an existing location.

func (*Client) UpdatePreferenceTranslations added in v1.0.1

func (c *Client) UpdatePreferenceTranslations(ctx context.Context, preferenceID string, localization *PreferenceLocalization) (*PreferenceLocalization, error)

UpdatePreferenceTranslations updates translations for a device preference.

func (*Client) UpdateRoom

func (c *Client) UpdateRoom(ctx context.Context, locationID, roomID string, update *RoomUpdate) (*Room, error)

UpdateRoom updates an existing room.

func (*Client) UpdateRule

func (c *Client) UpdateRule(ctx context.Context, ruleID string, rule *RuleUpdate) (*Rule, error)

UpdateRule updates an existing rule.

func (*Client) UpdateSchemaApp added in v1.0.1

func (c *Client) UpdateSchemaApp(ctx context.Context, appID string, req *SchemaAppRequest, organizationID string) error

UpdateSchemaApp updates an existing ST Schema connector.

func (*Client) UpdateServiceSubscription added in v1.0.1

func (c *Client) UpdateServiceSubscription(ctx context.Context, subscriptionID string, req *ServiceSubscriptionRequest, installedAppID, locationID string) (*ServiceNewSubscription, error)

UpdateServiceSubscription updates an existing service subscription.

func (*Client) UploadDriver added in v1.0.1

func (c *Client) UploadDriver(ctx context.Context, archiveData []byte) (*EdgeDriver, error)

UploadDriver uploads a new driver package. The archiveData should be a ZIP archive containing the driver source code.

func (*Client) WaitForRateLimit added in v1.0.1

func (c *Client) WaitForRateLimit(ctx context.Context) error

WaitForRateLimit blocks until the rate limit window resets. It returns immediately if no rate limit info is available or if the reset time has passed. The context can be used to cancel the wait.

Example:

for {
    err := client.ExecuteCommand(ctx, deviceID, cmd)
    if errors.Is(err, ErrRateLimited) {
        if err := client.WaitForRateLimit(ctx); err != nil {
            return err // Context canceled
        }
        continue // Retry
    }
    break
}

func (*Client) WaitForRateLimitErr added in v1.0.1

func (c *Client) WaitForRateLimitErr(ctx context.Context, err error) error

WaitForRateLimitErr waits based on a RateLimitError's RetryAfter duration. If the error is not a RateLimitError, it returns immediately.

Example:

err := client.ExecuteCommand(ctx, deviceID, cmd)
if err != nil {
    if waitErr := client.WaitForRateLimitErr(ctx, err); waitErr != nil {
        return waitErr // Context canceled
    }
    // Retry the command
}

type Command

type Command struct {
	Component  string `json:"component,omitempty"`
	Capability string `json:"capability"`
	Command    string `json:"command"`
	Arguments  []any  `json:"arguments,omitempty"`
}

Command represents a SmartThings command to execute on a device.

func NewChildLockCommand added in v1.0.5

func NewChildLockCommand(enabled bool) Command

NewChildLockCommand creates a child lock on/off command. Works with Samsung CE appliances that support samsungce.kidsLock.

Example:

cmd := NewChildLockCommand(true) // Enable child lock

func NewCommand

func NewCommand(capability, command string, args ...any) Command

NewCommand creates a command with the given capability and command name.

func NewComponentCommand

func NewComponentCommand(component, capability, command string, args ...any) Command

NewComponentCommand creates a command for a specific component.

func NewCycleCommand added in v1.0.5

func NewCycleCommand(capability, cycle string) Command

NewCycleCommand creates a cycle selection command for laundry appliances. The capability should be "samsungce.washerCycle", "samsungce.dryerCycle", etc.

Example:

cmd := NewCycleCommand("samsungce.washerCycle", "normal")

func NewLampCommand added in v1.0.5

func NewLampCommand(on bool) Command

NewLampCommand creates a lamp/light on/off command for appliances. Works with oven lights, refrigerator lights, etc.

Example:

cmd := NewLampCommand(true) // Turn on oven light

func NewLevelCommand added in v1.0.5

func NewLevelCommand(capability, command, value string) Command

NewLevelCommand creates a level/value selection command. Works with spin level, soil level, water temperature, etc.

Example:

cmd := NewLevelCommand("custom.washerSpinLevel", "setWasherSpinLevel", "high")

func NewModeCommand added in v1.0.5

func NewModeCommand(capability, command, mode string) Command

NewModeCommand creates a mode selection command. Works with oven modes, AC modes, wash modes, etc.

Example:

cmd := NewModeCommand("ovenMode", "setOvenMode", "Bake")

func NewOperationCommand added in v1.0.5

func NewOperationCommand(capability, operation string) Command

NewOperationCommand creates a start/pause/stop operation command. The capability should be "samsungce.washerOperatingState", "samsungce.dryerOperatingState", "samsungce.dishwasherOperation", etc.

Example:

cmd := NewOperationCommand("samsungce.washerOperatingState", "start")
cmd := NewOperationCommand("samsungce.washerOperatingState", "pause")
cmd := NewOperationCommand("samsungce.washerOperatingState", "stop")

func NewPowerCommand added in v1.0.5

func NewPowerCommand(on bool) Command

NewPowerCommand creates a switch on/off command.

Example:

cmd := NewPowerCommand(true) // Turn on
client.ExecuteCommand(ctx, deviceID, cmd)

func NewRefreshCommand added in v1.0.5

func NewRefreshCommand() Command

NewRefreshCommand creates a refresh command to force device status update.

Example:

cmd := NewRefreshCommand()

func NewTemperatureCommand added in v1.0.5

func NewTemperatureCommand(capability, command string, temp int) Command

NewTemperatureCommand creates a temperature setpoint command. Useful for ovens, thermostats, and temperature-controlled appliances.

Example:

cmd := NewTemperatureCommand("ovenSetpoint", "setOvenSetpoint", 350)

func NewToggleCommand added in v1.0.5

func NewToggleCommand(capability, command string, enabled bool) Command

NewToggleCommand creates a generic toggle command with enabled/disabled state. Works with features like power cool, power freeze, vacation mode, etc.

Example:

cmd := NewToggleCommand("samsungce.powerCool", "setPowerCool", true)

type CommandRequest

type CommandRequest struct {
	Commands []Command `json:"commands"`
}

CommandRequest is the request body for executing commands.

type Component

type Component struct {
	ID           string           `json:"id"`
	Label        string           `json:"label,omitempty"`
	Capabilities []CapabilityRef  `json:"capabilities,omitempty"`
	Categories   []DeviceCategory `json:"categories,omitempty"`
	Icon         string           `json:"icon,omitempty"`
}

Component represents a device component (e.g., "main", "cooler", "freezer").

type ConfigEntry

type ConfigEntry struct {
	ValueType        ConfigValueType   `json:"valueType"`
	StringConfig     *StringConfig     `json:"stringConfig,omitempty"`
	DeviceConfig     *DeviceConfig     `json:"deviceConfig,omitempty"`
	PermissionConfig *PermissionConfig `json:"permissionConfig,omitempty"`
	ModeConfig       *ModeConfig       `json:"modeConfig,omitempty"`
	SceneConfig      *SceneConfig      `json:"sceneConfig,omitempty"`
	MessageConfig    *MessageConfig    `json:"messageConfig,omitempty"`
}

ConfigEntry represents a single configuration entry in an installed app.

type ConfigMap

type ConfigMap map[string][]ConfigEntry

ConfigMap represents SmartApp configuration values. ConfigEntry is defined in installedapps.go with full support for all config types.

type ConfigValueType added in v1.0.1

type ConfigValueType string

ConfigValueType represents the type of configuration value.

const (
	ConfigValueTypeString     ConfigValueType = "STRING"
	ConfigValueTypeDevice     ConfigValueType = "DEVICE"
	ConfigValueTypePermission ConfigValueType = "PERMISSION"
	ConfigValueTypeMode       ConfigValueType = "MODE"
	ConfigValueTypeScene      ConfigValueType = "SCENE"
	ConfigValueTypeMessage    ConfigValueType = "MESSAGE"
)

Configuration value type constants.

type ConfigurationData

type ConfigurationData struct {
	InstalledAppID string    `json:"installedAppId"`
	Phase          string    `json:"phase"` // INITIALIZE, PAGE
	PageID         string    `json:"pageId,omitempty"`
	PreviousPageID string    `json:"previousPageId,omitempty"`
	Config         ConfigMap `json:"config,omitempty"`
}

ConfigurationData contains data for CONFIGURATION lifecycle events.

type ConfirmationData

type ConfirmationData struct {
	AppID           string `json:"appId"`
	ConfirmationURL string `json:"confirmationUrl"`
}

ConfirmationData contains data for CONFIRMATION lifecycle events.

type CronSchedule

type CronSchedule struct {
	Expression string `json:"expression"`
	Timezone   string `json:"timezone,omitempty"`
}

CronSchedule represents a cron-based schedule.

type DailyAirQualityForecast added in v1.0.1

type DailyAirQualityForecast struct {
	ForecastDate    string `json:"forecastDate,omitempty"`
	AirQualityIndex int    `json:"airQualityIndex,omitempty"`
}

DailyAirQualityForecast contains daily air quality forecast.

type DailyForecast added in v1.0.1

type DailyForecast struct {
	ForecastDate        string  `json:"forecastDate,omitempty"`
	ConditionState      string  `json:"conditionState,omitempty"`
	RelativeHumidity    int     `json:"relativeHumidity,omitempty"`
	TemperatureMax      float64 `json:"temperatureMax,omitempty"`
	TemperatureMin      float64 `json:"temperatureMin,omitempty"`
	PrecipitationChance int     `json:"precipitationChance,omitempty"`
	WxPhraseLong        string  `json:"wxPhraseLong,omitempty"`
}

DailyForecast contains daily forecast information.

type DeepLinkType added in v1.0.1

type DeepLinkType string

DeepLinkType represents the type of deep link.

const (
	// DeepLinkDevice links to a device.
	DeepLinkDevice DeepLinkType = "device"
	// DeepLinkInstalledApp links to an installed app.
	DeepLinkInstalledApp DeepLinkType = "installedApp"
	// DeepLinkLocation links to a location.
	DeepLinkLocation DeepLinkType = "location"
)

type Device

type Device struct {
	DeviceID               string           `json:"deviceId"`
	Name                   string           `json:"name"`
	Label                  string           `json:"label"`
	ManufacturerName       string           `json:"manufacturerName,omitempty"`
	PresentationID         string           `json:"presentationId,omitempty"`
	DeviceTypeID           string           `json:"deviceTypeId,omitempty"`
	Type                   DeviceType       `json:"type,omitempty"`
	RoomID                 string           `json:"roomId,omitempty"`
	LocationID             string           `json:"locationId,omitempty"`
	ParentDeviceID         string           `json:"parentDeviceId,omitempty"`
	ChildDevices           []ChildDevice    `json:"childDevices,omitempty"`
	Components             []Component      `json:"components,omitempty"`
	Profile                *DeviceProfile   `json:"profile,omitempty"`
	App                    *DeviceApp       `json:"app,omitempty"`
	OCF                    *OCFDeviceInfo   `json:"ocf,omitempty"`
	Viper                  *ViperDeviceInfo `json:"viper,omitempty"`
	Hub                    *HubDeviceInfo   `json:"hub,omitempty"`
	DeviceManufacturerCode string           `json:"deviceManufacturerCode,omitempty"`
	CreateTime             string           `json:"createTime,omitempty"`
	RestrictionTier        int              `json:"restrictionTier,omitempty"`
	Allowed                []string         `json:"allowed,omitempty"`
}

Device represents a SmartThings device with all available API fields.

func FilterByManufacturer

func FilterByManufacturer(devices []Device, manufacturer string) []Device

FilterByManufacturer returns devices from a specific manufacturer.

func FilterDevices

func FilterDevices(devices []Device, filter func(Device) bool) []Device

FilterDevices returns devices matching the given filter function.

func FindDeviceByID

func FindDeviceByID(devices []Device, deviceID string) *Device

FindDeviceByID returns the device with the given ID. Returns a pointer to the device in the slice, or nil if not found.

func FindDeviceByLabel

func FindDeviceByLabel(devices []Device, label string) *Device

FindDeviceByLabel returns the first device matching the given label. Returns a pointer to the device in the slice, or nil if not found.

type DeviceApp

type DeviceApp struct {
	InstalledAppID string         `json:"installedAppId"`
	ExternalID     string         `json:"externalId,omitempty"`
	Profile        *DeviceProfile `json:"profile,omitempty"`
}

DeviceApp references the installed app for the device.

type DeviceCategory

type DeviceCategory struct {
	Name         string `json:"name"`
	CategoryType string `json:"categoryType,omitempty"`
}

DeviceCategory describes a device's category.

type DeviceConfig added in v1.0.1

type DeviceConfig struct {
	DeviceID    string   `json:"deviceId"`
	ComponentID string   `json:"componentId,omitempty"`
	Permissions []string `json:"permissions,omitempty"`
}

DeviceConfig represents a device configuration value.

type DeviceEvent

type DeviceEvent struct {
	DeviceID    string    `json:"deviceId"`
	ComponentID string    `json:"componentId"`
	Capability  string    `json:"capability"`
	Attribute   string    `json:"attribute"`
	Value       any       `json:"value"`
	Unit        string    `json:"unit,omitempty"`
	StateChange bool      `json:"stateChange,omitempty"`
	Timestamp   time.Time `json:"time"`
}

DeviceEvent represents a single event from a device's history.

type DeviceEventData

type DeviceEventData struct {
	EventType   string             `json:"eventType"` // DEVICE_EVENT, TIMER_EVENT, etc.
	DeviceEvent *DeviceEventDetail `json:"deviceEvent,omitempty"`
	TimerEvent  *TimerEventDetail  `json:"timerEvent,omitempty"`
}

DeviceEventData represents an event from a device.

type DeviceEventDetail

type DeviceEventDetail struct {
	EventID          string `json:"eventId"`
	LocationID       string `json:"locationId"`
	DeviceID         string `json:"deviceId"`
	ComponentID      string `json:"componentId"`
	Capability       string `json:"capability"`
	Attribute        string `json:"attribute"`
	Value            any    `json:"value"`
	StateChange      bool   `json:"stateChange,omitempty"`
	SubscriptionName string `json:"subscriptionName,omitempty"`
}

DeviceEventDetail contains details of a device event.

type DeviceHealth

type DeviceHealth struct {
	DeviceID        string `json:"deviceId"`
	State           string `json:"state"` // ONLINE, OFFLINE, UNKNOWN
	LastUpdatedDate string `json:"lastUpdatedDate,omitempty"`
}

DeviceHealth represents the health status of a device.

type DeviceHealthSubscription

type DeviceHealthSubscription struct {
	DeviceIDs  []string `json:"deviceIds,omitempty"`
	LocationID string   `json:"locationId,omitempty"`
}

DeviceHealthSubscription specifies device health subscription.

type DeviceIntegrationProfileKey added in v1.0.1

type DeviceIntegrationProfileKey struct {
	ID           string `json:"id"`
	MajorVersion int    `json:"majorVersion,omitempty"`
}

DeviceIntegrationProfileKey represents a device integration profile reference.

type DeviceLifecycleSubscription

type DeviceLifecycleSubscription struct {
	DeviceIDs  []string `json:"deviceIds,omitempty"`
	LocationID string   `json:"locationId,omitempty"`
	Lifecycle  string   `json:"lifecycle,omitempty"` // CREATE, DELETE, UPDATE, etc.
}

DeviceLifecycleSubscription specifies device lifecycle subscription.

type DeviceListResponse

type DeviceListResponse struct {
	Items []Device `json:"items"`
}

DeviceListResponse is the response from the list devices API. Deprecated: Use PagedDevices instead for pagination support.

type DevicePreference added in v1.0.1

type DevicePreference struct {
	PreferenceID   string         `json:"preferenceId"`
	Name           string         `json:"name"`
	Title          string         `json:"title,omitempty"`
	Description    string         `json:"description,omitempty"`
	Required       bool           `json:"required,omitempty"`
	PreferenceType PreferenceType `json:"preferenceType"`

	// Type-specific fields
	// Integer
	MinimumInt *int `json:"minimum,omitempty"`
	MaximumInt *int `json:"maximum,omitempty"`
	DefaultInt *int `json:"default,omitempty"`

	// Number (stored in separate fields to avoid JSON conflicts)
	MinimumNum *float64 `json:"-"`
	MaximumNum *float64 `json:"-"`
	DefaultNum *float64 `json:"-"`

	// Boolean
	DefaultBool *bool `json:"-"`

	// String
	MinLength  *int       `json:"minLength,omitempty"`
	MaxLength  *int       `json:"maxLength,omitempty"`
	StringType StringType `json:"stringType,omitempty"`
	DefaultStr *string    `json:"-"`

	// Enumeration
	Options     map[string]string `json:"options,omitempty"`
	DefaultEnum *string           `json:"-"`
}

DevicePreference represents a device preference definition.

type DevicePreferenceCreate added in v1.0.1

type DevicePreferenceCreate struct {
	Name           string         `json:"name"`
	Title          string         `json:"title,omitempty"`
	Description    string         `json:"description,omitempty"`
	Required       bool           `json:"required,omitempty"`
	PreferenceType PreferenceType `json:"preferenceType"`

	// Integer/Number type fields (use int for integer, float64 for number)
	Minimum any `json:"minimum,omitempty"`
	Maximum any `json:"maximum,omitempty"`

	// String type fields
	MinLength  *int       `json:"minLength,omitempty"`
	MaxLength  *int       `json:"maxLength,omitempty"`
	StringType StringType `json:"stringType,omitempty"`

	// Enumeration type fields
	Options map[string]string `json:"options,omitempty"`

	// Default value (type depends on PreferenceType)
	Default any `json:"default,omitempty"`
}

DevicePreferenceCreate is the request for creating a device preference.

type DeviceProfile

type DeviceProfile struct {
	ID string `json:"id"`
}

DeviceProfile references a device profile.

type DeviceProfileCreate

type DeviceProfileCreate struct {
	Name        string              `json:"name"`
	Components  []ProfileComponent  `json:"components"`
	Metadata    map[string]string   `json:"metadata,omitempty"`
	Preferences []ProfilePreference `json:"preferences,omitempty"`
}

DeviceProfileCreate is the request body for creating a device profile.

type DeviceProfileFull

type DeviceProfileFull struct {
	ID          string              `json:"id"`
	Name        string              `json:"name"`
	Components  []ProfileComponent  `json:"components"`
	Metadata    map[string]string   `json:"metadata,omitempty"`
	Status      DeviceProfileStatus `json:"status,omitempty"`
	Preferences []ProfilePreference `json:"preferences,omitempty"`
	Owner       *ProfileOwner       `json:"owner,omitempty"`
}

DeviceProfileFull represents a complete device profile definition.

type DeviceProfileStatus

type DeviceProfileStatus string

DeviceProfileStatus represents the status of a device profile.

const (
	ProfileStatusDevelopment DeviceProfileStatus = "DEVELOPMENT"
	ProfileStatusPublished   DeviceProfileStatus = "PUBLISHED"
)

Device profile status constants.

type DeviceProfileUpdate

type DeviceProfileUpdate struct {
	Components  []ProfileComponent  `json:"components,omitempty"`
	Metadata    map[string]string   `json:"metadata,omitempty"`
	Preferences []ProfilePreference `json:"preferences,omitempty"`
}

DeviceProfileUpdate is the request body for updating a device profile.

type DeviceState

type DeviceState struct {
	ComponentID string    `json:"componentId"`
	Capability  string    `json:"capability"`
	Attribute   string    `json:"attribute"`
	Value       any       `json:"value"`
	Unit        string    `json:"unit,omitempty"`
	Timestamp   time.Time `json:"timestamp"`
}

DeviceState represents a historical state snapshot.

type DeviceSubscription

type DeviceSubscription struct {
	DeviceID        string      `json:"deviceId"`
	ComponentID     string      `json:"componentId,omitempty"`
	Capability      string      `json:"capability,omitempty"`
	Attribute       string      `json:"attribute,omitempty"`
	StateChangeOnly bool        `json:"stateChangeOnly,omitempty"`
	Value           interface{} `json:"value,omitempty"`
	Modes           []string    `json:"modes,omitempty"`
}

DeviceSubscription specifies a device-level subscription.

type DeviceType

type DeviceType string

DeviceType represents the type of device integration.

const (
	DeviceTypeDTH         DeviceType = "DTH"
	DeviceTypeEndpointApp DeviceType = "ENDPOINT_APP"
	DeviceTypeHUB         DeviceType = "HUB"
	DeviceTypeViper       DeviceType = "VIPER"
	DeviceTypeBLE         DeviceType = "BLE"
	DeviceTypeBLED2D      DeviceType = "BLE_D2D"
	DeviceTypeMobile      DeviceType = "MOBILE"
	DeviceTypeOCF         DeviceType = "OCF"
	DeviceTypeLAN         DeviceType = "LAN"
	DeviceTypeVideo       DeviceType = "VIDEO"
)

Device type constants.

type DeviceUpdate

type DeviceUpdate struct {
	Label string `json:"label,omitempty"`
}

DeviceUpdate is the request body for updating a device.

type DiscoveredHub added in v1.0.1

type DiscoveredHub struct {
	// IP is the hub's local IP address.
	IP string

	// Port is the hub's local API port (typically 39500).
	Port int

	// Location is the SSDP location URL for the hub description.
	Location string

	// Server is the server header from the SSDP response.
	Server string

	// USN is the unique service name.
	USN string

	// ST is the search target that matched.
	ST string
}

DiscoveredHub represents a SmartThings Hub found via SSDP discovery.

type DiscoveredTV added in v1.0.1

type DiscoveredTV struct {
	// IP is the TV's local IP address.
	IP string

	// Port is the TV's control port.
	Port int

	// Name is the friendly name of the TV.
	Name string

	// Model is the TV model name.
	Model string

	// UUID is the unique device identifier.
	UUID string
}

DiscoveredTV represents a Samsung TV found via mDNS or SSDP discovery.

type Discovery added in v1.0.1

type Discovery struct {
	// Timeout is the maximum time to wait for discovery responses.
	// Defaults to 3 seconds if zero.
	Timeout time.Duration
}

Discovery provides local network device discovery functionality.

func NewDiscovery added in v1.0.1

func NewDiscovery(timeout time.Duration) *Discovery

NewDiscovery creates a new Discovery instance.

func (*Discovery) DiscoverAll added in v1.0.1

func (d *Discovery) DiscoverAll(ctx context.Context) ([]DiscoveredHub, []DiscoveredTV, error)

DiscoverAll performs discovery for all supported device types. Returns hubs and TVs found on the local network.

func (*Discovery) FindHubs added in v1.0.1

func (d *Discovery) FindHubs(ctx context.Context) ([]DiscoveredHub, error)

FindHubs discovers SmartThings Hubs on the local network using SSDP. Returns all hubs that respond within the timeout period.

Example
package main

import (
	"context"
	"fmt"
	"log"
	"time"

	st "github.com/tj-smith47/smartthings-go"
)

func main() {
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	discovery := st.NewDiscovery(3 * time.Second)
	hubs, err := discovery.FindHubs(ctx)
	if err != nil {
		log.Fatal(err)
	}

	for _, hub := range hubs {
		fmt.Printf("Hub found at %s\n", hub.IP)
	}
}

func (*Discovery) FindTVs added in v1.0.1

func (d *Discovery) FindTVs(ctx context.Context) ([]DiscoveredTV, error)

FindTVs discovers Samsung TVs on the local network using SSDP. Samsung TVs respond to SSDP with urn:samsung.com:device:RemoteControlReceiver:1.

Example
package main

import (
	"context"
	"fmt"
	"log"
	"time"

	st "github.com/tj-smith47/smartthings-go"
)

func main() {
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	discovery := st.NewDiscovery(3 * time.Second)
	tvs, err := discovery.FindTVs(ctx)
	if err != nil {
		log.Fatal(err)
	}

	for _, tv := range tvs {
		fmt.Printf("TV found at %s: %s\n", tv.IP, tv.Name)
	}
}

type DishwasherDetailedStatus added in v1.0.5

type DishwasherDetailedStatus struct {
	// Operating state
	State          string  `json:"state"`                     // "idle", "running", "paused", etc.
	RemainingMins  *int    `json:"remaining_mins,omitempty"`  // Minutes remaining
	CompletionTime *string `json:"completion_time,omitempty"` // ISO8601 completion time
	CycleProgress  *int    `json:"cycle_progress,omitempty"`  // 0-100%

	// CRITICAL: Remote control status
	RemoteControlEnabled bool `json:"remote_control_enabled"`

	// Current settings
	CurrentCourse string `json:"current_course,omitempty"` // Wash course/cycle

	// Child lock
	ChildLockOn bool `json:"child_lock_on"`

	// Supported options
	SupportedCourses []string `json:"supported_courses,omitempty"`
}

DishwasherDetailedStatus provides comprehensive dishwasher status. Use ExtractDishwasherDetailedStatus to extract from a device status response.

func ExtractDishwasherDetailedStatus added in v1.0.5

func ExtractDishwasherDetailedStatus(status Status) *DishwasherDetailedStatus

ExtractDishwasherDetailedStatus extracts comprehensive dishwasher status. Dishwashers have simpler controls than washers/dryers.

Example:

status, _ := client.GetDeviceStatus(ctx, dishwasherID)
dishwasher := st.ExtractDishwasherDetailedStatus(status)

type DriverChannelDetails added in v1.0.1

type DriverChannelDetails struct {
	ChannelID        string `json:"channelId"`
	DriverID         string `json:"driverId"`
	Version          string `json:"version"`
	CreatedDate      string `json:"createdDate,omitempty"`
	LastModifiedDate string `json:"lastModifiedDate,omitempty"`
}

DriverChannelDetails represents a driver assigned to a channel.

type DryerDetailedStatus added in v1.0.5

type DryerDetailedStatus struct {
	// Operating state
	State          string  `json:"state"`                     // "idle", "running", "paused", etc.
	RemainingMins  *int    `json:"remaining_mins,omitempty"`  // Minutes remaining
	CompletionTime *string `json:"completion_time,omitempty"` // ISO8601 completion time
	CycleProgress  *int    `json:"cycle_progress,omitempty"`  // 0-100%

	// CRITICAL: Remote control status
	RemoteControlEnabled bool `json:"remote_control_enabled"`

	// Current settings
	CurrentCycle      string `json:"current_cycle,omitempty"`
	DryingTemperature string `json:"drying_temperature,omitempty"`
	DryingTime        string `json:"drying_time,omitempty"`
	DryingLevel       string `json:"drying_level,omitempty"` // wrinkleFree, normal, etc.

	// Child lock
	ChildLockOn bool `json:"child_lock_on"`

	// Supported options
	SupportedCycles       []string `json:"supported_cycles,omitempty"`
	SupportedTemperatures []string `json:"supported_temperatures,omitempty"`
	SupportedDryingLevels []string `json:"supported_drying_levels,omitempty"`
}

DryerDetailedStatus provides comprehensive dryer status including remote control state. Use ExtractDryerDetailedStatus to extract from a device status response.

func ExtractDryerDetailedStatus added in v1.0.5

func ExtractDryerDetailedStatus(status Status) *DryerDetailedStatus

ExtractDryerDetailedStatus extracts comprehensive dryer status. Similar to washer but with dryer-specific fields (temperature, drying level).

Example:

status, _ := client.GetDeviceStatus(ctx, dryerID)
dryer := st.ExtractDryerDetailedStatus(status)
if dryer.State == "running" {
    fmt.Printf("Drying: %d mins remaining\n", *dryer.RemainingMins)
}

type EdgeCommandClass added in v1.0.1

type EdgeCommandClass struct {
	Controlled []string `json:"controlled,omitempty"`
	Supported  []string `json:"supported,omitempty"`
	Either     []string `json:"either,omitempty"`
}

EdgeCommandClass represents Z-Wave command class requirements.

type EdgeDriver added in v1.0.1

type EdgeDriver struct {
	DriverID                  string                        `json:"driverId"`
	Name                      string                        `json:"name"`
	Description               string                        `json:"description,omitempty"`
	Version                   string                        `json:"version"`
	PackageKey                string                        `json:"packageKey,omitempty"`
	Permissions               map[string]any                `json:"permissions,omitempty"`
	Fingerprints              []EdgeDriverFingerprint       `json:"fingerprints,omitempty"`
	DeviceIntegrationProfiles []DeviceIntegrationProfileKey `json:"deviceIntegrationProfiles,omitempty"`
}

EdgeDriver represents a SmartThings Edge driver.

type EdgeDriverFingerprint added in v1.0.1

type EdgeDriverFingerprint struct {
	DeviceLabel        string                             `json:"deviceLabel,omitempty"`
	ZigbeeManufacturer *EdgeZigbeeManufacturerFingerprint `json:"zigbeeManufacturer,omitempty"`
	ZigbeeGeneric      *EdgeZigbeeGenericFingerprint      `json:"zigbeeGeneric,omitempty"`
	ZWaveManufacturer  *EdgeZWaveManufacturerFingerprint  `json:"zwaveManufacturer,omitempty"`
	ZWaveGeneric       *EdgeZWaveGenericFingerprint       `json:"zwaveGeneric,omitempty"`
}

EdgeDriverFingerprint defines device identification rules for driver matching.

type EdgeDriverSummary added in v1.0.1

type EdgeDriverSummary struct {
	DriverID                  string                        `json:"driverId"`
	Name                      string                        `json:"name"`
	Description               string                        `json:"description,omitempty"`
	Version                   string                        `json:"version"`
	Permissions               map[string]any                `json:"permissions,omitempty"`
	DeviceIntegrationProfiles []DeviceIntegrationProfileKey `json:"deviceIntegrationProfiles,omitempty"`
}

EdgeDriverSummary represents summary information for an Edge driver.

type EdgeZWaveGenericFingerprint added in v1.0.1

type EdgeZWaveGenericFingerprint struct {
	GenericType  int               `json:"genericType,omitempty"`
	SpecificType int               `json:"specificType,omitempty"`
	CommandClass *EdgeCommandClass `json:"commandClass,omitempty"`
}

EdgeZWaveGenericFingerprint matches Z-Wave devices by generic/specific type.

type EdgeZWaveManufacturerFingerprint added in v1.0.1

type EdgeZWaveManufacturerFingerprint struct {
	ManufacturerID int `json:"manufacturerId,omitempty"`
	ProductType    int `json:"productType,omitempty"`
	ProductID      int `json:"productId,omitempty"`
}

EdgeZWaveManufacturerFingerprint matches Z-Wave devices by manufacturer info.

type EdgeZigbeeGenericFingerprint added in v1.0.1

type EdgeZigbeeGenericFingerprint struct {
	DeviceIdentifier int `json:"deviceIdentifier,omitempty"`
}

EdgeZigbeeGenericFingerprint matches Zigbee devices by generic device type.

type EdgeZigbeeManufacturerFingerprint added in v1.0.1

type EdgeZigbeeManufacturerFingerprint struct {
	Manufacturer string `json:"manufacturer,omitempty"`
	Model        string `json:"model,omitempty"`
}

EdgeZigbeeManufacturerFingerprint matches Zigbee devices by manufacturer info.

type EnrolledChannel added in v1.0.1

type EnrolledChannel struct {
	ChannelID        string `json:"channelId"`
	Name             string `json:"name"`
	Description      string `json:"description,omitempty"`
	CreatedDate      string `json:"createdDate,omitempty"`
	LastModifiedDate string `json:"lastModifiedDate,omitempty"`
	SubscriptionURL  string `json:"subscriptionUrl,omitempty"`
}

EnrolledChannel represents a driver channel that a hub is enrolled in.

type EventData

type EventData struct {
	AuthToken    string            `json:"authToken"`
	InstalledApp InstalledAppRef   `json:"installedApp"`
	Events       []DeviceEventData `json:"events,omitempty"`
}

EventData contains data for EVENT lifecycle events.

type ExecutionTarget added in v1.0.1

type ExecutionTarget string

ExecutionTarget represents where virtual device commands execute.

const (
	// ExecutionTargetCloud executes commands in the cloud.
	ExecutionTargetCloud ExecutionTarget = "CLOUD"
	// ExecutionTargetLocal executes commands locally on the hub.
	ExecutionTargetLocal ExecutionTarget = "LOCAL"
)

type FileTokenStore

type FileTokenStore struct {
	// contains filtered or unexported fields
}

FileTokenStore stores OAuth tokens in a JSON file

func NewFileTokenStore

func NewFileTokenStore(filepath string) *FileTokenStore

NewFileTokenStore creates a new FileTokenStore

func (*FileTokenStore) Delete

func (f *FileTokenStore) Delete(ctx context.Context) error

Delete removes the token file

func (*FileTokenStore) Exists

func (f *FileTokenStore) Exists() bool

Exists checks if the token file exists

func (*FileTokenStore) LoadTokens

func (f *FileTokenStore) LoadTokens(ctx context.Context) (*TokenResponse, error)

LoadTokens loads the tokens from the file

func (*FileTokenStore) SaveTokens

func (f *FileTokenStore) SaveTokens(ctx context.Context, tokens *TokenResponse) error

SaveTokens saves the tokens to the file

type GenericApplianceStatus added in v1.0.2

type GenericApplianceStatus struct {
	// State is the operating state (e.g., "idle", "running", "paused", "finished").
	State string `json:"state"`

	// RemainingMins is the time remaining in minutes (if applicable).
	RemainingMins *int `json:"remaining_mins,omitempty"`

	// CompletionTime is the ISO8601 completion timestamp (if applicable).
	CompletionTime *string `json:"completion_time,omitempty"`

	// Progress is the cycle progress 0-100% (if applicable).
	Progress *int `json:"progress,omitempty"`

	// Temperature is the current temperature in Fahrenheit (if applicable).
	Temperature *int `json:"temperature,omitempty"`

	// TargetTemp is the target temperature in Fahrenheit (if applicable).
	TargetTemp *int `json:"target_temp,omitempty"`

	// Mode is the current operating mode (e.g., "cooling", "heating", "auto").
	Mode string `json:"mode,omitempty"`

	// PowerConsumption is the current power usage in watts (if available).
	PowerConsumption *float64 `json:"power_consumption,omitempty"`

	// DoorOpen indicates if any door/lid is open (if applicable).
	DoorOpen bool `json:"door_open,omitempty"`

	// Extra contains additional capability-specific data that doesn't fit standard fields.
	Extra map[string]any `json:"extra,omitempty"`

	// DiscoveredCapabilities lists all capability names found on the device.
	DiscoveredCapabilities []string `json:"discovered_capabilities,omitempty"`
}

GenericApplianceStatus provides a unified status structure for ANY Samsung appliance. This works with washers, dryers, dishwashers, microwaves, air conditioners, robot vacuums, air purifiers, ovens, and other Samsung CE devices. Use ExtractGenericApplianceStatus to auto-discover capabilities from any device.

func ExtractGenericApplianceStatus added in v1.0.2

func ExtractGenericApplianceStatus(status Status) *GenericApplianceStatus

ExtractGenericApplianceStatus extracts status from ANY Samsung appliance by auto-discovering capabilities. This works with washers, dryers, dishwashers, microwaves, air conditioners, robot vacuums, air purifiers, ovens, and more.

The function searches for common Samsung CE capability patterns and extracts relevant data into a unified structure. Use DiscoverCapabilities to see what capabilities are available on a specific device.

Example:

status, _ := client.GetDeviceStatus(ctx, deviceID)
appStatus := st.ExtractGenericApplianceStatus(status)
if appStatus.State == "running" {
    fmt.Printf("Appliance running: %d mins remaining\n", *appStatus.RemainingMins)
}

type HistoryOptions

type HistoryOptions struct {
	Before *time.Time // Events before this time (exclusive)
	After  *time.Time // Events after this time (exclusive)
	Max    int        // Max results per page (1-200, default 20)
	Page   int        // Page number (0-based)
}

HistoryOptions configures event/state history queries.

type HourlyForecast added in v1.0.1

type HourlyForecast struct {
	ForecastTime        string  `json:"forecastTime,omitempty"`
	ConditionState      string  `json:"conditionState,omitempty"`
	RelativeHumidity    int     `json:"relativeHumidity,omitempty"`
	Temperature         float64 `json:"temperature,omitempty"`
	PrecipitationChance int     `json:"precipitationChance,omitempty"`
	WxPhraseLong        string  `json:"wxPhraseLong,omitempty"`
}

HourlyForecast contains hourly forecast information.

type Hub added in v1.0.1

type Hub struct {
	HubID           string `json:"hubId"`
	Name            string `json:"name"`
	EUI             string `json:"eui,omitempty"`
	Owner           string `json:"owner,omitempty"`
	SerialNumber    string `json:"serialNumber,omitempty"`
	FirmwareVersion string `json:"firmwareVersion,omitempty"`
}

Hub represents a SmartThings hub device.

type HubCharacteristics added in v1.0.1

type HubCharacteristics map[string]any

HubCharacteristics contains detailed hub characteristics.

type HubData added in v1.0.1

type HubData struct {
	LocalIP                 string `json:"localIP,omitempty"`
	MacAddress              string `json:"macAddress,omitempty"`
	HardwareType            string `json:"hardwareType,omitempty"`
	HubLocalAPIAvailability string `json:"hubLocalApiAvailability,omitempty"`
	ZigbeeEUI               string `json:"zigbeeEui,omitempty"`
	ZigbeeChannel           int    `json:"zigbeeChannel,omitempty"`
	ZigbeeNodeID            string `json:"zigbeeNodeId,omitempty"`
	ZigbeePanID             string `json:"zigbeePanId,omitempty"`
	ZWaveRegion             string `json:"zwaveRegion,omitempty"`
	ZWaveSUCID              int    `json:"zwaveSucId,omitempty"`
	ZWaveHomeID             string `json:"zwaveHomeId,omitempty"`
	ZWaveNodeID             string `json:"zwaveNodeId,omitempty"`
}

HubData contains hub-specific data extracted from device status. This includes network information like local IP, MAC address, and radio topology.

func ExtractHubData added in v1.0.1

func ExtractHubData(status map[string]any) (*HubData, error)

ExtractHubData extracts hub-specific data from a device status response. This is useful for getting network information like localIP, macAddress, and radio topology. Pass the status map from GetDeviceStatus or GetDeviceStatusAllComponents.

type HubDeviceData added in v1.0.6

type HubDeviceData struct {
	LocalIP                 string `json:"localIP,omitempty"`
	MacAddress              string `json:"macAddress,omitempty"`
	HardwareType            string `json:"hardwareType,omitempty"`
	HubLocalAPIAvailability string `json:"hubLocalApiAvailability,omitempty"`
	SerialNumber            string `json:"serialNumber,omitempty"`
	ZigbeeEUI               string `json:"zigbeeEui,omitempty"`
	ZigbeeChannel           string `json:"zigbeeChannel,omitempty"`
	ZigbeeNodeID            string `json:"zigbeeNodeID,omitempty"`
	ZigbeePanID             string `json:"zigbeePanId,omitempty"`
	ZWaveRegion             string `json:"zwaveRegion,omitempty"`
	ZWaveSUCID              string `json:"zwaveSucId,omitempty"`
	ZWaveHomeID             string `json:"zwaveHomeId,omitempty"`
	ZWaveNodeID             string `json:"zwaveNodeID,omitempty"`
}

HubDeviceData contains detailed hub data from the device response.

type HubDeviceInfo added in v1.0.6

type HubDeviceInfo struct {
	HubEUI          string          `json:"hubEui,omitempty"`
	FirmwareVersion string          `json:"firmwareVersion,omitempty"`
	HubData         *HubDeviceData  `json:"hubData,omitempty"`
	HubDrivers      []HubDriverInfo `json:"hubDrivers,omitempty"`
}

HubDeviceInfo contains hub-specific information embedded in a device response. This is present when the device type is "HUB".

type HubDriverInfo added in v1.0.6

type HubDriverInfo struct {
	DriverID      string `json:"driverId"`
	DriverVersion string `json:"driverVersion,omitempty"`
	ChannelID     string `json:"channelId,omitempty"`
}

HubDriverInfo represents a driver installed on a hub.

type HubHealthSubscription

type HubHealthSubscription struct {
	LocationID string `json:"locationId"`
}

HubHealthSubscription specifies hub health subscription.

type HubLocalClient added in v1.0.1

type HubLocalClient struct {
	// contains filtered or unexported fields
}

HubLocalClient provides real-time device events via WebSocket connection to a SmartThings Hub's local API.

func NewHubLocalClient added in v1.0.1

func NewHubLocalClient(cfg *HubLocalConfig) (*HubLocalClient, error)

NewHubLocalClient creates a new client for connecting to a SmartThings Hub's local API. The token should be obtained from the hub's local API authentication.

func (*HubLocalClient) Close added in v1.0.1

func (c *HubLocalClient) Close() error

Close closes the WebSocket connection and prevents automatic reconnection.

func (*HubLocalClient) Connect added in v1.0.1

func (c *HubLocalClient) Connect(ctx context.Context) error

Connect establishes a WebSocket connection to the hub's local API. The connection will remain open until Close is called or an error occurs.

func (*HubLocalClient) Errors added in v1.0.1

func (c *HubLocalClient) Errors() <-chan error

Errors returns a channel that receives connection errors. The channel is closed when the connection is closed.

func (*HubLocalClient) Events added in v1.0.1

func (c *HubLocalClient) Events() <-chan HubLocalEvent

Events returns a channel that receives device events. The channel is closed when the connection is closed.

func (*HubLocalClient) IsConnected added in v1.0.1

func (c *HubLocalClient) IsConnected() bool

IsConnected returns true if the client is currently connected.

func (*HubLocalClient) IsReconnecting added in v1.0.5

func (c *HubLocalClient) IsReconnecting() bool

IsReconnecting returns true if the client is currently attempting to reconnect.

func (*HubLocalClient) SetReconnectEnabled added in v1.0.5

func (c *HubLocalClient) SetReconnectEnabled(enabled bool)

SetReconnectEnabled enables or disables automatic reconnection.

func (*HubLocalClient) Subscribe added in v1.0.1

func (c *HubLocalClient) Subscribe(ctx context.Context, deviceIDs ...string) error

Subscribe sends a subscription request for device events. Call this after Connect to start receiving events for specific devices. Subscriptions are tracked and automatically restored after reconnection.

func (*HubLocalClient) SubscribeAll added in v1.0.1

func (c *HubLocalClient) SubscribeAll(ctx context.Context) error

SubscribeAll subscribes to events from all devices on the hub. This subscription is tracked and automatically restored after reconnection.

func (*HubLocalClient) Unsubscribe added in v1.0.1

func (c *HubLocalClient) Unsubscribe(ctx context.Context, deviceIDs ...string) error

Unsubscribe removes subscription for device events.

type HubLocalConfig added in v1.0.1

type HubLocalConfig struct {
	// HubIP is the local IP address of the SmartThings hub.
	HubIP string

	// HubPort is the local API port (default: 39500).
	HubPort int

	// Token is the local API bearer token from the hub.
	Token string

	// EventBufferSize is the size of the events channel buffer (default: 100).
	EventBufferSize int

	// ReconnectEnabled enables automatic reconnection on disconnect (default: true).
	ReconnectEnabled *bool

	// ReconnectDelay is the initial delay before reconnecting (default: 5s).
	ReconnectDelay time.Duration

	// ReconnectMaxDelay is the maximum delay between reconnection attempts (default: 5m).
	ReconnectMaxDelay time.Duration

	// OnReconnect is called when a reconnection occurs.
	OnReconnect func()

	// OnDisconnect is called when the connection is lost.
	OnDisconnect func(error)
}

HubLocalConfig configures the HubLocalClient.

type HubLocalConnectionInfo added in v1.0.5

type HubLocalConnectionInfo struct {
	HubID   string
	Name    string
	LocalIP string
	Port    int // Default: 39500
}

HubLocalConnectionInfo holds configuration for connecting to a hub's local API.

type HubLocalError added in v1.0.1

type HubLocalError struct {
	Code    string `json:"code"`
	Message string `json:"message"`
}

HubLocalError represents an error from the hub's local API.

type HubLocalEvent added in v1.0.1

type HubLocalEvent struct {
	// DeviceID is the UUID of the device that generated the event.
	DeviceID string `json:"deviceId"`

	// Component is the device component (e.g., "main").
	Component string `json:"component"`

	// Capability is the capability that changed (e.g., "switch", "temperatureMeasurement").
	Capability string `json:"capability"`

	// Attribute is the specific attribute (e.g., "switch", "temperature").
	Attribute string `json:"attribute"`

	// Value is the new value of the attribute.
	Value any `json:"value"`

	// Unit is the unit of measurement (if applicable).
	Unit string `json:"unit,omitempty"`

	// Timestamp is when the event occurred.
	Timestamp time.Time `json:"timestamp"`

	// StateChange indicates if this is a state change (true) or just a report (false).
	StateChange bool `json:"stateChange"`
}

HubLocalEvent represents a real-time device event from the hub's local API.

type HubLocalMessage added in v1.0.1

type HubLocalMessage struct {
	MessageType string          `json:"messageType"`
	DeviceEvent *HubLocalEvent  `json:"deviceEvent,omitempty"`
	Error       *HubLocalError  `json:"error,omitempty"`
	Raw         json.RawMessage `json:"-"`
}

HubLocalMessage represents a message from the hub's local WebSocket API.

type IconImage

type IconImage struct {
	URL string `json:"url"`
}

IconImage represents an app icon.

type InstallData

type InstallData struct {
	AuthToken    string          `json:"authToken"`
	RefreshToken string          `json:"refreshToken"`
	InstalledApp InstalledAppRef `json:"installedApp"`
}

InstallData contains data for INSTALL lifecycle events.

type InstalledApp

type InstalledApp struct {
	InstalledAppID     string   `json:"installedAppId"`
	InstalledAppType   string   `json:"installedAppType"`   // WEBHOOK_SMART_APP, LAMBDA_SMART_APP
	InstalledAppStatus string   `json:"installedAppStatus"` // PENDING, AUTHORIZED, REVOKED, DISABLED
	DisplayName        string   `json:"displayName"`
	AppID              string   `json:"appId"`
	ReferenceID        string   `json:"referenceId,omitempty"`
	LocationID         string   `json:"locationId"`
	Permissions        []string `json:"permissions,omitempty"`
	CreatedDate        string   `json:"createdDate,omitempty"`
	LastUpdatedDate    string   `json:"lastUpdatedDate,omitempty"`
	Classifications    []string `json:"classifications,omitempty"`
}

InstalledApp represents an installed SmartApp.

type InstalledAppConfigItem added in v1.0.1

type InstalledAppConfigItem struct {
	ConfigurationID     string `json:"configurationId"`
	ConfigurationStatus string `json:"configurationStatus"` // STAGED, AUTHORIZED, REVOKED
	CreatedDate         string `json:"createdDate,omitempty"`
	LastUpdatedDate     string `json:"lastUpdatedDate,omitempty"`
}

InstalledAppConfigItem represents a configuration item in the list response.

type InstalledAppConfiguration added in v1.0.1

type InstalledAppConfiguration struct {
	InstalledAppID      string                   `json:"installedAppId"`
	ConfigurationID     string                   `json:"configurationId"`
	ConfigurationStatus string                   `json:"configurationStatus"` // STAGED, AUTHORIZED, REVOKED
	CreatedDate         string                   `json:"createdDate,omitempty"`
	LastUpdatedDate     string                   `json:"lastUpdatedDate,omitempty"`
	Config              map[string][]ConfigEntry `json:"config"`
}

InstalledAppConfiguration represents the full configuration of an installed app.

type InstalledAppRef

type InstalledAppRef struct {
	InstalledAppID string    `json:"installedAppId"`
	LocationID     string    `json:"locationId"`
	Config         ConfigMap `json:"config,omitempty"`
}

InstalledAppRef contains reference data for an installed app.

type InstalledDriver added in v1.0.1

type InstalledDriver struct {
	DriverID                 string         `json:"driverId"`
	Name                     string         `json:"name"`
	Description              string         `json:"description,omitempty"`
	Version                  string         `json:"version"`
	ChannelID                string         `json:"channelId,omitempty"`
	Developer                string         `json:"developer,omitempty"`
	VendorSupportInformation string         `json:"vendorSupportInformation,omitempty"`
	Permissions              map[string]any `json:"permissions,omitempty"`
}

InstalledDriver represents a driver installed on a hub.

type InstalledSchemaApp added in v1.0.1

type InstalledSchemaApp struct {
	IsaID           string               `json:"isaId"`
	AppName         string               `json:"appName,omitempty"`
	PartnerName     string               `json:"partnerName,omitempty"`
	LocationID      string               `json:"locationId,omitempty"`
	InstalledAppID  string               `json:"installedAppId,omitempty"`
	CreatedDate     string               `json:"createdDate,omitempty"`
	LastUpdatedDate string               `json:"lastUpdatedDate,omitempty"`
	Devices         []SchemaDeviceResult `json:"devices,omitempty"`
}

InstalledSchemaApp represents an installed instance of a Schema app.

type LambdaAppInfo

type LambdaAppInfo struct {
	Functions []string `json:"functions"`
}

LambdaAppInfo contains Lambda SmartApp configuration.

type Links struct {
	Next     string `json:"next,omitempty"`
	Previous string `json:"previous,omitempty"`
}

Links contains pagination links from API responses.

type ListCapabilitiesOptions added in v1.0.1

type ListCapabilitiesOptions struct {
	// Namespace filters capabilities by namespace ("st" for standard, "custom" for custom).
	Namespace CapabilityNamespace
}

ListCapabilitiesOptions contains options for listing capabilities.

type ListDevicesOptions

type ListDevicesOptions struct {
	Capability        []string // Filter by capability
	LocationID        []string // Filter by location
	DeviceID          []string // Filter by device IDs
	Type              string   // Filter by device type
	Max               int      // Max results per page (1-200, default 200)
	Page              int      // Page number (0-based)
	IncludeRestricted bool     // Include restricted devices
}

ListDevicesOptions contains options for listing devices with pagination and filtering.

type LocaleReference added in v1.0.1

type LocaleReference struct {
	Tag string `json:"tag"`
}

LocaleReference is a reference to a locale.

type Location

type Location struct {
	LocationID           string                 `json:"locationId"`
	Name                 string                 `json:"name"`
	CountryCode          string                 `json:"countryCode,omitempty"`
	Latitude             float64                `json:"latitude,omitempty"`
	Longitude            float64                `json:"longitude,omitempty"`
	RegionRadius         int                    `json:"regionRadius,omitempty"`
	TemperatureScale     string                 `json:"temperatureScale,omitempty"` // "F" or "C"
	TimeZoneID           string                 `json:"timeZoneId,omitempty"`
	Locale               string                 `json:"locale,omitempty"`
	BackgroundImage      string                 `json:"backgroundImage,omitempty"`
	AdditionalProperties map[string]interface{} `json:"additionalProperties,omitempty"`
	Created              string                 `json:"created,omitempty"`
	LastModified         string                 `json:"lastModified,omitempty"`
}

Location represents a SmartThings location.

type LocationCreate

type LocationCreate struct {
	Name             string  `json:"name"`
	CountryCode      string  `json:"countryCode,omitempty"`
	Latitude         float64 `json:"latitude,omitempty"`
	Longitude        float64 `json:"longitude,omitempty"`
	RegionRadius     int     `json:"regionRadius,omitempty"`
	TemperatureScale string  `json:"temperatureScale,omitempty"`
	TimeZoneID       string  `json:"timeZoneId,omitempty"`
	Locale           string  `json:"locale,omitempty"`
}

LocationCreate is the request body for creating a location.

type LocationUpdate

type LocationUpdate struct {
	Name             string  `json:"name,omitempty"`
	Latitude         float64 `json:"latitude,omitempty"`
	Longitude        float64 `json:"longitude,omitempty"`
	RegionRadius     int     `json:"regionRadius,omitempty"`
	TemperatureScale string  `json:"temperatureScale,omitempty"`
	TimeZoneID       string  `json:"timeZoneId,omitempty"`
	Locale           string  `json:"locale,omitempty"`
}

LocationUpdate is the request body for updating a location.

type Logger added in v1.0.1

type Logger interface {
	// LogAttrs logs a message with the given level and attributes.
	LogAttrs(ctx context.Context, level slog.Level, msg string, attrs ...slog.Attr)
}

Logger is an optional interface for structured logging. It uses the standard library's slog interface for compatibility.

type LoggingTransport added in v1.0.1

type LoggingTransport struct {
	Base   http.RoundTripper
	Logger *slog.Logger
}

LoggingTransport wraps an http.RoundTripper and logs requests/responses.

func (*LoggingTransport) RoundTrip added in v1.0.1

func (t *LoggingTransport) RoundTrip(req *http.Request) (*http.Response, error)

RoundTrip implements http.RoundTripper with logging.

type MemoryCache added in v1.0.1

type MemoryCache struct {
	// contains filtered or unexported fields
}

MemoryCache is a thread-safe in-memory cache implementation.

func NewMemoryCache added in v1.0.1

func NewMemoryCache() *MemoryCache

NewMemoryCache creates a new in-memory cache.

func (*MemoryCache) Cleanup added in v1.0.1

func (c *MemoryCache) Cleanup() int

Cleanup removes all expired entries from the cache. Call this periodically to prevent memory leaks from expired entries.

func (*MemoryCache) Clear added in v1.0.1

func (c *MemoryCache) Clear()

Clear removes all values from the cache.

func (*MemoryCache) Delete added in v1.0.1

func (c *MemoryCache) Delete(key string)

Delete removes a value from the cache.

func (*MemoryCache) Get added in v1.0.1

func (c *MemoryCache) Get(key string) (any, bool)

Get retrieves a value from the cache.

func (*MemoryCache) Set added in v1.0.1

func (c *MemoryCache) Set(key string, value any, ttl time.Duration)

Set stores a value in the cache with the given TTL.

func (*MemoryCache) Size added in v1.0.1

func (c *MemoryCache) Size() int

Size returns the number of entries in the cache (including expired ones).

type MemoryTokenStore

type MemoryTokenStore struct {
	// contains filtered or unexported fields
}

MemoryTokenStore stores tokens in memory (useful for testing)

func NewMemoryTokenStore

func NewMemoryTokenStore() *MemoryTokenStore

NewMemoryTokenStore creates a new in-memory token store

func (*MemoryTokenStore) Clear

func (m *MemoryTokenStore) Clear()

Clear removes stored tokens

func (*MemoryTokenStore) LoadTokens

func (m *MemoryTokenStore) LoadTokens(ctx context.Context) (*TokenResponse, error)

LoadTokens loads tokens from memory

func (*MemoryTokenStore) SaveTokens

func (m *MemoryTokenStore) SaveTokens(ctx context.Context, tokens *TokenResponse) error

SaveTokens saves tokens to memory

type MessageConfig added in v1.0.1

type MessageConfig struct {
	MessageGroupKey string `json:"messageGroupKey"`
}

MessageConfig represents a message group configuration value.

type Mode

type Mode struct {
	ID    string `json:"id"`
	Name  string `json:"name"`
	Label string `json:"label,omitempty"`
}

Mode represents a SmartThings location mode (e.g., "Home", "Away", "Night").

type ModeConfig added in v1.0.1

type ModeConfig struct {
	ModeID string `json:"modeId"`
}

ModeConfig represents a mode configuration value.

type ModeSubscription

type ModeSubscription struct {
	LocationID string `json:"locationId"`
}

ModeSubscription specifies a mode change subscription.

type NotificationDeepLink struct {
	Type DeepLinkType `json:"type"`
	ID   string       `json:"id"`
}

NotificationDeepLink defines a deep link target.

type NotificationMessage added in v1.0.1

type NotificationMessage struct {
	Title string `json:"title,omitempty"`
	Body  string `json:"body,omitempty"`
}

NotificationMessage contains the title and body for a locale.

type NotificationReplacement added in v1.0.1

type NotificationReplacement struct {
	Key   string `json:"key,omitempty"`
	Value string `json:"value,omitempty"`
}

NotificationReplacement contains a key-value replacement for message templates.

type NotificationRequest added in v1.0.1

type NotificationRequest struct {
	LocationID   string                         `json:"locationId,omitempty"`
	Type         NotificationRequestType        `json:"type"`
	Messages     map[string]NotificationMessage `json:"messages"` // key is locale code (e.g., "en", "ko")
	Replacements []NotificationReplacement      `json:"replacements,omitempty"`
	DeepLink     *NotificationDeepLink          `json:"deepLink,omitempty"`
	ImageURL     string                         `json:"imageUrl,omitempty"`
}

NotificationRequest is the request body for creating a notification.

type NotificationRequestType added in v1.0.1

type NotificationRequestType string

NotificationRequestType represents the type of notification.

const (
	// NotificationTypeAlert is an alert notification.
	NotificationTypeAlert NotificationRequestType = "ALERT"
	// NotificationTypeSuggestedAction is a suggested action notification.
	NotificationTypeSuggestedAction NotificationRequestType = "SUGGESTED_ACTION"
	// NotificationTypeEventLogging is an event logging notification.
	NotificationTypeEventLogging NotificationRequestType = "EVENT_LOGGING"
	// NotificationTypeAutomationInfo is an automation info notification.
	NotificationTypeAutomationInfo NotificationRequestType = "AUTOMATION_INFO"
)

type NotificationResponse added in v1.0.1

type NotificationResponse struct {
	Code    int    `json:"code,omitempty"`
	Message string `json:"message,omitempty"`
}

NotificationResponse is the response from creating a notification.

type OAuthCallbackData

type OAuthCallbackData struct {
	InstalledAppID string `json:"installedAppId"`
	URLPath        string `json:"urlPath"`
}

OAuthCallbackData contains data for OAUTH_CALLBACK lifecycle events.

type OAuthClient

type OAuthClient struct {
	*Client
	// contains filtered or unexported fields
}

OAuthClient wraps a Client and manages OAuth token lifecycle. It automatically refreshes tokens before they expire.

func NewOAuthClient

func NewOAuthClient(cfg *OAuthConfig, store TokenStore, opts ...Option) (*OAuthClient, error)

NewOAuthClient creates a new OAuth-enabled SmartThings client. It attempts to load existing tokens from the store. If no tokens are available, the client will be created but API calls will fail until tokens are set via SetTokens or obtained through the OAuth flow.

func (*OAuthClient) ClearTokens

func (c *OAuthClient) ClearTokens(ctx context.Context) error

ClearTokens removes all stored tokens.

func (*OAuthClient) Config

func (c *OAuthClient) Config() *OAuthConfig

Config returns the OAuth configuration.

func (*OAuthClient) EnsureValidToken

func (c *OAuthClient) EnsureValidToken(ctx context.Context) error

EnsureValidToken checks if the access token is valid and refreshes if needed. This is the public version for manual token validation.

func (*OAuthClient) ExchangeCode

func (c *OAuthClient) ExchangeCode(ctx context.Context, code string) error

ExchangeCode exchanges an authorization code for tokens.

func (*OAuthClient) GetAuthorizationURL

func (c *OAuthClient) GetAuthorizationURL(state string) string

GetAuthorizationURL returns the URL to start the OAuth flow.

func (*OAuthClient) GetTokens

func (c *OAuthClient) GetTokens() *TokenResponse

GetTokens returns the current tokens (read-only copy).

func (*OAuthClient) IsAuthenticated

func (c *OAuthClient) IsAuthenticated() bool

IsAuthenticated returns true if valid tokens are available.

func (*OAuthClient) NeedsReauthentication

func (c *OAuthClient) NeedsReauthentication() bool

NeedsReauthentication returns true if the refresh token is invalid/expired and the user needs to go through the OAuth flow again.

func (*OAuthClient) SetTokens

func (c *OAuthClient) SetTokens(ctx context.Context, tokens *TokenResponse) error

SetTokens sets the OAuth tokens and updates the underlying client.

func (*OAuthClient) TokenStore

func (c *OAuthClient) TokenStore() TokenStore

TokenStore returns the token store.

type OAuthConfig

type OAuthConfig struct {
	ClientID     string
	ClientSecret string
	RedirectURL  string
	Scopes       []string
}

OAuthConfig holds the configuration for OAuth authentication

type OCFDeviceInfo

type OCFDeviceInfo struct {
	DeviceID                  string `json:"ocfDeviceId,omitempty"`
	Name                      string `json:"name,omitempty"`
	SpecVersion               string `json:"specVersion,omitempty"`
	VerticalDomainSpecVersion string `json:"verticalDomainSpecVersion,omitempty"`
	ManufacturerName          string `json:"manufacturerName,omitempty"`
	ModelNumber               string `json:"modelNumber,omitempty"`
	PlatformVersion           string `json:"platformVersion,omitempty"`
	PlatformOS                string `json:"platformOS,omitempty"`
	HwVersion                 string `json:"hwVersion,omitempty"`
	FirmwareVersion           string `json:"firmwareVersion,omitempty"`
	VendorID                  string `json:"vendorId,omitempty"`
}

OCFDeviceInfo contains OCF (Open Connectivity Foundation) device information.

type Option

type Option func(*Client)

Option configures a Client.

func WithBaseURL

func WithBaseURL(url string) Option

WithBaseURL sets a custom base URL for the API.

func WithCache added in v1.0.1

func WithCache(config *CacheConfig) Option

WithCache enables response caching for the client. Cached resources include capability definitions and device profiles.

Example:

client, _ := smartthings.NewClient(token,
    smartthings.WithCache(smartthings.DefaultCacheConfig()),
)
Example
package main

import (
	"context"
	"fmt"
	"time"

	st "github.com/tj-smith47/smartthings-go"
)

func main() {
	// Enable caching for capability and device profile lookups
	client, _ := st.NewClient("your-api-token",
		st.WithCache(&st.CacheConfig{
			CapabilityTTL:    1 * time.Hour,
			DeviceProfileTTL: 30 * time.Minute,
		}),
	)

	ctx := context.Background()

	// First call fetches from API
	cap1, _ := client.GetCapability(ctx, "switch", 1)

	// Second call returns cached result
	cap2, _ := client.GetCapability(ctx, "switch", 1)

	// Both return the same data
	fmt.Printf("Cached: %v\n", cap1.ID == cap2.ID)
}

func WithHTTPClient

func WithHTTPClient(client *http.Client) Option

WithHTTPClient sets a custom HTTP client.

func WithLogger added in v1.0.1

func WithLogger(logger *slog.Logger) Option

WithLogger configures a structured logger for the client. When set, the client will log API requests and responses.

Example:

logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
client, _ := st.NewClient("token", st.WithLogger(logger))

func WithRateLimitCallback

func WithRateLimitCallback(callback RateLimitCallback) Option

WithRateLimitCallback sets a callback that is invoked when rate limit headers are received. This can be used for monitoring, logging, or preemptive throttling.

Example
package main

import (
	"fmt"

	st "github.com/tj-smith47/smartthings-go"
)

func main() {
	// Get notified when rate limits are encountered
	client, _ := st.NewClient("your-api-token",
		st.WithRateLimitCallback(func(info st.RateLimitInfo) {
			fmt.Printf("Rate limit: %d remaining, resets at %s\n", info.Remaining, info.Reset)
		}),
	)

	_ = client
}

func WithRetry

func WithRetry(config *RetryConfig) Option

WithRetry enables automatic retry with the given configuration. Retries are attempted on rate limits (429), server errors (5xx), and timeouts.

func WithTimeout

func WithTimeout(timeout time.Duration) Option

WithTimeout sets the HTTP request timeout. This option can be applied in any order relative to other options.

type Organization added in v1.0.1

type Organization struct {
	OrganizationID   string `json:"organizationId"`
	Name             string `json:"name"`
	Label            string `json:"label,omitempty"`
	ManufacturerName string `json:"manufacturerName,omitempty"`
	MNID             string `json:"mnid,omitempty"`
	WarehouseGroupID string `json:"warehouseGroupId,omitempty"`
	DeveloperGroupID string `json:"developerGroupId,omitempty"`
	AdminGroupID     string `json:"adminGroupId,omitempty"`
	IsDefaultUserOrg bool   `json:"isDefaultUserOrg,omitempty"`
}

Organization represents a SmartThings organization.

type PageInfo

type PageInfo struct {
	TotalPages   int `json:"totalPages,omitempty"`
	TotalResults int `json:"totalResults,omitempty"`
	CurrentPage  int `json:"currentPage,omitempty"`
}

PageInfo contains pagination information from API responses.

type PagedDevices

type PagedDevices struct {
	Items    []Device `json:"items"`
	Links    Links    `json:"_links,omitempty"`
	PageInfo PageInfo `json:"_page,omitempty"`
}

PagedDevices is the response from ListDevicesWithOptions.

type PagedEvents

type PagedEvents struct {
	Items    []DeviceEvent `json:"items"`
	Links    Links         `json:"_links,omitempty"`
	PageInfo PageInfo      `json:"_page,omitempty"`
}

PagedEvents is the paginated response for device events.

type PagedStates

type PagedStates struct {
	Items    []DeviceState `json:"items"`
	Links    Links         `json:"_links,omitempty"`
	PageInfo PageInfo      `json:"_page,omitempty"`
}

PagedStates is the paginated response for device states.

type PatchItem added in v1.0.1

type PatchItem struct {
	Op    PatchOp `json:"op"`
	Path  string  `json:"path"`
	Value any     `json:"value,omitempty"`
}

PatchItem represents a JSON Patch operation.

type PatchOp added in v1.0.1

type PatchOp string

PatchOp represents a JSON Patch operation type.

const (
	// PatchOpAdd adds a value at a path.
	PatchOpAdd PatchOp = "ADD"
	// PatchOpReplace replaces a value at a path.
	PatchOpReplace PatchOp = "REPLACE"
	// PatchOpRemove removes a value at a path.
	PatchOpRemove PatchOp = "REMOVE"
)

type PermissionConfig added in v1.0.1

type PermissionConfig struct {
	Permissions []string `json:"permissions"`
}

PermissionConfig represents a permission configuration value.

type PingData

type PingData struct {
	Challenge string `json:"challenge"`
}

PingData contains data for PING lifecycle events.

type PreferenceLocalization added in v1.0.1

type PreferenceLocalization struct {
	Tag         string            `json:"tag"` // Locale tag, e.g., "en", "ko"
	Label       string            `json:"label,omitempty"`
	Description string            `json:"description,omitempty"`
	Options     map[string]string `json:"options,omitempty"` // For enumeration types
}

PreferenceLocalization contains localized strings for a preference.

type PreferenceType added in v1.0.1

type PreferenceType string

PreferenceType represents the type of device preference.

const (
	// PreferenceTypeInteger is an integer preference.
	PreferenceTypeInteger PreferenceType = "integer"
	// PreferenceTypeNumber is a number (decimal) preference.
	PreferenceTypeNumber PreferenceType = "number"
	// PreferenceTypeBoolean is a boolean preference.
	PreferenceTypeBoolean PreferenceType = "boolean"
	// PreferenceTypeString is a string preference.
	PreferenceTypeString PreferenceType = "string"
	// PreferenceTypeEnumeration is an enumeration preference.
	PreferenceTypeEnumeration PreferenceType = "enumeration"
)

type PresentationAutomation added in v1.0.1

type PresentationAutomation struct {
	Conditions []PresentationConfigEntry `json:"conditions,omitempty"`
	Actions    []PresentationConfigEntry `json:"actions,omitempty"`
}

PresentationAutomation defines automation presentation.

type PresentationConfigEntry added in v1.0.1

type PresentationConfigEntry struct {
	Component        string                      `json:"component"`
	Capability       string                      `json:"capability"`
	Version          int                         `json:"version,omitempty"`
	Values           []PresentationConfigValue   `json:"values,omitempty"`
	Patch            []PatchItem                 `json:"patch,omitempty"`
	VisibleCondition *CapabilityVisibleCondition `json:"visibleCondition,omitempty"`
}

PresentationConfigEntry defines how a capability is displayed.

type PresentationConfigValue added in v1.0.1

type PresentationConfigValue struct {
	Key           string                  `json:"key"`
	EnabledValues []string                `json:"enabledValues,omitempty"`
	Range         *PresentationValueRange `json:"range,omitempty"`
	Step          float64                 `json:"step,omitempty"`
}

PresentationConfigValue defines a specific value configuration.

type PresentationDPInfo added in v1.0.1

type PresentationDPInfo struct {
	OS            string `json:"os,omitempty"`
	DPURI         string `json:"dpUri,omitempty"`
	OperatingMode string `json:"operatingMode,omitempty"` // "easySetup" or "deviceControl"
}

PresentationDPInfo contains device presentation info for specific OS/mode.

type PresentationDashboard added in v1.0.1

type PresentationDashboard struct {
	States  []PresentationConfigEntry `json:"states,omitempty"`
	Actions []PresentationConfigEntry `json:"actions,omitempty"`
}

PresentationDashboard defines dashboard presentation.

type PresentationDeviceConfig added in v1.0.1

type PresentationDeviceConfig struct {
	ManufacturerName string                    `json:"manufacturerName"`
	PresentationID   string                    `json:"presentationId"`
	Type             string                    `json:"type,omitempty"`
	IconURL          string                    `json:"iconUrl,omitempty"`
	Dashboard        *PresentationDashboard    `json:"dashboard,omitempty"`
	DetailView       []PresentationConfigEntry `json:"detailView,omitempty"`
	Automation       *PresentationAutomation   `json:"automation,omitempty"`
	DPInfo           []PresentationDPInfo      `json:"dpInfo,omitempty"`
}

PresentationDeviceConfig represents a device presentation configuration.

type PresentationDeviceConfigCreate added in v1.0.1

type PresentationDeviceConfigCreate struct {
	Type       string                    `json:"type,omitempty"` // "profile" or "dth"
	IconURL    string                    `json:"iconUrl,omitempty"`
	Dashboard  *PresentationDashboard    `json:"dashboard,omitempty"`
	DetailView []PresentationConfigEntry `json:"detailView,omitempty"`
	Automation *PresentationAutomation   `json:"automation,omitempty"`
}

PresentationDeviceConfigCreate is the request body for creating a device configuration.

type PresentationDevicePresentation added in v1.0.1

type PresentationDevicePresentation struct {
	ManufacturerName string                    `json:"manufacturerName"`
	PresentationID   string                    `json:"presentationId"`
	IconURL          string                    `json:"iconUrl,omitempty"`
	Dashboard        *PresentationDashboard    `json:"dashboard,omitempty"`
	DetailView       []PresentationConfigEntry `json:"detailView,omitempty"`
	Automation       *PresentationAutomation   `json:"automation,omitempty"`
	DPInfo           []PresentationDPInfo      `json:"dpInfo,omitempty"`
	Language         []map[string]any          `json:"language,omitempty"`
}

PresentationDevicePresentation represents a full device presentation.

type PresentationValueRange added in v1.0.1

type PresentationValueRange struct {
	Min float64 `json:"min,omitempty"`
	Max float64 `json:"max,omitempty"`
}

PresentationValueRange defines a value range.

type ProfileComponent

type ProfileComponent struct {
	ID           string          `json:"id"`
	Label        string          `json:"label,omitempty"`
	Capabilities []CapabilityRef `json:"capabilities"`
	Categories   []string        `json:"categories,omitempty"`
}

ProfileComponent defines a component within a device profile.

type ProfileOwner

type ProfileOwner struct {
	OwnerType string `json:"ownerType"` // USER, ORGANIZATION
	OwnerID   string `json:"ownerId"`
}

ProfileOwner represents the owner of a device profile.

type ProfilePreference

type ProfilePreference struct {
	Name        string   `json:"name"`
	Title       string   `json:"title,omitempty"`
	Description string   `json:"description,omitempty"`
	Type        string   `json:"type"` // integer, boolean, string, enumeration
	Required    bool     `json:"required,omitempty"`
	Default     any      `json:"default,omitempty"`
	Minimum     *float64 `json:"minimum,omitempty"`
	Maximum     *float64 `json:"maximum,omitempty"`
	Options     []string `json:"options,omitempty"` // For enumeration type
}

ProfilePreference defines a user-configurable preference for a device.

type RangeDetailedStatus added in v1.0.5

type RangeDetailedStatus struct {
	// Cooktop state (read-only, NOT controllable)
	CooktopActive bool `json:"cooktop_active"` // true if any burner is on

	// Oven state
	OvenActive     bool   `json:"oven_active"`                // true if oven is running
	OvenTemp       *int   `json:"oven_temp,omitempty"`        // Current temp (F)
	OvenTargetTemp *int   `json:"oven_target_temp,omitempty"` // Target temp (F)
	OvenMode       string `json:"oven_mode,omitempty"`        // Bake, Broil, Convection, etc.
	RemainingMins  *int   `json:"remaining_mins,omitempty"`   // Cook time remaining
	OvenLightOn    bool   `json:"oven_light_on"`              // Oven light state

	// CRITICAL: Remote control status
	RemoteControlEnabled bool `json:"remote_control_enabled"`

	// Child lock
	ChildLockOn bool `json:"child_lock_on"`

	// Supported options
	SupportedOvenModes []string `json:"supported_oven_modes,omitempty"`
	OvenTempMin        *int     `json:"oven_temp_min,omitempty"` // Min temp (F)
	OvenTempMax        *int     `json:"oven_temp_max,omitempty"` // Max temp (F)
}

RangeDetailedStatus provides comprehensive range/oven status. Note: Cooktop is NOT controllable via API for safety reasons. Use ExtractRangeDetailedStatus to extract from a device status response.

func ExtractRangeDetailedStatus added in v1.0.5

func ExtractRangeDetailedStatus(status Status) *RangeDetailedStatus

ExtractRangeDetailedStatus extracts comprehensive range/oven status. Note: Cooktop state is read-only - it cannot be controlled via API for safety.

Example:

status, _ := client.GetDeviceStatus(ctx, rangeID)
rangeStatus := st.ExtractRangeDetailedStatus(status)
if rangeStatus.CooktopActive {
    fmt.Println("Warning: Cooktop is on (cannot be controlled remotely)")
}

type RangeStatus

type RangeStatus struct {
	CooktopActive  bool `json:"cooktop_active"`             // true if any burner is on
	OvenActive     bool `json:"oven_active"`                // true if oven is running
	OvenTemp       *int `json:"oven_temp,omitempty"`        // Current oven temperature (F)
	OvenTargetTemp *int `json:"oven_target_temp,omitempty"` // Target oven temperature (F)
}

RangeStatus represents the status of a Samsung range/oven.

func ExtractRangeStatus

func ExtractRangeStatus(status Status) *RangeStatus

ExtractRangeStatus extracts status from a Samsung range/oven.

type RateLimitCallback

type RateLimitCallback func(RateLimitInfo)

RateLimitCallback is called when rate limit headers are received. Can be used for monitoring or preemptive throttling.

type RateLimitError added in v1.0.1

type RateLimitError struct {
	// RetryAfter is the recommended wait duration from the Retry-After header.
	// Zero if the header was not present.
	RetryAfter time.Duration

	// Info contains the rate limit headers from the response.
	Info *RateLimitInfo
}

RateLimitError provides detailed information about a rate limit response. It includes the recommended wait time from the Retry-After header if available.

func (*RateLimitError) Error added in v1.0.1

func (e *RateLimitError) Error() string

Error implements the error interface.

func (*RateLimitError) Is added in v1.0.1

func (e *RateLimitError) Is(target error) bool

Is allows errors.Is() to match ErrRateLimited.

type RateLimitInfo

type RateLimitInfo struct {
	Limit     int       // Maximum requests allowed in the window
	Remaining int       // Requests remaining in current window
	Reset     time.Time // When the rate limit window resets
}

RateLimitInfo contains rate limit information from API response headers.

type RateLimitThrottler added in v1.0.1

type RateLimitThrottler struct {
	// contains filtered or unexported fields
}

RateLimitThrottler provides automatic rate limiting for bulk operations. It tracks API calls and automatically throttles when approaching limits.

func NewRateLimitThrottler added in v1.0.1

func NewRateLimitThrottler(client *Client, threshold int, delay time.Duration) *RateLimitThrottler

NewRateLimitThrottler creates a throttler that monitors rate limits and automatically slows down when approaching the limit.

Example:

throttler := NewRateLimitThrottler(client, 10, 100*time.Millisecond)
for _, deviceID := range devices {
    throttler.Wait(ctx) // Automatically waits if needed
    client.ExecuteCommand(ctx, deviceID, cmd)
}

func (*RateLimitThrottler) Wait added in v1.0.1

func (t *RateLimitThrottler) Wait(ctx context.Context) error

Wait blocks if the rate limit is approaching the threshold. Returns immediately if plenty of requests remain.

func (*RateLimitThrottler) WaitUntilReset added in v1.0.1

func (t *RateLimitThrottler) WaitUntilReset(ctx context.Context) error

WaitUntilReset blocks until the rate limit window resets. Useful when you've hit the rate limit and want to wait for a full reset.

type RefrigeratorStatus

type RefrigeratorStatus struct {
	FridgeTemp  *int `json:"fridge_temp,omitempty"`  // Fridge temperature (F)
	FreezerTemp *int `json:"freezer_temp,omitempty"` // Freezer temperature (F)
	DoorOpen    bool `json:"door_open"`              // true if any door is open
}

RefrigeratorStatus represents the status of a Samsung refrigerator.

func ExtractRefrigeratorStatus

func ExtractRefrigeratorStatus(allComponents Status) *RefrigeratorStatus

ExtractRefrigeratorStatus extracts status from a Samsung refrigerator. Note: This requires the full component status (from GetDeviceStatusAllComponents), not just the main component status.

type RetryConfig

type RetryConfig struct {
	// MaxRetries is the maximum number of retry attempts (default: 3).
	MaxRetries int
	// InitialBackoff is the initial backoff duration (default: 100ms).
	InitialBackoff time.Duration
	// MaxBackoff is the maximum backoff duration (default: 5s).
	MaxBackoff time.Duration
	// Multiplier is the backoff multiplier (default: 2.0).
	Multiplier float64
}

RetryConfig configures automatic retry behavior for transient failures.

func DefaultRetryConfig

func DefaultRetryConfig() *RetryConfig

DefaultRetryConfig returns sensible retry defaults.

type Room

type Room struct {
	RoomID          string `json:"roomId"`
	LocationID      string `json:"locationId"`
	Name            string `json:"name"`
	BackgroundImage string `json:"backgroundImage,omitempty"`
}

Room represents a room within a location.

type RoomCreate

type RoomCreate struct {
	Name string `json:"name"`
}

RoomCreate is the request body for creating a room.

type RoomUpdate

type RoomUpdate struct {
	Name            string `json:"name,omitempty"`
	BackgroundImage string `json:"backgroundImage,omitempty"`
}

RoomUpdate is the request body for updating a room.

type Rule

type Rule struct {
	ID                string       `json:"id"`
	Name              string       `json:"name"`
	Actions           []RuleAction `json:"actions"`
	TimeZoneID        string       `json:"timeZoneId,omitempty"`
	OwnerID           string       `json:"ownerId,omitempty"`
	OwnerType         string       `json:"ownerType,omitempty"`
	ExecutionLocation string       `json:"executionLocation,omitempty"`
	DateCreated       string       `json:"dateCreated,omitempty"`
	DateUpdated       string       `json:"dateUpdated,omitempty"`
}

Rule represents an automation rule.

type RuleAction

type RuleAction struct {
	If       *RuleCondition `json:"if,omitempty"`
	Sleep    *RuleSleep     `json:"sleep,omitempty"`
	Command  *RuleCommand   `json:"command,omitempty"`
	Every    *RuleEvery     `json:"every,omitempty"`
	Location *RuleLocation  `json:"location,omitempty"`
}

RuleAction represents an action within a rule.

type RuleCommand

type RuleCommand struct {
	Devices    []RuleDeviceCommand `json:"devices,omitempty"`
	Component  string              `json:"component,omitempty"`
	Capability string              `json:"capability,omitempty"`
	Command    string              `json:"command,omitempty"`
	Arguments  []interface{}       `json:"arguments,omitempty"`
}

RuleCommand represents a command in a rule.

type RuleCondition

type RuleCondition struct {
	Equals      map[string]interface{} `json:"equals,omitempty"`
	GreaterThan map[string]interface{} `json:"greaterThan,omitempty"`
	LessThan    map[string]interface{} `json:"lessThan,omitempty"`
	And         []RuleCondition        `json:"and,omitempty"`
	Or          []RuleCondition        `json:"or,omitempty"`
	Then        []RuleAction           `json:"then,omitempty"`
	Else        []RuleAction           `json:"else,omitempty"`
}

RuleCondition represents a conditional in a rule.

type RuleCreate

type RuleCreate struct {
	Name    string       `json:"name"`
	Actions []RuleAction `json:"actions"`
}

RuleCreate is the request body for creating a rule.

type RuleDeviceCommand

type RuleDeviceCommand struct {
	DeviceID   string        `json:"deviceId"`
	Component  string        `json:"component,omitempty"`
	Capability string        `json:"capability"`
	Command    string        `json:"command"`
	Arguments  []interface{} `json:"arguments,omitempty"`
}

RuleDeviceCommand represents a device command in a rule.

type RuleEvery

type RuleEvery struct {
	Specific *RuleSpecificTime `json:"specific,omitempty"`
	Interval *RuleInterval     `json:"interval,omitempty"`
	Actions  []RuleAction      `json:"actions,omitempty"`
}

RuleEvery represents a time-based trigger.

type RuleInterval

type RuleInterval struct {
	Value struct {
		Integer int `json:"integer,omitempty"`
	} `json:"value,omitempty"`
	Unit string `json:"unit,omitempty"` // "Minute", "Hour", "Day"
}

RuleInterval represents a recurring interval.

type RuleLocation

type RuleLocation struct {
	Mode string `json:"mode,omitempty"`
}

RuleLocation represents a location mode change.

type RuleOffset

type RuleOffset struct {
	Value struct {
		Integer int `json:"integer,omitempty"`
	} `json:"value,omitempty"`
	Unit string `json:"unit,omitempty"` // "Minute", "Hour"
}

RuleOffset represents a time offset.

type RuleSleep

type RuleSleep struct {
	Duration int `json:"duration"` // seconds
}

RuleSleep represents a delay in a rule.

type RuleSpecificTime

type RuleSpecificTime struct {
	Reference string      `json:"reference,omitempty"` // "Sunrise", "Sunset", "Now"
	Offset    *RuleOffset `json:"offset,omitempty"`
}

RuleSpecificTime represents a specific time trigger.

type RuleUpdate

type RuleUpdate struct {
	Name    string       `json:"name,omitempty"`
	Actions []RuleAction `json:"actions,omitempty"`
}

RuleUpdate is the request body for updating a rule.

type Scene

type Scene struct {
	SceneID          string `json:"sceneId"`
	SceneName        string `json:"sceneName"`
	SceneIcon        string `json:"sceneIcon,omitempty"`
	SceneColor       string `json:"sceneColor,omitempty"`
	LocationID       string `json:"locationId"`
	CreatedBy        string `json:"createdBy,omitempty"`
	CreatedDate      string `json:"createdDate,omitempty"`
	LastUpdatedDate  string `json:"lastUpdatedDate,omitempty"`
	LastExecutedDate string `json:"lastExecutedDate,omitempty"`
	Editable         bool   `json:"editable,omitempty"`
	APIOnly          bool   `json:"apiOnly,omitempty"`
}

Scene represents a SmartThings scene.

type SceneConfig added in v1.0.1

type SceneConfig struct {
	SceneID     string   `json:"sceneId"`
	Permissions []string `json:"permissions,omitempty"`
}

SceneConfig represents a scene configuration value.

type SceneLifecycleSubscription

type SceneLifecycleSubscription struct {
	LocationID string `json:"locationId"`
}

SceneLifecycleSubscription specifies scene lifecycle subscription.

type Schedule

type Schedule struct {
	Name           string        `json:"name"`
	Cron           *CronSchedule `json:"cron,omitempty"`
	InstalledAppID string        `json:"installedAppId"`
	LocationID     string        `json:"locationId,omitempty"`
}

Schedule represents a scheduled task for an installed app.

type ScheduleCreate

type ScheduleCreate struct {
	Name string        `json:"name"`
	Cron *CronSchedule `json:"cron,omitempty"`
}

ScheduleCreate is the request body for creating a schedule.

type SchemaApp added in v1.0.1

type SchemaApp struct {
	EndpointAppID         string         `json:"endpointAppId"`
	AppName               string         `json:"appName,omitempty"`
	PartnerName           string         `json:"partnerName,omitempty"`
	OAuthClientID         string         `json:"oauthClientId,omitempty"`
	OAuthClientSecret     string         `json:"oauthClientSecret,omitempty"`
	STClientID            string         `json:"stClientId,omitempty"`
	STClientSecret        string         `json:"stClientSecret,omitempty"`
	OAuthAuthorizationURL string         `json:"oauthAuthorizationUrl,omitempty"`
	OAuthTokenURL         string         `json:"oauthTokenUrl,omitempty"`
	WebhookURL            string         `json:"webhookUrl,omitempty"`
	HostingType           string         `json:"hostingType,omitempty"`
	UserEmail             string         `json:"userEmail,omitempty"`
	IconURL               string         `json:"icon,omitempty"`
	IconX2URL             string         `json:"icon2x,omitempty"`
	IconX3URL             string         `json:"icon3x,omitempty"`
	CertificationStatus   string         `json:"certificationStatus,omitempty"`
	CreatedDate           string         `json:"createdDate,omitempty"`
	LastUpdatedDate       string         `json:"lastUpdatedDate,omitempty"`
	ViperAppLinks         *ViperAppLinks `json:"viperAppLinks,omitempty"`
}

SchemaApp represents a SmartThings Schema (C2C) connector.

type SchemaAppInvitation added in v1.0.1

type SchemaAppInvitation struct {
	ID          string `json:"id"`
	SchemaAppID string `json:"schemaAppId"`
	Description string `json:"description,omitempty"`
	Expiration  string `json:"expiration,omitempty"`
	AcceptURL   string `json:"acceptUrl,omitempty"`
	DeclineURL  string `json:"declineUrl,omitempty"`
	ShortCode   string `json:"shortCode,omitempty"`
	Acceptances int    `json:"acceptances,omitempty"`
	AcceptLimit int    `json:"acceptLimit,omitempty"`
}

SchemaAppInvitation represents an invitation to use a Schema app.

type SchemaAppInvitationCreate added in v1.0.1

type SchemaAppInvitationCreate struct {
	SchemaAppID string `json:"schemaAppId"`
	Description string `json:"description,omitempty"`
	AcceptLimit int    `json:"acceptLimit,omitempty"`
}

SchemaAppInvitationCreate is the request body for creating an invitation.

type SchemaAppInvitationID added in v1.0.1

type SchemaAppInvitationID struct {
	InvitationID string `json:"invitationId"`
}

SchemaAppInvitationID is the response from creating an invitation.

type SchemaAppRequest added in v1.0.1

type SchemaAppRequest struct {
	AppName               string         `json:"appName"`
	PartnerName           string         `json:"partnerName,omitempty"`
	OAuthAuthorizationURL string         `json:"oauthAuthorizationUrl,omitempty"`
	OAuthTokenURL         string         `json:"oauthTokenUrl,omitempty"`
	OAuthClientID         string         `json:"oauthClientId,omitempty"`
	OAuthClientSecret     string         `json:"oauthClientSecret,omitempty"`
	WebhookURL            string         `json:"webhookUrl,omitempty"`
	HostingType           string         `json:"hostingType,omitempty"`
	UserEmail             string         `json:"userEmail,omitempty"`
	IconURL               string         `json:"icon,omitempty"`
	IconX2URL             string         `json:"icon2x,omitempty"`
	IconX3URL             string         `json:"icon3x,omitempty"`
	ViperAppLinks         *ViperAppLinks `json:"viperAppLinks,omitempty"`
}

SchemaAppRequest is the request body for creating/updating a Schema app.

type SchemaCreateResponse added in v1.0.1

type SchemaCreateResponse struct {
	EndpointAppID  string `json:"endpointAppId"`
	STClientID     string `json:"stClientId,omitempty"`
	STClientSecret string `json:"stClientSecret,omitempty"`
}

SchemaCreateResponse is the response from creating a Schema app.

type SchemaDeviceResult added in v1.0.1

type SchemaDeviceResult struct {
	DeviceID         string `json:"deviceId,omitempty"`
	ExternalDeviceID string `json:"externalDeviceId,omitempty"`
	Label            string `json:"label,omitempty"`
}

SchemaDeviceResult represents a device created by a Schema app.

type SchemaPage added in v1.0.1

type SchemaPage struct {
	PageType SchemaPageType `json:"pageType"`
	// Authorized page fields
	PartnerName   string `json:"partnerName,omitempty"`
	AppName       string `json:"appName,omitempty"`
	ConnectedDate string `json:"connectedDate,omitempty"`
	// Unauthorized page fields
	AuthorizationURI string `json:"authorizationUri,omitempty"`
}

SchemaPage represents a page configuration for a Schema app.

type SchemaPageType added in v1.0.1

type SchemaPageType string

SchemaPageType indicates the type of schema app page.

const (
	// SchemaPageTypeAuthorized indicates the user is authorized.
	SchemaPageTypeAuthorized SchemaPageType = "AUTHORIZED"
	// SchemaPageTypeUnauthorized indicates the user needs authorization.
	SchemaPageTypeUnauthorized SchemaPageType = "UNAUTHORIZED"
)

type SecuritySystemSubscription

type SecuritySystemSubscription struct {
	LocationID string `json:"locationId"`
}

SecuritySystemSubscription specifies security arm state subscription.

type ServiceCapability added in v1.0.1

type ServiceCapability string

ServiceCapability represents an available service capability.

const (
	// ServiceCapabilityWeather is weather data.
	ServiceCapabilityWeather ServiceCapability = "weather"
	// ServiceCapabilityAirQuality is air quality data.
	ServiceCapabilityAirQuality ServiceCapability = "airQuality"
	// ServiceCapabilityForecast is weather forecast data.
	ServiceCapabilityForecast ServiceCapability = "forecast"
	// ServiceCapabilityAirQualityForecast is air quality forecast data.
	ServiceCapabilityAirQualityForecast ServiceCapability = "airQualityForecast"
)

type ServiceCapabilityData added in v1.0.1

type ServiceCapabilityData struct {
	LocationID         string               `json:"locationId,omitempty"`
	Weather            *WeatherData         `json:"weather,omitempty"`
	AirQuality         *AirQualityData      `json:"airQuality,omitempty"`
	Forecast           *WeatherForecastData `json:"forecast,omitempty"`
	AirQualityForecast *AirQualityForecast  `json:"airQualityForecast,omitempty"`
}

ServiceCapabilityData contains service capability data.

type ServiceLocationInfo added in v1.0.1

type ServiceLocationInfo struct {
	LocationID    string                    `json:"locationId,omitempty"`
	City          string                    `json:"city,omitempty"`
	Latitude      float64                   `json:"latitude,omitempty"`
	Longitude     float64                   `json:"longitude,omitempty"`
	Subscriptions []ServiceSubscriptionInfo `json:"subscriptions,omitempty"`
}

ServiceLocationInfo contains location service information.

type ServiceNewSubscription added in v1.0.1

type ServiceNewSubscription struct {
	SubscriptionID string              `json:"subscriptionId,omitempty"`
	Capabilities   []ServiceCapability `json:"capabilities,omitempty"`
}

ServiceNewSubscription is the response from creating a subscription.

type ServiceSubscriptionInfo added in v1.0.1

type ServiceSubscriptionInfo struct {
	SubscriptionID string                  `json:"subscriptionId,omitempty"`
	Type           ServiceSubscriptionType `json:"type,omitempty"`
	Capabilities   []ServiceCapability     `json:"capabilities,omitempty"`
}

ServiceSubscriptionInfo contains subscription details.

type ServiceSubscriptionRequest added in v1.0.1

type ServiceSubscriptionRequest struct {
	Type                   ServiceSubscriptionType `json:"type"`
	Predicate              string                  `json:"predicate,omitempty"`
	SubscribedCapabilities []ServiceCapability     `json:"subscribedCapabilities"`
}

ServiceSubscriptionRequest is the request for creating/updating a subscription.

type ServiceSubscriptionType added in v1.0.1

type ServiceSubscriptionType string

ServiceSubscriptionType represents the type of service subscription.

const (
	// ServiceSubscriptionDirect sends events directly.
	ServiceSubscriptionDirect ServiceSubscriptionType = "DIRECT"
	// ServiceSubscriptionExecution triggers executions.
	ServiceSubscriptionExecution ServiceSubscriptionType = "EXECUTION"
)

type SmartThingsClient

type SmartThingsClient interface {
	ListDevices(ctx context.Context) ([]Device, error)
	ListDevicesWithOptions(ctx context.Context, opts *ListDevicesOptions) (*PagedDevices, error)
	ListAllDevices(ctx context.Context) ([]Device, error)
	GetDevice(ctx context.Context, deviceID string) (*Device, error)
	GetDeviceStatus(ctx context.Context, deviceID string) (Status, error)
	GetDeviceFullStatus(ctx context.Context, deviceID string) (map[string]Status, error)
	GetDeviceStatusAllComponents(ctx context.Context, deviceID string) (Status, error)
	GetComponentStatus(ctx context.Context, deviceID, componentID string) (Status, error)
	ExecuteCommand(ctx context.Context, deviceID string, cmd Command) error
	ExecuteCommands(ctx context.Context, deviceID string, cmds []Command) error
	ExecuteComponentCommand(ctx context.Context, deviceID, component, capability, command string, args ...any) error
	DeleteDevice(ctx context.Context, deviceID string) error
	UpdateDevice(ctx context.Context, deviceID string, update *DeviceUpdate) (*Device, error)
	GetDeviceHealth(ctx context.Context, deviceID string) (*DeviceHealth, error)
	Devices(ctx context.Context) iter.Seq2[Device, error]
	DevicesWithOptions(ctx context.Context, opts *ListDevicesOptions) iter.Seq2[Device, error]

	ExecuteCommandBatch(ctx context.Context, deviceIDs []string, cmd Command, cfg *BatchConfig) []BatchResult
	ExecuteCommandsBatch(ctx context.Context, batch []BatchCommand, cfg *BatchConfig) []BatchResult
	GetDeviceStatusBatch(ctx context.Context, deviceIDs []string, cfg *BatchConfig) []BatchStatusResult

	ListLocations(ctx context.Context) ([]Location, error)
	GetLocation(ctx context.Context, locationID string) (*Location, error)
	CreateLocation(ctx context.Context, location *LocationCreate) (*Location, error)
	UpdateLocation(ctx context.Context, locationID string, update *LocationUpdate) (*Location, error)
	DeleteLocation(ctx context.Context, locationID string) error
	Locations(ctx context.Context) iter.Seq2[Location, error]

	ListRooms(ctx context.Context, locationID string) ([]Room, error)
	GetRoom(ctx context.Context, locationID, roomID string) (*Room, error)
	CreateRoom(ctx context.Context, locationID string, room *RoomCreate) (*Room, error)
	UpdateRoom(ctx context.Context, locationID, roomID string, update *RoomUpdate) (*Room, error)
	DeleteRoom(ctx context.Context, locationID, roomID string) error
	Rooms(ctx context.Context, locationID string) iter.Seq2[Room, error]

	ListScenes(ctx context.Context, locationID string) ([]Scene, error)
	GetScene(ctx context.Context, sceneID string) (*Scene, error)
	ExecuteScene(ctx context.Context, sceneID string) error
	Scenes(ctx context.Context, locationID string) iter.Seq2[Scene, error]

	ListCapabilities(ctx context.Context) ([]CapabilityReference, error)
	ListCapabilitiesWithOptions(ctx context.Context, opts *ListCapabilitiesOptions) ([]CapabilityReference, error)
	GetCapability(ctx context.Context, capabilityID string, version int) (*Capability, error)
	Capabilities(ctx context.Context) iter.Seq2[CapabilityReference, error]

	ListSubscriptions(ctx context.Context, installedAppID string) ([]Subscription, error)
	CreateSubscription(ctx context.Context, installedAppID string, sub *SubscriptionCreate) (*Subscription, error)
	DeleteSubscription(ctx context.Context, installedAppID, subscriptionID string) error
	DeleteAllSubscriptions(ctx context.Context, installedAppID string) error
	Subscriptions(ctx context.Context, installedAppID string) iter.Seq2[Subscription, error]

	ListRules(ctx context.Context, locationID string) ([]Rule, error)
	GetRule(ctx context.Context, ruleID string) (*Rule, error)
	CreateRule(ctx context.Context, locationID string, rule *RuleCreate) (*Rule, error)
	UpdateRule(ctx context.Context, ruleID string, rule *RuleUpdate) (*Rule, error)
	DeleteRule(ctx context.Context, ruleID string) error
	ExecuteRule(ctx context.Context, ruleID string) error
	Rules(ctx context.Context, locationID string) iter.Seq2[Rule, error]

	ListSchedules(ctx context.Context, installedAppID string) ([]Schedule, error)
	GetSchedule(ctx context.Context, installedAppID, scheduleName string) (*Schedule, error)
	CreateSchedule(ctx context.Context, installedAppID string, schedule *ScheduleCreate) (*Schedule, error)
	DeleteSchedule(ctx context.Context, installedAppID, scheduleName string) error
	Schedules(ctx context.Context, installedAppID string) iter.Seq2[Schedule, error]

	ListInstalledApps(ctx context.Context, locationID string) ([]InstalledApp, error)
	GetInstalledApp(ctx context.Context, installedAppID string) (*InstalledApp, error)
	DeleteInstalledApp(ctx context.Context, installedAppID string) error
	ListInstalledAppConfigs(ctx context.Context, installedAppID string) ([]InstalledAppConfigItem, error)
	GetInstalledAppConfig(ctx context.Context, installedAppID, configID string) (*InstalledAppConfiguration, error)
	GetCurrentInstalledAppConfig(ctx context.Context, installedAppID string) (*InstalledAppConfiguration, error)
	InstalledApps(ctx context.Context, locationID string) iter.Seq2[InstalledApp, error]

	ListModes(ctx context.Context, locationID string) ([]Mode, error)
	GetMode(ctx context.Context, locationID, modeID string) (*Mode, error)
	GetCurrentMode(ctx context.Context, locationID string) (*Mode, error)
	SetCurrentMode(ctx context.Context, locationID, modeID string) (*Mode, error)
	Modes(ctx context.Context, locationID string) iter.Seq2[Mode, error]

	GetDeviceEvents(ctx context.Context, deviceID string, opts *HistoryOptions) (*PagedEvents, error)
	GetDeviceStates(ctx context.Context, deviceID string, opts *HistoryOptions) (*PagedStates, error)
	DeviceEvents(ctx context.Context, deviceID string, opts *HistoryOptions) iter.Seq2[DeviceEvent, error]

	ListApps(ctx context.Context) ([]App, error)
	GetApp(ctx context.Context, appID string) (*App, error)
	CreateApp(ctx context.Context, app *AppCreate) (*App, error)
	UpdateApp(ctx context.Context, appID string, update *AppUpdate) (*App, error)
	DeleteApp(ctx context.Context, appID string) error
	GetAppOAuth(ctx context.Context, appID string) (*AppOAuth, error)
	UpdateAppOAuth(ctx context.Context, appID string, oauth *AppOAuth) (*AppOAuth, error)
	GenerateAppOAuth(ctx context.Context, appID string) (*AppOAuthGenerated, error)
	Apps(ctx context.Context) iter.Seq2[App, error]

	ListDeviceProfiles(ctx context.Context) ([]DeviceProfileFull, error)
	GetDeviceProfile(ctx context.Context, profileID string) (*DeviceProfileFull, error)
	CreateDeviceProfile(ctx context.Context, profile *DeviceProfileCreate) (*DeviceProfileFull, error)
	UpdateDeviceProfile(ctx context.Context, profileID string, update *DeviceProfileUpdate) (*DeviceProfileFull, error)
	DeleteDeviceProfile(ctx context.Context, profileID string) error
	DeviceProfiles(ctx context.Context) iter.Seq2[DeviceProfileFull, error]

	ListDevicePreferences(ctx context.Context, namespace string) ([]DevicePreference, error)
	GetDevicePreference(ctx context.Context, preferenceID string) (*DevicePreference, error)
	CreateDevicePreference(ctx context.Context, pref *DevicePreferenceCreate) (*DevicePreference, error)
	UpdateDevicePreference(ctx context.Context, preferenceID string, pref *DevicePreference) (*DevicePreference, error)
	CreatePreferenceTranslations(ctx context.Context, preferenceID string, localization *PreferenceLocalization) (*PreferenceLocalization, error)
	GetPreferenceTranslations(ctx context.Context, preferenceID, locale string) (*PreferenceLocalization, error)
	ListPreferenceTranslations(ctx context.Context, preferenceID string) ([]LocaleReference, error)
	UpdatePreferenceTranslations(ctx context.Context, preferenceID string, localization *PreferenceLocalization) (*PreferenceLocalization, error)
	DevicePreferences(ctx context.Context, namespace string) iter.Seq2[DevicePreference, error]

	GeneratePresentation(ctx context.Context, profileID string) (*PresentationDeviceConfig, error)
	CreatePresentationConfig(ctx context.Context, config *PresentationDeviceConfigCreate) (*PresentationDeviceConfig, error)
	GetPresentationConfig(ctx context.Context, presentationID, manufacturerName string) (*PresentationDeviceConfig, error)
	GetDevicePresentation(ctx context.Context, presentationID, manufacturerName string) (*PresentationDevicePresentation, error)

	GetHub(ctx context.Context, hubID string) (*Hub, error)
	GetHubCharacteristics(ctx context.Context, hubID string) (HubCharacteristics, error)
	ListEnrolledChannels(ctx context.Context, hubID string) ([]EnrolledChannel, error)
	ListInstalledDrivers(ctx context.Context, hubID string, deviceID string) ([]InstalledDriver, error)
	GetInstalledDriver(ctx context.Context, hubID, driverID string) (*InstalledDriver, error)
	InstallDriver(ctx context.Context, driverID, hubID, channelID string) error
	UninstallDriver(ctx context.Context, driverID, hubID string) error
	SwitchDriver(ctx context.Context, driverID, hubID, deviceID string, forceUpdate bool) error
	EnrolledChannels(ctx context.Context, hubID string) iter.Seq2[EnrolledChannel, error]
	InstalledDrivers(ctx context.Context, hubID, deviceID string) iter.Seq2[InstalledDriver, error]

	ListDrivers(ctx context.Context) ([]EdgeDriverSummary, error)
	ListDefaultDrivers(ctx context.Context) ([]EdgeDriver, error)
	GetDriver(ctx context.Context, driverID string) (*EdgeDriver, error)
	GetDriverRevision(ctx context.Context, driverID, version string) (*EdgeDriver, error)
	DeleteDriver(ctx context.Context, driverID string) error
	UploadDriver(ctx context.Context, archiveData []byte) (*EdgeDriver, error)
	Drivers(ctx context.Context) iter.Seq2[EdgeDriverSummary, error]

	ListChannels(ctx context.Context, opts *ChannelListOptions) ([]Channel, error)
	GetChannel(ctx context.Context, channelID string) (*Channel, error)
	CreateChannel(ctx context.Context, channel *ChannelCreate) (*Channel, error)
	UpdateChannel(ctx context.Context, channelID string, update *ChannelUpdate) (*Channel, error)
	DeleteChannel(ctx context.Context, channelID string) error
	ListAssignedDrivers(ctx context.Context, channelID string) ([]DriverChannelDetails, error)
	AssignDriver(ctx context.Context, channelID, driverID, version string) (*DriverChannelDetails, error)
	UnassignDriver(ctx context.Context, channelID, driverID string) error
	GetDriverChannelMetaInfo(ctx context.Context, channelID, driverID string) (*EdgeDriver, error)
	EnrollHub(ctx context.Context, channelID, hubID string) error
	UnenrollHub(ctx context.Context, channelID, hubID string) error
	Channels(ctx context.Context, opts *ChannelListOptions) iter.Seq2[Channel, error]
	AssignedDrivers(ctx context.Context, channelID string) iter.Seq2[DriverChannelDetails, error]

	CreateVirtualDevice(ctx context.Context, req *VirtualDeviceCreateRequest) (*Device, error)
	CreateStandardVirtualDevice(ctx context.Context, req *VirtualDeviceStandardCreateRequest) (*Device, error)
	ListVirtualDevices(ctx context.Context, opts *VirtualDeviceListOptions) ([]Device, error)
	CreateVirtualDeviceEvents(ctx context.Context, deviceID string, events []VirtualDeviceEvent) (*VirtualDeviceEventsResponse, error)

	ListSchemaApps(ctx context.Context, includeAllOrganizations bool) ([]SchemaApp, error)
	GetSchemaApp(ctx context.Context, appID string) (*SchemaApp, error)
	CreateSchemaApp(ctx context.Context, req *SchemaAppRequest, organizationID string) (*SchemaCreateResponse, error)
	UpdateSchemaApp(ctx context.Context, appID string, req *SchemaAppRequest, organizationID string) error
	DeleteSchemaApp(ctx context.Context, appID string) error
	GetSchemaAppPage(ctx context.Context, appID, locationID string) (*SchemaPage, error)
	RegenerateSchemaAppOAuth(ctx context.Context, appID string) (*SchemaCreateResponse, error)
	ListInstalledSchemaApps(ctx context.Context, locationID string) ([]InstalledSchemaApp, error)
	GetInstalledSchemaApp(ctx context.Context, isaID string) (*InstalledSchemaApp, error)
	DeleteInstalledSchemaApp(ctx context.Context, isaID string) error
	SchemaApps(ctx context.Context, includeAllOrganizations bool) iter.Seq2[SchemaApp, error]
	InstalledSchemaApps(ctx context.Context, locationID string) iter.Seq2[InstalledSchemaApp, error]

	CreateSchemaAppInvitation(ctx context.Context, invitation *SchemaAppInvitationCreate) (*SchemaAppInvitationID, error)
	ListSchemaAppInvitations(ctx context.Context, schemaAppID string) ([]SchemaAppInvitation, error)
	RevokeSchemaAppInvitation(ctx context.Context, invitationID string) error
	SchemaAppInvitations(ctx context.Context, schemaAppID string) iter.Seq2[SchemaAppInvitation, error]

	ListOrganizations(ctx context.Context) ([]Organization, error)
	GetOrganization(ctx context.Context, organizationID string) (*Organization, error)
	Organizations(ctx context.Context) iter.Seq2[Organization, error]

	CreateNotification(ctx context.Context, req *NotificationRequest) (*NotificationResponse, error)

	GetLocationServiceInfo(ctx context.Context, locationID string) (*ServiceLocationInfo, error)
	GetServiceCapabilitiesList(ctx context.Context, locationID string) ([]ServiceCapability, error)
	GetServiceCapability(ctx context.Context, capability ServiceCapability, locationID string) (*ServiceCapabilityData, error)
	GetServiceCapabilitiesData(ctx context.Context, capabilities []ServiceCapability, locationID string) (*ServiceCapabilityData, error)
	CreateServiceSubscription(ctx context.Context, req *ServiceSubscriptionRequest, installedAppID, locationID string) (*ServiceNewSubscription, error)
	UpdateServiceSubscription(ctx context.Context, subscriptionID string, req *ServiceSubscriptionRequest, installedAppID, locationID string) (*ServiceNewSubscription, error)
	DeleteServiceSubscription(ctx context.Context, subscriptionID, installedAppID, locationID string) error
	DeleteAllServiceSubscriptions(ctx context.Context, installedAppID, locationID string) error

	FetchTVStatus(ctx context.Context, deviceID string) (*TVStatus, error)
	FetchTVInputs(ctx context.Context, deviceID string) ([]TVInput, error)
	SetTVPower(ctx context.Context, deviceID string, on bool) error
	SetTVVolume(ctx context.Context, deviceID string, volume int) error
	SetTVMute(ctx context.Context, deviceID string, muted bool) error
	SetTVInput(ctx context.Context, deviceID, inputID string) error
	SetTVChannel(ctx context.Context, deviceID string, channel int) error
	SendTVKey(ctx context.Context, deviceID, key string) error
	LaunchTVApp(ctx context.Context, deviceID, appID string) error
	TVPlay(ctx context.Context, deviceID string) error
	TVPause(ctx context.Context, deviceID string) error
	TVStop(ctx context.Context, deviceID string) error
	TVChannelUp(ctx context.Context, deviceID string) error
	TVChannelDown(ctx context.Context, deviceID string) error
	TVVolumeUp(ctx context.Context, deviceID string) error
	TVVolumeDown(ctx context.Context, deviceID string) error
	SetPictureMode(ctx context.Context, deviceID, mode string) error
	SetSoundMode(ctx context.Context, deviceID, mode string) error

	RateLimitInfo() *RateLimitInfo
	RateLimitResetTime() time.Time
	RemainingRequests() int
	ShouldThrottle(threshold int) bool
	WaitForRateLimit(ctx context.Context) error
	WaitForRateLimitErr(ctx context.Context, err error) error

	InvalidateCache(resourceType string, ids ...string)
	InvalidateCapabilityCache()

	Token() string
	SetToken(token string)

	LogRequest(ctx context.Context, method, path string)
	LogResponse(ctx context.Context, method, path string, statusCode int, duration time.Duration, err error)
	LogDeviceCommand(ctx context.Context, deviceID string, capability, command string, err error)
	LogRateLimit(ctx context.Context, info RateLimitInfo)
}

SmartThingsClient defines the interface for SmartThings API operations. Both Client and OAuthClient implement this interface, enabling mocking for tests.

type Status

type Status map[string]any

Status represents the raw device status response as a flexible map. The SmartThings API returns deeply nested JSON structures that vary by device type.

type StringConfig added in v1.0.1

type StringConfig struct {
	Value string `json:"value"`
}

StringConfig represents a string configuration value.

type StringType added in v1.0.1

type StringType string

StringType represents the type of string input.

const (
	// StringTypeText is plain text.
	StringTypeText StringType = "text"
	// StringTypePassword is a password field.
	StringTypePassword StringType = "password"
	// StringTypeEmail is an email address.
	StringTypeEmail StringType = "email"
)

type SubscriberType added in v1.0.1

type SubscriberType string

SubscriberType represents the type of channel subscriber.

const (
	// SubscriberTypeHub indicates hub subscribers.
	SubscriberTypeHub SubscriberType = "HUB"
)

type Subscription

type Subscription struct {
	ID              string                       `json:"id"`
	InstalledAppID  string                       `json:"installedAppId"`
	SourceType      string                       `json:"sourceType"` // DEVICE, CAPABILITY, MODE, DEVICE_LIFECYCLE, etc.
	Device          *DeviceSubscription          `json:"device,omitempty"`
	Capability      *CapabilitySubscription      `json:"capability,omitempty"`
	Mode            *ModeSubscription            `json:"mode,omitempty"`
	DeviceLifecycle *DeviceLifecycleSubscription `json:"deviceLifecycle,omitempty"`
	DeviceHealth    *DeviceHealthSubscription    `json:"deviceHealth,omitempty"`
	SecuritySystem  *SecuritySystemSubscription  `json:"securityArmState,omitempty"`
	HubHealth       *HubHealthSubscription       `json:"hubHealth,omitempty"`
	SceneLifecycle  *SceneLifecycleSubscription  `json:"sceneLifecycle,omitempty"`
}

Subscription represents a webhook subscription.

type SubscriptionCreate

type SubscriptionCreate struct {
	SourceType      string                       `json:"sourceType"`
	Device          *DeviceSubscription          `json:"device,omitempty"`
	Capability      *CapabilitySubscription      `json:"capability,omitempty"`
	Mode            *ModeSubscription            `json:"mode,omitempty"`
	DeviceLifecycle *DeviceLifecycleSubscription `json:"deviceLifecycle,omitempty"`
	DeviceHealth    *DeviceHealthSubscription    `json:"deviceHealth,omitempty"`
	SecuritySystem  *SecuritySystemSubscription  `json:"securityArmState,omitempty"`
	HubHealth       *HubHealthSubscription       `json:"hubHealth,omitempty"`
	SceneLifecycle  *SceneLifecycleSubscription  `json:"sceneLifecycle,omitempty"`
}

SubscriptionCreate is the request body for creating a subscription.

type TVApp

type TVApp struct {
	ID   string `json:"id"`
	Name string `json:"name"`
}

TVApp represents an installed TV application.

func CommonTVApps

func CommonTVApps() []TVApp

CommonTVApps returns a list of commonly available Samsung TV apps. Use this as a fallback when apps can't be retrieved from the device.

func GetTVApps

func GetTVApps(status Status) []TVApp

GetTVApps extracts available apps from a device status.

type TVDeviceInfo added in v1.0.5

type TVDeviceInfo struct {
	ID             string `json:"id"`
	Name           string `json:"name"`
	Model          string `json:"model"`
	ModelName      string `json:"modelName"`
	Type           string `json:"type"`
	NetworkType    string `json:"networkType"`
	SSID           string `json:"ssid,omitempty"`
	WifiMac        string `json:"wifiMac,omitempty"`
	IP             string `json:"ip"`
	Device         string `json:"device"`
	TokenAuth      string `json:"tokenAuthSupport,omitempty"`
	PowerState     string `json:"PowerState,omitempty"`
	FrameTVSupport string `json:"FrameTVSupport,omitempty"`
	OS             string `json:"OS,omitempty"`
}

TVDeviceInfo contains information about a Samsung TV.

type TVInput

type TVInput struct {
	ID   string `json:"id"`
	Name string `json:"name"`
}

TVInput represents an available TV input source.

func GetTVInputs

func GetTVInputs(status Status) []TVInput

GetTVInputs extracts available TV inputs from a device status.

type TVLocalClient added in v1.0.5

type TVLocalClient struct {
	// contains filtered or unexported fields
}

TVLocalClient provides direct control of Samsung TVs via their local WebSocket API. This is separate from the SmartThings API and provides lower latency control.

func NewTVLocalClient added in v1.0.5

func NewTVLocalClient(cfg *TVLocalConfig) (*TVLocalClient, error)

NewTVLocalClient creates a new client for connecting to a Samsung TV's local API.

func (*TVLocalClient) Close added in v1.0.5

func (c *TVLocalClient) Close() error

Close closes the WebSocket connection.

func (*TVLocalClient) Connect added in v1.0.5

func (c *TVLocalClient) Connect(ctx context.Context) error

Connect establishes a WebSocket connection to the TV's local API.

func (*TVLocalClient) Errors added in v1.0.5

func (c *TVLocalClient) Errors() <-chan error

Errors returns a channel that receives connection errors.

func (*TVLocalClient) GetDeviceInfo added in v1.0.5

func (c *TVLocalClient) GetDeviceInfo(ctx context.Context) (*TVDeviceInfo, error)

GetDeviceInfo fetches TV device information via HTTP REST API.

func (*TVLocalClient) IsConnected added in v1.0.5

func (c *TVLocalClient) IsConnected() bool

IsConnected returns true if the client is connected.

func (*TVLocalClient) LaunchApp added in v1.0.5

func (c *TVLocalClient) LaunchApp(appID string, actionType string, metaTag string) error

LaunchApp launches an app on the TV.

func (*TVLocalClient) OpenBrowser added in v1.0.5

func (c *TVLocalClient) OpenBrowser(urlStr string) error

OpenBrowser opens a URL in the TV's browser.

func (*TVLocalClient) Responses added in v1.0.5

func (c *TVLocalClient) Responses() <-chan tvLocalResponse

Responses returns a channel that receives TV responses.

func (*TVLocalClient) SendKey added in v1.0.5

func (c *TVLocalClient) SendKey(key string) error

SendKey sends a remote control key press to the TV. Common keys: KEY_POWER, KEY_HOME, KEY_MENU, KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_ENTER, KEY_RETURN, KEY_EXIT, KEY_VOLUP, KEY_VOLDOWN, KEY_MUTE, KEY_CHUP, KEY_CHDOWN, KEY_0 through KEY_9, KEY_PLAY, KEY_PAUSE, KEY_STOP

func (*TVLocalClient) SendText added in v1.0.5

func (c *TVLocalClient) SendText(text string) error

SendText sends text input to the TV. This is used when the TV has a text input field active (e.g., search box).

type TVLocalConfig added in v1.0.5

type TVLocalConfig struct {
	// TVIP is the local IP address of the Samsung TV.
	TVIP string

	// Port is the TV API port (default: 8002 for secure, 8001 for non-secure).
	Port int

	// Token is the authentication token (required for secure connections on port 8002).
	// This is obtained on first connection when the TV prompts the user.
	Token string

	// AppName is the name shown on the TV when connecting (default: "SmartThings-Go").
	AppName string

	// Secure enables TLS for the WebSocket connection (default: true if port is 8002).
	Secure *bool

	// OnTokenReceived is called when the TV provides an authentication token.
	// This allows persisting the token for future connections.
	OnTokenReceived func(token string)
}

TVLocalConfig configures the TVLocalClient.

type TVStatus

type TVStatus struct {
	Power       string `json:"power"`        // "on" or "off"
	Volume      int    `json:"volume"`       // 0-100
	Muted       bool   `json:"muted"`        // true if muted
	InputSource string `json:"input_source"` // e.g., "HDMI1", "Netflix"
}

TVStatus represents the current status of a Samsung TV.

func GetTVStatus

func GetTVStatus(status Status) *TVStatus

GetTVStatus extracts TV status from a device status response. This is a helper that parses the status without making an API call.

type TimerEventDetail

type TimerEventDetail struct {
	EventID string `json:"eventId"`
	Name    string `json:"name"`
	Type    string `json:"type"` // CRON, ONCE
	Time    string `json:"time"`
}

TimerEventDetail contains details of a timer event.

type TokenResponse

type TokenResponse struct {
	AccessToken           string    `json:"access_token"`
	RefreshToken          string    `json:"refresh_token"`
	ExpiresIn             int       `json:"expires_in"`
	RefreshTokenExpiresIn int       `json:"refresh_token_expires_in,omitempty"`
	TokenType             string    `json:"token_type"`
	Scope                 string    `json:"scope"`
	InstalledAppID        string    `json:"installed_app_id,omitempty"`
	ExpiresAt             time.Time `json:"expires_at"`
	RefreshTokenExpiresAt time.Time `json:"refresh_token_expires_at,omitempty"`
}

TokenResponse represents the response from the OAuth token endpoint

func ExchangeCode

func ExchangeCode(ctx context.Context, cfg *OAuthConfig, code string) (*TokenResponse, error)

ExchangeCode exchanges an authorization code for access and refresh tokens

func RefreshTokens

func RefreshTokens(ctx context.Context, cfg *OAuthConfig, refreshToken string) (*TokenResponse, error)

RefreshTokens refreshes the access token using a refresh token

func (*TokenResponse) IsRefreshTokenValid

func (t *TokenResponse) IsRefreshTokenValid() bool

IsRefreshTokenValid checks if the refresh token is still valid

func (*TokenResponse) IsValid

func (t *TokenResponse) IsValid() bool

IsValid checks if the access token is still valid (with buffer)

func (*TokenResponse) NeedsRefresh

func (t *TokenResponse) NeedsRefresh() bool

NeedsRefresh returns true if the access token should be refreshed

type TokenStore

type TokenStore interface {
	SaveTokens(ctx context.Context, tokens *TokenResponse) error
	LoadTokens(ctx context.Context) (*TokenResponse, error)
}

TokenStore is the interface for persisting OAuth tokens

type UninstallData

type UninstallData struct {
	InstalledApp InstalledAppRef `json:"installedApp"`
}

UninstallData contains data for UNINSTALL lifecycle events.

type UpdateData

type UpdateData struct {
	AuthToken      string          `json:"authToken"`
	RefreshToken   string          `json:"refreshToken"`
	InstalledApp   InstalledAppRef `json:"installedApp"`
	PreviousConfig ConfigMap       `json:"previousConfig,omitempty"`
}

UpdateData contains data for UPDATE lifecycle events.

type ViperAppLinks struct {
	Android string `json:"android,omitempty"`
	IOS     string `json:"ios,omitempty"`
	Web     string `json:"web,omitempty"`
}

ViperAppLinks contains links for ST Schema app configuration.

type ViperDeviceInfo

type ViperDeviceInfo struct {
	UniqueID        string `json:"uniqueIdentifier,omitempty"`
	MACAddress      string `json:"macAddress,omitempty"`
	HubID           string `json:"hubId,omitempty"`
	ProvisionedTime string `json:"provisionedTime,omitempty"`
}

ViperDeviceInfo contains Viper (Samsung Connect) device information.

type VirtualDeviceCreateRequest added in v1.0.1

type VirtualDeviceCreateRequest struct {
	Name            string              `json:"name"`
	Owner           *VirtualDeviceOwner `json:"owner,omitempty"`
	RoomID          string              `json:"roomId,omitempty"`
	DeviceProfileID string              `json:"deviceProfileId,omitempty"`
	ExecutionTarget ExecutionTarget     `json:"executionTarget,omitempty"`
	HubID           string              `json:"hubId,omitempty"`
}

VirtualDeviceCreateRequest is the request body for creating a virtual device.

type VirtualDeviceEvent added in v1.0.1

type VirtualDeviceEvent struct {
	Component  string `json:"component,omitempty"`
	Capability string `json:"capability"`
	Attribute  string `json:"attribute"`
	Value      any    `json:"value"`
	Unit       string `json:"unit,omitempty"`
}

VirtualDeviceEvent represents an event to create on a virtual device.

type VirtualDeviceEventResponse added in v1.0.1

type VirtualDeviceEventResponse struct {
	Component   string `json:"component,omitempty"`
	Capability  string `json:"capability,omitempty"`
	Attribute   string `json:"attribute,omitempty"`
	Value       any    `json:"value,omitempty"`
	StateChange bool   `json:"stateChange,omitempty"`
}

VirtualDeviceEventResponse represents a single event response.

type VirtualDeviceEventsResponse added in v1.0.1

type VirtualDeviceEventsResponse struct {
	StateChanges []VirtualDeviceEventResponse `json:"stateChanges,omitempty"`
}

VirtualDeviceEventsResponse is the response from creating virtual device events.

type VirtualDeviceListOptions added in v1.0.1

type VirtualDeviceListOptions struct {
	LocationID string // Filter by location ID
}

VirtualDeviceListOptions contains options for listing virtual devices.

type VirtualDeviceOwner added in v1.0.1

type VirtualDeviceOwner struct {
	OwnerType VirtualDeviceOwnerType `json:"ownerType"`
	OwnerID   string                 `json:"ownerId"`
}

VirtualDeviceOwner specifies the owner of a virtual device.

type VirtualDeviceOwnerType added in v1.0.1

type VirtualDeviceOwnerType string

VirtualDeviceOwnerType represents the type of virtual device owner.

const (
	// VirtualDeviceOwnerUser indicates the device is owned by a user.
	VirtualDeviceOwnerUser VirtualDeviceOwnerType = "USER"
	// VirtualDeviceOwnerLocation indicates the device is owned by a location.
	VirtualDeviceOwnerLocation VirtualDeviceOwnerType = "LOCATION"
)

type VirtualDeviceStandardCreateRequest added in v1.0.1

type VirtualDeviceStandardCreateRequest struct {
	Name            string              `json:"name"`
	Owner           *VirtualDeviceOwner `json:"owner,omitempty"`
	RoomID          string              `json:"roomId,omitempty"`
	Prototype       string              `json:"prototype"` // e.g., "VIRTUAL_SWITCH", "VIRTUAL_DIMMER"
	ExecutionTarget ExecutionTarget     `json:"executionTarget,omitempty"`
	HubID           string              `json:"hubId,omitempty"`
}

VirtualDeviceStandardCreateRequest is the request body for creating a standard virtual device.

type WasherDetailedStatus added in v1.0.5

type WasherDetailedStatus struct {
	// Operating state
	State          string  `json:"state"`                     // "idle", "running", "paused", etc.
	RemainingMins  *int    `json:"remaining_mins,omitempty"`  // Minutes remaining
	CompletionTime *string `json:"completion_time,omitempty"` // ISO8601 completion time
	CycleProgress  *int    `json:"cycle_progress,omitempty"`  // 0-100%

	// CRITICAL: Remote control status - controls whether commands can be sent
	RemoteControlEnabled bool `json:"remote_control_enabled"`

	// Current settings
	CurrentCycle     string `json:"current_cycle,omitempty"`
	WaterTemperature string `json:"water_temperature,omitempty"`
	SpinLevel        string `json:"spin_level,omitempty"`
	SoilLevel        string `json:"soil_level,omitempty"`

	// Child lock
	ChildLockOn bool `json:"child_lock_on"`

	// Supported options (for UI dropdowns)
	SupportedCycles     []string `json:"supported_cycles,omitempty"`
	SupportedWaterTemps []string `json:"supported_water_temps,omitempty"`
	SupportedSpinLevels []string `json:"supported_spin_levels,omitempty"`
	SupportedSoilLevels []string `json:"supported_soil_levels,omitempty"`
}

WasherDetailedStatus provides comprehensive washer status including remote control state. Use ExtractWasherDetailedStatus to extract from a device status response.

func ExtractWasherDetailedStatus added in v1.0.5

func ExtractWasherDetailedStatus(status Status) *WasherDetailedStatus

ExtractWasherDetailedStatus extracts comprehensive washer status. This includes operating state, current settings, supported options, and the critical remoteControlEnabled flag for the UI warning banner.

Example:

status, _ := client.GetDeviceStatus(ctx, washerID)
washer := st.ExtractWasherDetailedStatus(status)
if !washer.RemoteControlEnabled {
    // Show warning: "Enable Remote Control on the washer to control it"
}

type WeatherData added in v1.0.1

type WeatherData struct {
	CloudCeiling          *float64 `json:"cloudCeiling,omitempty"`
	CloudCoverPhrase      string   `json:"cloudCoverPhrase,omitempty"`
	IconCode              int      `json:"iconCode,omitempty"`
	ConditionState        string   `json:"conditionState,omitempty"`
	RelativeHumidity      int      `json:"relativeHumidity,omitempty"`
	SunriseTimeLocal      string   `json:"sunriseTimeLocal,omitempty"`
	SunsetTimeLocal       string   `json:"sunsetTimeLocal,omitempty"`
	Temperature           float64  `json:"temperature,omitempty"`
	TemperatureFeelsLike  float64  `json:"temperatureFeelsLike,omitempty"`
	UVDescription         string   `json:"uvDescription,omitempty"`
	UVIndex               int      `json:"uvIndex,omitempty"`
	Visibility            float64  `json:"visibility,omitempty"`
	WindDirection         int      `json:"windDirection,omitempty"`
	WindDirectionCardinal string   `json:"windDirectionCardinal,omitempty"`
	WindGust              *float64 `json:"windGust,omitempty"`
	WindSpeed             float64  `json:"windSpeed,omitempty"`
	WxPhraseLong          string   `json:"wxPhraseLong,omitempty"`
}

WeatherData contains current weather information.

type WeatherForecastData added in v1.0.1

type WeatherForecastData struct {
	Daily  []DailyForecast  `json:"daily,omitempty"`
	Hourly []HourlyForecast `json:"hourly,omitempty"`
}

WeatherForecastData contains weather forecast information.

type WebhookAppInfo

type WebhookAppInfo struct {
	TargetURL        string   `json:"targetUrl"`
	TargetStatus     string   `json:"targetStatus,omitempty"` // PENDING, CONFIRMED
	PublicKey        string   `json:"publicKey,omitempty"`
	SignatureType    string   `json:"signatureType,omitempty"` // ST_PADLOCK, APP_RSA
	ConfirmationURL  string   `json:"confirmationUrl,omitempty"`
	MaxInstances     int      `json:"maxInstances,omitempty"`
	PermissionScopes []string `json:"permissionScopes,omitempty"`
}

WebhookAppInfo contains webhook SmartApp configuration.

type WebhookEvent

type WebhookEvent struct {
	Lifecycle         WebhookLifecycle   `json:"lifecycle"`
	ExecutionID       string             `json:"executionId"`
	AppID             string             `json:"appId"`
	Locale            string             `json:"locale,omitempty"`
	Version           string             `json:"version,omitempty"`
	PingData          *PingData          `json:"pingData,omitempty"`
	ConfirmationData  *ConfirmationData  `json:"confirmationData,omitempty"`
	ConfigurationData *ConfigurationData `json:"configurationData,omitempty"`
	InstallData       *InstallData       `json:"installData,omitempty"`
	UpdateData        *UpdateData        `json:"updateData,omitempty"`
	EventData         *EventData         `json:"eventData,omitempty"`
	UninstallData     *UninstallData     `json:"uninstallData,omitempty"`
	OAuthCallbackData *OAuthCallbackData `json:"oAuthCallbackData,omitempty"`
}

WebhookEvent represents a webhook request from SmartThings.

func ParseWebhookRequest

func ParseWebhookRequest(r *http.Request, secret string) (*WebhookEvent, error)

ParseWebhookRequest parses and validates a webhook request from SmartThings. It reads the request body and verifies the signature using the provided secret. If secret is empty, signature validation is skipped (not recommended for production).

type WebhookLifecycle

type WebhookLifecycle string

WebhookLifecycle represents the type of webhook event.

const (
	LifecyclePing          WebhookLifecycle = "PING"
	LifecycleConfirmation  WebhookLifecycle = "CONFIRMATION"
	LifecycleConfiguration WebhookLifecycle = "CONFIGURATION"
	LifecycleInstall       WebhookLifecycle = "INSTALL"
	LifecycleUpdate        WebhookLifecycle = "UPDATE"
	LifecycleEvent         WebhookLifecycle = "EVENT"
	LifecycleUninstall     WebhookLifecycle = "UNINSTALL"
	LifecycleOAuthCallback WebhookLifecycle = "OAUTH_CALLBACK"
)

Webhook lifecycle constants.

Directories

Path Synopsis
examples
oauth-server command
Example OAuth server demonstrating SmartThings OAuth 2.0 flow
Example OAuth server demonstrating SmartThings OAuth 2.0 flow
webhook-handler command
Example webhook handler demonstrating SmartThings webhook processing
Example webhook handler demonstrating SmartThings webhook processing

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL