Estimating Lithium-ion Battery Health

Introduction to Lithium-based batteries, their cycles characteristics and aging

Lithium-ion (or Li-ion) batteries are rechargeable batteries used for a variety of electronic devices, which range from eletric vehicles, smartphones, and even satellites.

However, despite their wide adoption, research isn't mature enough to avoid problems with battery health and safety, and given the ubiquity of consumer electronics using the technology, this has led to some poor outcomes that range from poor user-experience to public safety concerns (see, for example, the Samsung Galaxy Note 7 explosions from 2016).

Dataset

In this example of predictive maintenance, we propose a data-driven method to estimate the health of a battery using the Li-ion battery dataset released by NASA (csv).

This dataset includes information on Li-ion batteries over several charge and discharge cycles at room temperature. Charging was at a constant current (CC) at 1.5A until the battery voltage reached 4.2V and then continued in a constant voltage (CV) mode until the charge current dropped to 20mA. Discharge was at a constant current (CC) level of 2A until the battery voltage fell to 2.7V.

You can download the Jupyter notebook of this study here.

The dataset includes the following:

  • Voltage_measured: Battery's terminal voltage (Volts) for charging and discharging cycles
  • Current_measured: Battery's output current (Amps) for charging and discharging cycles
  • Temperature_measured: Battery temperature (degree Celsius)
  • Current_charge: Current measured at charger for charging cycles and at load for discharging cycles (Amps)
  • Voltage_charge: Voltage measured at charger for charging cycles and at load for discharging ones (Volts)
  • Start_time: Starting time of the cycle
  • Time: Time in seconds after the starting time for the cycle (seconds)
  • Capacity: Battery capacity (Ahr) for discharging until 2.7V. Battery capacity is the product of the current drawn from the battery (while the battery is able to supply the load) until its voltage drops lower than a certain value for each cell.

Initialization

This example uses the following version of VerticaPy:

In [1]:
import verticapy as vp
vp.__version__
Out[1]:
'0.9.0'

Connect to Vertica. This example uses an existing connection called "VerticaDSN." For details on how to create a connection, use see the connection tutorial.

In [2]:
vp.connect("VerticaDSN")

Before we import the data, we'll drop any existing schemas of the same name.

In [13]:
vp.drop("battery_data", method="schema")
vp.create_schema("battery_data", True)
Out[13]:
True

Since our data is in a .csv file, we'll injest it with read_csv().

In [15]:
battery5 = vp.read_csv("data/battery5_data.csv")

Understanding the Data

Let's examine our data. Here, we use vDataFrame.head() to retrieve the first five rows of the dataset.

In [16]:
display(battery5.head(5))
123
Voltage_measured
Float
123
Current_measured
Float
123
Temperature_measured
Float
123
Current_charge
Numeric(9,6)
123
Voltage_charge
Numeric(8,5)
123
Time
Float
Abc
type
Varchar(20)
📅
start_time
Timestamp
123
ambient_temp
Int
123
Capacity
Float
10.00336524422388181-0.0014957339000395823.3694339095750.00.0032.547charge2008-05-28 11:09:42.00004524[null]
20.236356184152679-0.0034844262761841423.37204750481210.00.0030.0charge2008-05-28 11:09:42.00004524[null]
32.45567932466456-2.0125901157714838.418742770556-1.99821.6853250.766discharge2008-04-05 22:46:35.000484241.8027776247196
42.47131476433413-2.0143889194729738.0765742576909-1.99821.6953270.922discharge2008-04-20 15:37:05.000280241.81396938871035
52.47244830185273-2.0092825187644138.4230398541122-1.99821.6843290.234discharge2008-04-04 09:57:19.000765241.82461955268645
Rows: 1-5 | Columns: 10

Let's perform a few aggregations with vDataFrame.describe() to get a high-level overview of the dataset.

In [17]:
battery5.describe()
Out[17]:
count
mean
std
min
approx_25%
approx_50%
approx_75%
max
"Voltage_measured"5914584.103945038382160.2134686704672740.003365244223881814.092153146510074.205141783239034.205903197728398.39314118056463
"Current_measured"5914580.3694043346408480.907557734956734-4.47965961959820.04296367296636270.1735766992393921.218539466848331.53130142697453
"Temperature_measured"59145826.36970063096272.7724244000932923.214801785728124.490373088316825.476333128955727.346736077890741.4502319190386
"Current_charge"5914580.6344756976826780.737028608855502-4.4680.0570.2611.4981.9984
"Voltage_charge"5914584.024930417713491.208825226982510.04.244.3054.6565.002
"Time"5914584763.856933565873147.859025807610.01927.865854922284492.690863673477535.173675075310807.328
"ambient_temp"59145824.00.024.024.024.024.024.0
"Capacity"502851.56034471765460.1823795278703871.287452522137941.386228767797831.538236598942561.746870617983791.85648742081816
Rows: 1-8 | Columns: 9

To get a better idea of the changes between each cycle, we look at an aggregation at their start time, duration, and voltage at the beginning and the end of each cycle.

In [18]:
battery5['start_time'].describe()
Out[18]:
value
name"start_time"
dtypetimestamp
count591458
min2008-04-02 13:08:17.000920
max2008-05-28 11:09:42.000045
Rows: 1-5 | Columns: 2

To see how the voltage changes during the cycle, we extract the initial and final voltage measurements for each cycle.

In [19]:
battery5.analytic(func="first_value",
                  columns="Voltage_measured",
                  by="start_time",
                  order_by={"Time":"asc"},
                  name="first_voltage_measured")

battery5.analytic(func="first_value",
                  columns="Voltage_measured",
                  by="start_time",
                  order_by={"Time":"desc"},
                  name="last_voltage_measured")

cycling_info = battery5.groupby(columns = ['start_time',
                                           'type',
                                           'first_voltage_measured',
                                           'last_voltage_measured'], 
                                expr = ["COUNT(*) AS nr_of_measurements",
                                        "MAX(Time) AS cycle_duration"]).sort('start_time')
cycling_info['cycle_id'] = "ROW_NUMBER() OVER(ORDER BY start_time)"
cycling_info
Out[19]:
📅
start_time
Datetime
Abc
type
Varchar(20)
123
first_voltage_measured
Float
123
last_voltage_measured
Float
123
nr_of_measurements
Integer
123
cycle_duration
Float
123
cycle_id
Integer
12008-04-02 13:08:17.000920charge3.8730172213014.1910775628027897597.8751
22008-04-02 15:25:41.000593discharge4.191491807505293.27716997682521973690.2342
32008-04-02 16:37:51.000984charge3.325054656844854.1890618410855194010516.03
42008-04-02 19:43:48.000405discharge4.189773213846613.300244887122251963672.3444
52008-04-02 20:55:40.000811charge3.352603659998784.1873982258061693710484.5475
62008-04-03 00:01:06.000687discharge4.18818673599133.327451009868631953651.6416
72008-04-03 01:12:38.000670charge3.378798976512954.1880549560742393310397.897
82008-04-03 04:16:37.000375discharge4.188461118855573.314181858907031943631.5638
92008-04-03 05:27:49.000125charge3.372870917439274.1884384309154193710495.2039
102008-04-03 08:33:25.000702discharge4.188298524761053.305496731286481943629.17210
112008-04-03 09:44:35.000078charge3.366774899409294.1886946835354595210792.67211
122008-04-03 12:55:10.000686discharge4.18881580794863.302329112973761953652.28112
132008-04-03 14:06:43.000234charge3.361035656604384.188638651396895210789.98513
142008-04-03 17:17:16.000015discharge4.188391637938793.29374066954991953650.82814
152008-04-03 18:28:47.000125charge3.353942647778254.1877086746418792010127.56215
162008-04-03 21:28:14.000718discharge4.188927891511963.316230740774151913572.45316
172008-04-03 22:38:27.000452charge3.386527224467544.1885126693926692110147.95317
182008-04-04 01:38:15.000217discharge4.189029250882123.297410935416151903550.59418
192008-04-04 02:48:06.000155charge3.37759546680984.1886422312887492110162.09419
202008-04-04 05:48:08.000609discharge4.189223427076423.288404483095291903551.2520
212008-04-04 06:58:00.000296charge3.371653071239994.1884991398290992010119.37521
222008-04-04 09:57:19.000765discharge4.188916055911243.266275575061471893530.2522
232008-04-04 11:06:50.000375charge3.361169507713134.1879485622144991310013.23523
242008-04-04 15:05:59.000905charge3.647842266057244.189108185681538979586.87524
252008-04-04 17:56:27.000609discharge4.189876247266323.296199859463091873491.01625
262008-04-04 19:05:19.000234charge3.391880207780124.18853685676099129952.35926
272008-04-04 22:01:54.000670discharge4.18928679476883.27175741553361863470.28127
282008-04-04 23:10:25.000420charge3.3810252523114.1892141386325395110758.03128
292008-04-05 02:20:26.000702discharge4.188837765892733.264855084085031863470.029
302008-04-05 03:28:57.000234charge3.375272107192294.188121217551759119921.7530
312008-04-05 06:25:01.000890discharge4.189110301768523.309111201518361853450.29731
322008-04-05 07:33:12.000734charge3.410781053861784.1885654447049291410000.2532
332008-04-05 10:30:32.000311discharge4.189212073040983.288149052868931843429.40733
342008-04-05 11:38:22.000140charge3.405082721309114.187420919333929119936.03134
352008-04-05 14:34:41.000468discharge4.188899969428113.260754100903531833409.48435
362008-04-05 15:42:11.000531charge3.396716679706654.188084604302349139989.53236
372008-04-05 18:39:25.000217discharge4.188779799856793.229466821784411823390.42237
382008-04-05 19:46:36.000125charge3.386943008500994.1890385293424192210158.78238
392008-04-05 22:46:35.000484discharge4.189272591516223.224378894859081823390.28139
402008-04-18 17:34:22.000890charge3.579549917938274.1882795478839693310289.31240
412008-04-18 21:10:19.000795discharge4.187614060563443.25874033216341923591.73441
422008-04-18 22:53:58.000343charge3.389085680145774.1880743483097492710283.07842
432008-04-19 02:29:09discharge4.18762878110843.218046214795761903552.29743
442008-04-19 04:12:06.000343charge3.380743064766384.1875905434737392410281.3944
452008-04-19 07:47:15.000702discharge4.187447226312933.257309626839771893531.57845
462008-04-19 09:29:52.000703charge3.412070285635064.1873633129068691410081.79746
472008-04-19 13:01:42.000561discharge4.187344026387163.280256747494591873492.90747
482008-04-19 14:43:41.000265charge3.436894873571874.1880820129211795010797.32848
492008-04-19 18:27:29.000827discharge4.187438187636333.279765451158691883511.59449
502008-04-19 20:09:47.000750charge3.431542312332484.1872539956451391610099.21850
512008-04-19 23:41:55.000686discharge4.187741381177993.205068915604991843431.9370000000151
522008-04-20 01:22:53.000953charge3.422833856716464.1877933464504691510078.71952
532008-04-20 04:54:41.000734discharge4.188261122540053.276866922356561843431.12553
542008-04-20 06:35:39.000765charge3.456980745548174.1882110168017294210617.37554
552008-04-20 10:16:28.000859discharge4.187338767288233.231130027730991833412.40655
562008-04-20 11:57:08.000765charge3.443131952235314.1880818825263393910564.15756
572008-04-20 15:37:05.000280discharge4.187560306288173.222025772526831833410.68857
582008-04-20 17:17:44.000030charge3.44094582238784.187938211684891810143.98458
592008-04-20 20:50:38.000920discharge4.188051762487133.290082793730791833410.71859
602008-04-20 22:31:18.000045charge3.472049220114074.1887522377346794910790.45360
612008-04-21 02:15:02.000921discharge4.187667484260543.251176185241491823392.71961
622008-04-21 17:51:26.000312charge3.482323938736564.1884126220303894110442.89162
632008-04-22 14:15:41.000186charge8.393141180564634.201935096732435821674.48463
642008-04-22 15:33:49.000875discharge4.201070177337873.249283482317553713470.67264
652008-04-22 17:04:53.000218charge3.405890143202774.20218728438283365910113.65665
662008-04-22 20:26:18.000920discharge4.199622334549583.260087599199013653414.10966
672008-04-22 21:56:21.000405charge3.450747729160214.20215882826111366610137.8967
682008-04-23 01:18:11.000795discharge4.199853323702163.281146601420843633395.21968
692008-04-23 02:47:55.000453charge3.477715920260944.20111410827477385010651.65769
702008-04-23 06:18:19.000920discharge4.199103467081433.309371520154763623386.070
712008-04-23 07:47:54.000718charge3.499765574702664.2027772821499362310032.48571
722008-04-23 11:08:00.000312discharge4.1999985368653.295594467656433603368.18772
732008-04-23 12:37:17.000515charge3.506969895111284.20136149792883381910574.29773
742008-04-23 16:06:25.000170discharge4.199675220998723.317198245350353603368.26674
752008-04-23 17:35:42.000828charge3.515679016850224.20127896701083378010461.73575
762008-04-23 21:02:58.000295discharge4.199184724880323.347818506503993593358.71976
772008-04-23 22:32:06.000671charge3.535634824082754.2021111720211736059993.0620000000177
782008-04-24 01:51:33.000890discharge4.2000124803353.337821923904863573339.578
792008-04-24 03:20:23.000359charge3.544135447281034.20114809274631382610602.28179
802008-04-24 06:50:00.000031discharge4.199237365654793.364372479379793563331.26580
812008-04-24 08:18:41.000703charge3.560236280744184.20106102920315384710667.96981
822008-04-24 11:49:24.000280discharge4.199395781118713.336014493650923553321.18882
832008-04-24 13:17:56.000250charge3.555356315220794.20109580259623378910504.78183
842008-04-24 16:45:56.000015discharge4.199578698026073.355659627946553553321.84484
852008-04-24 18:14:28.000937charge3.561078274872044.20157433593331369610246.78185
862008-04-24 21:38:11.000077discharge4.199546957512693.361490197711283543311.82886
872008-04-24 23:06:34.000155charge3.567581547144624.20145257180874366610166.21987
882008-04-25 12:03:44.000093discharge4.194091469340823.346968121975771793327.39188
892008-04-25 17:02:35.000703charge3.564808268019854.20113835250844390010804.92289
902008-04-25 20:03:55.000920discharge4.200715235801253.371210049221773543312.07890
912008-04-25 21:32:20.000468charge3.568077296760874.20069482424571388210758.98591
922008-04-26 01:04:35.000718discharge4.199098080718033.379951819113273523293.17292
932008-04-26 02:32:41.000093charge3.580462157726454.20144464421736371910317.51593
942008-04-26 05:57:35.000140discharge4.199398534411533.391867015789513503275.32894
952008-04-26 07:25:23.000030charge3.593352146996074.20069890818846389510805.73495
962008-04-26 10:58:25.000843discharge4.199122915612973.389321801243053493265.01696
972008-04-28 17:20:47.000859charge3.637556498781754.2017788304878735859946.39197
982008-04-29 12:15:56.000953discharge4.19040947808143.23996044347973563328.93798
992008-04-29 13:44:46.000545charge3.435745069757844.20225518963933364210063.54799
1002008-04-29 17:05:27.000780discharge4.199933846791873.311127639734913563329.266100
Rows: 1-100 | Columns: 7

We can see from the "duration" column that charging seems to take a longer time than discharging. Let's visualize this trend with an animated graph.

In [20]:
import warnings
warnings.filterwarnings('ignore')
cycling_info.animated(ts="start_time",
                      columns= ["type","cycle_duration"], 
                      by="type", 
                      kind="bar",)
Out[20]: