Enphase Envoy with Energy Dashboard

I am not in a hurry to bruteforce my Envoy Installer Password, but I was able to create 2 sensors based on the .json that doesnt need authentication at Enphase Envoy with Energy Dashboard - #100 by del13r

If you want to connect to the installer .json, I would check this link

and try these configuration variables

authentication string (optional)
Type of the HTTP authentication. basic or digest.

username string (optional)
The username for accessing the REST endpoint.

password string (optional)
The password for accessing the REST endpoint.

Thanks for your efforts @del13r - I’ve used your code example and I also have setup sensors using the production.json file. Your help was invaluable so thanks again! I changed the frequency the file is read by including

scan_interval: 1

Also thanks for the link to the RESTful sensor - I’ve spent a few hours and have been able to access the password protected installer .json however I have come across an issue I don’t know how to fix - the json data coming from that installer json isn’t 100% formatted correctly as json - this is what comes out - note it’s missing the start and end { } and the word data isn’t enclosed in quotes "

data: {"production":{"ph-a":{"p":3621.602,"q":305.704,"s":3627.168,"v":248.652,"i":14.582,"pf":1.0,"f":50.0},"ph-b":{"p":0.0,"q":0.0,"s":0.0,"v":0.0,"i":0.0,"pf":0.0,"f":0.0},"ph-c":{"p":0.0,"q":0.0,"s":0.0,"v":0.0,"i":0.0,"pf":0.0,"f":0.0}},"net-consumption":{"ph-a":{"p":-3195.826,"q":-686.842,"s":3277.01,"v":248.674,"i":13.17,"pf":-0.98,"f":50.0},"ph-b":{"p":0.0,"q":0.0,"s":0.0,"v":0.0,"i":0.0,"pf":0.0,"f":0.0},"ph-c":{"p":0.0,"q":0.0,"s":0.0,"v":0.0,"i":0.0,"pf":0.0,"f":0.0}},"total-consumption":{"ph-a":{"p":425.776,"q":-992.546,"s":351.08,"v":248.663,"i":1.412,"pf":1.0,"f":50.0},"ph-b":{"p":0.0,"q":0.0,"s":0.0,"v":0.0,"i":0.0,"pf":0.0,"f":0.0},"ph-c":{"p":0.0,"q":0.0,"s":0.0,"v":0.0,"i":0.0,"pf":0.0,"f":0.0}}}

It should look like this:

{"data":{"production":{"ph-a":{"p":3621.602,"q":305.704,"s":3627.168,"v":248.652,"i":14.582,"pf":1,"f":50},"ph-b":{"p":0,"q":0,"s":0,"v":0,"i":0,"pf":0,"f":0},"ph-c":{"p":0,"q":0,"s":0,"v":0,"i":0,"pf":0,"f":0}},"net-consumption":{"ph-a":{"p":-3195.826,"q":-686.842,"s":3277.01,"v":248.674,"i":13.17,"pf":-0.98,"f":50},"ph-b":{"p":0,"q":0,"s":0,"v":0,"i":0,"pf":0,"f":0},"ph-c":{"p":0,"q":0,"s":0,"v":0,"i":0,"pf":0,"f":0}},"total-consumption":{"ph-a":{"p":425.776,"q":-992.546,"s":351.08,"v":248.663,"i":1.412,"pf":1,"f":50},"ph-b":{"p":0,"q":0,"s":0,"v":0,"i":0,"pf":0,"f":0},"ph-c":{"p":0,"q":0,"s":0,"v":0,"i":0,"pf":0,"f":0}}}}

Which then formats correctly as:

{
  "data": {
    "production": {
      "ph-a": {
        "p": 3621.602,
        "q": 305.704,
        "s": 3627.168,
        "v": 248.652,
        "i": 14.582,
        "pf": 1,
        "f": 50
      },
      "ph-b": {
        "p": 0,
        "q": 0,
        "s": 0,
        "v": 0,
        "i": 0,
        "pf": 0,
        "f": 0
      },
      "ph-c": {
        "p": 0,
        "q": 0,
        "s": 0,
        "v": 0,
        "i": 0,
        "pf": 0,
        "f": 0
      }
    },
    "net-consumption": {
      "ph-a": {
        "p": -3195.826,
        "q": -686.842,
        "s": 3277.01,
        "v": 248.674,
        "i": 13.17,
        "pf": -0.98,
        "f": 50
      },
      "ph-b": {
        "p": 0,
        "q": 0,
        "s": 0,
        "v": 0,
        "i": 0,
        "pf": 0,
        "f": 0
      },
      "ph-c": {
        "p": 0,
        "q": 0,
        "s": 0,
        "v": 0,
        "i": 0,
        "pf": 0,
        "f": 0
      }
    },
    "total-consumption": {
      "ph-a": {
        "p": 425.776,
        "q": -992.546,
        "s": 351.08,
        "v": 248.663,
        "i": 1.412,
        "pf": 1,
        "f": 50
      },
      "ph-b": {
        "p": 0,
        "q": 0,
        "s": 0,
        "v": 0,
        "i": 0,
        "pf": 0,
        "f": 0
      },
      "ph-c": {
        "p": 0,
        "q": 0,
        "s": 0,
        "v": 0,
        "i": 0,
        "pf": 0,
        "f": 0
      }
    }
  }
}

My level of skills on Home Assistant are quite low - I know how to fix this in php or in a bash script but I’m struggling on how to fix it in Home Assistant - would I use a value template or something else?

Cheers

1 Like

Instead of focusing on trying to insert a missing character at the start, try figuring out how to ignore the string data: or the first 5 characters (6 including the space). The great news is that data: only appears once at the very beginning.

ive removed that string from the beginning of the JSON and your JSON is valid after that.

Screen Shot 2021-08-18 at 6.43.57 am

This approach might be easier as I feel that filtering a response is easier than modifying a response.

Maybe something like

sensor:
  platform: command_line
  command: curl ... | jq 

https://curl.se/docs/manual.html

https://stedolan.github.io/jq/manual/

1 Like

Thanks so much for the pointer @del13r - yes your suggestion to simply trim is a much better solution - I’ll investigate this now.

Thanks for that - I just did some testing too - I can’t use jq as it requires a properly formatted json input, however I haev had luck with sed

curl --anyauth -u installer:installerpassord --silent envoy.local/stream/meter --stderr - | sed 's/data://'

This strips the data: and leaves nicely formatted json as you predicted. I’m just about to create a sensor with this.

1 Like

maybe try adding ^ so that it only checks the start of the string and a space after data to be like this so it gets rid of the space

sed 's/^data: //'

even this first 6 character delete will work for what you are trying to do

sed 's/^......//'
1 Like

Not much luck - seems teh curl command fails

2021-08-18 14:17:47 ERROR (SyncWorker_1) [homeassistant.components.command_line] Timeout for command: curl --anyauth -u installer:Password --silent envoy/local/stream/meter --stderr - | sed 's/data: //'
2021-08-18 14:17:47 WARNING (SyncWorker_1) [homeassistant.components.command_line.sensor] Empty reply found when expecting JSON data

I noticed if I run that entire curl command from terminal within HA or another unix system that it sometimes runs and other times it doesn’t. Strange cause going to the url in a browser works 100% every time. I wonder if I need to fool it to think I’m accessing via a web-browser - I’ll check to see if curl allows this.

try removing --anyauth and test

and then try --digest
https://curl.se/docs/manpage.html#--digest

image

qop refers to digest

I’m still getting timeout when I try --digest, however from terminal it works 100% every time so that’s weird … I’m going to try a REST sensor instead of a command_line and see what happens

maybe try replacing envoy.local with static IP (I hope it is static) of envoy just incase its a dns issue

Yes I have that already - I change it to envoy.local when posting here to not confuse people with my internal ip … and of course rest: won’t work as I can’t use curl with that so I’m stumped

what is --stderr doing for you?
Also, have we confirmed sed is installed/available in home assistant?

I was looking at different online examples and saw that outputting to -stderr helps when piping commands so that the next command isn’t overloaded. I’ll try without it and see. sed seems to be installed - if I go to terminal within Home assistant I can run the command and it works fine. I assume of course that the terminal has the same environment that the sensors etc have?

Yeah, just troubleshooting and trying to eliminate the difference between why your terminal works but home assistant doesn’t.
I wasnt sure if your terminal testing was just trying the commands from another machine or the terminal of home assistant.
Perhaps try testing sed against the production.json as it doesnt have authentication it could be easier to test with before progressing to installer.json

image

image

Great idea to test against production.json - will try now

Interesting - connecting to production.json works, even with sed filter. … all I changed was the url … my fault finding continues

Not sure if you are aware or not, but there is an updated script to stream your production info

Have you tried perhaps reverse engineering his script and apply it to home assistant?

most importantly, he has excluded data: using

marker = b'data: '

fascinating script. Will probably save you some headaches.

Thanks for this extra data - I’ve created a script that can output the data nicely formatted, however for reasons unknown home assistant times out when trying to access it. So I’m currently experimenting with installing json-server on my Mac-mini which will then act as a middle man and serve the correctly formatted json into the json-server. In theory I should be able to connect directly to this, but I will see

1 Like

Sounds good. Interested to see how this goes

1 Like

Hey del13r

Wanted to say thank you for the tutorial above and the work in the whole post. It has helped me get the energy tab running and taught me some code. I can also run some separate meters that show immediately whether I am importing or exporting. (BTW I show -4watts at night)

I did want to check on the cost/payment figure. It seems to me that it is taking in time of day of use versus production, so the costs might be fairly accurate?

The longer version of the question is that if you produced 20kwh in a day and use 19kwh, in theory you imported no power and got paid for 1kwh. But that of course assumes you only used power when the sun was making it available. If you used 19kwr hours between midnight and 0600 you are paying the full rate for that (no sun) - let’s say 30c kwh. You then generated 20kwh and got paid 10cents/kwh, so you are out of pocket.

From what I can see it is taking the hourly totals and calculating in that basis, so the net cost should be reasonably close?

1 Like