DiedB / Homey-SolarPanels

Connects production statistics of a wide range of PV inverters to Homey
https://apps.athom.com/app/it.diederik.solar
GNU General Public License v3.0
52 stars 37 forks source link

Enphase Envoy Local API #110

Closed KvDaalen closed 3 years ago

KvDaalen commented 4 years ago

Enphase Envoy Local API output.txt

I have an Enphase micro inverter installation and would like to use the Homey SolarPanels App to integrate data that the Envoy Metered produces into my Homey. The Envoy metered is a type of Envoy that next to production also measures data for import/export and consumption. It does this via measuring devices that need to be installed separately in the fuse box. The current SolarPannels app does not support the Local API of the Enphase Envoy and it does also not deliver the Import/Export data nor consumption data. Because of the usage of the Cloud API, also the polling frequency is very low and on-boarding is cumbersome.

I suggest to enhance the SolarPanels app for enphase by implementing the local Envoy API instead of the Cloud API. This enables the app to:

The local API can be called via the following URL (no authentication is needed)

GET http:///production.json?details=1 or GET http://envoy.local/production.json?details=1

The output can be found in the attachment

I found that in order to get the most current power production you must follow the path $.production[1].wNow (eim). I do not know what $.production[0].wNow (inverters) means, but it is not the most current value. Might be a rolling average.

DiedB commented 4 years ago

Thanks for the detailed information! Will look into implementing this somewhere in the next few weeks.

KvDaalen commented 4 years ago

Thanks for the detailed information! Will look into implementing this somewhere in the next few weeks.

Great.

Retrospected commented 4 years ago

nice, i was looking into this api last week as well. would be great if this can be implemented.

Not sure which value to take though, I'll run some analysis tomorrow during the day to see if i can figure that out.

Retrospected commented 4 years ago

nice, i was looking into this api last week as well. would be great if this can be implemented.

Not sure which value to take though, I'll run some analysis tomorrow during the day to see if i can figure that out.

Ran it for 24 hours and compared the local API value of .production[0].wNow with the ones sent via the Envoy API and it seems to be quite spot on in contrast to what @KvDaalen mentioned

image

KvDaalen commented 4 years ago

nice, i was looking into this api last week as well. would be great if this can be implemented. Not sure which value to take though, I'll run some analysis tomorrow during the day to see if i can figure that out.

Ran it for 24 hours and compared the local API value of .production[0].wNow with the ones sent via the Envoy API and it seems to be quite spot on in contrast to what @KvDaalen mentioned

image

I think you misunderstood what I was explaining. Your findings are not in contrast to mine. The .production[0].wNow gives a rolling average (also used within the cloud API). If you however need the actual production at the moment you call the API the .production[1].wNow gives the right value.

Evidence:

  1. If you call the API many times, each time the .production[1].wNow value is different. The .production[0].wNow value remains the same for a long duration (at least 15 minutes).
  2. The values as seen in the webpage http://envoy.local/home are reflecting the .production[1].wNow value
  3. Using the Installer toolkit the Meters Tab.Production shows the .production[1].wNow data (including the lines).

So you are correct. The data as reported in the Cloud API has a very low resolution. It has intervals of 15 minutes of reporting. This is reflected in the local API via the .production[0].wNow value.

However I think that if you have the possibility to obtain data which is more accurate and has a higher resolution you should use that source. Automation on realtime data is much better than on averages.

Example of usage:

When you use the low quality, low resolution data you are bound to keep the boiler running whilst you are actually importing power from the grid. This is because you are using a data point which by itself is a rolling average. After a while the fact that a cloud appeared (leading to lower production) will also be reflected in you rolling average data points. but that takes time. Better to automate on realtime actuals then on averages .

Retrospected commented 4 years ago

Ah yes I see, I misunderstood you because for me .production[1].wNow does not return a valid value at all:

user@server:~ $ curl -s http://envoy.local/production.json?details=1 | jq '.production[1].wNow'
-6.379

I think this has to do with the fact that "metering" was not enabled by the installers. This is also shown on the /home page:

image

I contacted the installing party (CoolBlue) before about this and they confirmed that they do not connect the "Metered" function as part of their service yet :(. I checked out the Envoy manual and it requires the installation and wiring of an extra "CT" (Current Transformer) component, so it is not just a simple configuration on the software side.

Long story short: the value of .production[1].wNow indeed sounds like the most accurate value.

Ideally the feature would support both unmetered as well as the metered installation. I think this can be check via the same json results using .production[1].activeCount. For me (unmetered) this is on 0, for @KvDaalen (metered) this is 1.

Alternatively i can also fork it afterwards and change the JSON query myself to support the local API on my unmetered version, until i figured out how to wire and configure metering without blowing up my house. :)

DiedB commented 4 years ago

Thanks for the extended research on the differences between the metered and unmetered setups. I wonder why the unmetered Envoy does not have a higher resolution, it should have more granular production values right? Most inverters report at least every few seconds (on an LCD or something). Maybe I don't understand the Enphase setup quite well.

Could you guys check whether your Envoy responds to mDNS queries? This would improve the pairing process. You can check this using https://apps.apple.com/us/app/discovery-dns-sd-browser/id305441017 or https://hobbyistsoftware.com/bonjourbrowser or https://play.google.com/store/apps/details?id=com.druk.servicebrowser&hl=en

If it does, please make a screenshot of all values for the Envoy service.

Retrospected commented 4 years ago

Thanks for the extended research on the differences between the metered and unmetered setups. I wonder why the unmetered Envoy does not have a higher resolution, it should have more granular production values right? Most inverters report at least every few seconds (on an LCD or something). Maybe I don't understand the Enphase setup quite well.

Could you guys check whether your Envoy responds to mDNS queries? This would improve the pairing process. You can check this using https://apps.apple.com/us/app/discovery-dns-sd-browser/id305441017 or https://hobbyistsoftware.com/bonjourbrowser or https://play.google.com/store/apps/details?id=com.druk.servicebrowser&hl=en

If it does, please make a screenshot of all values for the Envoy service.

Sure:

envoy._enphase-envoy._tcp.local. Enphase Energy Envoy

envoy.local:80 192.168.1.114:80 fd50:d85:9682:1:aae2:c1ff:fe5a:217c:80

protovers = 4.10.35 serialnum = 122015061668 txtvers = 1

DiedB commented 4 years ago

Perfect, that should make pairing a lot more user-friendly ;-)

DiedB commented 4 years ago

@Retrospected could you send your output of http://envoy.local/production.json?details=1, like @KvDaalen did?

DiedB commented 4 years ago

I have built an implementation, could you give it a try? It should work for both situations (metered and unmetered).

You can find it here: https://homey.app/nl-nl/app/it.diederik.solar/Zonnepanelen/test/

Please check if it works and send me a crash report after a few minutes (from the Homey app). Chances are it doesn't, since I have no way to test it myself πŸ˜„

Retrospected commented 4 years ago

@Retrospected could you send your output of http://envoy.local/production.json?details=1, like @KvDaalen did?

Thanks! i will test the build

In case you still need my production.json output:

production.txt

DiedB commented 4 years ago

Ah, your JSON output is different than I anticipated. If the app works, you will probably get some strange production/consumption values.

I'll implement the activeCount check you mentioned. Still, let me know if you are able to pair your inverter and if you see any output.

Retrospected commented 4 years ago

I tried to pair it, but the device can’t be found I double checked and i still do see the mDNS broadcasting on the same device.

https://user-images.githubusercontent.com/5727023/88386632-185ee880-cdb1-11ea-9118-23b26b19c374.png

edit: removed the preview of the picture because it's way too big

DiedB commented 4 years ago

Strange, I have no idea why it wouldn't find your Envoy. Sure Homey is on the same network (segment)?

Retrospected commented 4 years ago

Strange, I have no idea why it wouldn't find your Envoy. Sure Homey is on the same network (segment)?

Hmm that's strange... i still have the issue. Envoy, Homey and my phone are in the same WiFi network/VLAN and subnet. My phone can see the mdns just fine.

Is there any way i can help out with debugging? If you can add some console.log's and push it to a remote branch i can give you the output by running the version manually myself.

DiedB commented 4 years ago

Do you have experience with manually running Homey apps? You can try to change the mDNS query in .homeycompose/discovery/enphase-envoy.json. Maybe try changing the name to enphase-envoy?

Retrospected commented 4 years ago

Do you have experience with manually running Homey apps? You can try to change the mDNS query in .homeycompose/discovery/enphase-envoy.json. Maybe try changing the name to enphase-envoy?

Yes i know how to run local apps based on the source code repo. But i cant seem to find the branch you pushed it to :o did you push it to github? If so can you link it πŸ™ˆ?

DiedB commented 4 years ago

Forgot to push, see b43fc9f.

KvDaalen commented 4 years ago

I have built an implementation, could you give it a try? It should work for both situations (metered and unmetered).

You can find it here: https://homey.app/nl-nl/app/it.diederik.solar/Zonnepanelen/test/

Please check if it works and send me a crash report after a few minutes (from the Homey app). Chances are it doesn't, since I have no way to test it myself πŸ˜„

Hi Tried to install the new test version. That seems to have succeeded as it now mentions that the zonnepanelen app is of version 4.1.

Then tried to add a new device (enphase Envoy) But it does not find any.

geurti64 commented 4 years ago

Here it also doesn't find anything when I try to install Enphase Envoy. Should I give permission somewhere in my Envoy to work with a third party?

DiedB commented 4 years ago

It's an issue with the (beta) app, not your Envoy. @Retrospected have you found the correct mDNS name?

Retrospected commented 4 years ago

I have just ran it, strangely enough when running it with "homey app run", discovery works just fine.. πŸ‘ However now i end up with " Only HTTP(S) protocols are supported" when looking at the device status.

this is the console output:


2020-07-26 22:53:09 [log] [ManagerDrivers] [enphase-envoy] {
  '122015061668': DiscoveryResultMDNSSD {
    _events: [Object: null prototype] {},
    _eventsCount: 0,
    _maxListeners: undefined,
    address: '192.168.1.50',
    host: 'envoy',
    port: 80,
    name: 'envoy',
    fullname: 'envoy._enphase-envoy._tcp.local.',
    txt: { serialnum: '122015XXXXXX', protovers: '4.10.35', txtvers: '1' },
    id: '122015XXXXXX',
    lastSeen: 2020-07-26T20:52:57.698Z,
    [Symbol(kCapture)]: false
  }
}
2020-07-26 22:53:11 [log] [ManagerDrivers] [enphase-envoy] [0] Initializing device
2020-07-26 22:53:11 [log] [ManagerDrivers] [enphase-envoy] [0] Added device
2020-07-26 22:53:11 [log] [ManagerDrivers] [enphase-envoy] [0] Checking production
2020-07-26 22:53:11 [log] [ManagerDrivers] [enphase-envoy] [0] Tried fetching production before API init or device unavailable!
2020-07-26 22:53:11 [log] [ManagerDrivers] [enphase-envoy] [0] Discovery available
2020-07-26 22:53:11 [err] [ManagerDrivers] [enphase-envoy] Error executing Device.onDiscoveryResult TypeError: Only HTTP(S) protocols are supported
    at getNodeRequestOptions (/node_modules/node-fetch/lib/index.js:1303:9)
    at /node_modules/node-fetch/lib/index.js:1404:19
    at new Promise (<anonymous>)
    at fetch (/node_modules/node-fetch/lib/index.js:1401:9)
    at EnphaseEnvoyApi.apiRequest (/drivers/enphase-envoy/api.js:9:35)
    at EnphaseEnvoyApi.getProductionData (/drivers/enphase-envoy/api.js:20:27)
    at EnphaseEnvoy.onDiscoveryAvailable (/drivers/enphase-envoy/device.js:18:31)
    at /opt/homey-client/system/manager/ManagerApps/bootstrap/sdk/v2/lib/Driver.js:1:4290
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
2020-07-26 22:53:11 [log] [ManagerDrivers] [enphase-envoy] [0] Cron job f8c4f77223ad45b2b1649f8cb311a145 created successfully
2020-07-26 22:53:12 [log] [ManagerDrivers] [enphase-envoy] [0] Initialized cron job f8c4f77223ad45b2b1649f8cb311a145
2020-07-26 22:53:15 [log] [ManagerDrivers] [enphase-envoy] [0] Running task f8c4f77223ad45b2b1649f8cb311a145
2020-07-26 22:53:15 [log] [ManagerDrivers] [enphase-envoy] [0] Checking production
2020-07-26 22:53:15 [log] [ManagerDrivers] [enphase-envoy] [0] Tried fetching production before API init or device unavailable!```
DiedB commented 4 years ago

Interesting! I changed the mDNS name to enphase-envoy in the branch I sent you and apparently that is the correct one (it was envoy in the app store version).

An updated version has been pushed to the app store (test channel), that should also fix the other bug you encountered and implements the activeCount check.

Retrospected commented 4 years ago

Interesting! I changed the mDNS name to enphase-envoy in the branch I sent you and apparently that is the correct one (it was envoy in the app store version).

An updated version has been pushed to the app store (test channel), that should also fix the other bug you encountered and implements the activeCount check.

Cool thx for picking it up so fast, I'm getting a step further now. Now i get the following error:

Error retrieving data (ReferenceError: currentEnergy is not defined)

DiedB commented 4 years ago

Thanks for the quick feedback! Please try the next build (4.1.2).

Retrospected commented 4 years ago

Thanks for the quick feedback! Please try the next build (4.1.2).

same thing

DiedB commented 4 years ago

That is strange, could you run the app manually and see if you get more error output?

Retrospected commented 4 years ago

That is strange, could you run the app manually and see if you get more error output?

2020-07-26 23:45:36 [log] [ManagerDrivers] [enphase-envoy] [0] Cron job 5a6df3ce267f49eea5b271c8d60b27d5 created successfully
2020-07-26 23:45:36 [log] [ManagerDrivers] [enphase-envoy] [0] Initialized cron job 5a6df3ce267f49eea5b271c8d60b27d5
2020-07-26 23:45:40 [log] [ManagerDrivers] [enphase-envoy] [0] Running task 5a6df3ce267f49eea5b271c8d60b27d5
2020-07-26 23:45:40 [log] [ManagerDrivers] [enphase-envoy] [0] Checking production
2020-07-26 23:45:40 [log] [ManagerDrivers] [enphase-envoy] [0] Unavailable (ReferenceError: currentEnergy is not defined)
2020-07-26 23:45:45 [log] [ManagerDrivers] [enphase-envoy] [0] Running task 5a6df3ce267f49eea5b271c8d60b27d5
2020-07-26 23:45:45 [log] [ManagerDrivers] [enphase-envoy] [0] Checking production
2020-07-26 23:45:45 [log] [ManagerDrivers] [enphase-envoy] [0] Tried fetching production before API init or device unavailable!
2020-07-26 23:45:50 [log] [ManagerDrivers] [enphase-envoy] [0] Running task 5a6df3ce267f49eea5b271c8d60b27d5
2020-07-26 23:45:50 [log] [ManagerDrivers] [enphase-envoy] [0] Checking production
2020-07-26 23:45:50 [log] [ManagerDrivers] [enphase-envoy] [0] Tried fetching production before API init or device unavailable!
2020-07-26 23:45:55 [log] [ManagerDrivers] [enphase-envoy] [0] Running task 5a6df3ce267f49eea5b271c8d60b27d5
2020-07-26 23:45:55 [log] [ManagerDrivers] [enphase-envoy] [0] Checking production
2020-07-26 23:45:55 [log] [ManagerDrivers] [enphase-envoy] [0] Tried fetching production before API init or device unavailable!
DiedB commented 4 years ago

Please try 4.1.3 :wink:

geurti64 commented 4 years ago

Is it possible it doesn't work now because of sleep modus of Envoy? My SMA doesn't do anything after sunset...

Retrospected commented 4 years ago

Please try 4.1.3 πŸ˜‰

alright no more errors :) Energy shows 0 Watt now though.. so let's see what it does in the morning

Energymeter for me shows a "-".. i would expect it to show around 14.00kWh that i have according to the cloud version

DiedB commented 4 years ago

@Retrospected that is (still) an issue with unmetered setups and the local version. As you can see in your JSON output, the local version does not contain a whToday field. Will probably have to record a value from whLifetime at the start of each day and then subtract it from the latest value, but haven't implemented that yet.

DiedB commented 4 years ago

@geurti64 That is possible, but do you get errors with version 4.1.3?

Retrospected commented 4 years ago

@Retrospected that is (still) an issue with unmetered setups and the local version. As you can see in your JSON output, the local version does not contain a whToday field. Will probably have to record a value from whLifetime at the start of each day and then subtract it from the latest value, but haven't implemented that yet.

ah of course.. makes sense. I have already fixed it the way you describe using the cloud data anyway :) Thanks for the feature!

Maybe @KvDaalen can test how it works on a metered Envoy.

geurti64 commented 4 years ago

@DiedB I get device is not available. Error retrieving data. TypeError: cannot read property activeCount of undefined.

DiedB commented 4 years ago

@geurti64 Can you try to access http://envoy.local/production.json?details=1

If that works, can you send the output it gives?

geurti64 commented 4 years ago

@geurti64 Can you try to access http://envoy.local/production.json?details=1

If that works, can you send the output it gives?

This is what I got:

{"production":[{"type":"inverters","activeCount":6,"readingTime":0,"wNow":0,"whLifetime":5106119}],"storage":[{"type":"acb","activeCount":0,"readingTime":0,"wNow":0,"whNow":0,"state":"idle"}]}

DiedB commented 4 years ago

I made a new build that should work with all the three JSON outputs in this thread, see 4.1.5. I wonder what other variations we are going to encounter :wink:

@Retrospected The energy value might work now.

geurti64 commented 4 years ago

I made a new build that should work with all the three JSON outputs in this thread, see 4.1.5. I wonder what other variations we are going to encounter πŸ˜‰

@Retrospected The energy value might work now.

I get the same error. {"production":[{"type":"inverters","activeCount":6,"readingTime":0,"wNow":0,"whLifetime":5106119}],"storage":[{"type":"acb","activeCount":0,"readingTime":0,"wNow":0,"whNow":0,"state":"idle"}]}

geurti64 commented 4 years ago

2ABA223F-A5F4-43E6-88D6-305F745D38FA

DiedB commented 4 years ago

@geurti64 Sure you are running 4.1.5? Can you remove the app and reinstall? Do you get the exact same error?

geurti64 commented 4 years ago

Oops 😬 0EF10A72-20F3-4922-81F9-6DB06169FF58

geurti64 commented 4 years ago

I'll try again after sunrise πŸ˜‰

DiedB commented 4 years ago

That error won't be fixed after sunrise, but it will in 4.1.6 :smile:

geurti64 commented 4 years ago

That error won't be fixed after sunrise, but it will in 4.1.6 πŸ˜„

I know, there was an other message behind it... Give me a second, then I try once again before sleeping.

geurti64 commented 4 years ago

Seems like it's good now. You're a master! C7F3A2B5-738C-46B0-B146-C811734B533D

geurti64 commented 4 years ago

Good night.

geurti64 commented 4 years ago

Seems like the "energiemeter" is not working correctly as the meter in my other tile says 0.18 kWh.

{"production":[{"type":"inverters","activeCount":6,"readingTime":1595833466,"wNow":134,"whLifetime":5106337}],"storage":[{"type":"acb","activeCount":0,"readingTime":0,"wNow":0,"whNow":0,"state":"idle"}]}

9A11DA7D-7A39-4AE3-91C2-428E3031D991

geurti64 commented 4 years ago

An other question. Is it also possible to make an option that we choose one panel? My solar panel set is East/West. I would like to know the Energie on East side to control my sunscreens. Maybe just make a new topic for this question?