OpenEVSE / openevse_esp32_firmware

OpenEVSE V4 WiFi gateway using ESP32
167 stars 110 forks source link

Add Support for Tesla Energy Gateway 2 Powerwall/Solar #120

Open chris1howell opened 3 years ago

chris1howell commented 3 years ago

Add support for Tesla Gateway 2 as a Solar Diversion Input. Add section in services tab to enter Tesla Gateway 2 IP address and save to EEPROM. Publish to MQTT base_topic/powerwall/

Powerwall Gateway 2 uses an IP on the local network with self signed https: portal.

HTTP get to:

/api/system_status/soe provides the current state of charge of Powerwall battery in JSON. {"percentage":86.01886315180862}

/api/meters/aggregates provides metering data in JSON (below) from Utility (site), Powerwall Batteries, Solar and Total Loads. The following JSON should be parsed by OpenEVSE WiFi:

/api/systemstatus/soe "percentage"_

/api/meters/aggregates _"site":"instant_power" "battery":"instant_power" "battery":"instant_average_voltage" "battery":"frequency" "solar":"instant_power" "load":"instantpower"

Publish to MQTT base_topic/powerwall/soe base_topic/powerwall/sitePower base_topic/powerwall/solarPower base_topic/powerwall/batteryPower base_topic/powerwall/loadPower base_topic/powerwall/voltage base_topic/powerwall/frequency

{
"site":{
"last_communication_time":"2020-10-05T05:36:09.690481386-07:00",
"instant_power":3,
"instant_reactive_power":-96,
"instant_apparent_power":96.04686356149273,
"frequency":0,
"energy_exported":3671,
"energy_imported":163167,
"instant_average_voltage":214.5664540416325,
"instant_total_current":11.52,
"i_a_current":0,
"i_b_current":0,
"i_c_current":0,
"timeout":1500000000
},
"battery":{
"last_communication_time":"2020-10-05T05:36:09.690303397-07:00",
"instant_power":-1350,
"instant_reactive_power":-40,
"instant_apparent_power":1350.5924625881785,
"frequency":59.987,
"energy_exported":61300,
"energy_imported":87260,
"instant_average_voltage":248.45000000000002,
"instant_total_current":25.6,
"i_a_current":0,
"i_b_current":0,
"i_c_current":0,
"timeout":1500000000
},
"load":{
"last_communication_time":"2020-10-05T05:36:09.690303397-07:00",
"instant_power":836.9999999999998,
"instant_reactive_power":-41.5,
"instant_apparent_power":838.0281916498989,
"frequency":0,
"energy_exported":0,
"energy_imported":173334,
"instant_average_voltage":214.5664540416325,
"instant_total_current":3.9008893712602246,
"i_a_current":0,
"i_b_current":0,
"i_c_current":0,
"timeout":1500000000
},
"solar":{
"last_communication_time":"2020-10-05T05:36:09.690721122-07:00",
"instant_power":2176,
"instant_reactive_power":80,
"instant_apparent_power":2177.4700916430515,
"frequency":0,
"energy_exported":39846,
"energy_imported":48,
"instant_average_voltage":214.5491335335568,
"instant_total_current":8.85,
"i_a_current":0,
"i_b_current":0,
"i_c_current":0,
"timeout":1500000000
}
}
chris1howell commented 3 years ago

Example in Python

import time
import requests
import json
import paho.mqtt.client as mqtt
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

powerwall_ip = "192.168.50.2"  # local IP address for powerwall garteway

mqtt_broker = ""               #MQTT broker
mqtt_port = 8883              #MQTT port standard 1883 or 8883
mqtt_user = ""                  #MQTT username
mqtt_password = ""          #MQTT password
mqtt_topic = "powerwall"   #MQTT base topic

baseline_load = 800 

def on_connect(client, userdata, flags, rc):     # Setup for MQTT connection
    if rc==0:
        client.connected_flag=True 
    else:
        print("Bad connection Returned code=",rc)
mqtt.Client.connected_flag=False 

client = mqtt.Client('openevse') 
client.username_pw_set(username = mqtt_user,password = mqtt_password)    #For MQTT connections with username and passrord
client.on_connect=on_connect  
client.connect(mqtt_broker, mqtt_port)
client.loop_start()

print("Connecting to broker ",mqtt_broker)
client.connect(mqtt_broker)     
while not client.connected_flag: 
    time.sleep(1)
while client.connected_flag:
    soe = requests.get('https://' + powerwall_ip + '/api/system_status/soe', verify=False)       #HTTP GET /api/system_status/soe
    meters = requests.get('https://' + powerwall_ip + '/api/meters/aggregates', verify=False)  #HTTP GET /api/meters/aggregates

    soe.json()
    soe_json = json.loads(soe.text)                 #parse JSON
    meters.json()
    meters_json = json.loads(meters.text)       # parse JSON

    site_json = meters_json["site"]                #Extract site JSON
    battery_json = meters_json["battery"]      #Extract battery JSON
    load_json = meters_json["load"]               #Extract load JSON
    solar_json = meters_json["solar"]           #Extract solar JSON

    battery_soe = soe_json["percentage"]
    site_power = site_json["instant_power"]
    battery_power = battery_json["instant_power"]
    battery_voltage = battery_json["instant_average_voltage"]
    battery_freq = battery_json["frequency"]
    load_power = load_json["instant_power"]
    solar_power = solar_json["instant_power"]

    ret= client.publish(mqtt_topic +"soe", battery_soe)
    ret= client.publish(mqtt_topic +"sitePower", site_power)
    ret= client.publish(mqtt_topic +"batteryPower", battery_power)
    ret= client.publish(mqtt_topic +"loadPower", load_power)
    ret= client.publish(mqtt_topic +"solarPower", solar_power)
    ret= client.publish(mqtt_topic +"voltage", battery_voltage)
    ret= client.publish(mqtt_topic +"frequency", battery_freq)
    print ("Published to MQTT")
    print ()
    time.sleep(5)

client.loop_stop()    #Stop loop 
client.disconnect() # disconnect
chris1howell commented 3 years ago

Tesla Energy Gateway Firmware version 20.49.0 broke HTTP get without authentication to:

/api/system_status/soe /api/meters/aggregates

Now TWG_PASSWORD is needed in addition to the TEG_IP Address.

POST to https://TEG_IP/api/login/Basic with JSON: {"username": "customer", "password": "TEG_PASSWORD"}.

This should return two Set-Cookie headers (AuthCookie, UserRecord). Include these cookies when calling TEG API (e.g., /api/meters/aggregates)

chris1howell commented 3 years ago

Here is a working Python Example with the new authentication.

https://github.com/OpenEVSE/Solar_MQTT/blob/main/Tesla%20Energy%20Gateway/Tesla_Energy_Gateway_mqtt.py