Enphase: Connection fails
Describe the bug
I set up my Enphase PV System.
But when starting it shows connections errors
Wenn I look in the documentation the URL is wrong. If I enter the URL written in the documentation I get the information from the enphase envoy:
https://10.150.0.76/api/v1/production
{
"wattHoursToday": 19969,
"wattHoursSevenDays": 472706,
"wattHoursLifetime": 16548752,
"wattsNow": 2625
}
Steps to reproduce
- Setup evcc.yaml
- Start evcc
Configuration details
- name: my_pv
type: template
template: enphase
usage: pv
host: 10.150.0.76
token: ey...
Log details
2025-06-16 11:26:42.413915302 +0200 CEST m=+603.420745950 !! 10000ms Get "https://10.150.0.76/production.json": net/http: request canceled (Client.Timeout exceeded while awaiting headers)
[site ] ERROR 2025/06/16 11:26:52 pv 1 power: Get "https://10.150.0.76/production.json": net/http: request canceled (Client.Timeout exceeded while awaiting headers)
[site ] ERROR 2025/06/16 11:26:52 grid power: Get "https://10.150.0.76/production.json": net/http: request canceled (Client.Timeout exceeded while awaiting headers)
[site ] ERROR 2025/06/16 11:27:02
What type of operating system or environment does evcc run on?
HomeAssistant Add-on
External automation
- [x] I have made sure that no external automation like HomeAssistant or Node-RED is active or accessing any of the mentioned devices when this issue occurs.
Nightly build
- [x] I have verified that the issue is reproducible with the latest nightly build
Version
0.204.2
Wenn I look in the documentation the URL is wrong
So- what‘s the right url? Does it maybe depend on firmware version?
I use the one written above
https://10.150.0.76/api/v1/production
This deliveries the information for the production.
For the net consumption the one already there seems to work but only for a while then it stops working. So I raised the the cache to 1 min but that didn't help either.
My solution was to use my Tasmota SML to get the net consumption information.
For battery information I use this (but this somehow doesn't deliver the power for charging and decharching):
- name: batterie
type: custom
power:
source: http
uri: https://10.150.0.76/ivp/livedata/status
method: GET
jq: .meters.storage.agg_p_mw
auth:
type: bearer
token: ey...
insecure: true
scale: 0.001
soc:
source: http
uri: https://10.150.0.76/ivp/ensemble/inventory
method: GET
auth:
type: bearer
token: ey...
insecure: true
jq: .[].devices | map(.percentFull) | add / length
/cc @ivoks @pdeliot
Hi,
One stupid check... :-| does your enphase token still valid? It has an expiration date.
Maybe you can try to renew it?
Yes my token is valid. Otherwise my above shown connection wouldn't work ;-)
I have an Enphase Envoy S. One of the older models that doesn't require the auth token. It's running software version D5.0.34.
I'm able to access all 3 of these URLs:
http://envoy.home/api/v1/productionhttp://envoy.home/production.jsonhttp://envoy.home/production.json?details=1
I've listed in order of execution time (using "time curl"), from fastest to slowest. At worst the duration is ~1.5 seconds. Though the time varies and can be a lot faster.
I have seen timeout messages in the log, infrequently. Possibly because I'm running EVCC in Docker on a fairly old NAS - so it could just be busy at the time. However I got two error messages ~20 minutes ago, which may have been when I was running those curl commands.
[site ] ERROR 2025/06/18 23:01:48 grid currents: Get "http://envoy.home/production.json?details=1": net/http: request canceled (Client.Timeout exceeded while awaiting headers)
...
[site ] ERROR 2025/06/18 23:02:18 grid currents: Get "http://envoy.home/production.json?details=1": net/http: request canceled (Client.Timeout exceeded while awaiting headers)
I just tried issuing two curl commands concurrently and triggered another timeout in the EVCC log. The curl commands completed successfully though with one taking 2.1 sec and the other 2.9 sec. I guess there's some global lock on the inverter.
Please advise if you need me to perform any other tests.
/api/v1/production for me returns very little and quite wrong info (version D8.2.4382):
{ "wattHoursToday": 0, "wattHoursSevenDays": 0, "wattHoursLifetime": 0, "wattsNow": 0 }
FWIW, plugin doesn't use that URL. Where have you found that URL? It must be a documentation mistake. Plugin uses /production.json, /production.json?details=1 (we use this one only when we have to as it's a bit slower) and /ivp/ensemble/inventory for battery SOC.
As for the problem itself, "Client.Timeout exceeded while awaiting headers" is strange. It indicates you connected to the inverter, but didn't get any response. Does it work if you open https://10.150.0.76/production.json in your browser or via curl? It shouldn't take more than couple of seconds.
The URL is from the documentation you provide here: https://docs.evcc.io/docs/devices/meters#enphase-iq-envoy
In there is a link in how to obtain the Token. In that document on page 10 it says how to get which data (page 10).
The link https://10.150.0.76/production.json works but does not delivery the PV-production.
I don't see /api/v1/production being mentioned anywhere on evcc's site. Anyway, plugin doesn't use that URL. It uses /production.json. Can you paste output of your https://10.150.0.76/production.json?
@ivoks I think you didn’t understand my post.
The API-Documentation is on the Enphase Webpage. The link to that Enphase webpage can be found in the evcc documentation of the Enphase PV (see my post):
Scroll to the right where it says token:
meters:
- name: my_grid
type: template
template: enphase
usage: grid
host: 192.0.2.2 # IP-Adresse oder Hostname
token: # Token, Ab Envoy Firmware D7.x.xxx notwendig. Token ist ein Jahr gültig. Anleitung (Obtaining a token via web UI): https://enphase.com/download/accessing-iq-gateway-local-apis-or-local-ui-token-based-authentication (optional)
Here’s the information from https://10.150.0.76/production.json. But this only works sporadically or a few times, then a timeout occurs. The https://10.150.0.76/api/v1/production works always.
{"production":[{"type":"inverters","activeCount":30,"readingTime":1750445458,"wNow":1390,"whLifetime":16951357},{"type":"eim","activeCount":1,"measurementType":"production","readingTime":1750445789,"wNow":251.479,"whLifetime":16891367.524,"varhLeadLifetime":1736.216,"varhLagLifetime":7029117.956,"vahLifetime":21542949.24,"rmsCurrent":2.464,"rmsVoltage":688.41,"reactPwr":453.554,"apprntPwr":564.919,"pwrFactor":0.43,"whToday":83407.524,"whLastSevenDays":487340.524,"vahToday":79391.24,"varhLeadToday":1.216,"varhLagToday":8827.956}],"consumption":[{"type":"eim","activeCount":1,"measurementType":"total-consumption","readingTime":1750445789,"wNow":338.056,"whLifetime":16741068.434,"varhLeadLifetime":16484020.151,"varhLagLifetime":-6986795.168,"vahLifetime":34689821.756,"rmsCurrent":2.123,"rmsVoltage":688.11,"reactPwr":-629.818,"apprntPwr":485.287,"pwrFactor":0.69,"whToday":26732.434,"whLastSevenDays":79.434,"vahToday":75032.756,"varhLeadToday":20234.151,"varhLagToday":0.0},{"type":"eim","activeCount":1,"measurementType":"net-consumption","readingTime":1750445789,"wNow":86.577,"whLifetime":-149663.499,"varhLeadLifetime":16485756.367,"varhLagLifetime":42322.788,"vahLifetime":34689821.756,"rmsCurrent":-0.341,"rmsVoltage":688.11,"reactPwr":-1083.372,"apprntPwr":-79.898,"pwrFactor":1.0,"whToday":0,"whLastSevenDays":0,"vahToday":0,"varhLeadToday":0,"varhLagToday":0}],"storage":[{"type":"acb","activeCount":0,"readingTime":0,"wNow":0,"whNow":0,"state":"idle"}]}
I captured a timeout with Wireshark. Envoy Timeout pcap.zip Note I was using curl at the same time, so apply the filter "http && ip.addr == 192.168.30.211" to just see the packets from EVCC.
[lp-1 ] DEBUG 2025/06/20 18:53:58 charge power: 0W
[lp-1 ] DEBUG 2025/06/20 18:53:58 charge currents: [0 0 0]A
[site ] DEBUG 2025/06/20 18:54:00 grid power: 547W
[site ] DEBUG 2025/06/20 18:54:02 pv 1 power: -1W
[site ] DEBUG 2025/06/20 18:54:14 grid currents: [3.69 0 0]A
[site ] DEBUG 2025/06/20 18:54:14 site power: 547W
[lp-1 ] DEBUG 2025/06/20 18:54:14 charge voltages: [228 0 0]V
[lp-1 ] DEBUG 2025/06/20 18:54:14 detected connected phases: 1p
[lp-1 ] DEBUG 2025/06/20 18:54:14 charge total import: 178.386kWh
[lp-1 ] DEBUG 2025/06/20 18:54:14 charger status: A
[lp-1 ] WARN 2025/06/20 18:54:14 charger out of sync: expected disabled, got enabled
[lp-1 ] DEBUG 2025/06/20 18:54:14 charger enable
[lp-1 ] DEBUG 2025/06/20 18:54:14 charger disable
[lp-1 ] DEBUG 2025/06/20 18:54:14 wake-up timer: stop
[site ] DEBUG 2025/06/20 18:54:14 solar forecast: accumulated 0.002kWh, produced 0.000kWh, scale 0.000
[site ] DEBUG 2025/06/20 18:54:28 ----
[lp-1 ] DEBUG 2025/06/20 18:54:28 charge power: 0W
[lp-1 ] DEBUG 2025/06/20 18:54:28 charge currents: [0 0 0]A
[site ] DEBUG 2025/06/20 18:54:35 grid power: 552W
[site ] ERROR 2025/06/20 18:54:38 2025-06-20 18:54:28.645739093 +1000 AEST m=+979.626296421 !! 10002ms Get "http://envoy.home/production.json": net/http: request canceled (Client.Timeout exceeded while awaiting headers)
[site ] ERROR 2025/06/20 18:54:38 pv 1 power: Get "http://envoy.home/production.json": net/http: request canceled (Client.Timeout exceeded while awaiting headers)
[site ] DEBUG 2025/06/20 18:54:52 grid currents: [3.68 0 0]A
[site ] DEBUG 2025/06/20 18:54:52 site power: 552W
[lp-1 ] DEBUG 2025/06/20 18:54:52 charge voltages: [228 0 0]V
[lp-1 ] DEBUG 2025/06/20 18:54:52 detected connected phases: 1p
[lp-1 ] DEBUG 2025/06/20 18:54:52 charge total import: 178.386kWh
Looking at enphase.yaml, it will potentially send many consecutive requests for grid power & currents3 and pv power, energy & currents3.
Packet 162 is the one that was not responded to - and it is the Envoy which doesn't respond. After 10 seconds EVCC sends a TCP/FIN to close the socket.
In this case you'll notice that an equivalent request (packet 161 )was sent at the same time as the other packet. This could be a factor... Given the template has a cache configuration, I'm assuming this is supposed to prevent sending out too many requests. For some reason it doesn't appear to have worked here. Perhaps there was a race condition. (Regardless the Envoy should have still responded.)
Since the responses are not super fast, I'd suggest a longer cache duration might work better. I guess the ideal situation is that all the readings for grid/pv/battery could be resolved in two requests. You could even get all the readings (not sure about battery) by only getting production.json?details=1. That request takes longer - but if the caching works you'll get everything at once.
BTW I tried using a much larger cache duration in the Enphase meters (yaml config) but it had no effect. This is because the HTTP responses contain "Cache-Control: no-cache", and the httpcache implementation complies with that.