jcallaghan / home-assistant-config

My Home Assistant configuration & documentation.
https://www.jcallaghan.com/
MIT License
173 stars 8 forks source link

Volvo on call integration 🚗 #78

Open jcallaghan opened 4 years ago

jcallaghan commented 4 years ago

Add the Volvo on call integration.

jcallaghan commented 4 years ago

Refresh interval

I've noticed the data in Home Assistant doesn't refresh that often (~ 60 minutes).

Within the code in GitHub for the integration I noticed interval = config[DOMAIN][CONF_SCAN_INTERVAL] that is used update calls.

I will try exploring if I can add something in the integration that sets the CONF_SCAN_INTERVAL variable.

jcallaghan commented 4 years ago

Boot and sunroof open missing

The integration exposes so much information about the state of the car. I've noticed that among the doors and windows the hood is included. I'm assuming this is what we would call the bonnet. I'm keen to explore if I am able to see if the boot or sunroof is open.

jcallaghan commented 4 years ago

Entity name obfuscation

The Volvo on-call integration #78 creates entities with the vehicle registration in the name. This makes sharing code that uses these entities difficult as I really don't want to share my vehicle registration so openly. Sorry. To avoid this I have mapped the entities I've used so far as !secrets to obfuscate my vehicle registration. I'm going to raise this as an issue as that is far from ideal. If I rename the entities then this could break if the integration updates and reverts the entities.

image

If I continue to use !secrets I need to be really disciplined in ensuring I create new secrets when required. I'd rather see a name/nickname referenced in the config that is used in the entity name.

Originally posted by @jcallaghan in https://github.com/jcallaghan/home-assistant-config/issues/77#issuecomment-640867673

jcallaghan commented 3 years ago

Remaining fuel range is incorrect Integration only supports metric values

The fuel range seems to be incorrect for me. For example sensor.x_range has a state of 17.6 miles whereas in the Volvo app I have a fuel range of 109 miles.

The sensor.x_fuel_consumption has a state of 0.96 L/mil and in the Volvo app I have 29.4 mpg with sensor.x_fuel_amount reporting I have 17 L of fuel left.

I think there is something wrong with the litre to gallon conversion (possibly US 0.26417205 vs. imperial gallon 0.21996915) or the mile/L conversion.

Template

I was able to correct this with a template but this is with an assumed average MPG rather than using the data from the integration.

Car fuel: {{ states('sensor.x_fuel_level') }}% ({{ states('sensor.x_range') }} miles)
* The fuel range does not appear to be coming through correctly.
If I use the fuel amount (L) and convert to gallons and then multiply by an average of 29.4 MPG I get the same reading as the car.
{{ ((states('sensor.x_fuel_amount') | int * 0.21996915) * 30) | round(1) }} miles.

This is the template output.

Car fuel: 24% (17.6 miles)
* The fuel range does not appear to be coming through correctly.
If I use the fuel amount (L) and convert to gallons and then multiply by an average of 29.4 MPG I get the same reading as the car.
112.2 miles.

Exploration

Let's break this down and see if we can see what is going on.

Existing data:

Fuel tank capacity = 15 imperial gallons or 70 litres 17 litres of fuel remaining via integration or 24.28%.

0.96 l/mile consumption via integration. 9.6 l/100km consumption via the app. 29.4 mpg consumption via the app

17.70 mile range via integration. 176 km range via the app. 109 miles range via the app.

Definitions:

Litre = 0.22 imperial gallon. Litre = 0.26 US gallon. US gallon = 3.78 liters Imperial gallon = 4.54 litres Mile = 1.6 kilometers

Convert l/mile to MPG

(0.96 l/mile * 10) = 9.6 l/100km Miles in 100km = 100km / 1.6mile = 62.5 miles 9.6 l/mile / 4.54 litres in an imperial gallon = 2.11 imperial gallons 62.5 miles / 2.11 imperial gallons = 29.62 MPG

Convert MPG to range

29.62 MPG * (17 litres of remaining fuel to gallons = 17 / 0.22 = 3.74) = 110.7 miles

https://www.youtube.com/watch?v=UaeXJTEVDhA was useful to understand the conversion process.

Conclusion

While I now know how to convert l/mile into MPG and was able to use templates to correct the data it turns out that my Volvo on call integration was using Scandinavian miles. This is standardised as 1 mil being 10 kilometres (6.2 miles). Disabling this leaves me in a position where I have KM for everything. This will be easier to convert but it would be nicer to convert the integration allow for imperial values (MPH, miles, MPG).

jcallaghan commented 3 years ago

Metric to Imperial conversation

The following entities have metric values. Create template sensors to convert these to imperial values until such a time when the integration provides them.

sensor.x_battery_range km to miles (mdi:ruler)
{{ ((states('sensor.x_battery_range') | int) / 1.6 ) | round(1) }}

sensor.x_range km to miles (mdi:ruler)
{{ ((states('sensor.x_range') | int) / 1.6 ) | round(1) }}

sensor.x_odometer km to miles (mdi:speedometer)
{{ ((states('sensor.x_odometer') | int) / 1.6 ) | round(1) }}

sensor.x_trip_meter_1 km to miles (mdi:speedometer)
{{ ((states('sensor.x_trip_meter_1') | int) / 1.6 ) | round(1) }}

sensor.x_trip_meter_2 km to miles (mdi:speedometer)
{{ ((states('sensor.x_trip_meter_2') | int) / 1.6 ) | round(1) }}

sensor.x_fuel_consumption L/100 km to MPG (mdi:gas-station)
{{ (62.5/((states('sensor.x_fuel_consumption') | float) / 4.54)) | round(1) }}

sensor.x_fuel_amount L to gallons (mdi:gas-station)
{{ ((states('sensor.x_fuel_amount') | int) * 0.22 ) | round(1) }}
derekcentrico commented 2 years ago

Metric to Imperial conversation

The following entities have metric values. Create template sensors to convert these to imperial values until such a time when the integration provides them.

sensor.x_battery_range km to miles (mdi:ruler)
{{ ((states('sensor.x_battery_range') | int) / 1.6 ) | round(1) }}

sensor.x_range km to miles (mdi:ruler)
{{ ((states('sensor.x_range') | int) / 1.6 ) | round(1) }}

sensor.x_odometer km to miles (mdi:speedometer)
{{ ((states('sensor.x_odometer') | int) / 1.6 ) | round(1) }}

sensor.x_trip_meter_1 km to miles (mdi:speedometer)
{{ ((states('sensor.x_trip_meter_1') | int) / 1.6 ) | round(1) }}

sensor.x_trip_meter_2 km to miles (mdi:speedometer)
{{ ((states('sensor.x_trip_meter_2') | int) / 1.6 ) | round(1) }}

sensor.x_fuel_consumption L/100 km to MPG (mdi:gas-station)
{{ (62.5/((states('sensor.x_fuel_consumption') | float) / 4.54)) | round(1) }}

sensor.x_fuel_amount L to gallons (mdi:gas-station)
{{ ((states('sensor.x_fuel_amount') | int) * 0.22 ) | round(1) }}

New to this and haven't done templates before. So, would this be dropped into the templates yaml and that's basically it?

Such as:

sensor:
  - name: Gas Left
    state: {{ (62.5/((states('sensor.x_fuel_consumption') | float) / 4.54)) | round(1) }}

Thanks.

jcallaghan commented 2 years ago

@derekcentrico. It depends on how your configuration is set up but each of those templates above should be created as template sensors and should look something like this.

platform: template
sensors:
  x_fuel_consumption_imperial:
    friendly_name_template: "x Fuel consumption"
    value_template: "{{ (62.5/((states('sensor.x_fuel_consumption') | float) / 4.54)) | round(1) }}"
    unit_of_measurement: 'MPG'
    icon_template: mdi:gas-station
JonLaliberte commented 1 year ago

Thanks @jcallaghan for all the maths...

Just wanted to share my full config (for converting to US imperial) if it helps anyone.

NOTE: I am using US Gallons here! What a mess :)

I'm using a separate file for template sensors, so in configuration.yaml I have template: !include template.yaml.

Then in template.yaml I have:

- sensor:
  - name: "Volvo XC90 Fuel Amount Imperial"
    unique_id: volvo_xc90_fuel_amount_imperial
    state: "{{ ((states('sensor.volvo_xc90_fuel_amount') | int) * 0.264 ) | round(1) }}"
    unit_of_measurement: 'gallons'
    icon: mdi:gas-station
  - name: "Volvo XC90 Range Imperial"
    unique_id: volvo_xc90_range_imperial
    state: "{{ ((states('sensor.volvo_xc90_range') | int) / 1.609344 ) | round(1) }}"
    unit_of_measurement: 'miles'
    icon: mdi:ruler
  - name: "Volvo XC90 Odometer Imperial"
    unique_id: volvo_xc90_odometer_imperial
    state: "{{ ((states('sensor.volvo_xc90_odometer') | int) / 1.609344 ) | round(1) }}"
    unit_of_measurement: 'miles'
    icon: mdi:speedometer
  - name: "Volvo XC90 Trip Meter 1 Imperial"
    unique_id: volvo_xc90_trip_meter_1_imperial
    state: "{{ ((states('sensor.volvo_xc90_trip_meter_1') | int) / 1.609344 ) | round(1) }}"
    unit_of_measurement: 'miles'
    icon: mdi:speedometer
  - name: "Volvo XC90 Trip Meter 2 Imperial"
    unique_id: volvo_xc90_trip_meter_2_imperial
    state: "{{ ((states('sensor.volvo_xc90_trip_meter_2') | int) / 1.609344 ) | round(1) }}"
    unit_of_measurement: 'miles'
    icon: mdi:speedometer
  - name: "Volvo XC90 Fuel Consumption Imperial"
    unique_id: volvo_xc90_fuel_consumption_imperial
    state: "{{ (62.1371/((states('sensor.volvo_xc90_fuel_consumption') | float) / 3.78541)) | round(1) }}"
    unit_of_measurement: 'MPG'
    icon: mdi:gas-station
  - name: "Volvo XC90 Average Speed Imperial"
    unique_id: volvo_xc90_average_speed_imperial
    state: "{{ ((states('sensor.volvo_xc90_average_speed') | int) / 1.609344 ) | round(1) }}"
    unit_of_measurement: 'MPH'
    icon: mdi:speedometer      

UPDATE (2023-01-27): Changed from 1.6 to 1.609344 for the KM to miles conversion - 1.6 was not precise enough and ended up being off by a few hundred miles on the odometer. Made the others more precise as well, just because.