Updating Cells#
examples/cells/03_update.py#
"""
Example: Updating cell specifications, instances, and measurements.
This example demonstrates how to update existing cell data:
- Updating cell specification with nested component/material data
- Updating cell instance measured properties
- Updating measurement metadata
"""
from ionworks import Ionworks
client = Ionworks()
# Configuration - these should exist from running 01_create.py
cell_spec_name = "NCM622/Graphite Coin Cell"
# Resolve spec name -> spec id
specs = client.cell_spec.list()
spec = next((s for s in specs if s.name == cell_spec_name), None)
if spec is None:
raise RuntimeError(f"Cell spec name not found: {cell_spec_name}")
cell_spec_id = spec.id
print("=== UPDATING CELL SPECIFICATION ===\n")
# Update cell specification with nested component/material data
# Only provided fields will be updated - this is a partial update
updated_spec = client.cell_spec.update(
cell_spec_id,
{
# Update ratings
"ratings": {
"capacity": {"value": 0.0022, "unit": "A*h"}, # Updated capacity
"voltage_min": {"value": 2.5, "unit": "V"},
"voltage_max": {"value": 4.2, "unit": "V"},
"max_discharge_rate": {"value": 3, "unit": "C"}, # Updated max rate
},
# Update cathode component (material will be upserted)
"cathode": {
"properties": {
"diameter": {"value": 14, "unit": "mm"},
"thickness": {"value": 55, "unit": "um"}, # Updated thickness
"loading": {"value": 13.0, "unit": "mg/cm**2"}, # Updated loading
"porosity": {"value": 28, "unit": "percent"}, # Updated porosity
"binder": "PVDF",
"conductive_additive": "Carbon Black",
},
"material": {
"name": "NCM622",
"manufacturer": "BASF",
"definition": {
"formula": "LiNi0.6Co0.2Mn0.2O2",
"type": "layered_oxide",
"specific_capacity": {"value": 180, "unit": "mA*h/g"},
"tap_density": {"value": 2.5, "unit": "g/cm**3"}, # Added field
},
},
},
# Update source info
"source": {
"creator_name": "Battery Lab - Updated",
"creator_orcid": "0000-0001-2345-6789",
"publication_date": "2024-06-15",
"license": "CC-BY-4.0",
"doi": "10.1234/example.2024.001", # Added DOI
},
# Update notes
"notes": "Updated: Optimized cathode loading for improved rate capability",
},
)
print(f"Updated cell specification: {updated_spec.name}")
cap = updated_spec.ratings["capacity"]
print(f" New capacity: {cap['value']} {cap['unit']}")
max_rate = updated_spec.ratings["max_discharge_rate"]
print(f" New max discharge rate: {max_rate['value']} {max_rate['unit']}")
if updated_spec.cathode:
loading = updated_spec.cathode["properties"].get("loading")
if loading:
print(f" New cathode loading: {loading['value']} {loading['unit']}")
print(f" Notes: {updated_spec.notes}")
print("\n=== UPDATING CELL INSTANCE ===\n")
# Get instance by ID (use first instance for this example)
instances = client.cell_instance.list(cell_spec_id)
if not instances:
raise RuntimeError("No instances found for spec")
cell_instance_id = instances[0].id
# Update cell instance with new measured properties
updated_instance = client.cell_instance.update(
cell_instance_id,
{
# Update measured properties (as-built values from QC)
"measured_properties": {
"cathode": {
"loading": {"value": 12.8, "unit": "mg/cm**2"}, # Updated
"thickness": {"value": 54, "unit": "um"}, # Updated
"porosity": {"value": 29, "unit": "percent"}, # Added
},
"anode": {
"loading": {"value": 6.5, "unit": "mg/cm**2"},
"thickness": {"value": 45, "unit": "um"},
"porosity": {"value": 36, "unit": "percent"}, # Added
},
"cell": {
"initial_ocv": {"value": 3.05, "unit": "V"}, # Updated
"weight": {"value": 3.18, "unit": "g"}, # Updated
"initial_impedance": {"value": 15.2, "unit": "ohm"}, # Added
},
},
"notes": "Updated with post-rest OCV and impedance measurements",
},
)
print(f"Updated cell instance: {updated_instance.name}")
print(f" Notes: {updated_instance.notes}")
if updated_instance.measured_properties:
cell_props = updated_instance.measured_properties.get("cell", {})
if cell_props:
print(" Cell measurements:")
for prop_name, prop_value in cell_props.items():
if isinstance(prop_value, dict) and "value" in prop_value:
print(f" {prop_name}: {prop_value['value']} {prop_value['unit']}")
print("\n=== UPDATING CELL MEASUREMENT ===\n")
# Get measurement by ID (use first measurement for this example)
measurements = client.cell_measurement.list(cell_instance_id)
if not measurements:
raise RuntimeError("No measurements found for instance")
cell_measurement_id = measurements[0].id
# Update measurement metadata
updated_measurement = client.cell_measurement.update(
cell_measurement_id,
{
"protocol": {
"name": "CC-CV charge at C/10 to 4.2V (50mA cutoff), "
"CC discharge at C/10 to 2.5V",
"ambient_temperature_degc": 25.3, # More precise
},
"test_setup": {
"operator": "Jane Smith",
"lab": "Battery Research Lab - Building A",
},
"notes": "Formation cycle completed successfully - high coulombic efficiency",
},
)
print(f"Updated measurement: {updated_measurement.name}")
if updated_measurement.protocol:
print(f" Protocol: {updated_measurement.protocol.get('name')}")
if updated_measurement.protocol.get("ambient_temperature_degc"):
temp = updated_measurement.protocol["ambient_temperature_degc"]
print(f" Temperature: {temp} °C")
print(f" Notes: {updated_measurement.notes}")
print("\n=== Summary ===")
print("Successfully updated:")
print(f" - Cell Specification: {updated_spec.name}")
print(f" - Cell Instance: {updated_instance.name}")
print(f" - Measurement: {updated_measurement.name}")