A SmartThings Edge LAN driver for local integration with Enphase IQ Gateway (Envoy) running Firmware 7.x or newer. Communicates directly over your local network — no cloud dependency, no Enphase cloud polling.
The driver creates a single Enphase Envoy device in SmartThings with three components visible as separate tiles:
| Component | Label | Data Source | Shows |
|---|---|---|---|
main |
Solar Production | /production.json → production[type=eim] |
Current watts + today kWh |
consumed |
Home Consumption | /production.json → consumption[total-consumption] |
Current watts + today kWh |
grid |
Grid | /production.json → consumption[net-consumption] |
Absolute watts + direction switch |
No CT clamps installed? See No CT Clamps Mode — the data sources and available fields differ.
The grid component uses two capabilities together to represent flow direction without negative numbers:
- powerMeter — absolute wattage (always positive, great for automations)
- switch —
ON= exporting to grid (solar surplus),OFF= importing from grid
This makes ST automations clean and readable:
"When Grid switch is ON AND Grid power > 2000 → run dishwasher" "When Grid switch turns OFF → notify 'Drawing from grid'"
- SmartThings Hub (v2, v3, or Aeotec) on the same local network as your Envoy
- Enphase IQ Gateway (Envoy) running Firmware 7.x or newer
- Static/reserved IP for your Envoy (set in your router — strongly recommended)
- An Enphase JWT token (valid for 1 year — see below)
- SmartThings CLI installed
Enphase Firmware 7.x+ requires a JWT for local API access. Tokens are valid for 1 year — you'll need to repeat this annually.
- Go to entrez.enphaseenergy.com
- Log in with your Enphase app credentials
- In Select System, type your system name (as it appears in the Enphase app)
- Select your gateway serial number from Select Gateway
- Click Generate Token
- Copy the full token text — it is approximately 1,000+ characters long
Important: The SmartThings app preference field cannot hold the full token in one paste. The driver splits the token across two fields — see Configuration below.
git clone https://github.com/JaragonCR/envoy.git
cd envoysmartthings edge:channels:create \
--name "MyDrivers" \
--description "Personal edge drivers" \
--termsOfServiceUrl "https://example.com"Save the channel ID from the output.
smartthings edge:channels:enroll \
<HUB_ID> \
--channel <CHANNEL_ID>Find your hub ID with: smartthings edge:drivers:install (it lists hubs before prompting).
smartthings edge:drivers:package --assignSelect your channel when prompted.
smartthings edge:drivers:installSelect your channel → select Enphase Envoy Local → select your hub.
- Tap + → Add device → Scan for nearby devices
- Wait up to 30 seconds — Enphase Envoy will appear
- Tap it to add it to a room
Open the device in the ST app → tap ⋮ → Settings:
| Field | Value |
|---|---|
| Envoy IP Address | Local IPv4 of your Envoy, e.g. 192.168.1.50 |
| API Token (Part 1) | First half of your JWT token |
| API Token (Part 2) | Second half of your JWT token |
If your Envoy has no current transformer (CT) clamps installed, enable No CT Clamps Installed in the device settings. This switches the driver to inverter-based data sources.
| Field | Available | Source |
|---|---|---|
| Solar watts now | Yes | Sum of lastReportWatts across all inverters (/api/v1/production/inverters) |
| Solar lifetime kWh | Yes | production[type=inverters].whLifetime from /production.json |
| Solar today kWh | No | Not available without CTs |
| Solar 7-day kWh | No | Not available without CTs |
| Home consumption | No | Requires CT clamps |
| Grid export/import | No | Requires CT clamps — grid switch is locked OFF |
The consumed component will show 0W / 0 kWh. The grid component will show 0W with the switch permanently OFF. The main (Solar Production) energy tile shows lifetime kWh instead of today kWh.
Each poll cycle makes two HTTP calls in this mode: /production.json for lifetime energy and /api/v1/production/inverters for current wattage.
The ST app truncates long text fields, so the token must be split in two. Find the midpoint and paste each half:
# Check total token length
echo -n "YOUR_FULL_TOKEN" | wc -c
# Find the midpoint, e.g. if length is 1100, split at 550
echo -n "YOUR_FULL_TOKEN" | cut -c1-550 # → Part 1
echo -n "YOUR_FULL_TOKEN" | cut -c551- # → Part 2Paste Part 1 into API Token (Part 1) and Part 2 into API Token (Part 2). The driver concatenates them automatically.
After making changes to the source:
smartthings edge:drivers:package --assign
smartthings edge:drivers:installThe hub pulls the update within ~60 seconds. If the profile changed (e.g. new components or capabilities), delete the device in the ST app and re-discover it so it picks up the new profile.
Your JWT expires after 1 year. When it does, the driver will log:
[ENVOY] HTTP GET /production.json → 401
To renew:
- Generate a new token at entrez.enphaseenergy.com
- Split it into two halves (see above)
- Open the device in the ST app → ⋮ → Settings → update both token fields
- The driver detects the preference change and polls immediately
CT mode (default): single call per poll cycle:
GET https://<ENVOY_IP>/production.json
| Field | Used For |
|---|---|
production[type=eim].wNow |
Solar watts now |
production[type=eim].whToday |
Solar kWh today |
production[type=eim].whLastSevenDays |
Solar kWh last 7 days (logged) |
production[type=eim].whLifetime |
Solar kWh lifetime (logged) |
consumption[total-consumption].wNow |
Home consumption watts now |
consumption[total-consumption].whToday |
Home consumption kWh today |
consumption[net-consumption].wNow |
Net grid flow (negative = exporting) |
The driver uses production[type=eim] (the energy meter) for production data, as the EIM provides accurate metered values including reactive power and true RMS measurements.
No-CT mode: two calls per poll cycle:
GET https://<ENVOY_IP>/production.json
GET https://<ENVOY_IP>/api/v1/production/inverters
| Field | Used For |
|---|---|
Sum of [*].lastReportWatts |
Solar watts now (sum of all 40 inverter reports) |
production[type=inverters].whLifetime |
Solar kWh lifetime |
Today and 7-day energy fields are not provided by either inverter endpoint and are unavailable without CT clamps.
Polling interval: every 30 seconds. An immediate poll fires on driver init and on any preference change.
Because the grid component uses a switch + powerMeter, you can build automations entirely within SmartThings without any third-party apps:
Export surplus to appliances:
If Grid switch = ON AND Grid power ≥ 1500 → turn on EV charger / washing machine
Grid protection alert:
If Grid switch changes to OFF → send notification "Drawing from grid"
Peak solar notification:
If Solar Production power ≥ 8000 → send notification "System near peak output"
Away mode solar optimization:
If Grid switch = ON AND mode = Away → turn on water heater
401 Unauthorized — Token is expired or incorrectly split. Regenerate at entrez.enphaseenergy.com and re-enter both halves.
IP or token not set — Both preference fields must be saved before the first poll fires.
Device not appearing during scan — Make sure the driver is installed on the hub (smartthings edge:drivers:installed). Delete the device and re-scan if the profile looks stale.
-0W showing for solar — Normal nighttime behavior. The driver clamps wNow to 0 for display but the raw EIM value is -0.0 when no production is occurring.
Stream live logs:
smartthings edge:drivers:logcatenvoy/
├── config.yml # Driver metadata and LAN permissions
├── profiles/
│ └── envoy.yaml # Device profile (3 components)
└── src/
└── init.lua # Driver logic
Inspired by prior Enphase SmartThings integrations:
- ahndee/Envoy-ST — original classic DTH
- Matthew1471/Enphase-API — comprehensive local API documentation
- vpsupun/hubitat — Hubitat consumption metering approach
MIT