vloschiavo / powerwall2

Tesla Powerwall 2 - Local Gateway API documentation
Apache License 2.0
288 stars 51 forks source link

Feature Proposal: Convert API documentation to OpenAPI spec #91

Closed vls29 closed 1 year ago

vls29 commented 1 year ago

Hi @vloschiavo, Everyone,

I'd like to propose an alternative way we could document the Tesla Powerwall APIs and that's using OpenAPI spec. I've put together an example here: https://vls29.github.io/powerwall2/openapi/ of a few endpoints. The files I've added for this example can be found in the openapi directory (https://github.com/vls29/powerwall2/tree/openapi/openapi) and I've enabled GitHub pages to deploy the repo content as a site.

What's worth looking at? post:/login/Basic just because I spent ages adding this one endpoint into OpenAPI spec :laughing: get:/meters and get:/meters/aggregates both of which use examples from @foogod. delete:/meters I've switched off the try it now button for all delete methods, hopefully for obvious reasons!

Pros

Cons

I still think there would be benefit to keeping the first couple of sections on the readme because there's infromation on how to call the API and use the GUI which sit outside API documentation.

Does anyone have any thoughts on whether this is an idea to progress with or abandon?

Regards vls29

* It took me a little bit of time to get this feature working as by default your browser will not receive the correct CORS headers back from the Powerwall. I have an nginx and HAProxy instance sitting in front of my Powerwall IP addresses (HAProxy load balances the two connections), so I was able to add in the relevant CORS response headers to nginx, but not sure how you could use the "try it out" feature directly against the Powerwall?

BJReplay commented 1 year ago

I have an nginx ... sitting in front of my Powerwall IP ... so I was able to add in the relevant CORS response headers to nginx

Can you share how you did this? I'd love to be able to try this out (I have my powerwall IP mapped to the powerwall hostname via my router's DHCP static lease table, and I also have a nginx proxy on my network reverse proxying some other hosts.

I think this is great - I looked at the login/Basic section, and could see that if a customer login was set up by the installer (as was the case for me) the login parameters / instructions appear to be different, so adding this to the main project (and if @vloschiavo is up for accepting pull requests for a branch to work on this) would allow for this to be worked on over time.

So, in summary, I think it is a great idea to progress. I don't spend a lot of time now - as my code-base is relatively stable - but this repo is still my main reference, and I'd be happy to contribute where I can.

vls29 commented 1 year ago

Hi @BJReplay,

"Can you share how you did this" yes certainly:

# upgrade all http requests to https
server {
  listen              80;
  server_name         powerwall.example.co.uk;
  return              301 https://powerwall.example.co.uk$request_uri;
}

server {
  listen              443 ssl;
  server_name         powerwall.example.co.uk;
  ssl_certificate     /certbot/example.co.uk/fullchain.pem;
  ssl_certificate_key /certbot/example.co.uk/privkey.pem;

  location / {
    if ($request_method = OPTIONS ) {
        # if the example I've created is forked, you would need to change the below github address to your username
        add_header 'Access-Control-Allow-Origin' "https://vls29.github.io" always;
        add_header 'Access-Control-Allow-Headers' "authorization, content-type" always;
        return 200;
    }
    # this ip address is the address of the same server running this nginx docker container but port 12345 corresponds to the HAProxy container
    proxy_pass        https://192.168.0.XX:12345;
    add_header 'Access-Control-Allow-Origin' "https://vls29.github.io" always;
  }
}

and in case you're interested in the haproxy conf:

global
    ca-base /etc/ssl/example.co.uk
    crt-base /etc/ssl/example.co.uk
    ssl-default-bind-options ssl-min-ver TLSv1.2

frontend localnodes
    bind *:443 ssl crt /etc/ssl/example.co.uk/fullchain.pem
    mode http
    default_backend nodes

backend nodes
    mode http
    balance roundrobin
    option httpchk
    timeout check 10
    server ethernet 192.168.0.YY:443 check check-ssl ssl verify none
    server wifi     192.168.0.ZZ:443 check check-ssl ssl verify none

listen stats
    bind *:1936
    mode http
    stats enable
    stats hide-version
    stats realm Haproxy\ Statistics
    stats uri /
    stats auth Username:Password

powerwall swagger try it now

Although it looks in the image attached as if this is accessible from the internet, it's definately not - I'm just using a real domain name for internal services and making use of letsencrypt certificates so that internal services don't display a certificate warning in the browser.

BJReplay commented 1 year ago

Although it looks in the image attached as if this is accessible from the internet, it's definately not - I'm just using a real domain name for internal services and making use of letsencrypt certificates

Yep, that all makes sense - I have a similar setup for my router at https://router.example.com.au and scanner at https://scanner.example.com.au, again with letsencrypt certificates, and dns entries so that I can use DNS verification for letsencrypt rather than opening up 443 and 80 in the firewall.

vloschiavo commented 1 year ago

I am 100% in support of this!

@vls29, I've sent you an invite to be a contributor.

@BJReplay - pull requests are encouraged! :)