EV Battery Health Score
How to use electric vehicle data to score the treatment of the battery
As published in https://dimo.zone/news/dimo-insights-3-ev-battery-health-score, EV driving data can be scored to indicate how the battery has been treated. Batteries that have been supercharged (charged at a level 3 charger) frequently, frequently have a state of charge (soc) outside of 20% to 80%, and frequently discharge the battery nearly all the way to 0% (depth of discharge, which is 1 - state of charge) will tend to reduce their full capacity faster than vehicles that are rarely supercharged, generally keep state of charge between 20% and 80% and the average depth of discharge is small.
Driving outside of 20% to 80% state of charge
For an example vehicle, using this code, we find that this vehicle is driven while under 20% state of charge for 3.5% of the total miles drive and driven while over 80% state of charge for 8.37% of the total miles.
gdf = gdf.sort_values('timestamp').reset_index(drop = True)
gdf['distance_added'] = gdf['odometer'].diff()
vals = []
for left, right in zip(np.arange(0,0.95,0.05), np.arange(0.05,0.951,0.05)):
vals.append(gdf['distance_added'].loc[(gdf['soc'] >= round(left,2)) & (gdf['soc'] < round(right,2))].sum())
vals.append(temp['distance_added'].loc[(temp['soc'] >= 0.95)].sum())
lst = []
lst += (['(' + str(round(left,2)) +', ' + str(round(right,2)) + ']' + '_all' for left, right in zip(np.arange(0,0.95,0.05), np.arange(0.05,0.951,0.05))])
lst.append('[0.95, 1.0]_all')
miles_with_charges = pd.DataFrame(columns = lst)
miles_with_charges.loc[0] = vals
pct_20_to_80 = 100* miles_with_charges[miles_with_charges.columns[4:16]].sum(axis = 1)[0] / miles_with_charges.sum(axis = 1)
pct_0_to_20 = 100* miles_with_charges[miles_with_charges.columns[0:4]].sum(axis = 1)[0] / miles_with_charges.sum(axis = 1)
pct_80_to_100 = 100* miles_with_charges[miles_with_charges.columns[16:]].sum(axis = 1)[0] / miles_with_charges.sum(axis = 1)


In this manner, we have quantified how frequently the vehicle is driven while under- and over-charged as a percentage of the total amount of driving.
Charging At Level 3 Chargers
In this code, range added serves as a proxy for energy added, because charger.power does not exist before June 2023, so many charging sessions will not have it. Further, the approximate range added per hour for a level 1 charger is assumed to be between 0 and 8 kilometers per hour, a level 2 charger is assumed to be between 8 and 60 kilometers per hour, and a level 3 charger is assumed to be 60 or more kilometers per hour.
For an example vehicle, the percent of range charged from level 3 chargers is 8.53% out of the total. This vehicle added 25814.09 kilometers from level 1 chargers, 4412.35 kilometers from level 2 chargers, and 2818.46 kilometers from level 3 chargers.
Depth of Discharge
Since every charging session is captured in charging_df, as above, the depth of discharge reached during vehicle operation is 1-soc when a charging session begins. For an example vehicle, the average depth of discharge is 59.85% (meaning the average soc when the vehicle begins to charge is 40.15%).
Creating a score
These four pieces of information about the electric vehicle's battery can be used to score the treatment of the battery, for example:
For an example vehicle with pct_0_to_20 = 3.50, pct_80_to_100 = 8.37, level_3_charging_pct = 8.53, and avg_dod_when_charging_starts_pct = 59.85, the vehicle's battery health score is 77.128, where 100 would indicate the best battery health score and 0 would indicate the worst possible battery health score.
Code Appendix
Last updated