Solar Batteries: How do you calculate SOC (Voltage in Percent)

I am wondering how a LiFePo4 Battery discharge curve could be configured in HA, so that the SOC (in Voltage/ Percent) can be calculated.

Dischage table for Lifepo4:

lifepo4-voltage-chart

The 24V Battery is 100% full at 27V, and 0% empty at 20V. Since the discharge curve isn’t linear, I am wondering how a sensor formula could look like?

Just add all the points to this:

Thanks Tom,

I have read the documentation and wonder if this is what I am looking for, probably since I do not understand this 100% yet.

I don’t want to change any of the voltage values, but basically have the percentages adapt to the non linear curve.

xLiFePO4-discharging.gif.pagespeed.ic.EQVEXWFoto

At the moment I am reading the SOC through a Shelly UNI (sensor.solarbattery_soc_adc). This sensor shouldn’t change, but the percentage sensor (sensor.solarbattery_soc_percent) should.

It is.

This replaces whatever config already you have for the percentage sensor.

compensation:
  solarbattery_soc_percent:
    source: sensor.solarbattery_soc_adc
    unit_of_measurement: '%'
    data_points:
      - [27.2, 100]
      - [26.8, 90]
      - [26.6, 80]
      - [26.4, 70]
      - [26.1, 50]
      - [26, 40]
      - [25.8, 30]
      - [25.6, 20]
      - [24, 10]
      - [20, 0]

Like this?

# Sensor for Battery SOC in Prozent v2
      - name: "Solarspeicher SOC (Prozent)"
        unique_id: "socv2"
        unit_of_measurement: '%'

compensation:
  solarspeicher_soc_prozent:
    source: sensor.solarspeicher_soc_adc
    unit_of_measurement: '%'
    data_points:
      - [27, 100]
      - [26.8, 99]
      - [26.6, 90]
      - [26.4, 70]
      - [26.26, 50]
      - [26.2, 40]
      - [25.8, 20]
      - [25.6, 10]
      - [21.6, 1]
      - [20, 0]

The values are for my battery.

Yes. It goes in your configuration.yaml file (not your sensors.yaml file) and you probably want to specify a degree of 6 instead of the default 1 (which will try to fit a straight line).

yes, I am doing all this in my configuration.yaml.

However, if I validate the yaml I am receiving errors so I didn’t apply any of these settings yet. Playing around with this in Templating does produce anything.

Do I need to attach the compensate statement somehow with the sensor definition? As I have it right now the code doesn’t work and the documentation isn’t clear about this too.

# Sensor für Batterie SOC in Prozent v2
  - sensor:
      - name: "Solarspeicher SOC (Prozent)"
        unique_id: socv2
        unit_of_measurement: '%'
        state:
        
compensation:
  solarspeicher_soc_prozent:
    source: sensor.solarspeicher_soc_adc
    unit_of_measurement: '%'
    degree: 6
    data_points:
      - [27, 100]
      - [26.8, 99]
      - [26.6, 90]
      - [26.4, 70]
      - [26.26, 50]
      - [26.2, 40]
      - [25.8, 20]
      - [25.6, 10]
      - [21.6, 1]
      - [20, 0]

You need to remove the existing sensor definition: the top six lines that you pasted above. The compensation filter replaces this altogether.

The compensation filter should be in configuration.yaml with compensation: not indented, fully left aligned.

You will need to restart your system once you have done this.

Assuming you meant “does not”, that’s because there are no templates in use here.

Thanks much Troon & Tom - this was to simple (once you get it of course :slight_smile: )

Working code I am using, so others can copy paste:
Note: This is for a 24V 100Ah Powerqueen LiFePo4 Battery.

compensation:
    solarbattery_soc_percent:
    unique_id: sollarbatterysocpercent
    source: sensor.solarbattery_soc_adc
    unit_of_measurement: '%'
    degree: 5
    data_points:     
       - [27, 100]
       - [26.8, 99]
       - [26.6, 90]
       - [26.4, 70] 
       - [26.2, 40]
       - [26.0, 30]
       - [25.8, 20]
       - [25.6, 10]
       - [21.6, 1]
       - [19, 0]

edit: changed degree to 5, since 6 gave me values above 100%, although the measured voltage was below 27V. Not sure if this has en effect, but for now the values make sense.

1 Like

I would love to develop a better SoC calculation.
Defining SoC from the battery voltage curve is not ideal, and I would prefer using a similar method as what Coulombmeter are using.
Using the actual battery bank capacity in Ah, define a Wh capacity (easy part), and monitor the Charge/Discharge Amps versus Voltage to define what’s actually left. Way more accurate and reliable.
I’ll start to work on that, maybe using Node-RED… I will post an update if I am successful!

FYI: You will need to take charge/discharge efficiency into account for that to be true. You never get as much out as you put in. It’s about 95% for Li and 80% for Pb. It will change as the battery ages though.

This is why your laptop has to do a full charge / discharge cycle every so often for calibration.

Efficiency = Full discharge Wh / Full Charge Wh.