Hare’s internal range estimates are waaaay off when towing. Roughly off by a factor of 2. Since we’d rather not get stuck because we’ve run out of batteries, we’ve been experimenting with other routing tools. One that comes highly recommended is A Better Route Planner. One key feature is that it lets you plan assuming different settings.
For our purposes, the most important is the Reference consumption. The Rivian dashboard displays the power consumption in mi/kWh. We found that it was typically around 0.80 while towing Tourtoise at highway speed, so that suggested 1000/0.80 = 1250 Wh/mi. Plugging that into the box resulted in pretty good agreement between what ABRP thought our charge was and what it actually was.
So. Pretty good estimate. Nice. Blog post over, right?
Hah.
The ABRP API
A Better Route Planner has the ability to use telemetry from your actual vehicle to improve the routing. Sadly, Rivian integration doesn’t exist (yet?). So let’s figure out how to send it data using the Telemetry API! You need to actually email the ABRP folks to get an API key, but they were quite obliging.
You’ll also want to generate a data token for your vehicle. Because I want to calibrate the consumption separately for Hare alone and Tourtoise and Hare together, I’ve created two vehicles and generated keys for each.
The Rivian API
Sadly, Rivian doesn’t expose a documented public API. But there is an API, and happily, some enterprising folks have done the work of figuring it out, which lets me import the data into Home Assistant as described in the Data Collection post.
The Glue
In Home Assistant’s configuration.yaml file, I added a template sensor to populate the telemetry data:
sensor:
- platform: template
sensors:
rivian_abrp_telemetry:
value_template: >
{
"utc":{{ utcnow().timestamp() | int}},
"soc":{{ states("sensor.rivian_energy_storage_charger_adjusted_soc") }},
"lat":{{ state_attr('device_tracker.rivian_telematics_gnss_position', 'latitude') }},
"lon":{{ state_attr('device_tracker.rivian_telematics_gnss_position', 'longitude') }},
"is_charging":{{ is_state('binary_sensor.rivian_energy_storage_charger_vehicle_charger_state', 'on') and 1 or 0 }},
"is_parked":{{ is_state('sensor.rivian_dynamics_propulsion_status_prndl', 'Park') and 1 or 0 }},
"odometer":{{ float(states('sensor.rivian_dynamics_odometer_value')) * 1.609 }},
"est_battery_range":{{ float(states('sensor.rivian_energy_storage_vehicle_energy_vehicle_range')) * 1.609 }},
"car_model":"rivian:r1s:20:135:other"
}
And a rest_command to actually post the data, with the right token based on whether it’s in Towing mode or not:
rest_command:
abrp_telemetry:
url: https://api.iternio.com/1/tlm/send
#url: http://localhost:8000/1/tlm/send
method: POST
headers:
authorization: "APIKEY <MY API KEY FROM THE EMAIL>"
content_type: 'application/json; charset=utf-8'
payload: >
{
"tlm":{{ states('sensor.rivian_abrp_telemetry') }},
"token":"{{ is_state('sensor.rivian_dynamics_modes_drive_mode', 'Towing') and '<TOKEN FOR TOURTOISE AND HARE>' or '<TOKEN FOR HARE>' }}"
}
To test this, I swapped in the localhost url line above and ran this handy little one-liner on my Home Assistant machine that pretended to be an HTTP server:
while true; do printf 'HTTP/1.1 200 OK\n' | nc -Nl 8000; done
This let me capture some samples of the data I’d send, which I then tested in Postman to make sure I got a success response.
Finally, I want to send data whenever Hare is either charging or moving (with a little grace period after it stops), so I set up an automation:
alias: ABRP Telemetry
description: "Send Rivian Telemetry to ABRP"
trigger:
- platform: time_pattern
seconds: /5
condition:
- condition: or
conditions:
- condition: state
entity_id: >-
binary_sensor.rivian_energy_storage_charger_status_vehicle_charger_status
state: "on"
- condition: state
entity_id: binary_sensor.rivian_use_state
state: "on"
- condition: not
conditions:
- condition: state
entity_id: binary_sensor.rivian_use_state
state: "off"
for:
hours: 0
minutes: 1
seconds: 0
action:
- service: rest_command.abrp_telemetry
data: {}
mode: single