A MagicMirror² module that displays the status of your SmartThings devices in a clean, card-style interface.
- OAuth authentication with automatic token refresh (24-hour token expiration handled automatically)
- Interactive setup wizard - Complete guided configuration in one command
- Room-based device selection - Select devices by room or pick individual devices
- Intelligent alerts - Footer alerts for API issues with auto-dismiss on recovery
- Smart caching - Faster startup and offline resilience
- Rate limit aware - Respects SmartThings API limits with automatic backoff
- Multi-language support - English, German, French, Spanish, Dutch
- Test mode - Development and screenshots without API access
- MagicMirror² version 2.25.0 or later
- Node.js version 18.0.0 or later
- A SmartThings account with connected devices
- SmartThings CLI (for creating OAuth app)
cd ~/MagicMirror/modules
git clone https://github.com/sonnyb9/MMM-STStatus.git
cd MMM-STStatus
npm installDownload and install the SmartThings CLI from: https://github.com/SmartThingsCommunity/smartthings-cli/releases
- Windows: Download and run the
.msiinstaller - macOS:
brew install smartthingscommunity/smartthings/smartthings - Linux: Download the appropriate binary from releases
Verify installation:
smartthings --versionRun any command to trigger the login flow:
smartthings devicesA browser window will open - log in with your Samsung account.
Run:
smartthings apps:createWhen prompted, enter:
- App type: OAuth-In App
- Display name:
MMM-STStatus - Description:
MagicMirror SmartThings Status Display - Icon image URL: (leave blank, press Enter)
- Target URL: (leave blank, press Enter)
- Scopes: Select these permissions:
r:devices:*(read devices)x:devices:*(execute device commands)r:locations:*(read locations)
- Redirect URIs:
https://httpbin.org/get
Important: Save the OAuth Client Id and OAuth Client Secret displayed at the end. You won't be able to see the secret again!
cd ~/MagicMirror/modules/MMM-STStatus
node setup.jsThe setup wizard will guide you through:
- OAuth authentication - Enter your Client ID and Secret, authorize in browser
- Position selection - Choose where the module appears on your mirror
- Location selection - Pick your SmartThings location (if you have multiple)
- Room selection - Choose which rooms to include
- Device selection - Pick specific devices or include all from selected rooms
- Display options - Configure polling interval, temperature units, etc.
- Config generation - Produces a ready-to-paste configuration block
Copy the generated configuration block into your ~/MagicMirror/config/config.js file in the modules array.
Example output from setup wizard:
{
module: "MMM-STStatus",
position: "top_right",
header: "Smart Home",
config: {
devices: [
{ id: "device-uuid-1", name: "Front Door" },
{ id: "device-uuid-2", name: "Living Room Lamp" }
],
hiddenDevices: [],
pollInterval: 60000,
broadcastDeviceData: false,
broadcastNotification: "STSTATUS_DEVICE_DATA",
showLastUpdated: true,
temperatureUnit: "F",
defaultSort: "name",
debug: false,
testMode: false
}
}Note: OAuth credentials (clientId, clientSecret) are stored encrypted in oauth-data.enc, not in config.js.
pm2 restart MagicMirror| Option | Type | Default | Description |
|---|---|---|---|
devices |
Array | [] |
Explicit list of devices: [{ id: "uuid", name: "Display Name" }] |
hiddenDevices |
Array | [] |
Device IDs to fetch and broadcast but omit from the visible table |
rooms |
Array | [] |
List of room names to include (e.g., ["Living Room"]) |
pollInterval |
Number | 60000 |
How often to fetch updates (ms, minimum 30000) |
broadcastDeviceData |
Boolean | false |
Re-broadcast normalized device payloads to other frontend modules |
broadcastNotification |
String | "STSTATUS_DEVICE_DATA" |
Notification name used when broadcastDeviceData is enabled |
showLastUpdated |
Boolean | true |
Show clock time of last successful API update (e.g., "Last Update: 10:30:45 AM") |
showDeviceType |
Boolean | true |
Show device type column (e.g., "Lock", "Door Sensor") |
fontSize |
Number | 100 |
Font size as percentage (e.g., 80 for smaller, 120 for larger) |
temperatureUnit |
String | "F" |
Temperature unit: "F" or "C" |
defaultSort |
String | "name" |
Sort by: "name", "room", or "capability" |
debug |
Boolean | false |
Enable verbose console logging |
testMode |
Boolean | false |
Use mock data (no API calls) |
token |
String | "" |
Legacy: Personal Access Token (deprecated, use setup.js instead) |
Note: Use either devices (explicit list) or rooms (fetch all devices from rooms), not both.
If another frontend module needs SmartThings sensor data, you can let MMM-STStatus fetch the devices once and rebroadcast the normalized payload:
{
module: "MMM-STStatus",
position: "middle_center",
config: {
devices: [
{ id: "pool-sensor-uuid", name: "Pool Sensor" }
],
hiddenDevices: ["pool-sensor-uuid"],
broadcastDeviceData: true,
broadcastNotification: "STSTATUS_DEVICE_DATA"
}
}That pattern is useful when a sensor should feed another module, such as MMM-PoolTemp, without also adding another visible row to the SmartThings status table.
The rebroadcast payload preserves normalized temperature metadata when SmartThings provides it, including:
device.temperaturedevice.temperatureUpdatedAtdevice.capabilities.temperaturedevice.capabilities.temperatureUpdatedAt
That gives downstream modules a stable way to distinguish a fresh reading from a stale cached one.
Use the included connectivity check when you want to verify OAuth credentials, confirm device discovery, or inspect normalized SmartThings status data without launching MagicMirror.
cd ~/MagicMirror/modules/MMM-STStatus
npm run test:smartthingsWhat it does:
- Loads encrypted OAuth credentials from
oauth-data.enc - Refreshes the access token automatically if it is near expiry
- Reads
~/MagicMirror/config/config.jsand checks the devices configured forMMM-STStatus - Falls back to all SmartThings devices if no explicit device list is configured
- Updates
.cache.jsonwith the latest successful device status payloads
Optional flags:
# Check every SmartThings device, ignoring the MagicMirror config filter
npm run test:smartthings -- --all
# Print normalized JSON instead of the text summary
npm run test:smartthings -- --raw
# Show request and discovery details
npm run test:smartthings -- --debug
# Use a different MagicMirror config file
npm run test:smartthings -- --config /path/to/config.jsIf the script reports No OAuth data found or OAuth data is incomplete, re-run:
node setup.js| Capability | Display | Icon (Font Awesome) |
|---|---|---|
| Switch | ON / OFF | fa-lightbulb |
| Contact Sensor | OPEN / CLOSED | fa-door-open / fa-door-closed |
| Motion Sensor | MOTION / — | fa-person-walking / fa-person |
| Lock | LOCKED / UNLOCKED | fa-lock / fa-lock-open |
| Presence Sensor | HOME / AWAY | fa-house-user / fa-house |
| Temperature | ##°F/°C | fa-thermometer-half |
| Humidity | ##% | fa-droplet |
| Battery | ##% | fa-battery-full / fa-battery-half / fa-battery-quarter |
| Window Shade/Blinds | ##% | fa-window-maximize |
| Dimmer | ##% | fa-sliders |
For thermostats (like Ecobee), the module displays:
- Current temperature (primary value)
- Humidity (secondary column)
- Heating/cooling setpoints (secondary column)
- Color-coded temperature based on operating state:
- Red: Heating
- Blue: Cooling
- Green: Fan only
- White: Idle
The module supports multiple languages. Set the language option in your MagicMirror config.js:
language: "de", // GermanSupported languages:
en- English (default)de- German (Deutsch)fr- French (Français)es- Spanish (Español)nl- Dutch (Nederlands)
Contributions for additional languages are welcome! See the translations/ folder.
The module displays alerts in the footer when issues occur. Alerts auto-dismiss when the problem resolves.
| Alert | Meaning | Solution |
|---|---|---|
| "Auth failed - run setup.js" | OAuth tokens invalid or expired | Re-run node setup.js |
| "Permission denied - check OAuth scopes" | Missing API permissions | Recreate OAuth app with correct scopes |
| "Network error - check connection" | Cannot reach SmartThings API | Check internet connection |
| "Rate limited - increase pollInterval" | Too many API requests | Set pollInterval to 120000 or higher |
| "SmartThings unavailable - retrying" | SmartThings API is down | Wait for SmartThings to recover |
| "API error - please open GitHub issue" | Unexpected API response format | Open an issue with debug logs |
DNS-based ad blockers (Pi-hole, AdGuard Home, Eero Secure, router ad blocking, etc.) may block SmartThings API access.
Symptoms:
- Setup wizard fails with "Network error" but completes other steps
- Module shows "Network error - check connection" but internet is working
curl https://api.smartthings.com/v1fails or returns wrong IP
Solution:
- Access your DNS blocker's admin interface (Pi-hole, Eero app, router settings)
- Add to whitelist/allowed sites:
api.smartthings.comsmartthings.com(covers all SmartThings subdomains)
- Restart MagicMirror or re-run
node setup.js
Eero users: Open Eero app → Discover → eero Secure → Block & Allow Sites → Allowed tab → Add Allowed Site
Verification:
# Should return real AWS IPs (not 192.168.x.x or 127.0.0.1):
getent ahosts api.smartthings.com
# Should connect successfully:
curl -I https://api.smartthings.com/v1The redirect URI in your SmartThings app doesn't match. Update it:
smartthings apps:oauth:update YOUR_APP_IDSet redirect URI to: https://httpbin.org/get
Authorization codes expire within a few minutes. Run node setup.js again and complete the browser authorization promptly.
Run node setup.js to complete OAuth setup. Verify oauth-data.enc and oauth-key.bin exist in the module directory.
Refresh tokens expire after 30 days of non-use. Re-run node setup.js to get new tokens.
- Room names are case-sensitive and must match exactly
- Verify devices are assigned to rooms in the SmartThings app
- Run setup wizard again to see available rooms/devices
- Increase
pollIntervalto 120000 (2 minutes) or higher - SmartThings allows 250 requests per minute
- Check logs:
pm2 logs MagicMirror - Verify syntax in config.js (missing commas are common)
- Ensure
npm installcompleted successfully
- Run
npm installto ensure Font Awesome is installed - Check browser console for CSS loading errors
SmartThings limits API requests to 250 per minute per token. This module:
- Tracks request count and warns at 200/minute
- Implements automatic backoff on rate limit errors
- Caches data to reduce unnecessary requests
- Uses a minimum poll interval of 30 seconds
For large installations (20+ devices), increase pollInterval to 120000ms or higher.
- OAuth credentials and tokens are stored in
oauth-data.enc(encrypted with AES-256-GCM) - The encryption key is stored separately in
oauth-key.bin(random 32 bytes) - Credentials are NOT stored in config.js - they're fully encrypted
- Both
oauth-key.binandoauth-data.encare gitignored by default - If copying to a new Pi, copy both files together (they're paired)
- Never commit OAuth files to version control
MMM-STStatus/
├── MMM-STStatus.js # Frontend module
├── node_helper.js # Backend helper (API, OAuth, caching)
├── setup.js # Interactive setup wizard
├── oauth-utils.js # Token encryption utilities
├── oauth-key.bin # Encryption key (created by setup, gitignored)
├── oauth-data.enc # Encrypted OAuth data (created by setup, gitignored)
├── css/
│ └── MMM-STStatus.css # Styles
├── translations/ # Language files
│ ├── en.json # English
│ ├── de.json # German
│ ├── fr.json # French
│ ├── es.json # Spanish
│ └── nl.json # Dutch
├── package.json
├── README.md
└── .cache.json # Device cache (auto-generated)
- MagicMirror² - https://magicmirror.builders/
- MMM-Smartthings by buzzkc - Inspiration and prior art (GitHub)
- MMM-Ecobee by parnic - UI design inspiration (GitHub)
- SmartThings Community - OAuth implementation guidance
MIT License - see LICENSE for details.
Pull requests are welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Test thoroughly
- Submit a pull request
- Open an issue for bugs or feature requests
- Check existing issues before creating new ones
