Skip to content

Commit

Permalink
Merge pull request #11 from sftman18/add_http_proxy_support
Browse files Browse the repository at this point in the history
Adding support for TeslaBleHttpProxy
  • Loading branch information
sftman18 authored Aug 30, 2024
2 parents 5bb1b4a + be8d13e commit 0b5b330
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 3 deletions.
11 changes: 10 additions & 1 deletion PVCharge.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,17 @@

# Initialize classes
Energy = routines.PowerUsage()
Car = routines.TeslaCommands()
Messages = routines.MqttCallbacks()
if "ENABLE_TESLA_PROXY" in config:
if config["ENABLE_TESLA_PROXY"] == "True":
logging.debug("Using TeslaProxy")
Car = routines.TeslaProxy()
else:
logging.debug("Using TeslaCommands")
Car = routines.TeslaCommands()
else:
logging.debug("Using TeslaCommands")
Car = routines.TeslaCommands()

# Control loop variables
car_is_charging = False
Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ An adaptive charging controller for your Tesla, enabling you to direct excess so

## Requirements
- <a href="https://www.tesla.com/">Tesla vehicle</a>
- Configured <a href="https://github.com/teslamotors/vehicle-command">Tesla Vehicle Command SDK</a> environment with <a href="https://github.com/teslamotors/vehicle-command/tree/main/cmd/tesla-control">tesla-control</a> available
- Configured <a href="https://github.com/teslamotors/vehicle-command">Tesla Vehicle Command SDK</a> environment with <a href="https://github.com/teslamotors/vehicle-command/tree/main/cmd/tesla-control">tesla-control</a> available OR use the <a href="https://github.com/wimaha/TeslaBleHttpProxy">TeslaBleHttpProxy</a> (NEW!)
- <a href="https://github.com/teslamate-org/teslamate">TeslaMate</a>
- <a href="https://www.egauge.net">eGauge solar monitoring</a> with a CT on the charger circuit
- Linux computer with Bluetooth, such as a <a href="https://www.raspberrypi.com/products/raspberry-pi-zero-2-w/">Raspberry Pi Zero 2 W</a>
Expand All @@ -27,6 +27,12 @@ tesla-keygen -key-file /home/pi/.local/share/keyrings/private_key.pem create > p
While in the car, pair with this command:
tesla-control -ble add-key-request public_key.pem owner cloud_key</pre>

## TeslaBleHttpProxy
To use TeslaBleHttpProxy (not required if you are using <a href="https://github.com/teslamotors/vehicle-command/tree/main/cmd/tesla-control">tesla-control</a>), please follow the installation & configuration instructions <a href="https://github.com/wimaha/TeslaBleHttpProxy">here</a>
- Add the PROXY_HOST parameter to your .env file (see example.env)
- Enable use of the proxy by adding the ENABLE_TESLA_PROXY parameter to your config.toml file (see example_config.toml)<br>
- Note, when TeslaBleHttpProxy is running it seems to take over local bluetooth hardware. Please stop the proxy before switching back to the <a href="https://github.com/teslamotors/vehicle-command/tree/main/cmd/tesla-control">tesla-control</a> library.

## PVCharge Installation
- Install Python (3.11+) and Git using your package manager<br>
- Clone the repo <pre>git clone https://github.com/sftman18/PVCharge.git</pre>
Expand Down
3 changes: 3 additions & 0 deletions example.env
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ export TESLA_VIN='Tesla VIN'
export TESLA_KEY_FILE='private key location, i.e. /home/pi/.local/share/keyrings/private_key.pem'
TESLA_CONTROL_BIN='Tesla control bin location, i.e. /home/pi/go/bin/tesla-control'

#TeslaBleHttpProxy parameters (optional, enabled in config.toml)
PROXY_HOST='proxy local ip:8080'

#MQTT parameters
BROKER="local IP for your MQTT broker"
PORT="port to use, i.e. 1883"
Expand Down
1 change: 1 addition & 0 deletions example_config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
LOG_FILE = 'PVCharge.log' # Log file name to use
LOG_LEVEL = "INFO" # Default INFO, change to DEBUG to diagnose issues
PREVENT_NON_SOLAR_CHARGE = "False" # Default for after-hours charging, unless changed via MQTT
ENABLE_TESLA_PROXY = "False" # Optionally enable TeslaBleHttpProxy (requires additional parameter in .env, and a running proxy)

# MQTT Control topics
TOPIC_PREVENT_NON_SOLAR_CHARGE = "topic_base/prevent_non_solar_charge"
Expand Down
65 changes: 64 additions & 1 deletion routines.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import time
import logging
import tomllib
import requests
from dotenv import load_dotenv
from egauge import webapi
from egauge.webapi.device import Register, Local
Expand Down Expand Up @@ -129,6 +130,62 @@ def status_report(self, charge_tesla, charge_delay, sun_up, car_is_charging, new
return status


class TeslaProxy:
"""Class to send commands to TeslaBleHttpProxy"""
def __init__(self):
# Load parameters from .env
self.tesla_vin = os.getenv("TESLA_VIN")
self.tesla_proxy_host = os.getenv("PROXY_HOST")
# Test for existence of TeslaBleHttpProxy
if self.tesla_proxy_host == None:
logging.critical("PROXY_HOST not configured")
logging.critical("Please point to TeslaBleHttpProxy in .env")
sys.exit(1)
self.tesla_proxy_base_command = self.tesla_proxy_host + "/api/1/vehicles/" + self.tesla_vin + "/command/"

def set_charge_rate(self, charge_rate):
command = self.tesla_proxy_base_command + "set_charging_amps"
logging.debug(command)
data = {}
data["charging_amps"] = charge_rate
rc = call_http_post(command, data)
time.sleep(5)
return rc

def start_charging(self):
command = self.tesla_proxy_base_command + "charge_start"
logging.debug(command)
data = ""
return call_http_post(command, data)

def stop_charging(self):
command = self.tesla_proxy_base_command + "charge_stop"
logging.debug(command)
data = ""
rc = call_http_post(command, data)
time.sleep(5)
return rc

def wake(self):
command = self.tesla_proxy_base_command + "wake_up"
logging.debug(command)
data = ""
return call_http_post(command, data)


def call_http_post(cmd, data):
if data == "":
r = requests.post(url=cmd, data=data)
else:
r = requests.post(url=cmd, json=data)
if r.status_code == 200: # good return code
result = r.json()
logging.debug(result)
else:
logging.warning(result)
return result["response"]["result"]


class TeslaCommands:
"""Class to handle commands sent to Tesla Vehicle Command SDK"""
def __init__(self):
Expand Down Expand Up @@ -239,7 +296,13 @@ def __init__(self):
self.var_topic_teslamate_charge_limit_soc = 0
self.var_topic_teslamate_state = False

self.car_cmd = TeslaCommands()
if "ENABLE_TESLA_PROXY" in config:
if config["ENABLE_TESLA_PROXY"] == "True":
self.car_cmd = TeslaProxy()
else:
self.car_cmd = TeslaCommands()
else:
self.car_cmd = TeslaCommands()

self.client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=self.client_id, protocol=mqtt.MQTTv311,
clean_session=True)
Expand Down

0 comments on commit 0b5b330

Please sign in to comment.